Example #1
0
/**
 * 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;
}
Example #2
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;
}
Example #3
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;
}