/** * Friend Finder Thread (Receives Peer Information) * @param args Length of argp in Bytes (Unused) * @param argp Argument (Unused) * @return Unused Value - Return 0 */ int _friendFinder(SceSize args, void * argp) { // Receive Buffer int rxpos = 0; uint8_t rx[1024]; // Chat Packet SceNetAdhocctlChatPacketC2S chat; chat.base.opcode = OPCODE_CHAT; // Last Ping Time uint64_t lastping = 0; // Last Time Reception got updated uint64_t lastreceptionupdate = 0; // Finder Loop while(_init == 1) { // Acquire Network Lock _acquireNetworkLock(); // Ping Server if((sceKernelGetSystemTimeWide() - lastping) >= ADHOCCTL_PING_TIMEOUT) { // Update Ping Time lastping = sceKernelGetSystemTimeWide(); // Prepare Packet uint8_t opcode = OPCODE_PING; // Send Ping to Server sceNetInetSend(_metasocket, &opcode, 1, INET_MSG_DONTWAIT); } // Send Chat Messages while(popFromOutbox(chat.message)) { // Send Chat to Server sceNetInetSend(_metasocket, &chat, sizeof(chat), INET_MSG_DONTWAIT); } // Wait for Incoming Data int received = sceNetInetRecv(_metasocket, rx + rxpos, sizeof(rx) - rxpos, INET_MSG_DONTWAIT); // Free Network Lock _freeNetworkLock(); // Received Data if(received > 0) { // Fix Position rxpos += received; // Log Incoming Traffic #ifdef DEBUG printk("Received %d Bytes of Data from Server\n", received); #endif } // Handle Packets if(rxpos > 0) { // BSSID Packet if(rx[0] == OPCODE_CONNECT_BSSID) { // Enough Data available if(rxpos >= sizeof(SceNetAdhocctlConnectBSSIDPacketS2C)) { // Cast Packet SceNetAdhocctlConnectBSSIDPacketS2C * packet = (SceNetAdhocctlConnectBSSIDPacketS2C *)rx; // Update BSSID _parameter.bssid.mac_addr = packet->mac; // Change State _thread_status = ADHOCCTL_STATE_CONNECTED; // Notify Event Handlers int i = 0; for(; i < ADHOCCTL_MAX_HANDLER; i++) { // Active Handler if(_event_handler[i] != NULL) _event_handler[i](ADHOCCTL_EVENT_CONNECT, 0, _event_args[i]); } // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlConnectBSSIDPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlConnectBSSIDPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlConnectBSSIDPacketS2C); } } // Chat Packet else if(rx[0] == OPCODE_CHAT) { // Enough Data available if(rxpos >= sizeof(SceNetAdhocctlChatPacketS2C)) { // Cast Packet SceNetAdhocctlChatPacketS2C * packet = (SceNetAdhocctlChatPacketS2C *)rx; // Fix for Idiots that try to troll the "ME" Nametag if(stricmp((char *)packet->name.data, "ME") == 0) strcpy((char *)packet->name.data, "NOT ME"); // Add Incoming Chat to HUD addChatLog((char *)packet->name.data, packet->base.message); // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlChatPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlChatPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlChatPacketS2C); } } // Connect Packet else if(rx[0] == OPCODE_CONNECT) { // Enough Data available if(rxpos >= sizeof(SceNetAdhocctlConnectPacketS2C)) { // Log Incoming Peer #ifdef DEBUG printk("Incoming Peer Data...\n"); #endif // Cast Packet SceNetAdhocctlConnectPacketS2C * packet = (SceNetAdhocctlConnectPacketS2C *)rx; // Add User _addFriend(packet); // Update HUD User Count #ifdef LOCALHOST_AS_PEER setUserCount(_getActivePeerCount()); #else setUserCount(_getActivePeerCount()+1); #endif // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlConnectPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlConnectPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlConnectPacketS2C); } } // Disconnect Packet else if(rx[0] == OPCODE_DISCONNECT) { // Enough Data available if(rxpos >= sizeof(SceNetAdhocctlDisconnectPacketS2C)) { // Log Incoming Peer Delete Request #ifdef DEBUG printk("Incoming Peer Data Delete Request...\n"); #endif // Cast Packet SceNetAdhocctlDisconnectPacketS2C * packet = (SceNetAdhocctlDisconnectPacketS2C *)rx; // Delete User by IP _deleteFriendByIP(packet->ip); // Update HUD User Count #ifdef LOCALHOST_AS_PEER setUserCount(_getActivePeerCount()); #else setUserCount(_getActivePeerCount()+1); #endif // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlDisconnectPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlDisconnectPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlDisconnectPacketS2C); } } // Scan Packet else if(rx[0] == OPCODE_SCAN) { // Enough Data available if(rxpos >= sizeof(SceNetAdhocctlScanPacketS2C)) { // Log Incoming Network Information #ifdef DEBUG printk("Incoming Group Information...\n"); #endif // Cast Packet SceNetAdhocctlScanPacketS2C * packet = (SceNetAdhocctlScanPacketS2C *)rx; // Allocate Structure Data SceNetAdhocctlScanInfo * group = (SceNetAdhocctlScanInfo *)malloc(sizeof(SceNetAdhocctlScanInfo)); // Allocated Structure Data if(group != NULL) { // Clear Memory memset(group, 0, sizeof(SceNetAdhocctlScanInfo)); // Link to existing Groups group->next = _networks; // Copy Group Name group->group_name = packet->group; // Set Group Host group->bssid.mac_addr = packet->mac; // Link into Group List _networks = group; } // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlScanPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlScanPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlScanPacketS2C); } } // Scan Complete Packet else if(rx[0] == OPCODE_SCAN_COMPLETE) { // Log Scan Completion #ifdef DEBUG printk("Incoming Scan complete response...\n"); #endif // Change State _thread_status = ADHOCCTL_STATE_DISCONNECTED; // Notify Event Handlers int i = 0; for(; i < ADHOCCTL_MAX_HANDLER; i++) { // Active Handler if(_event_handler[i] != NULL) _event_handler[i](ADHOCCTL_EVENT_SCAN, 0, _event_args[i]); } // Move RX Buffer memmove(rx, rx + 1, sizeof(rx) - 1); // Fix RX Buffer Length rxpos -= 1; } } // Reception Update required if((sceKernelGetSystemTimeWide() - lastreceptionupdate) > 5000000) { // Clone Time into Last Update Field lastreceptionupdate = sceKernelGetSystemTimeWide(); // Update Reception Level union SceNetApctlInfo info; if(sceNetApctlGetInfo(PSP_NET_APCTL_INFO_STRENGTH, &info) >= 0) setReceptionPercentage((int)info.strength); else setReceptionPercentage(0); } // Delay Thread (10ms) sceKernelDelayThread(10000); } // Set WLAN HUD Reception to 0% on Shutdown setReceptionPercentage(0); // Notify Caller of Shutdown _init = -1; // Log Shutdown printk("End of Friend Finder Thread\n"); // Reset Thread Status _thread_status = ADHOCCTL_STATE_DISCONNECTED; // Kill Thread sceKernelExitDeleteThread(0); // Return Success return 0; }
int friendFinder(){ // Receive Buffer int rxpos = 0; uint8_t rx[1024]; // Chat Packet SceNetAdhocctlChatPacketC2S chat; chat.base.opcode = OPCODE_CHAT; // Last Ping Time uint64_t lastping = 0; // Last Time Reception got updated uint64_t lastreceptionupdate = 0; uint64_t now; // Finder Loop while(friendFinderRunning) { // Acquire Network Lock //_acquireNetworkLock(); // Ping Server now = real_time_now()*1000.0; if(now - lastping >= 100) { // Update Ping Time lastping = now; // Prepare Packet uint8_t opcode = OPCODE_PING; // Send Ping to Server send(metasocket, (const char *)&opcode, 1,0); } // Send Chat Messages //while(popFromOutbox(chat.message)) //{ // // Send Chat to Server // sceNetInetSend(metasocket, (const char *)&chat, sizeof(chat), 0); //} // Wait for Incoming Data int received = recv(metasocket, (char *)(rx + rxpos), sizeof(rx) - rxpos,0); // Free Network Lock //_freeNetworkLock(); // Received Data if(received > 0) { // Fix Position rxpos += received; // Log Incoming Traffic //printf("Received %d Bytes of Data from Server\n", received); INFO_LOG(SCENET, "Received %d Bytes of Data from Adhoc Server", received); } // Handle Packets if(rxpos > 0) { // BSSID Packet if(rx[0] == OPCODE_CONNECT_BSSID) { // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlConnectBSSIDPacketS2C)) { // Cast Packet SceNetAdhocctlConnectBSSIDPacketS2C * packet = (SceNetAdhocctlConnectBSSIDPacketS2C *)rx; // Update BSSID parameter.bssid.mac_addr = packet->mac; // Change State threadStatus = ADHOCCTL_STATE_CONNECTED; // Notify Event Handlers CoreTiming::ScheduleEvent_Threadsafe_Immediate(eventHandlerUpdate, join32(ADHOCCTL_EVENT_CONNECT, 0)); // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlConnectBSSIDPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlConnectBSSIDPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlConnectBSSIDPacketS2C); } } // Chat Packet else if(rx[0] == OPCODE_CHAT) { // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlChatPacketS2C)) { // Cast Packet SceNetAdhocctlChatPacketS2C * packet = (SceNetAdhocctlChatPacketS2C *)rx; // Fix for Idiots that try to troll the "ME" Nametag if(strcasecmp((char *)packet->name.data, "ME") == 0) strcpy((char *)packet->name.data, "NOT ME"); // Add Incoming Chat to HUD //printf("Receive chat message %s", packet->base.message); // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlChatPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlChatPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlChatPacketS2C); } } // Connect Packet else if(rx[0] == OPCODE_CONNECT) { // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlConnectPacketS2C)) { // Log Incoming Peer INFO_LOG(SCENET,"Incoming Peer Data..."); // Cast Packet SceNetAdhocctlConnectPacketS2C * packet = (SceNetAdhocctlConnectPacketS2C *)rx; // Add User addFriend(packet); // Update HUD User Count #ifdef LOCALHOST_AS_PEER setUserCount(getActivePeerCount()); #else // setUserCount(getActivePeerCount()+1); #endif // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlConnectPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlConnectPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlConnectPacketS2C); } } // Disconnect Packet else if(rx[0] == OPCODE_DISCONNECT) { // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlDisconnectPacketS2C)) { // Log Incoming Peer Delete Request INFO_LOG(SCENET,"FriendFinder: Incoming Peer Data Delete Request..."); // Cast Packet SceNetAdhocctlDisconnectPacketS2C * packet = (SceNetAdhocctlDisconnectPacketS2C *)rx; // Delete User by IP deleteFriendByIP(packet->ip); // Update HUD User Count #ifdef LOCALHOST_AS_PEER setUserCount(_getActivePeerCount()); #else //setUserCount(_getActivePeerCount()+1); #endif // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlDisconnectPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlDisconnectPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlDisconnectPacketS2C); } } // Scan Packet else if(rx[0] == OPCODE_SCAN) { // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlScanPacketS2C)) { // Log Incoming Network Information INFO_LOG(SCENET,"Incoming Group Information..."); // Cast Packet SceNetAdhocctlScanPacketS2C * packet = (SceNetAdhocctlScanPacketS2C *)rx; // Allocate Structure Data SceNetAdhocctlScanInfo * group = (SceNetAdhocctlScanInfo *)malloc(sizeof(SceNetAdhocctlScanInfo)); // Allocated Structure Data if(group != NULL) { // Clear Memory memset(group, 0, sizeof(SceNetAdhocctlScanInfo)); // Link to existing Groups group->next = networks; // Copy Group Name group->group_name = packet->group; // Set Group Host group->bssid.mac_addr = packet->mac; // Link into Group List networks = group; } // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlScanPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlScanPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlScanPacketS2C); } } // Scan Complete Packet else if(rx[0] == OPCODE_SCAN_COMPLETE) { // Log Scan Completion INFO_LOG(SCENET,"FriendFinder: Incoming Scan complete response..."); // Change State threadStatus = ADHOCCTL_STATE_DISCONNECTED; // Notify Event Handlers CoreTiming::ScheduleEvent_Threadsafe_Immediate(eventHandlerUpdate,join32(ADHOCCTL_EVENT_SCAN, 0)); //int i = 0; for(; i < ADHOCCTL_MAX_HANDLER; i++) //{ // // Active Handler // if(_event_handler[i] != NULL) _event_handler[i](ADHOCCTL_EVENT_SCAN, 0, _event_args[i]); //} // Move RX Buffer memmove(rx, rx + 1, sizeof(rx) - 1); // Fix RX Buffer Length rxpos -= 1; } } // Original value was 10 ms, I think 100 is just fine sleep_ms(100); } // Log Shutdown INFO_LOG(SCENET, "FriendFinder: End of Friend Finder Thread"); // Return Success return 0; }
int friendFinder(){ // Receive Buffer int rxpos = 0; uint8_t rx[1024]; // Chat Packet SceNetAdhocctlChatPacketC2S chat; chat.base.opcode = OPCODE_CHAT; // Last Ping Time uint64_t lastping = 0; // Last Time Reception got updated uint64_t lastreceptionupdate = 0; uint64_t now; // Log Startup INFO_LOG(SCENET, "FriendFinder: Begin of Friend Finder Thread"); // Finder Loop while(friendFinderRunning) { // Acquire Network Lock //_acquireNetworkLock(); // Ping Server now = real_time_now()*1000.0; if(now - lastping >= 100) { // Update Ping Time lastping = now; // Prepare Packet uint8_t opcode = OPCODE_PING; // Send Ping to Server, may failed with socket error 10054/10053 if someone else with the same IP already connected to AdHoc Server (the server might need to be modified to differentiate MAC instead of IP) int iResult = send(metasocket, (const char *)&opcode, 1,0); /*if (iResult == SOCKET_ERROR) { ERROR_LOG(SCENET, "FriendFinder: Socket Error (%i) when sending OPCODE_PING", errno); //friendFinderRunning = false; }*/ } // Send Chat Messages //while(popFromOutbox(chat.message)) //{ // // Send Chat to Server // sceNetInetSend(metasocket, (const char *)&chat, sizeof(chat), 0); //} // Wait for Incoming Data int received = recv(metasocket, (char *)(rx + rxpos), sizeof(rx) - rxpos,0); // Free Network Lock //_freeNetworkLock(); // Received Data if(received > 0) { // Fix Position rxpos += received; // Log Incoming Traffic //printf("Received %d Bytes of Data from Server\n", received); INFO_LOG(SCENET, "Received %d Bytes of Data from Adhoc Server", received); } // Handle Packets if(rxpos > 0) { // BSSID Packet if(rx[0] == OPCODE_CONNECT_BSSID) { INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CONNECT_BSSID"); // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlConnectBSSIDPacketS2C)) { // Cast Packet SceNetAdhocctlConnectBSSIDPacketS2C * packet = (SceNetAdhocctlConnectBSSIDPacketS2C *)rx; // Update BSSID parameter.bssid.mac_addr = packet->mac; // Change State threadStatus = ADHOCCTL_STATE_CONNECTED; // Notify Event Handlers CoreTiming::ScheduleEvent_Threadsafe_Immediate(eventHandlerUpdate, join32(ADHOCCTL_EVENT_CONNECT, 0)); // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlConnectBSSIDPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlConnectBSSIDPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlConnectBSSIDPacketS2C); } } // Chat Packet else if(rx[0] == OPCODE_CHAT) { INFO_LOG(SCENET, "FriendFinder: Incoming OPCODE_CHAT"); // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlChatPacketS2C)) { // Cast Packet SceNetAdhocctlChatPacketS2C * packet = (SceNetAdhocctlChatPacketS2C *)rx; // Fix for Idiots that try to troll the "ME" Nametag if(strcasecmp((char *)packet->name.data, "ME") == 0) strcpy((char *)packet->name.data, "NOT ME"); // Add Incoming Chat to HUD //printf("Receive chat message %s", packet->base.message); DEBUG_LOG(SCENET, "Received chat message %s", packet->base.message); // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlChatPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlChatPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlChatPacketS2C); } } // Connect Packet else if(rx[0] == OPCODE_CONNECT) { DEBUG_LOG(SCENET, "FriendFinder: OPCODE_CONNECT"); // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlConnectPacketS2C)) { // Log Incoming Peer INFO_LOG(SCENET,"Incoming Peer Data..."); // Cast Packet SceNetAdhocctlConnectPacketS2C * packet = (SceNetAdhocctlConnectPacketS2C *)rx; // Add User addFriend(packet); // Update HUD User Count #ifdef LOCALHOST_AS_PEER setUserCount(getActivePeerCount()); #else // setUserCount(getActivePeerCount()+1); #endif // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlConnectPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlConnectPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlConnectPacketS2C); } } // Disconnect Packet else if(rx[0] == OPCODE_DISCONNECT) { DEBUG_LOG(SCENET, "FriendFinder: OPCODE_DISCONNECT"); // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlDisconnectPacketS2C)) { // Log Incoming Peer Delete Request INFO_LOG(SCENET,"FriendFinder: Incoming Peer Data Delete Request..."); // Cast Packet SceNetAdhocctlDisconnectPacketS2C * packet = (SceNetAdhocctlDisconnectPacketS2C *)rx; // Delete User by IP, should delete by MAC since IP can be shared (behind NAT) isn't? deleteFriendByIP(packet->ip); // Update HUD User Count #ifdef LOCALHOST_AS_PEER setUserCount(_getActivePeerCount()); #else //setUserCount(_getActivePeerCount()+1); #endif // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlDisconnectPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlDisconnectPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlDisconnectPacketS2C); } } // Scan Packet else if(rx[0] == OPCODE_SCAN) { DEBUG_LOG(SCENET, "FriendFinder: OPCODE_SCAN"); // Enough Data available if(rxpos >= (int)sizeof(SceNetAdhocctlScanPacketS2C)) { // Log Incoming Network Information INFO_LOG(SCENET,"Incoming Group Information..."); // Cast Packet SceNetAdhocctlScanPacketS2C * packet = (SceNetAdhocctlScanPacketS2C *)rx; // Multithreading Lock peerlock.lock(); // It seems AdHoc Server always sent the full group list, so we should reset group list during Scan initialization // Should only add non-existing group (or replace an existing group) to prevent Ford Street Racing from showing a strange game session list /*SceNetAdhocctlScanInfo * group = findGroup(&packet->mac); if (group != NULL) { // Copy Group Name group->group_name = packet->group; // Set Group Host group->bssid.mac_addr = packet->mac; } else*/ { // Allocate Structure Data SceNetAdhocctlScanInfo * group = (SceNetAdhocctlScanInfo *)malloc(sizeof(SceNetAdhocctlScanInfo)); // Allocated Structure Data if (group != NULL) { // Clear Memory, should this be done only when allocating new group? memset(group, 0, sizeof(SceNetAdhocctlScanInfo)); // Link to existing Groups group->next = networks; // Copy Group Name group->group_name = packet->group; // Set Group Host group->bssid.mac_addr = packet->mac; // Link into Group List networks = group; } } // Multithreading Unlock peerlock.unlock(); // Move RX Buffer memmove(rx, rx + sizeof(SceNetAdhocctlScanPacketS2C), sizeof(rx) - sizeof(SceNetAdhocctlScanPacketS2C)); // Fix RX Buffer Length rxpos -= sizeof(SceNetAdhocctlScanPacketS2C); } } // Scan Complete Packet else if(rx[0] == OPCODE_SCAN_COMPLETE) { DEBUG_LOG(SCENET, "FriendFinder: OPCODE_SCAN_COMPLETE"); // Log Scan Completion INFO_LOG(SCENET,"FriendFinder: Incoming Scan complete response..."); // Change State threadStatus = ADHOCCTL_STATE_DISCONNECTED; // Notify Event Handlers CoreTiming::ScheduleEvent_Threadsafe_Immediate(eventHandlerUpdate,join32(ADHOCCTL_EVENT_SCAN, 0)); //int i = 0; for(; i < ADHOCCTL_MAX_HANDLER; i++) //{ // // Active Handler // if(_event_handler[i] != NULL) _event_handler[i](ADHOCCTL_EVENT_SCAN, 0, _event_args[i]); //} // Move RX Buffer memmove(rx, rx + 1, sizeof(rx) - 1); // Fix RX Buffer Length rxpos -= 1; } } // Original value was 10 ms, I think 100 is just fine sleep_ms(100); } // Groups/Networks should be deallocated isn't? // Prevent the games from having trouble to reInitiate Adhoc (the next NetInit -> PdpCreate after NetTerm) threadStatus = ADHOCCTL_STATE_DISCONNECTED; // Log Shutdown INFO_LOG(SCENET, "FriendFinder: End of Friend Finder Thread"); // Return Success return 0; }