summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--context.h190
-rw-r--r--include/pso/TTcpSocket.h41
-rw-r--r--include/pso/forward.h2
-rw-r--r--obj_files.mk1
-rw-r--r--src/pso/TTcpSocket.cpp181
5 files changed, 341 insertions, 74 deletions
diff --git a/context.h b/context.h
index 52f9bb8..8851136 100644
--- a/context.h
+++ b/context.h
@@ -88,6 +88,7 @@ typedef long ptrdiff_t;
#define FOREACH_NODE_NODECL_MULTI_ITER(type, first, varname, ...) for (varname = (type *)(first); varname != NULL; varname = (type *)(varname->next()), __VA_ARGS__)
#define __packed__
+#define WEAK_FUNC __declspec(weak)
#define PRIVATE_MEMBER_GETTER(type, name) \
type name() { \
@@ -118,6 +119,14 @@ typedef long ptrdiff_t;
PRIVATE_MEMBER_GETTER(type, name); \
PRIVATE_MEMBER_SETTER(type, name)
+#define PRIVATE_MEMBER_ACCESSORS(type, name) \
+ PRIVATE_MEMBER_GETTER(type &, name); \
+ PRIVATE_MEMBER_SETTER(type, name)
+
+#define PRIVATE_MEMBER_ACCESSORS_NON_REF(type, name) \
+ PRIVATE_MEMBER_GETTER(type, name); \
+ PRIVATE_MEMBER_SETTER(type, name)
+
#define PRIVATE_MEMBER_ACCESSORS_ARRAY(type, name, size) \
PRIVATE_MEMBER_GETTER_ARRAY(type, name, size)
@@ -148,6 +157,9 @@ typedef long ptrdiff_t;
// pso/forward.h
// Class forward.
+class TTcpSocket;
+class PSOV3EncryptionTCP;
+class TSocket;
class THeap;
class TObject;
class TMainTask;
@@ -434,8 +446,12 @@ TMenuListEntry<T> &TMenuListEntry<T>::operator=(const TMenuListEntry<T> &src) {
// Const defs.
static const int tl_object_count = 20;
-// TObject.cpp
+// TTcpSocket.cpp
// Extern defs.
+EXTERN_OBJECT_NAME(TTcpSocket);
+extern TTcpSocket *tcp_socket_table[16];
+
+// TObject.cpp
#define o(name) extern const char *name##_name;
OBJECT_NAMES
#undef o
@@ -568,77 +584,6 @@ private:
u32 m_seed;
};
-// pso/TSocket.h
-class TSocket : public TObject {
-private:
- void set_flags(u8 flags) {
- m_sock_flags |= flags;
- };
-
- void clear_flags(u8 flags) {
- m_sock_flags &= ~flags;
- };
-
- void toggle_flags(u8 flags) {
- m_sock_flags ^= flags;
- };
-
- u8 get_flags(u8 flags) {
- return m_sock_flags & flags;
- };
-
- ipv4_addr m_dst_addr;
- u16 m_dst_port;
- u16 m_src_port;
- ipv4_addr m_src_addr;
- s16 m_sock_fd;
- u8 m_sock_flags;
- bool m_buffer_cleared;
- s16 m_size;
- s16 m_buffer_offset;
- u32 m_unused;
- TArray<u8, 64> m_unused2;
- TArray<u8, 2048> m_packet_buffer;
- s16 m_stat;
- u16 m_unused3;
- u32 m_send_window;
- u32 m_recv_window;
- void (*m_callback)(TSocket *socket);
-public:
- TSocket(TObject *parent);
- virtual ~TSocket();
-
- virtual int open() = 0;
- virtual int close() = 0;
- virtual void recv() = 0;
- virtual int send(u8 *data) = 0;
- virtual int send(u8 *data, size_t size) = 0;
-
- int resolve_domain(char *domain);
- void set_ip_address(u32 addr);
- void set_port(u32 port);
- const u8 next();
- int is_empty();
-
- PRIVATE_MEMBER_ACCESSORS(ipv4_addr, dst_addr);
- PRIVATE_MEMBER_ACCESSORS(u16, dst_port);
- PRIVATE_MEMBER_ACCESSORS(u16, src_port);
- PRIVATE_MEMBER_ACCESSORS(ipv4_addr, src_addr);
- PRIVATE_MEMBER_ACCESSORS(s16, sock_fd);
- PRIVATE_MEMBER_ACCESSORS(u8, sock_flags);
- PRIVATE_MEMBER_ACCESSORS(bool, buffer_cleared);
- PRIVATE_MEMBER_ACCESSORS(s16, size);
- PRIVATE_MEMBER_ACCESSORS(s16, buffer_offset);
- PRIVATE_MEMBER_ACCESSORS(u32, unused);
- PRIVATE_MEMBER_ACCESSORS_ARRAY(u8, unused2, 64);
- PRIVATE_MEMBER_ACCESSORS_ARRAY(u8, packet_buffer, 2048);
- PRIVATE_MEMBER_ACCESSORS(s16, stat);
- PRIVATE_MEMBER_ACCESSORS(u16, unused3);
- PRIVATE_MEMBER_ACCESSORS(u32, send_window);
- PRIVATE_MEMBER_ACCESSORS(u32, recv_window);
- PRIVATE_MEMBER_ACCESSORS_FUNC(void, callback, TSocket *socket);
-};
-
// pso/THeap.h
class THeap {
public:
@@ -798,6 +743,103 @@ public:
bool toggle_flag_9_if_flag_10_is_clear();
};
+// pso/TSocket.h
+class TSocket : public TObject {
+private:
+ ipv4_addr m_dst_addr;
+ u16 m_dst_port;
+ u16 m_src_port;
+ ipv4_addr m_src_addr;
+ s16 m_sock_fd;
+ u8 m_sock_flags;
+ bool m_buffer_cleared;
+ s16 m_size;
+ s16 m_buffer_offset;
+ u32 m_unused;
+ TArray<u8, 64> m_unused2;
+ TArray<u8, 2048> m_packet_buffer;
+ s16 m_stat_val;
+ u16 m_unused3;
+ u32 m_send_window;
+ u32 m_recv_window;
+ void (*m_callback)(TSocket *socket);
+public:
+ TSocket(TObject *parent);
+ virtual ~TSocket();
+
+ virtual short open() = 0;
+ virtual short close() = 0;
+ virtual void recv() = 0;
+ virtual short send(u8 *data) = 0;
+ virtual int send(u8 *data, size_t size) = 0;
+
+ int resolve_domain(char *domain);
+ void set_ip_address(u32 addr);
+ void set_port(u32 port);
+ const u8 next();
+ int is_empty();
+
+ void set_flags(u8 flags) {
+ m_sock_flags |= flags;
+ };
+
+ void clear_flags(u8 flags) {
+ m_sock_flags &= ~flags;
+ };
+
+ void toggle_flags(u8 flags) {
+ m_sock_flags ^= flags;
+ };
+
+ u8 get_flags(u8 flags) {
+ return m_sock_flags & flags;
+ };
+
+ PRIVATE_MEMBER_ACCESSORS(ipv4_addr, dst_addr);
+ PRIVATE_MEMBER_ACCESSORS(u16, dst_port);
+ PRIVATE_MEMBER_ACCESSORS(u16, src_port);
+ PRIVATE_MEMBER_ACCESSORS(ipv4_addr, src_addr);
+ PRIVATE_MEMBER_ACCESSORS(s16, sock_fd);
+ PRIVATE_MEMBER_ACCESSORS(u8, sock_flags);
+ PRIVATE_MEMBER_ACCESSORS(bool, buffer_cleared);
+ PRIVATE_MEMBER_ACCESSORS(s16, size);
+ PRIVATE_MEMBER_ACCESSORS(s16, buffer_offset);
+ PRIVATE_MEMBER_ACCESSORS(u32, unused);
+ PRIVATE_MEMBER_ACCESSORS_ARRAY(u8, unused2, 64);
+ PRIVATE_MEMBER_ACCESSORS_ARRAY(u8, packet_buffer, 2048);
+ PRIVATE_MEMBER_ACCESSORS(s16, stat_val);
+ PRIVATE_MEMBER_ACCESSORS(u16, unused3);
+ PRIVATE_MEMBER_ACCESSORS(u32, send_window);
+ PRIVATE_MEMBER_ACCESSORS(u32, recv_window);
+ PRIVATE_MEMBER_ACCESSORS_FUNC(void, callback, TSocket *socket);
+};
+
+// pso/TTcpSocket.h
+class TTcpSocket : public TSocket {
+private:
+ PSOV3EncryptionTCP m_send_crypt;
+ PSOV3EncryptionTCP m_recv_crypt;
+ int m_is_encrypted;
+public:
+ WEAK_FUNC TTcpSocket(TObject *parent = nullptr);
+ virtual ~TTcpSocket();
+
+ virtual short open() override;
+ virtual short close() override;
+ virtual void recv() override;
+ virtual short send(u8 *data) override;
+ virtual int send(u8 *data, size_t size) override;
+
+ int stat();
+ int test_connection();
+
+ static void notify(short size, short sock_fd);
+
+ PRIVATE_MEMBER_ACCESSORS(PSOV3EncryptionTCP, send_crypt);
+ PRIVATE_MEMBER_ACCESSORS(PSOV3EncryptionTCP, recv_crypt);
+ PRIVATE_MEMBER_ACCESSORS(int, is_encrypted);
+};
+
// pso/TMainTask.h
class TMainTask : public TObject {
public:
@@ -864,8 +906,8 @@ public:
virtual u32 next() override;
PRIVATE_MEMBER_ACCESSORS_ARRAY(u32, buffer, 522);
- PRIVATE_MEMBER_ACCESSORS(u32 *, buffer_start);
- PRIVATE_MEMBER_ACCESSORS(u32 *, buffer_end);
+ PRIVATE_MEMBER_ACCESSORS_NON_REF(u32 *, buffer_start);
+ PRIVATE_MEMBER_ACCESSORS_NON_REF(u32 *, buffer_end);
private:
TArray<u32, 522> m_buffer;
diff --git a/include/pso/TTcpSocket.h b/include/pso/TTcpSocket.h
new file mode 100644
index 0000000..9740a3a
--- /dev/null
+++ b/include/pso/TTcpSocket.h
@@ -0,0 +1,41 @@
+#ifndef TTCPSOCKET_H
+#define TTCPSOCKET_H
+
+#include <global_types.h>
+#include <string.h>
+#include <pso/macros.h>
+#include <pso/forward.h>
+#include <pso/PSOV3EncryptionTCP.h>
+#include <pso/TArray.h>
+#include <pso/TSocket.h>
+#include <pso/TObject.h>
+
+EXTERN_OBJECT_NAME(TTcpSocket);
+extern TTcpSocket *tcp_socket_table[16];
+
+class TTcpSocket : public TSocket {
+private:
+ PSOV3EncryptionTCP m_send_crypt;
+ PSOV3EncryptionTCP m_recv_crypt;
+ int m_is_encrypted;
+public:
+ WEAK_FUNC TTcpSocket(TObject *parent = nullptr);
+ virtual ~TTcpSocket();
+
+ virtual short open() override;
+ virtual short close() override;
+ virtual void recv() override;
+ virtual short send(u8 *data) override;
+ virtual int send(u8 *data, size_t size) override;
+
+ int stat();
+ int test_connection();
+
+ static void notify(short size, short sock_fd);
+
+ PRIVATE_MEMBER_ACCESSORS(PSOV3EncryptionTCP, send_crypt);
+ PRIVATE_MEMBER_ACCESSORS(PSOV3EncryptionTCP, recv_crypt);
+ PRIVATE_MEMBER_ACCESSORS(int, is_encrypted);
+};
+
+#endif
diff --git a/include/pso/forward.h b/include/pso/forward.h
index 165b9ad..1bc71cf 100644
--- a/include/pso/forward.h
+++ b/include/pso/forward.h
@@ -1,6 +1,8 @@
#ifndef FORWARD_H
#define FORWARD_H
+class TTcpSocket;
+class PSOV3EncryptionTCP;
class TSocket;
class THeap;
class TObject;
diff --git a/obj_files.mk b/obj_files.mk
index 1f9de57..48bd54d 100644
--- a/obj_files.mk
+++ b/obj_files.mk
@@ -1,5 +1,6 @@
O_FILES := $(BUILD_DIR)/src/main.o \
$(BUILD_DIR)/src/pso/TPlyGuildCardTag.o \
+ $(BUILD_DIR)/src/pso/TTcpSocket.o \
$(BUILD_DIR)/src/pso/TSocket.o \
$(BUILD_DIR)/src/pso/PSOV3EncryptionTCP.o \
$(BUILD_DIR)/src/pso/THeap.o \
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) {}