#include <global_types.h>
#include <stdio.h>
#include <string.h>
#include "pso/macros.h"
#include "pso/TArray.h"
#include "pso/TMainTask.h"
#include "pso/TObject.h"
#include "pso/TSocket.h"
#include "pso/TTcpSocket.h"
OBJECT_NAME(TTcpSocket);
TTcpSocket *tcp_socket_table[16] = {nullptr};
struct at_ip4_opt {
u8 ttl;
u8 svctype;
u8 df_flag;
};
struct at_ip6_opt {
u8 traffic_class;
u32 flow_label;
u8 hop_limit;
};
struct at_ip_option {
u32 type;
union {
struct at_ip6_opt ip6;
struct at_ip4_opt ip4;
} ip46;
};
struct at_ip_addr {
u32 type;
union {
u8 ip6[16];
u32 ip4;
} ip46;
};
struct send_buffs {
short len;
u8 *buff;
};
void func_80019aa0();
void controller_stuff();
char func_801a5d1c();
void render_tick();
void func_803d96a4();
short tcp_abort(short nh);
short tcp_bind(short nh, struct at_ip_addr *addr, u16 port);
short tcp_connect(short nh, struct at_ip_addr *addr, u16 port, struct at_ip_option *option);
short tcp_create();
short tcp_delete(short nh);
short tcp_get_opt(short nh, short type, u32 *opt);
short tcp_send(short nh, void (*notify)(short size, short sock_fd), char bufnum, struct send_buffs *sb);
short tcp_stat(short nh, short *stat, short *backlog, u32 *sendwin, u32 *recvwin);
short tcp_receive(short nh, void (*notify)(short size, short sock_fd), short len, u8 *buf);
int get_link_status();
char *get_sock_status_name(short code);
WEAK_FUNC TTcpSocket::TTcpSocket(TObject *parent) : TSocket(parent) {
set_name(TTcpSocket_name);
}
TTcpSocket::~TTcpSocket() {
close();
}
void TTcpSocket::recv() {
if (sock_fd() != -1) {
packet_buffer().fill(0);
set_buffer_cleared(true);
(int)tcp_receive(sock_fd(), notify, packet_buffer().size(), packet_buffer().data());
}
}
void TTcpSocket::notify(short size, short sock_fd) {
char tmp_str[64];
TTcpSocket *socket = tcp_socket_table[sock_fd];
if (socket != nullptr) {
if (size > 0) {
socket->set_buffer_cleared(false);
socket->set_size(size);
socket->set_buffer_offset(0);
sprintf(tmp_str, "Rcv:%d byte", size);
socket->log(tmp_str);
if (socket->callback() != nullptr) {
socket->callback()(socket);
}
} else {
socket->set_flags(1);
}
}
}
int TTcpSocket::send(u8 *data, size_t size) {
if (sock_fd() != -1) {
if (!m_is_encrypted) {
m_send_crypt.encrypt(data, size);
}
const s8 flags = sock_flags();
if (flags || !get_link_status()) {
return -1;
} else {
if (int status = stat()) {
log(get_sock_status_name(status));
set_flags(1);
return 1;
} else {
if (send_window() <= size) {
set_flags(1);
return 1;
} else {
if (stat_val() < 0) {
set_flags(1);
return 1;
} else {
struct send_buffs sb;
sb.buff = data;
sb.len = size;
set_unused(0);
int ret = tcp_send(sock_fd(), nullptr, 1, &sb);
if (ret >= 1 || ret < -1) {
set_flags(1);
log(get_sock_status_name(ret));
close();
return ret;
}
}
}
}
}
} else {
return -1;
}
}
short TTcpSocket::send(u8 *data) {
if (sock_fd() != -1) {
const s8 flags = sock_flags();
if (flags || !get_link_status()) {
return -1;
} else {
if (short status = stat()) {
log(get_sock_status_name(status));
set_flags(1);
return 1;
} else {
if (stat_val() < 0) {
set_flags(1);
return 1;
} else {
s8 len = strlen(reinterpret_cast<const char *>(data));
struct send_buffs sb;
sb.buff = data;
sb.len = len;
if (send_window() <= len) {
set_flags(1);
return 1;
} else {
short ret = tcp_send(sock_fd(), nullptr, 1, &sb);
if (ret) {
close();
}
return ret;
}
}
}
}
} else {
return -1;
}
}
int TTcpSocket::test_connection() {
for (int i = 0; i < 1800; ++i) {
if (int status = stat()) {
log(get_sock_status_name(status));
set_flags(1);
return 1;
} else if (send_window() <= 128) {
set_flags(1);
return 1;
} else if (stat_val() < 0) {
set_flags(1);
return 1;
} else if (!get_link_status()) {
set_flags(1);
return 1;
} else if (send_window() > 4095) {
return 0;
} else {
main_task.some_empty_func();
main_task.run_tl_camera_tasks();
main_task.render();
main_task.render_screen_overlay();
func_80019aa0();
render_tick();
}
}
set_flags(1);
return 1;
}
void TTcpSocket::some_stub() {}
short TTcpSocket::stat() {
if (sock_fd() != -1) {
return tcp_stat(sock_fd(), &stat_val(), nullptr, &send_window(), &recv_window());
} else {
return 0;
}
}
short TTcpSocket::close() {
if (sock_fd() != -1) {
(short)tcp_abort(sock_fd());
(short)tcp_delete(sock_fd());
tcp_socket_table[sock_fd()] = nullptr;
set_sock_fd(-1);
m_is_encrypted = 0;
set_size(0);
set_buffer_offset(0);
set_buffer_cleared(true);
}
return sock_fd();
}
short TTcpSocket::open() {
set_sock_fd(-1);
m_is_encrypted = 0;
set_size(0);
set_buffer_offset(0);
set_buffer_cleared(true);
set_unused(0);
set_sock_fd(tcp_create());
if (sock_fd() < 0) {
log(get_sock_status_name(sock_fd()));
return -1;
} else {
struct at_ip_option connect_option;
struct at_ip_addr connect_addr;
struct at_ip_addr bind_addr;
u32 opt = 1;
tcp_get_opt(sock_fd(), 0x2001, &opt);
bind_addr.type = 4;
bind_addr.ip46.ip4 = 0;
tcp_bind(sock_fd(), &bind_addr, src_port());
connect_addr.type = 4;
connect_addr.ip46.ip4 = dst_addr().addr;
connect_option.type = 4;
connect_option.ip46.ip4.ttl = 120;
connect_option.ip46.ip4.svctype = 0;
connect_option.ip46.ip4.df_flag = 0;
if (tcp_connect(sock_fd(), &connect_addr, dst_port(), &connect_option)) {
log(get_sock_status_name(sock_fd()));
return -1;
} else {
for (;;) {
func_803d96a4();
controller_stuff();
if (short status = stat()) {
log(get_sock_status_name(status));
return -2;
} else if (stat_val() < 0) {
return -2;
} else {
some_stub();
if (stat_val() < 4) {
if (!get_link_status()) {
return -3;
} else if (func_801a5d1c()) {
return -2;
} else {
main_task.some_empty_func();
main_task.run_tl_camera_tasks();
main_task.render();
main_task.render_screen_overlay();
func_80019aa0();
render_tick();
}
} else {
tcp_socket_table[sock_fd()] = this;
return sock_fd();
}
}
}
}
}
}
void func_80019aa0() {}
void controller_stuff() {}
char func_801a5d1c() {}
void render_tick() {}
void func_803d96a4() {}
short tcp_abort(short nh) {}
short tcp_bind(short nh, struct at_ip_addr *addr, u16 port) {}
short tcp_connect(short nh, struct at_ip_addr *addr, u16 port, struct at_ip_option *option) {}
short tcp_create() {}
short tcp_delete(short nh) {}
short tcp_get_opt(short nh, short type, u32 *opt) {}
short tcp_send(short nh, void (*notify)(short size, short sock_fd), char bufnum, struct send_buffs *sb) {}
short tcp_stat(short nh, short *stat, short *backlog, u32 *sendwin, u32 *recvwin) {}
short tcp_receive(short nh, void (*notify)(short size, short sock_fd), short len, u8 *buf) {}
int get_link_status() {}
char *get_sock_status_name(short code) {}