diff --git a/server/server.cpp b/server/server.cpp index ae20f35..2147651 100644 --- a/server/server.cpp +++ b/server/server.cpp @@ -15,24 +15,7 @@ #include #include #include - -#define DFF_CONN_PORT 15342 - -#define CMD_HANDSHAKE 0x00 // First command ever sent; used for exchanging version and handshake tokens -#define CMD_STREAM_DFF 0x01 // Start uploading a new fifo log -#define CMD_RUN_DFF 0x02 // Run most recently uploaded fifo log -#define CMD_SET_CONTEXT_FRAME 0x03 // Specify what frame the following communication is referring to -#define CMD_SET_CONTEXT_COMMAND 0x04 // Specify what command the following communication is referring to -#define CMD_ENABLE_COMMAND 0x05 // Enable current command -#define CMD_DISABLE_COMMAND 0x06 // Enable current command - -#define RET_FAIL 0 -#define RET_SUCCESS 1 -#define RET_WOULDBLOCK 2 - -const int version = 0; -const uint32_t handshake = 0x6fe62ac7; -const int dff_stream_chunk_size = 32; // in bytes +#include "../source/protocol.h" void WriteHandshake(int socket) { @@ -59,14 +42,16 @@ void DffClient::Connect(const QString& hostName) qDebug() << "Error at creating socket!"; } + memset(&serv_name, 0, sizeof(serv_name)); serv_name.sin_family = AF_INET; - inet_aton(hostName.toLatin1().constData(), &serv_name.sin_addr); +// inet_aton(hostName.toLatin1().constData(), &serv_name.sin_addr); + inet_aton("192.168.178.22", &serv_name.sin_addr); serv_name.sin_port = htons(DFF_CONN_PORT); status = ::connect(socket, (struct sockaddr*)&serv_name, sizeof(serv_name)); if (status == -1) { - qDebug() << "Client couldn't connect"; + perror("connect"); } else { @@ -77,49 +62,10 @@ void DffClient::Connect(const QString& hostName) void DffClient::OnConnected() { qDebug() << "Client connected successfully"; - qDebug() << "OMG " << socket; WriteHandshake(socket); } -int ReadHandshake(int socket) -{ - char data[5]; - recv(socket, data, sizeof(data), 0); - uint32_t received_handshake = ntohl(*(uint32_t*)&data[1]); - - if (data[0] != CMD_HANDSHAKE || received_handshake != handshake) - return RET_FAIL; - - return RET_SUCCESS; -} - -void ReadStreamedDff(int socket) -{ - char cmd = CMD_STREAM_DFF; - recv(socket, &cmd, 1, 0); - - int32_t n_size; - recv(socket, &n_size, 4, 0); - int32_t size = ntohl(n_size); - QFile file("dffout.dff"); - file.open(QIODevice::WriteOnly); - - qDebug() << "About to read " << size << " bytes of dff data!"; - - QDataStream stream(&file); - - for (; size > 0; size -= dff_stream_chunk_size) - { - char data[dff_stream_chunk_size]; - recv(socket, data, std::min(size,dff_stream_chunk_size), 0); - stream.writeRawData(data, std::min(size,dff_stream_chunk_size)); - qDebug() << size << " bytes left to be read!"; - } - - file.close(); -} - // Dummy code used for testing // This should actually be running on the Wii // inside native fifo player and using /dev/net/ip/top @@ -208,16 +154,16 @@ begin: switch (cmd) { case CMD_HANDSHAKE: - if (RET_SUCCESS == ReadHandshake(client_socket)) +/* if (RET_SUCCESS == ReadHandshake(client_socket)) qDebug() << tr("Successfully exchanged handshake token!"); else qDebug() << tr("Failed to exchange handshake token!"); - +*/ // TODO: should probably write a handshake in return, but ... I'm lazy break; case CMD_STREAM_DFF: - ReadStreamedDff(client_socket); +// ReadStreamedDff(client_socket); break; default:; @@ -285,8 +231,19 @@ void WriteStreamDff(int socket, QString filename) { char data[dff_stream_chunk_size]; stream.readRawData(data, std::min(size,dff_stream_chunk_size)); - send(socket, data, std::min(size,dff_stream_chunk_size), 0); - qDebug() << size << " bytes left to be sent!"; + int ret = send(socket, data, std::min(size,dff_stream_chunk_size), 0); + if (ret == -1) + { + perror("send"); + } + else if (ret != std::min(size,dff_stream_chunk_size)) + { + qDebug() << "Only printed " << ret << " bytes of data..."; + } + else + { + qDebug() << size << " bytes left to be sent!"; + } } file.close(); diff --git a/source/main.cpp b/source/main.cpp index 868386d..f2db0f3 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -13,6 +13,8 @@ #include #include #include +#include +#include "protocol.h" typedef uint64_t u64; @@ -415,11 +417,6 @@ struct FifoData void LoadDffData(FifoData& out) { - if(!fatInitDefault()) - { - printf("fatInitDefault failed!\n"); - } - out.file = fopen(DFF_FILENAME, "r"); if (!out.file) printf("Failed to open file!\n"); @@ -693,14 +690,143 @@ void Init() #endif WPAD_Init(); + + if(!fatInitDefault()) + { + printf("fatInitDefault failed!\n"); + } + + net_init(); } #include "mygx.h" +int ReadHandshake(int socket) +{ + char data[5]; + net_recv(socket, data, sizeof(data), 0); + uint32_t received_handshake = ntohl(*(uint32_t*)&data[1]); + + if (data[0] != CMD_HANDSHAKE || received_handshake != handshake) + return RET_FAIL; + + return RET_SUCCESS; +} + +bool CheckIfHomePressed() +{ +/* VIDEO_WaitVSync(); + fb ^= 1; +*/ + WPAD_ScanPads(); + + if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) + { + return true; + } +} + +void ReadStreamedDff(int socket) +{ + char cmd = CMD_STREAM_DFF; + net_recv(socket, &cmd, 1, 0); + + int32_t n_size; + net_recv(socket, &n_size, 4, 0); + int32_t size = ntohl(n_size); + printf("About to read %d bytes of dff data!", size); + + FILE* file = fopen("sd:/dff/test.dff", "wb"); // TODO: Change! + + if (file == NULL) + { + printf("Failed to open output file!\n"); + } + + for (; size > 0; ) + { + char data[dff_stream_chunk_size]; + ssize_t num_received = net_recv(socket, data, std::min(size,dff_stream_chunk_size), 0); + if (num_received == -1) + { + printf("Error in recv!\n"); + } + else if (num_received > 0) + { + fwrite(data, num_received, 1, file); + size -= num_received; + } +// printf("%d bytes left to be read!\n", size); + CheckIfHomePressed(); + } + printf ("Done reading :)\n"); + + fclose(file); +} + +int WaitForConnection() +{ + int addrlen; + struct sockaddr_in my_name, peer_name; + int status; + + int server_socket = net_socket(AF_INET, SOCK_STREAM, 0); + if (server_socket == -1) + { + printf("Failed to create server socket\n"); + } + int yes = 1; + net_setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); + + memset(&my_name, 0, sizeof(my_name)); + my_name.sin_family = AF_INET; + my_name.sin_port = htons(DFF_CONN_PORT); + my_name.sin_addr.s_addr = htonl(INADDR_ANY); + + status = net_bind(server_socket, (struct sockaddr*)&my_name, sizeof(my_name)); + if (status == -1) + { + printf("Failed to bind server socket\n"); + } + + status = net_listen(server_socket, 5); // TODO: Change second parameter.. + if (status == -1) + { + printf("Failed to listen on server socket\n"); + } + printf("Listening now!\n"); + + int client_socket = -1; + + struct sockaddr_in client_info; + socklen_t ssize = sizeof(client_info); + int new_socket = net_accept(server_socket, (struct sockaddr*)&client_info, &ssize); + if (new_socket < 0) + { + printf("accept failed!\n"); + } + else + { + client_socket = new_socket; + printf("accept succeeded and returned %d\n", client_socket); + } + + return client_socket; +} + int main() { Init(); + printf("Init done!\n"); + int client_socket = WaitForConnection(); + if (RET_SUCCESS == ReadHandshake(client_socket)) + printf("Successfully exchanged handshake token!\n"); + else + printf("Failed to exchanged handshake token!\n"); + + ReadStreamedDff(client_socket); + FifoData fifo_data; LoadDffData(fifo_data); printf("Loaded dff data\n"); diff --git a/source/protocol.h b/source/protocol.h new file mode 100644 index 0000000..3deab39 --- /dev/null +++ b/source/protocol.h @@ -0,0 +1,27 @@ +#ifndef FIFOPLAYER_PROTOCOL_H +#define FIFOPLAYER_PROTOCOL_H + +#define DFF_CONN_PORT 15342 + +#define CMD_HANDSHAKE 0x00 // First command ever sent; used for exchanging version and handshake tokens +#define CMD_STREAM_DFF 0x01 // Start uploading a new fifo log +#define CMD_RUN_DFF 0x02 // Run most recently uploaded fifo log +#define CMD_SET_CONTEXT_FRAME 0x03 // Specify what frame the following communication is referring to +#define CMD_SET_CONTEXT_COMMAND 0x04 // Specify what command the following communication is referring to +#define CMD_ENABLE_COMMAND 0x05 // Enable current command +#define CMD_DISABLE_COMMAND 0x06 // Enable current command + +#define RET_FAIL 0 +#define RET_SUCCESS 1 +#define RET_WOULDBLOCK 2 + +static const int version = 0; +static const uint32_t handshake = 0x6fe62ac7; +static const int dff_stream_chunk_size = 4096; // in bytes + +// TODO: Move client side here, too! + +// TODO: Move client and server side to different files... + + +#endif // FIFOPLAYER_PROTOCOL_H