Updated the TCP Handshake

Updated the TCP Handshake to also negotiate a protocol version.
This commit is contained in:
Maschell 2017-04-10 15:39:58 +02:00
parent 73bf9bfb74
commit 74d422a87e
8 changed files with 228 additions and 174 deletions

View File

@ -13,7 +13,7 @@ s32 ControllerPatcherNet::recvwait(s32 sock, void *buffer, s32 len) {
return 0; return 0;
} }
s32 ControllerPatcherNet::recvbyte(s32 sock) { u8 ControllerPatcherNet::recvbyte(s32 sock) {
unsigned char buffer[1]; unsigned char buffer[1];
s32 ret; s32 ret;

View File

@ -6,7 +6,7 @@ class ControllerPatcherNet{
friend class UDPServer; friend class UDPServer;
private: private:
static s32 recvwait(s32 sock, void *buffer, s32 len); static s32 recvwait(s32 sock, void *buffer, s32 len);
static s32 recvbyte(s32 sock); static u8 recvbyte(s32 sock);
static s32 checkbyte(s32 sock); static s32 checkbyte(s32 sock);
static s32 sendwait(s32 sock, const void *buffer, s32 len); static s32 sendwait(s32 sock, const void *buffer, s32 len);
static s32 sendbyte(s32 sock, unsigned char byte); static s32 sendbyte(s32 sock, unsigned char byte);

View File

@ -21,25 +21,9 @@
#include <string.h> #include <string.h>
#include "../ControllerPatcher.hpp" #include "../ControllerPatcher.hpp"
#include "./ControllerPatcherNet.hpp" #include "./ControllerPatcherNet.hpp"
#include "../utils/CPRetainVars.hpp"
#define WIIU_CP_TCP_HANDSHAKE 0x12 #define wiiu_errno (*__gh_errno_ptr())
#define WIIU_CP_TCP_SAME_CLIENT 0x20
#define WIIU_CP_TCP_NEW_CLIENT 0x21
#define ATTACH 0x01
#define DETACH 0x00
#define WIIU_CP_TCP_ATTACH 0x01
#define WIIU_CP_TCP_DETACH 0x02
#define WIIU_CP_TCP_PING 0xF0
#define WIIU_CP_TCP_PONG 0xF1
#define WIIU_CP_TCP_ATTACH_CONFIG_FOUND 0xE0
#define WIIU_CP_TCP_ATTACH_CONFIG_NOT_FOUND 0xE1
#define WIIU_CP_TCP_ATTACH_USER_DATA_OKAY 0xE8
#define WIIU_CP_TCP_ATTACH_USER_DATA_BAD 0xE9
#define errno (*__gh_errno_ptr())
ControllerPatcherThread * TCPServer::pThread = NULL; ControllerPatcherThread * TCPServer::pThread = NULL;
TCPServer * TCPServer::instance = NULL; TCPServer * TCPServer::instance = NULL;
@ -128,143 +112,152 @@ s32 TCPServer::RunTCP(){
if(exitThread) break; if(exitThread) break;
ret = ControllerPatcherNet::checkbyte(clientfd); ret = ControllerPatcherNet::checkbyte(clientfd);
if (ret < 0) { if (ret < 0) {
if(errno != 6) return ret; if(wiiu_errno != 6) return ret;
usleep(1000); usleep(1000);
continue; continue;
} }
//log_printf("got byte from tcp! %01X\n",ret); //log_printf("got byte from tcp! %01X\n",ret);
switch (ret) { switch (ret) {
case WIIU_CP_TCP_ATTACH: { /*attach */ case WIIU_CP_TCP_ATTACH: { /*attach */
s32 handle; if(gUsedProtocolVersion >= WIIU_CP_TCP_HANDSHAKE_VERSION_1){
ret = ControllerPatcherNet::recvwait(clientfd, &handle, 4); s32 handle;
if(ret < 0){ ret = ControllerPatcherNet::recvwait(clientfd, &handle, 4);
log_printf("TCPServer::RunTCP(line %d): Error in %02X: recvwait handle\n",__LINE__,WIIU_CP_TCP_ATTACH);
return ret;
}
if(HID_DEBUG) log_printf("TCPServer::RunTCP(line %d): got handle %d\n",handle);
u16 vid = 0;
u16 pid = 0;
ret = ControllerPatcherNet::recvwait(clientfd, &vid, 2);
if(ret < 0){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: recvwait vid\n",__LINE__,WIIU_CP_TCP_ATTACH);
return ret;
}
if(HID_DEBUG) log_printf("TCPServer::RunTCP(line %d): got vid %04X\n",vid);
ret = ControllerPatcherNet::recvwait(clientfd, &pid, 2);
if(ret < 0){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: recvwait pid\n",__LINE__,WIIU_CP_TCP_ATTACH);
return ret;
}
if(HID_DEBUG) log_printf("TCPServer::RunTCP(line %d): got pid %04X\n",pid);
HIDDevice device;
memset(&device,0,sizeof(device));
device.handle = handle;
device.interface_index = 0;
device.vid = SWAP16(vid);
device.pid = SWAP16(pid);
device.max_packet_size_rx = 8;
my_cb_user * user = NULL;
ControllerPatcherHID::externAttachDetachCallback(&device,1);
if((ret = ControllerPatcherUtils::getDataByHandle(handle,&user)) < 0){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: getDataByHandle(%d,%08X).\n",__LINE__,WIIU_CP_TCP_ATTACH,handle,&user);
log_printf("TCPServer::RunTCP(line %d): Error in %02X: Config for the controller is missing.\n",__LINE__,WIIU_CP_TCP_ATTACH);
if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_CONFIG_NOT_FOUND) < 0)){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: Sending the WIIU_CP_TCP_ATTACH_CONFIG_NOT_FOUND byte failed. Error: %d.\n",__LINE__,WIIU_CP_TCP_ATTACH,ret);
}
return -1;
}
if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_CONFIG_FOUND) < 0)){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: Sending the WIIU_CP_TCP_ATTACH_CONFIG_FOUND byte failed. Error: %d.\n",__LINE__,WIIU_CP_TCP_ATTACH,ret);
return ret;
}
if(user != NULL){
if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_USER_DATA_OKAY) < 0)){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: Sending the WIIU_CP_TCP_ATTACH_USER_DATA_OKAY byte failed. Error: %d.\n",__LINE__,WIIU_CP_TCP_ATTACH,ret);
return ret;
}
ret = ControllerPatcherNet::sendwait(clientfd,&user->slotdata.deviceslot,2);
if(ret < 0){ if(ret < 0){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: sendwait slotdata: %04X\n",__LINE__,WIIU_CP_TCP_ATTACH,user->slotdata.deviceslot); log_printf("TCPServer::RunTCP(line %d): Error in %02X: recvwait handle\n",__LINE__,WIIU_CP_TCP_ATTACH);
return ret; return ret;
} }
ret = ControllerPatcherNet::sendwait(clientfd,&user->pad_slot,1); if(HID_DEBUG) log_printf("TCPServer::RunTCP(line %d): got handle %d\n",handle);
u16 vid = 0;
u16 pid = 0;
ret = ControllerPatcherNet::recvwait(clientfd, &vid, 2);
if(ret < 0){ if(ret < 0){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: sendwait pad_slot: %04X\n",__LINE__,WIIU_CP_TCP_ATTACH,user->pad_slot); log_printf("TCPServer::RunTCP(line %d): Error in %02X: recvwait vid\n",__LINE__,WIIU_CP_TCP_ATTACH);
return ret; return ret;
} }
}else{ if(HID_DEBUG) log_printf("TCPServer::RunTCP(line %d): got vid %04X\n",vid);
log_printf("TCPServer::RunTCP(line %d): Error in %02X: invalid user data.\n",__LINE__,WIIU_CP_TCP_ATTACH);
if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_USER_DATA_BAD) < 0)){ ret = ControllerPatcherNet::recvwait(clientfd, &pid, 2);
log_printf("TCPServer::RunTCP(line %d): Error in %02X: Sending the WIIU_CP_TCP_ATTACH_USER_DATA_BAD byte failed. Error: %d.\n",__LINE__,WIIU_CP_TCP_ATTACH,ret); if(ret < 0){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: recvwait pid\n",__LINE__,WIIU_CP_TCP_ATTACH);
return ret; return ret;
} }
return -1; if(HID_DEBUG) log_printf("TCPServer::RunTCP(line %d): got pid %04X\n",pid);
HIDDevice device;
memset(&device,0,sizeof(device));
device.handle = handle;
device.interface_index = 0;
device.vid = SWAP16(vid);
device.pid = SWAP16(pid);
device.max_packet_size_rx = 8;
my_cb_user * user = NULL;
ControllerPatcherHID::externAttachDetachCallback(&device,1);
if((ret = ControllerPatcherUtils::getDataByHandle(handle,&user)) < 0){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: getDataByHandle(%d,%08X).\n",__LINE__,WIIU_CP_TCP_ATTACH,handle,&user);
log_printf("TCPServer::RunTCP(line %d): Error in %02X: Config for the controller is missing.\n",__LINE__,WIIU_CP_TCP_ATTACH);
if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_CONFIG_NOT_FOUND) < 0)){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: Sending the WIIU_CP_TCP_ATTACH_CONFIG_NOT_FOUND byte failed. Error: %d.\n",__LINE__,WIIU_CP_TCP_ATTACH,ret);
}
return -1;
}
if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_CONFIG_FOUND) < 0)){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: Sending the WIIU_CP_TCP_ATTACH_CONFIG_FOUND byte failed. Error: %d.\n",__LINE__,WIIU_CP_TCP_ATTACH,ret);
return ret;
}
if(user != NULL){
if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_USER_DATA_OKAY) < 0)){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: Sending the WIIU_CP_TCP_ATTACH_USER_DATA_OKAY byte failed. Error: %d.\n",__LINE__,WIIU_CP_TCP_ATTACH,ret);
return ret;
}
ret = ControllerPatcherNet::sendwait(clientfd,&user->slotdata.deviceslot,2);
if(ret < 0){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: sendwait slotdata: %04X\n",__LINE__,WIIU_CP_TCP_ATTACH,user->slotdata.deviceslot);
return ret;
}
ret = ControllerPatcherNet::sendwait(clientfd,&user->pad_slot,1);
if(ret < 0){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: sendwait pad_slot: %04X\n",__LINE__,WIIU_CP_TCP_ATTACH,user->pad_slot);
return ret;
}
}else{
log_printf("TCPServer::RunTCP(line %d): Error in %02X: invalid user data.\n",__LINE__,WIIU_CP_TCP_ATTACH);
if((ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_ATTACH_USER_DATA_BAD) < 0)){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: Sending the WIIU_CP_TCP_ATTACH_USER_DATA_BAD byte failed. Error: %d.\n",__LINE__,WIIU_CP_TCP_ATTACH,ret);
return ret;
}
return -1;
break;
}
if(HID_DEBUG) log_printf("TCPServer::RunTCP(line %d): attachted to device slot: %d , pad slot is: %d\n",__LINE__,user->slotdata.deviceslot,user->pad_slot);
gNetworkController[user->slotdata.deviceslot][user->pad_slot][NETWORK_CONTROLLER_VID] = device.vid;
gNetworkController[user->slotdata.deviceslot][user->pad_slot][NETWORK_CONTROLLER_PID] = device.pid;
gNetworkController[user->slotdata.deviceslot][user->pad_slot][NETWORK_CONTROLLER_ACTIVE] = 1;
gNetworkController[user->slotdata.deviceslot][user->pad_slot][NETWORK_CONTROLLER_HANDLE] = handle;
if(HID_DEBUG) log_printf("TCPServer::RunTCP(line %d): handle %d connected! vid: %02X pid: %02X deviceslot %d, padslot %d\n",__LINE__,handle,vid,pid,user->slotdata.deviceslot,user->pad_slot);
break; break;
} }
if(HID_DEBUG) log_printf("TCPServer::RunTCP(line %d): attachted to device slot: %d , pad slot is: %d\n",__LINE__,user->slotdata.deviceslot,user->pad_slot);
gNetworkController[user->slotdata.deviceslot][user->pad_slot][NETWORK_CONTROLLER_VID] = device.vid;
gNetworkController[user->slotdata.deviceslot][user->pad_slot][NETWORK_CONTROLLER_PID] = device.pid;
gNetworkController[user->slotdata.deviceslot][user->pad_slot][NETWORK_CONTROLLER_ACTIVE] = 1;
gNetworkController[user->slotdata.deviceslot][user->pad_slot][NETWORK_CONTROLLER_HANDLE] = handle;
if(HID_DEBUG) log_printf("TCPServer::RunTCP(line %d): handle %d connected! vid: %02X pid: %02X deviceslot %d, padslot %d\n",__LINE__,handle,vid,pid,user->slotdata.deviceslot,user->pad_slot);
break; break;
} }
case WIIU_CP_TCP_DETACH: { /*detach */ case WIIU_CP_TCP_DETACH: { /*detach */
s32 handle; if(gUsedProtocolVersion >= WIIU_CP_TCP_HANDSHAKE_VERSION_1){
ret = ControllerPatcherNet::recvwait(clientfd, &handle, 4); s32 handle;
if(ret < 0){ ret = ControllerPatcherNet::recvwait(clientfd, &handle, 4);
log_printf("TCPServer::RunTCP(line %d): Error in %02X: recvwait handle\n",__LINE__,WIIU_CP_TCP_DETACH); if(ret < 0){
return ret; log_printf("TCPServer::RunTCP(line %d): Error in %02X: recvwait handle\n",__LINE__,WIIU_CP_TCP_DETACH);
return ret;
break;
}
if(HID_DEBUG) log_printf("TCPServer::RunTCP(line %d): got detach for handle: %d\n",__LINE__,handle);
my_cb_user * user = NULL;
if(ControllerPatcherUtils::getDataByHandle(handle,&user) < 0){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: getDataByHandle(%d,%08X).\n",__LINE__,WIIU_CP_TCP_DETACH,handle,&user);
return -1;
break;
}
if(user == NULL){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: invalid user data.\n",__LINE__,WIIU_CP_TCP_DETACH);
return -1;
break;
}
s32 deviceslot = user->slotdata.deviceslot;
if(HID_DEBUG) log_printf("TCPServer::RunTCP(line %d): device slot is: %d , pad slot is: %d\n",__LINE__,deviceslot,user->pad_slot);
DeviceVIDPIDInfo vidpid;
s32 result;
if((result = ControllerPatcherUtils::getVIDPIDbyDeviceSlot(deviceslot,&vidpid)) < 0){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: Couldn't find a valid VID/PID for device slot %d. Error: %d\n",__LINE__,WIIU_CP_TCP_DETACH,deviceslot,ret);
return -1;
break;
}
HIDDevice device;
memset(&device,0,sizeof(device));
device.handle = handle;
device.interface_index = 0;
device.vid = SWAP16(vidpid.vid);
device.pid = SWAP16(vidpid.pid);
device.max_packet_size_rx = 14;
ControllerPatcherHID::externAttachDetachCallback(&device,DETACH);
memset(gNetworkController[deviceslot][user->pad_slot],0,sizeof(gNetworkController[deviceslot][user->pad_slot]));
if(HID_DEBUG) log_printf("TCPServer::RunTCP(line %d): handle %d disconnected!\n",__LINE__,handle);
break; break;
} }
if(HID_DEBUG) log_printf("TCPServer::RunTCP(line %d): got detach for handle: %d\n",__LINE__,handle);
my_cb_user * user = NULL;
if(ControllerPatcherUtils::getDataByHandle(handle,&user) < 0){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: getDataByHandle(%d,%08X).\n",__LINE__,WIIU_CP_TCP_DETACH,handle,&user);
return -1;
break;
}
if(user == NULL){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: invalid user data.\n",__LINE__,WIIU_CP_TCP_DETACH);
return -1;
break;
}
s32 deviceslot = user->slotdata.deviceslot;
if(HID_DEBUG) log_printf("TCPServer::RunTCP(line %d): device slot is: %d , pad slot is: %d\n",__LINE__,deviceslot,user->pad_slot);
DeviceVIDPIDInfo vidpid;
s32 result;
if((result = ControllerPatcherUtils::getVIDPIDbyDeviceSlot(deviceslot,&vidpid)) < 0){
log_printf("TCPServer::RunTCP(line %d): Error in %02X: Couldn't find a valid VID/PID for device slot %d. Error: %d\n",__LINE__,WIIU_CP_TCP_DETACH,deviceslot,ret);
return -1;
break;
}
HIDDevice device;
memset(&device,0,sizeof(device));
device.handle = handle;
device.interface_index = 0;
device.vid = SWAP16(vidpid.vid);
device.pid = SWAP16(vidpid.pid);
device.max_packet_size_rx = 14;
ControllerPatcherHID::externAttachDetachCallback(&device,DETACH);
memset(gNetworkController[deviceslot][user->pad_slot],0,sizeof(gNetworkController[deviceslot][user->pad_slot]));
if(HID_DEBUG) log_printf("TCPServer::RunTCP(line %d): handle %d disconnected!\n",__LINE__,handle);
break; break;
} }
case WIIU_CP_TCP_PING: { /*ping*/ case WIIU_CP_TCP_PING: { /*ping*/
if(HID_DEBUG) log_printf("TCPServer::RunTCP(line %d): Got Ping, sending now a Pong\n",__LINE__); if(gUsedProtocolVersion >= WIIU_CP_TCP_HANDSHAKE_VERSION_1){
s32 ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_PONG); if(HID_DEBUG) log_printf("TCPServer::RunTCP(line %d): Got Ping, sending now a Pong\n",__LINE__);
if(ret < 0){ log_printf("TCPServer::RunTCP(line %d): Error in %02X: sendbyte PONG\n",__LINE__); return -1;} s32 ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_PONG);
if(ret < 0){ log_printf("TCPServer::RunTCP(line %d): Error in %02X: sendbyte PONG\n",__LINE__); return -1;}
break;
}
break; break;
} }
default: default:
@ -306,15 +299,44 @@ void TCPServer::DoTCPThreadInternal(){
if(exitThread) break; if(exitThread) break;
len = 16; len = 16;
/**
Handshake
1. At first this server sends his protocol version
2. The network clients answers with his preferred version (which needs to be equals or lower the version this server sent him) or an abort command.
3a. If the client sent a abort, close the connection and wait for another connection
3b. If the client sent his highest supported version, the server confirm that he is able to use this version (by sending the version back) or sending a abort command to disconnect.
**/
clientfd = ret = accept(sockfd, (sockaddr *)&(sock_addr), &len); clientfd = ret = accept(sockfd, (sockaddr *)&(sock_addr), &len);
if(ret == -1){ ErrorHandling(); break;} if(ret == -1){ ErrorHandling(); break;}
log_printf("TCPServer::DoTCPThreadInternal(line %d): TCP Connection accepted\n",__LINE__); log_printf("TCPServer::DoTCPThreadInternal(line %d): TCP Connection accepted! Sending my protocol version: %d (0x%02X)\n",__LINE__, (WIIU_CP_TCP_HANDSHAKE - WIIU_CP_TCP_HANDSHAKE_VERSION_1)+1,WIIU_CP_TCP_HANDSHAKE);
s32 ret; s32 ret;
ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_HANDSHAKE); //Hey I'm a WiiU console! ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_HANDSHAKE); //Hey I'm a WiiU console!
if(ret < 0){ log_printf("TCPServer::DoTCPThreadInternal(line %d): Error sendbyte: %02X\n",__LINE__,WIIU_CP_TCP_HANDSHAKE); ErrorHandling(); break;} if(ret < 0){ log_printf("TCPServer::DoTCPThreadInternal(line %d): Error sendbyte: %02X\n",__LINE__,WIIU_CP_TCP_HANDSHAKE); ErrorHandling(); break;}
u8 clientProtocolVersion = ControllerPatcherNet::recvbyte(clientfd);
if(ret < 0){ log_printf("TCPServer::DoTCPThreadInternal(line %d): Error recvbyte: %02X\n",__LINE__,WIIU_CP_TCP_HANDSHAKE); ErrorHandling(); break;}
if(clientProtocolVersion == WIIU_CP_TCP_HANDSHAKE_ABORT){
log_printf("TCPServer::DoTCPThreadInternal(line %d): The network client wants to abort.\n",__LINE__);
ErrorHandling(); break;
}
log_printf("TCPServer::DoTCPThreadInternal(line %d): received protocol version: %d (0x%02X)\n",__LINE__,(clientProtocolVersion - WIIU_CP_TCP_HANDSHAKE_VERSION_1)+1,clientProtocolVersion);
if(clientProtocolVersion >= WIIU_CP_TCP_HANDSHAKE_VERSION_MIN && clientProtocolVersion <= WIIU_CP_TCP_HANDSHAKE_VERSION_MAX){
log_printf("TCPServer::DoTCPThreadInternal(line %d): We support this protocol version. Let's confirm it to the network client.\n",__LINE__);
gUsedProtocolVersion = clientProtocolVersion;
ret = ControllerPatcherNet::sendbyte(clientfd, clientProtocolVersion);
if(ret < 0){ log_printf("TCPServer::DoTCPThreadInternal(line %d): Error sendbyte: %02X\n",__LINE__,clientProtocolVersion); ErrorHandling(); break;}
}else{
log_printf("TCPServer::DoTCPThreadInternal(line %d): We don't support this protocol version. We need to abort =(.\n",__LINE__);
ret = ControllerPatcherNet::sendbyte(clientfd, WIIU_CP_TCP_HANDSHAKE_ABORT);
ErrorHandling(); break;
}
log_printf("TCPServer::DoTCPThreadInternal(line %d): Handshake done! Success!\n",__LINE__);
if(ret < 0){ log_printf("TCPServer::DoTCPThreadInternal(line %d): Error sendbyte %02X/02X\n",__LINE__,WIIU_CP_TCP_NEW_CLIENT,WIIU_CP_TCP_SAME_CLIENT); ErrorHandling(); break;}
TCPServer::DetachAndDelete(); //Clear connected controller TCPServer::DetachAndDelete(); //Clear connected controller
RunTCP(); RunTCP();

View File

@ -21,6 +21,29 @@
#include "dynamic_libs/socket_functions.h" #include "dynamic_libs/socket_functions.h"
#include "utils/logger.h" #include "utils/logger.h"
#define WIIU_CP_TCP_HANDSHAKE WIIU_CP_TCP_HANDSHAKE_VERSION_2
#define WIIU_CP_TCP_HANDSHAKE_VERSION_MIN WIIU_CP_TCP_HANDSHAKE_VERSION_1
#define WIIU_CP_TCP_HANDSHAKE_VERSION_MAX WIIU_CP_TCP_HANDSHAKE_VERSION_2
#define WIIU_CP_TCP_HANDSHAKE_VERSION_1 0x12
#define WIIU_CP_TCP_HANDSHAKE_VERSION_2 0x13
#define WIIU_CP_TCP_HANDSHAKE_ABORT 0x30
#define ATTACH 0x01
#define DETACH 0x00
#define WIIU_CP_TCP_ATTACH 0x01
#define WIIU_CP_TCP_DETACH 0x02
#define WIIU_CP_TCP_PING 0xF0
#define WIIU_CP_TCP_PONG 0xF1
#define WIIU_CP_TCP_ATTACH_CONFIG_FOUND 0xE0
#define WIIU_CP_TCP_ATTACH_CONFIG_NOT_FOUND 0xE1
#define WIIU_CP_TCP_ATTACH_USER_DATA_OKAY 0xE8
#define WIIU_CP_TCP_ATTACH_USER_DATA_BAD 0xE9
#define DEFAULT_TCP_PORT 8112 #define DEFAULT_TCP_PORT 8112
class TCPServer{ class TCPServer{

View File

@ -20,7 +20,7 @@
#include <string.h> #include <string.h>
#include "../ControllerPatcher.hpp" #include "../ControllerPatcher.hpp"
#define MAX_UDP_SIZE 0x578 #define MAX_UDP_SIZE 0x578
#define errno (*__gh_errno_ptr()) #define wiiu_errno (*__gh_errno_ptr())
ControllerPatcherThread * UDPServer::pThread = NULL; ControllerPatcherThread * UDPServer::pThread = NULL;
UDPServer * UDPServer::instance = NULL; UDPServer * UDPServer::instance = NULL;
@ -92,7 +92,7 @@ void UDPServer::DoUDPThreadInternal(){
memset(buffer,0,MAX_UDP_SIZE); memset(buffer,0,MAX_UDP_SIZE);
n = recv(sockfd,buffer,MAX_UDP_SIZE,0); n = recv(sockfd,buffer,MAX_UDP_SIZE,0);
if (n < 0){ if (n < 0){
s32 errno_ = errno; s32 errno_ = wiiu_errno;
usleep(2000); usleep(2000);
if(errno_ != 11 && errno_ != 9){ if(errno_ != 11 && errno_ != 9){
break; break;
@ -104,47 +104,50 @@ void UDPServer::DoUDPThreadInternal(){
memcpy((void *)&type,buffer,sizeof(type)); memcpy((void *)&type,buffer,sizeof(type));
bufferoffset += sizeof(type); bufferoffset += sizeof(type);
switch (buffer[0]) { switch (buffer[0]) {
case 0x03: { case WIIU_CP_UDP_CONTROLLER_READ_DATA: {
u8 count_commands; if(gUsedProtocolVersion >= WIIU_CP_TCP_HANDSHAKE_VERSION_1){
memcpy((void *)&count_commands,buffer+bufferoffset,sizeof(count_commands)); u8 count_commands;
bufferoffset += sizeof(count_commands); memcpy((void *)&count_commands,buffer+bufferoffset,sizeof(count_commands));
for(s32 i = 0;i<count_commands;i++){ bufferoffset += sizeof(count_commands);
for(s32 i = 0;i<count_commands;i++){
s32 handle; s32 handle;
u16 deviceSlot; u16 deviceSlot;
u16 hid; u16 hid;
u8 padslot; u8 padslot;
u8 datasize; u8 datasize;
if(!cpyIncrementBufferOffset((void *)&handle, (void *)buffer,&bufferoffset,sizeof(handle), n))continue; if(!cpyIncrementBufferOffset((void *)&handle, (void *)buffer,&bufferoffset,sizeof(handle), n))continue;
if(!cpyIncrementBufferOffset((void *)&deviceSlot, (void *)buffer,&bufferoffset,sizeof(deviceSlot),n))continue; if(!cpyIncrementBufferOffset((void *)&deviceSlot, (void *)buffer,&bufferoffset,sizeof(deviceSlot),n))continue;
hid = (1 << deviceSlot); hid = (1 << deviceSlot);
if(!cpyIncrementBufferOffset((void *)&padslot, (void *)buffer,&bufferoffset,sizeof(padslot), n))continue; if(!cpyIncrementBufferOffset((void *)&padslot, (void *)buffer,&bufferoffset,sizeof(padslot), n))continue;
if(!cpyIncrementBufferOffset((void *)&datasize, (void *)buffer,&bufferoffset,sizeof(datasize), n))continue; if(!cpyIncrementBufferOffset((void *)&datasize, (void *)buffer,&bufferoffset,sizeof(datasize), n))continue;
u8 * databuffer = (u8*) malloc(datasize * sizeof(u8)); u8 * databuffer = (u8*) malloc(datasize * sizeof(u8));
if(!databuffer){ if(!databuffer){
log_printf("UDPServer::DoUDPThreadInternal(line %d): Allocating memory failed\n",__LINE__); log_printf("UDPServer::DoUDPThreadInternal(line %d): Allocating memory failed\n",__LINE__);
continue; continue;
} }
//log_printf("UDPServer::DoUDPThreadInternal(): Got handle: %d slot %04X hid %04X pad %02X datasize %02X\n",handle,deviceSlot,hid,padslot,datasize); //log_printf("UDPServer::DoUDPThreadInternal(): Got handle: %d slot %04X hid %04X pad %02X datasize %02X\n",handle,deviceSlot,hid,padslot,datasize);
if(!cpyIncrementBufferOffset((void *)databuffer, (void *)buffer,&bufferoffset,datasize, n))continue; if(!cpyIncrementBufferOffset((void *)databuffer, (void *)buffer,&bufferoffset,datasize, n))continue;
memset(&user,0,sizeof(user)); memset(&user,0,sizeof(user));
user.pad_slot = padslot; user.pad_slot = padslot;
user.slotdata.deviceslot = deviceSlot; user.slotdata.deviceslot = deviceSlot;
user.slotdata.hidmask = hid; user.slotdata.hidmask = hid;
if(gNetworkController[deviceSlot][padslot][0] == 0){ if(gNetworkController[deviceSlot][padslot][0] == 0){
log_printf("UDPServer::DoUDPThreadInternal(line %d): Ehm. Pad is not connected. STOP SENDING DATA ;) \n",__LINE__); log_printf("UDPServer::DoUDPThreadInternal(line %d): Ehm. Pad is not connected. STOP SENDING DATA ;) \n",__LINE__);
}else{ }else{
ControllerPatcherHID::externHIDReadCallback(handle,databuffer,datasize,&user); ControllerPatcherHID::externHIDReadCallback(handle,databuffer,datasize,&user);
} }
if(databuffer){ if(databuffer){
free(databuffer); free(databuffer);
databuffer = NULL; databuffer = NULL;
}
} }
break;
} }
break; break;
} }

View File

@ -23,6 +23,8 @@
#define DEFAULT_UDP_PORT 8113 #define DEFAULT_UDP_PORT 8113
#define WIIU_CP_UDP_CONTROLLER_READ_DATA 0x03
class UDPServer{ class UDPServer{
friend class ControllerPatcher; friend class ControllerPatcher;

View File

@ -16,6 +16,7 @@
****************************************************************************/ ****************************************************************************/
#include <gctypes.h> #include <gctypes.h>
#include "../patcher/ControllerPatcherDefs.h" #include "../patcher/ControllerPatcherDefs.h"
#include "../network/TCPServer.hpp"
#include "../utils/CPRetainVars.hpp" #include "../utils/CPRetainVars.hpp"
ControllerMapping gControllerMapping __attribute__((section(".data"))); ControllerMapping gControllerMapping __attribute__((section(".data")));
@ -54,3 +55,4 @@ u8 gOriginalAPDState __attribute__((section(".data"))) = 0;
u16 gNetworkController[gHIDMaxDevices][HID_MAX_PADS_COUNT][4] __attribute__((section(".data"))); u16 gNetworkController[gHIDMaxDevices][HID_MAX_PADS_COUNT][4] __attribute__((section(".data")));
s32 gHIDNetworkClientID __attribute__((section(".data"))) = 0; s32 gHIDNetworkClientID __attribute__((section(".data"))) = 0;
u8 gUsedProtocolVersion __attribute__((section(".data"))) = WIIU_CP_TCP_HANDSHAKE;

View File

@ -56,4 +56,6 @@ extern u8 gOriginalAPDState;
extern u16 gNetworkController[gHIDMaxDevices][HID_MAX_PADS_COUNT][4]; extern u16 gNetworkController[gHIDMaxDevices][HID_MAX_PADS_COUNT][4];
extern s32 gHIDNetworkClientID; extern s32 gHIDNetworkClientID;
extern u8 gUsedProtocolVersion;
#endif // CP_RETAINS_VARS_H_ #endif // CP_RETAINS_VARS_H_