From 5e732f123cb70465b73aa8c365528c6645f606f7 Mon Sep 17 00:00:00 2001 From: Maschell Date: Thu, 13 Apr 2017 15:30:40 +0200 Subject: [PATCH] Added rumble support for the network controller, changed protocol version to Version 3 --- ControllerPatcher.cpp | 1 + ControllerPatcher.hpp | 1 + network/TCPServer.cpp | 9 ++++ network/TCPServer.hpp | 5 ++- network/UDPClient.cpp | 58 ++++++++++++++++++++++++++ network/UDPClient.hpp | 70 ++++++++++++++++++++++++++++++++ patcher/ControllerPatcherDefs.h | 1 + patcher/ControllerPatcherHID.cpp | 24 ++++++++++- utils/CPRetainVars.cpp | 5 ++- utils/CPRetainVars.hpp | 2 + 10 files changed, 172 insertions(+), 4 deletions(-) create mode 100644 network/UDPClient.cpp create mode 100644 network/UDPClient.hpp diff --git a/ControllerPatcher.cpp b/ControllerPatcher.cpp index bc580e6..be98ed1 100644 --- a/ControllerPatcher.cpp +++ b/ControllerPatcher.cpp @@ -457,6 +457,7 @@ void ControllerPatcher::startNetworkServer(){ void ControllerPatcher::stopNetworkServer(){ UDPServer::destroyInstance(); + UDPClient::destroyInstance(); TCPServer::destroyInstance(); } diff --git a/ControllerPatcher.hpp b/ControllerPatcher.hpp index 826baed..d2364f6 100644 --- a/ControllerPatcher.hpp +++ b/ControllerPatcher.hpp @@ -38,6 +38,7 @@ #include "./config/ConfigValues.hpp" #include "network/TCPServer.hpp" #include "network/UDPServer.hpp" +#include "network/UDPClient.hpp" #include "dynamic_libs/sys_functions.h" #include "dynamic_libs/syshid_functions.h" diff --git a/network/TCPServer.cpp b/network/TCPServer.cpp index 2e4f856..07f65af 100644 --- a/network/TCPServer.cpp +++ b/network/TCPServer.cpp @@ -15,6 +15,7 @@ * along with this program. If not, see . ****************************************************************************/ #include "TCPServer.hpp" +#include "UDPClient.hpp" #include #include #include @@ -317,8 +318,13 @@ void TCPServer::DoTCPThreadInternal(){ **/ clientfd = ret = accept(sockfd, (sockaddr *)&(sock_addr), &len); + if(ret == -1){ ErrorHandling(); break;} 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); + + gUDPClientip = sock_addr.sin_addr.s_addr; + UDPClient::createInstance(); + s32 ret; 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;} @@ -355,10 +361,13 @@ void TCPServer::DoTCPThreadInternal(){ clientfd = -1; }while(0); log_printf("TCPServer::DoTCPThreadInternal(line %d): Connection closed\n",__LINE__); + gUDPClientip = 0; + UDPClient::destroyInstance(); TCPServer::DetachAndDelete(); //Clear connected controller CloseSockets(); continue; } + } void TCPServer::DoTCPThread(ControllerPatcherThread *thread, void *arg){ diff --git a/network/TCPServer.hpp b/network/TCPServer.hpp index a089bac..4ddbc6a 100644 --- a/network/TCPServer.hpp +++ b/network/TCPServer.hpp @@ -21,13 +21,14 @@ #include "dynamic_libs/socket_functions.h" #include "utils/logger.h" -#define WIIU_CP_TCP_HANDSHAKE WIIU_CP_TCP_HANDSHAKE_VERSION_2 +#define WIIU_CP_TCP_HANDSHAKE WIIU_CP_TCP_HANDSHAKE_VERSION_3 #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_MAX WIIU_CP_TCP_HANDSHAKE_VERSION_3 #define WIIU_CP_TCP_HANDSHAKE_VERSION_1 0x12 #define WIIU_CP_TCP_HANDSHAKE_VERSION_2 0x13 +#define WIIU_CP_TCP_HANDSHAKE_VERSION_3 0x14 #define WIIU_CP_TCP_HANDSHAKE_ABORT 0x30 diff --git a/network/UDPClient.cpp b/network/UDPClient.cpp new file mode 100644 index 0000000..e9d2009 --- /dev/null +++ b/network/UDPClient.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#include "UDPClient.hpp" +#include +#include +#include +#define MAX_UDP_SIZE 0x578 + +UDPClient * UDPClient::instance = NULL; + +UDPClient::UDPClient(u32 ip, s32 port){ + sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sockfd < 0) + return; + + struct sockaddr_in connect_addr; + memset(&connect_addr, 0, sizeof(connect_addr)); + connect_addr.sin_family = AF_INET; + connect_addr.sin_port = port; + connect_addr.sin_addr.s_addr = ip; + + if(connect(sockfd, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0) + { + socketclose(sockfd); + sockfd = -1; + } +} + +UDPClient::~UDPClient(){ + if (this->sockfd != -1){ + socketclose(sockfd); + } + if(HID_DEBUG) log_printf("UDPClient::~UDPClient(line %d): Thread has been closed\n",__LINE__); +} + +bool UDPClient::sendData(char * data,s32 length){ + if(sockfd < 0 || data == 0 || length < 0 || gUsedProtocolVersion < WIIU_CP_TCP_HANDSHAKE_VERSION_3){ + return false; + } + if(length > 1400) length = 1400; + + s32 ret = send(sockfd, data, length, 0); + return (ret >= 0); +} diff --git a/network/UDPClient.hpp b/network/UDPClient.hpp new file mode 100644 index 0000000..e975cdb --- /dev/null +++ b/network/UDPClient.hpp @@ -0,0 +1,70 @@ +/**************************************************************************** + * Copyright (C) 2016,2017 Maschell + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#ifndef _UDPCLIENT_WINDOW_H_ +#define _UDPCLIENT_WINDOW_H_ + +#include + +#include "../ControllerPatcher.hpp" +#include "../patcher/ControllerPatcherHID.hpp" +#include "../utils/CPRetainVars.hpp" +#include "dynamic_libs/socket_functions.h" +#include "utils/logger.h" + +#define DEFAULT_UDP_CLIENT_PORT 8114 + +class UDPClient{ + friend class ControllerPatcher; + friend class ControllerPatcherHID; + friend class TCPServer; +public: + +private: + static UDPClient *getInstance() { + if(instance == NULL){ + createInstance(); + } + return instance; + } + + + static UDPClient *createInstance() { + if(instance != NULL){ + destroyInstance(); + } + instance = new UDPClient(gUDPClientip,DEFAULT_UDP_CLIENT_PORT); + + return getInstance(); + } + + static void destroyInstance() { + if(instance != NULL){ + delete instance; + instance = NULL; + } + } + + UDPClient(u32 ip,s32 port); + ~UDPClient(); + bool sendData(char * data, s32 length); + + volatile s32 sockfd = -1; + struct sockaddr_in addr; + static UDPClient *instance; +}; + +#endif //_UDPClient_WINDOW_H_ diff --git a/patcher/ControllerPatcherDefs.h b/patcher/ControllerPatcherDefs.h index 728b59b..ddc305f 100644 --- a/patcher/ControllerPatcherDefs.h +++ b/patcher/ControllerPatcherDefs.h @@ -232,6 +232,7 @@ typedef struct _my_cb_user{ u32 pads_per_device; /**< Number of maximum pads of this device */ u8 pad_slot; /**< number of the pad that will be used */ u8 rumblestatus[HID_MAX_PADS_COUNT]; /**< Current status of the device rumble */ + u8 rumbleForce[HID_MAX_PADS_COUNT]; }my_cb_user; /** diff --git a/patcher/ControllerPatcherHID.cpp b/patcher/ControllerPatcherHID.cpp index 1e1b840..17ed39d 100644 --- a/patcher/ControllerPatcherHID.cpp +++ b/patcher/ControllerPatcherHID.cpp @@ -508,18 +508,40 @@ void ControllerPatcherHID::HIDGCRumble(u32 handle,my_cb_user *usr){ } void ControllerPatcherHID::HIDRumble(u32 handle,my_cb_user *usr,u32 pad){ + if(usr == NULL || pad > HID_MAX_PADS_COUNT) return; + s32 rumblechanged = 0; HID_Data * data_ptr = &(gHID_Devices[usr->slotdata.deviceslot].pad_data[pad]); if(data_ptr->rumbleActive != usr->rumblestatus[pad]){ usr->rumblestatus[pad] = data_ptr->rumbleActive; rumblechanged = 1; } - if(rumblechanged){ + usr->rumbleForce[pad]--; + if(rumblechanged || usr->rumbleForce[pad] <= 0){ + //log_printf("Rumble: %d %d\n",usr->rumblestatus[pad],usr->rumbleForce[pad]); + //Seding to the network client! + char bytes[6]; + + s32 i = 0; + bytes[i++] = 0x01; + bytes[i++] = (handle >> 24) & 0xFF; + bytes[i++] = (handle >> 16) & 0xFF; + bytes[i++] = (handle >> 8) & 0xFF; + bytes[i++] = handle & 0xFF; + bytes[i++] = usr->rumblestatus[pad]; + + UDPClient * instance = UDPClient::getInstance(); + if(instance != NULL){ + instance->sendData(bytes,6); + } + + if(usr->slotdata.hidmask == gHID_LIST_DS3){ HIDDS3Rumble(handle,usr,usr->rumblestatus[pad]); }else{ // Not implemented for other devices =( } + usr->rumbleForce[pad] = 10; } } diff --git a/utils/CPRetainVars.cpp b/utils/CPRetainVars.cpp index b1fa62f..1878def 100644 --- a/utils/CPRetainVars.cpp +++ b/utils/CPRetainVars.cpp @@ -59,4 +59,7 @@ u8 gUsedProtocolVersion __attribute__((section(".data"))) = WIIU_CP_TCP_HANDSHA wpad_connect_callback_t gConnectCallback[4] __attribute__((section(".data"))); wpad_extension_callback_t gExtensionCallback[4] __attribute__((section(".data"))); -u8 gCallbackCooldown __attribute__((section(".data"))) = 0; +u8 gCallbackCooldown __attribute__((section(".data"))) = 0; + +u32 gUDPClientip __attribute__((section(".data"))) = 0; + diff --git a/utils/CPRetainVars.hpp b/utils/CPRetainVars.hpp index f894ac3..0dd7944 100644 --- a/utils/CPRetainVars.hpp +++ b/utils/CPRetainVars.hpp @@ -63,5 +63,7 @@ extern wpad_connect_callback_t gConnectCallback[4]; extern wpad_extension_callback_t gExtensionCallback[4]; extern u8 gCallbackCooldown; +extern u32 gUDPClientip; + #endif // CP_RETAINS_VARS_H_