Move DffServer to DffPlayer, fix some bugs. Streaming dffs from PC to Wii works :)

This commit is contained in:
neobrain
2013-09-14 14:44:07 +02:00
parent 752b490dd2
commit a272f73dbf
3 changed files with 179 additions and 69 deletions

View File

@@ -15,24 +15,7 @@
#include <stdint.h>
#include <arpa/inet.h>
#include <unistd.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
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();

View File

@@ -13,6 +13,8 @@
#include <unistd.h>
#include <fat.h>
#include <dirent.h>
#include <network.h>
#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");

27
source/protocol.h Normal file
View File

@@ -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