diff options
Diffstat (limited to 'src/pso')
-rw-r--r-- | src/pso/TTcpSocket.cpp | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/src/pso/TTcpSocket.cpp b/src/pso/TTcpSocket.cpp new file mode 100644 index 0000000..71bdd99 --- /dev/null +++ b/src/pso/TTcpSocket.cpp @@ -0,0 +1,181 @@ +#include <global_types.h> +#include <stdio.h> +#include <string.h> +#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<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() { + +} + +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) {} |