#include #include #include #include "pso/macros.h" #include "pso/TArray.h" #include "pso/TObject.h" #include "pso/TSocket.h" #include "pso/TTcpSocket.h" OBJECT_NAME(TTcpSocket); TTcpSocket *tcp_socket_table[16] = {nullptr}; struct send_buffs { short len; u8 *buff; }; short tcp_abort(short nh); short tcp_delete(short nh); 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(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() { } void some_stub() {} int 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() { } short tcp_abort(short nh) {} short tcp_delete(short nh) {} 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) {}