Beispiel #1
0
/**
 * Handle Death Packet
 * @param context Matching Context Pointer
 * @param sendermac Packet Sender MAC
 * @param length Packet Length
 */
void _actOnDeathPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * sendermac, uint32_t length)
{
	// Find Peer
	SceNetAdhocMatchingMemberInternal * peer = _findPeer(context, sendermac);
	
	// Valid Circumstances
	if(peer != NULL && context->mode == ADHOC_MATCHING_MODE_CHILD && peer == _findParent(context))
	{
		// Complete Packet available
		if(length >= (1 + sizeof(SceNetEtherAddr)))
		{
			// Extract Child MAC
			SceNetEtherAddr mac;
			memcpy(&mac, context->rxbuf + 1, sizeof(SceNetEtherAddr));
			
			// Find Peer
			SceNetAdhocMatchingMemberInternal * deadkid = _findPeer(context, &mac);
			
			// Valid Sibling
			if(deadkid->state == ADHOC_MATCHING_PEER_CHILD)
			{
				// Spawn Leave Event
				_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_LEAVE, &mac, 0, NULL);
				
				// Delete Peer
				_deletePeer(context, deadkid);
			}
		}
	}
}
Beispiel #2
0
/**
 * Handle Bulk Data Packet
 * @param context Matching Context Pointer
 * @param sendermac Packet Sender MAC
 * @param length Packet Length
 */
void _actOnBulkDataPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * sendermac, uint32_t length)
{
	// Find Peer
	SceNetAdhocMatchingMemberInternal * peer = _findPeer(context, sendermac);
	
	// Established Peer
	if(peer != NULL && (
	(context->mode == ADHOC_MATCHING_MODE_PARENT && peer->state == ADHOC_MATCHING_PEER_CHILD) || 
	(context->mode == ADHOC_MATCHING_MODE_CHILD && (peer->state == ADHOC_MATCHING_PEER_CHILD || peer->state == ADHOC_MATCHING_PEER_PARENT)) || 
	(context->mode == ADHOC_MATCHING_MODE_P2P && peer->state == ADHOC_MATCHING_PEER_P2P)))
	{
		// Complete Packet Header available
		if(length > 5)
		{
			// Extract Data Length
			int datalen = 0; memcpy(&datalen, context->rxbuf + 1, sizeof(datalen));
			
			// Complete Valid Packet available
			if(datalen > 0 && length >= (5 + datalen))
			{
				// Extract Data
				void * data = context->rxbuf + 5;
				
				// Spawn Data Event
				_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_DATA, sendermac, datalen, data);
			}
		}
	}
}
Beispiel #3
0
/**
 * Handle Hello Packet
 * @param context Matching Context Pointer
 * @param sendermac Packet Sender MAC
 * @param length Packet Length
 */
void _actOnHelloPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * sendermac, uint32_t length)
{
	// Interested in Hello Data
	if((context->mode == ADHOC_MATCHING_MODE_CHILD && _findParent(context) == NULL) || (context->mode == ADHOC_MATCHING_MODE_P2P && _findP2P(context) == NULL))
	{
		// Complete Packet Header available
		if(length >= 5)
		{
			// Extract Optional Data Length
			int optlen = 0; memcpy(&optlen, context->rxbuf + 1, sizeof(optlen));
			
			// Complete Valid Packet available
			if(optlen >= 0 && length >= (5 + optlen))
			{
				// Set Default Null Data
				void * opt = NULL;
				
				// Extract Optional Data Pointer
				if(optlen > 0) opt = context->rxbuf + 5;
				
				// Find Peer
				SceNetAdhocMatchingMemberInternal * peer = _findPeer(context, sendermac);
				
				// Peer not found
				if(peer == NULL)
				{
					// Allocate Memory
					peer = (SceNetAdhocMatchingMemberInternal *)_malloc(sizeof(SceNetAdhocMatchingMemberInternal));
					
					// Allocated Memory
					if(peer != NULL)
					{
						// Clear Memory
						memset(peer, 0, sizeof(SceNetAdhocMatchingMemberInternal));
						
						// Copy Sender MAC
						peer->mac = *sendermac;
						
						// Set Peer State
						peer->state = ADHOC_MATCHING_PEER_OFFER;
						
						// Initialize Ping Timer
						peer->lastping = sceKernelGetSystemTimeWide();
						
						// Link Peer into List
						peer->next = context->peerlist;
						context->peerlist = peer;
					}
				}
				
				// Peer available now
				if(peer != NULL)
				{
					// Spawn Hello Event
					_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_HELLO, sendermac, optlen, opt);
				}
			}
		}
	}
}
Beispiel #4
0
/**
 * Tell Established Peers of abandoned Child
 * @param context Matching Context Pointer
 * @param mac Dead Child's MAC
 */
void _sendDeathPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac)
{
	// Find abandoned Child
	SceNetAdhocMatchingMemberInternal * deadkid = _findPeer(context, mac);
	
	// Found abandoned Child
	if(deadkid != NULL)
	{
		// Packet Buffer
		uint8_t packet[7];
		
		// Set Opcode
		packet[0] = ADHOC_MATCHING_PACKET_DEATH;
		
		// Set abandoned Child MAC
		memcpy(packet + 1, mac, sizeof(SceNetEtherAddr));
		
		// Iterate Peers
		SceNetAdhocMatchingMemberInternal * peer = context->peerlist; for(; peer != NULL; peer = peer->next)
		{
			// Skip dead Child
			if(peer == deadkid) continue;
			
			// Send only to children
			if(peer->state == ADHOC_MATCHING_PEER_CHILD)
			{
				// Send Packet
				sceNetAdhocPdpSend(context->socket, &peer->mac, context->port, packet, sizeof(packet), 0, ADHOC_F_NONBLOCK);
			}
		}
	}
}
Beispiel #5
0
/**
 * Send Join Packet to Player
 * @param context Matching Context Pointer
 * @param mac Target Player MAC
 * @param optlen Optional Data Length
 * @param opt Optional Data
 */
void _sendJoinPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac, int optlen, void * opt)
{
	// Find Peer
	SceNetAdhocMatchingMemberInternal * peer = _findPeer(context, mac);
	
	// Valid Peer
	if(peer != NULL && peer->state == ADHOC_MATCHING_PEER_OUTGOING_REQUEST)
	{
		// Allocate Join Message Buffer
		uint8_t * join = (uint8_t *)_malloc(5 + optlen);
		
		// Allocated Join Message Buffer
		if(join != NULL)
		{
			// Join Opcode
			join[0] = ADHOC_MATCHING_PACKET_JOIN;
			
			// Optional Data Length
			memcpy(join + 1, &optlen, sizeof(optlen));
			
			// Copy Optional Data
			if(optlen > 0) memcpy(join + 5, opt, optlen);
			
			// Send Data
			sceNetAdhocPdpSend(context->socket, mac, context->port, join, 5 + optlen, 0, ADHOC_F_NONBLOCK);
			
			// Free Memory
			_free(join);
		}
	}
}
Beispiel #6
0
/**
 * Abort Data-Sending to Matching Target
 * @param id Matching Context ID
 * @param target Target MAC
 * @return 0 on success or... ADHOC_MATCHING_NOT_INITIALIZED, ADHOC_MATCHING_INVALID_ARG, ADHOC_MATCHING_INVALID_ID, ADHOC_MATCHING_NOT_RUNNING, ADHOC_MATCHING_UNKNOWN_TARGET
 */
int proNetAdhocMatchingAbortSendData(int id, const SceNetEtherAddr * target)
{
	// Initialized Library
	if(_init == 1)
	{
		// Valid Arguments
		if(target != NULL)
		{
			// Find Matching Context
			SceNetAdhocMatchingContext * context = _findMatchingContext(id);
			
			// Found Context
			if(context != NULL)
			{
				// Running Context
				if(context->running)
				{
					// Find Target Peer
					SceNetAdhocMatchingMemberInternal * peer = _findPeer(context, (SceNetEtherAddr *)target);
					
					// Found Peer
					if(peer != NULL)
					{
						// Peer is sending
						if(peer->sending)
						{
							// Set Peer as Bulk Idle
							peer->sending = 0;
							
							// Stop Bulk Data Sending (if in progress)
							_abortBulkTransfer(context, peer);
						}
						
						// Return Success
						return 0;
					}
					
					// Peer not found
					return ADHOC_MATCHING_UNKNOWN_TARGET;
				}
				
				// Context not running
				return ADHOC_MATCHING_NOT_RUNNING;
			}
			
			// Invalid Matching ID
			return ADHOC_MATCHING_INVALID_ID;
		}
		
		// Invalid Arguments
		return ADHOC_MATCHING_INVALID_ARG;
	}
	
	// Uninitialized Library
	return ADHOC_MATCHING_NOT_INITIALIZED;
}
Beispiel #7
0
/**
 * Handle Ping Packet
 * @param context Matching Context Pointer
 * @param sendermac Packet Sender MAC
 */
void _actOnPingPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * sendermac)
{
	// Find Peer
	SceNetAdhocMatchingMemberInternal * peer = _findPeer(context, sendermac);
	
	// Found Peer
	if(peer != NULL)
	{
		// Update Receive Timer
		peer->lastping = sceKernelGetSystemTimeWide();
	}
}
Beispiel #8
0
/**
 * Handle Birth Packet
 * @param context Matching Context Pointer
 * @param sendermac Packet Sender MAC
 * @param length Packet Length
 */
void _actOnBirthPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * sendermac, uint32_t length)
{
	// Find Peer
	SceNetAdhocMatchingMemberInternal * peer = _findPeer(context, sendermac);
	
	// Valid Circumstances
	if(peer != NULL && context->mode == ADHOC_MATCHING_MODE_CHILD && peer == _findParent(context))
	{
		// Complete Packet available
		if(length >= (1 + sizeof(SceNetEtherAddr)))
		{
			// Extract Child MAC
			SceNetEtherAddr mac;
			memcpy(&mac, context->rxbuf + 1, sizeof(SceNetEtherAddr));
			
			// Allocate Memory (If this fails... we are f****d.)
			SceNetAdhocMatchingMemberInternal * sibling = (SceNetAdhocMatchingMemberInternal *)_malloc(sizeof(SceNetAdhocMatchingMemberInternal));
			
			// Allocated Memory
			if(sibling != NULL)
			{
				// Clear Memory
				memset(sibling, 0, sizeof(SceNetAdhocMatchingMemberInternal));
				
				// Save MAC Address
				sibling->mac = mac;
				
				// Set Peer State
				sibling->state = ADHOC_MATCHING_PEER_CHILD;
				
				// Initialize Ping Timer
				peer->lastping = sceKernelGetSystemTimeWide();
				
				// Link Peer
				sibling->next = context->peerlist;
				context->peerlist = sibling;
				
				// Spawn Established Event
				_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_ESTABLISHED, &sibling->mac, 0, NULL);
			}
		}
	}
}
Beispiel #9
0
/**
 * Send Cancel Packet to Player
 * @param context Matching Context Pointer
 * @param mac Target Player MAC
 * @param optlen Optional Data Length
 * @param opt Optional Data
 */
void _sendCancelPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac, int optlen, void * opt)
{
	// Allocate Cancel Message Buffer
	uint8_t * cancel = (uint8_t *)_malloc(5 + optlen);
	
	// Allocated Cancel Message Buffer
	if(cancel != NULL)
	{
		// Cancel Opcode
		cancel[0] = ADHOC_MATCHING_PACKET_CANCEL;
		
		// Optional Data Length
		memcpy(cancel + 1, &optlen, sizeof(optlen));
		
		// Copy Optional Data
		if(optlen > 0) memcpy(cancel + 5, opt, optlen);
		
		// Send Data
		sceNetAdhocPdpSend(context->socket, mac, context->port, cancel, 5 + optlen, 0, ADHOC_F_NONBLOCK);
		
		// Free Memory
		_free(cancel);
	}
	
	// Find Peer
	SceNetAdhocMatchingMemberInternal * peer = _findPeer(context, mac);
	
	// Found Peer
	if(peer != NULL)
	{
		// Child Mode Fallback - Delete All
		if(context->mode == ADHOC_MATCHING_MODE_CHILD)
		{
			// Delete Peer List
			_clearPeerList(context);
		}
		
		// Delete Peer
		else _deletePeer(context, peer);
	}
}
Beispiel #10
0
/**
 * Handle Bye Packet
 * @param context Matching Context Pointer
 * @param sendermac Packet Sender MAC
 */
void _actOnByePacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * sendermac)
{
	// Find Peer
	SceNetAdhocMatchingMemberInternal * peer = _findPeer(context, sendermac);
	
	// We know this guy
	if(peer != NULL)
	{
		// P2P or Child Bye
		if((context->mode == ADHOC_MATCHING_MODE_PARENT && peer->state == ADHOC_MATCHING_PEER_CHILD) || 
		(context->mode == ADHOC_MATCHING_MODE_CHILD && peer->state == ADHOC_MATCHING_PEER_CHILD) ||
		(context->mode == ADHOC_MATCHING_MODE_P2P && peer->state == ADHOC_MATCHING_PEER_P2P))
		{
			// Spawn Leave / Kick Event
			_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_BYE, sendermac, 0, NULL);
			
			// Delete Peer
			_deletePeer(context, peer);
		}
		
		// Parent Bye
		else if(context->mode == ADHOC_MATCHING_MODE_CHILD && peer->state == ADHOC_MATCHING_PEER_PARENT)
		{
			// Iterate Peers
			SceNetAdhocMatchingMemberInternal * item = context->peerlist; for(; item != NULL; item = item->next)
			{
				// Established Peer
				if(item->state == ADHOC_MATCHING_PEER_CHILD || item->state == ADHOC_MATCHING_PEER_PARENT)
				{
					// Spawn Leave / Kick Event
					_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_BYE, &item->mac, 0, NULL);
				}
			}
			
			// Delete Peer from List
			_clearPeerList(context);
		}
	}
}
Beispiel #11
0
/**
 * Send Bulk Data Packet to Player
 * @param context Matching Context Pointer
 * @param mac Target Player MAC
 * @param datalen Data Length
 * @param data Data
 */
void _sendBulkDataPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac, int datalen, void * data)
{
	// Find Peer
	SceNetAdhocMatchingMemberInternal * peer = _findPeer(context, mac);
	
	// Valid Peer (rest is already checked in send.c)
	if(peer != NULL)
	{
		// Allocate Send Message Buffer
		uint8_t * send = (uint8_t *)_malloc(5 + datalen);
		
		// Allocated Send Message Buffer
		if(send != NULL)
		{
			// Send Opcode
			send[0] = ADHOC_MATCHING_PACKET_BULK;
			
			// Data Length
			memcpy(send + 1, &datalen, sizeof(datalen));
			
			// Copy Data
			memcpy(send + 5, data, datalen);
			
			// Send Data
			sceNetAdhocPdpSend(context->socket, mac, context->port, send, 5 + datalen, 0, ADHOC_F_NONBLOCK);
			
			// Free Memory
			_free(send);
			
			// Remove Busy Bit from Peer
			peer->sending = 0;
			
			// Spawn Data Event
			_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_DATA_ACK, mac, 0, NULL);
		}
	}
}
Beispiel #12
0
/**
 * Select / Accept Matching Target
 * @param id Matching Context ID
 * @param target Target MAC
 * @param optlen Length of Optional Data
 * @param opt Optional Data
 * @return 0 on success or... ADHOC_MATCHING_NOT_INITIALIZED, ADHOC_MATCHING_INVALID_ARG, ADHOC_MATCHING_INVALID_ID, ADHOC_MATCHING_NOT_RUNNING, ADHOC_MATCHING_UNKNOWN_TARGET, ADHOC_MATCHING_INVALID_OPTLEN, ADHOC_MATCHING_TARGET_NOT_READY, ADHOC_MATCHING_EXCEED_MAXNUM, ADHOC_MATCHING_NO_SPACE, ADHOC_MATCHING_REQUEST_IN_PROGRESS, ADHOC_MATCHING_ALREADY_ESTABLISHED
 */
int proNetAdhocMatchingSelectTarget(int id, const SceNetEtherAddr * target, int optlen, const void * opt)
{
	// Initialized Library
	if(_init == 1)
	{
		// Valid Arguments
		if(target != NULL)
		{
			// Find Matching Context for ID
			SceNetAdhocMatchingContext * context = _findMatchingContext(id);
			
			// Found Matching Context
			if(context != NULL)
			{
				// Running Context
				if(context->running)
				{
					// Search Result
					SceNetAdhocMatchingMemberInternal * peer = _findPeer(context, (SceNetEtherAddr *)target);
					
					// Found Peer in List
					if(peer != NULL)
					{
						// Valid Optional Data Length
						if((optlen == 0 && opt == NULL) || (optlen > 0 && opt != NULL))
						{
							// Host Mode
							if(context->mode == ADHOC_MATCHING_MODE_PARENT)
							{
								// Already Connected
								if(peer->state == ADHOC_MATCHING_PEER_CHILD) return ADHOC_MATCHING_ALREADY_ESTABLISHED;
								
								// Not enough space
								if(_countChildren(context) == (context->maxpeers - 1)) return ADHOC_MATCHING_EXCEED_MAXNUM;
								
								// Requesting Peer
								if(peer->state == ADHOC_MATCHING_PEER_INCOMING_REQUEST)
								{
									// Accept Peer in Group
									peer->state = ADHOC_MATCHING_PEER_CHILD;
									
									// Send Accept Confirmation to Peer
									_sendAcceptMessage(context, peer, optlen, opt);
									
									// Tell Children about new Sibling
									_sendBirthMessage(context, peer);
									
									// Return Success
									return 0;
								}
							}
							
							// Client Mode
							else if(context->mode == ADHOC_MATCHING_MODE_CHILD)
							{
								// Already connected
								if(_findParent(context) != NULL) return ADHOC_MATCHING_ALREADY_ESTABLISHED;
								
								// Outgoing Request in Progress
								if(_findOutgoingRequest(context) != NULL) return ADHOC_MATCHING_REQUEST_IN_PROGRESS;
								
								// Valid Offer
								if(peer->state == ADHOC_MATCHING_PEER_OFFER)
								{
									// Switch into Join Request Mode
									peer->state = ADHOC_MATCHING_PEER_OUTGOING_REQUEST;
									
									// Send Join Request to Peer
									_sendJoinRequest(context, peer, optlen, opt);
									
									// Return Success
									return 0;
								}
							}
							
							// P2P Mode
							else
							{
								// Already connected
								if(_findP2P(context) != NULL) return ADHOC_MATCHING_ALREADY_ESTABLISHED;
								
								// Outgoing Request in Progress
								if(_findOutgoingRequest(context) != NULL) return ADHOC_MATCHING_REQUEST_IN_PROGRESS;
								
								// Join Request Mode
								if(peer->state == ADHOC_MATCHING_PEER_OFFER)
								{
									// Switch into Join Request Mode
									peer->state = ADHOC_MATCHING_PEER_OUTGOING_REQUEST;
									
									// Send Join Request to Peer
									_sendJoinRequest(context, peer, optlen, opt);
									
									// Return Success
									return 0;
								}
								
								// Requesting Peer
								else if(peer->state == ADHOC_MATCHING_PEER_INCOMING_REQUEST)
								{
									// Accept Peer in Group
									peer->state = ADHOC_MATCHING_PEER_P2P;
									
									// Send Accept Confirmation to Peer
									_sendAcceptMessage(context, peer, optlen, opt);
									
									// Return Success
									return 0;
								}
							}
							
							// How did this happen?! It shouldn't!
							return ADHOC_MATCHING_TARGET_NOT_READY;
						}
						
						// Invalid Optional Data Length
						return ADHOC_MATCHING_INVALID_OPTLEN;
					}
					
					// Peer not found
					return ADHOC_MATCHING_UNKNOWN_TARGET;
				}
				
				// Idle Context
				return ADHOC_MATCHING_NOT_RUNNING;
			}
			
			// Invalid Matching ID
			return ADHOC_MATCHING_INVALID_ID;
		}
		
		// Invalid Arguments
		return ADHOC_MATCHING_INVALID_ARG;
	}
	
	// Uninitialized Library
	return ADHOC_MATCHING_NOT_INITIALIZED;
}
Beispiel #13
0
/**
 * Handle Cancel Packet
 * @param context Matching Context Pointer
 * @param sendermac Packet Sender MAC
 * @param length Packet Length
 */
void _actOnCancelPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * sendermac, uint32_t length)
{
	// Find Peer
	SceNetAdhocMatchingMemberInternal * peer = _findPeer(context, sendermac);
	
	// Get Parent
	SceNetAdhocMatchingMemberInternal * parent = _findParent(context);
	
	// Get Outgoing Join Request
	SceNetAdhocMatchingMemberInternal * request = _findOutgoingRequest(context);
	
	// Get P2P Partner
	SceNetAdhocMatchingMemberInternal * p2p = _findP2P(context);
	
	// Interest Condition fulfilled
	if(peer != NULL)
	{
		// Complete Packet Header available
		if(length >= 5)
		{
			// Extract Optional Data Length
			int optlen = 0; memcpy(&optlen, context->rxbuf + 1, sizeof(optlen));
			
			// Complete Valid Packet available
			if(optlen >= 0 && length >= (5 + optlen))
			{
				// Set Default Null Data
				void * opt = NULL;
				
				// Extract Optional Data Pointer
				if(optlen > 0) opt = context->rxbuf + 5;
				
				// Child Mode
				if(context->mode == ADHOC_MATCHING_MODE_CHILD)
				{
					// Join Request denied
					if(request == peer)
					{
						// Spawn Deny Event
						_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_DENY, sendermac, optlen, opt);
						
						// Delete Peer from List
						_deletePeer(context, peer);
					}
					
					// Kicked from Room
					else if(parent == peer)
					{
						// Iterate Peers
						SceNetAdhocMatchingMemberInternal * item = context->peerlist; for(; item != NULL; item = item->next)
						{
							// Established Peer
							if(item->state == ADHOC_MATCHING_PEER_CHILD || item->state == ADHOC_MATCHING_PEER_PARENT)
							{
								// Spawn Leave / Kick Event
								_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_LEAVE, &item->mac, optlen, opt);
							}
						}
						
						// Delete Peer from List
						_clearPeerList(context);
					}
				}
				
				// Parent Mode
				else if(context->mode == ADHOC_MATCHING_MODE_PARENT)
				{
					// Cancel Join Request
					if(peer->state == ADHOC_MATCHING_PEER_INCOMING_REQUEST)
					{
						// Spawn Request Cancel Event
						_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_CANCEL, sendermac, optlen, opt);
						
						// Delete Peer from List
						_deletePeer(context, peer);
					}
					
					// Leave Room
					else if(peer->state == ADHOC_MATCHING_PEER_CHILD)
					{
						// Spawn Leave / Kick Event
						_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_LEAVE, sendermac, optlen, opt);
						
						// Delete Peer from List
						_deletePeer(context, peer);
					}
				}
				
				// P2P Mode
				else
				{
					// Join Request denied
					if(request == peer)
					{
						// Spawn Deny Event
						_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_DENY, sendermac, optlen, opt);
						
						// Delete Peer from List
						_deletePeer(context, peer);
					}
					
					// Kicked from Room
					else if(p2p == peer)
					{
						// Spawn Leave / Kick Event
						_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_LEAVE, sendermac, optlen, opt);
						
						// Delete Peer from List
						_deletePeer(context, peer);
					}
					
					// Cancel Join Request
					else if(peer->state == ADHOC_MATCHING_PEER_INCOMING_REQUEST)
					{
						// Spawn Request Cancel Event
						_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_CANCEL, sendermac, optlen, opt);
						
						// Delete Peer from List
						_deletePeer(context, peer);
					}
				}
			}
		}
	}
}
Beispiel #14
0
/**
 * Handle Accept Packet
 * @param context Matching Context Pointer
 * @param sendermac Packet Sender MAC
 * @param length Packet Length
 */
void _actOnAcceptPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * sendermac, uint32_t length)
{
	// Not a parent context
	if(context->mode != ADHOC_MATCHING_MODE_PARENT)
	{
		// Don't have a master yet
		if((context->mode == ADHOC_MATCHING_MODE_CHILD && _findParent(context) == NULL) || (context->mode == ADHOC_MATCHING_MODE_P2P && _findP2P(context) == NULL))
		{
			// Complete Packet Header available
			if(length >= 9)
			{
				// Extract Optional Data Length
				int optlen = 0; memcpy(&optlen, context->rxbuf + 1, sizeof(optlen));
				
				// Extract Sibling Count
				int siblingcount = 0; memcpy(&siblingcount, context->rxbuf + 5, sizeof(siblingcount));
				
				// Complete Valid Packet available
				if(optlen >= 0 && length >= (9 + optlen + sizeof(SceNetEtherAddr) * siblingcount))
				{
					// Set Default Null Data
					void * opt = NULL;
					
					// Extract Optional Data Pointer
					if(optlen > 0) opt = context->rxbuf + 9;
					
					// Sibling MAC Array Null Data
					SceNetEtherAddr * siblings = NULL;
					
					// Extract Optional Sibling MAC Array
					if(siblingcount > 0) siblings = (SceNetEtherAddr *)(context->rxbuf + 9 + optlen);
					
					// Find Outgoing Request
					SceNetAdhocMatchingMemberInternal * request = _findOutgoingRequest(context);
					
					// We are waiting for a answer to our request...
					if(request != NULL)
					{
						// Find Peer
						SceNetAdhocMatchingMemberInternal * peer = _findPeer(context, sendermac);
						
						// It's the answer we wanted!
						if(request == peer)
						{
							// Change Peer State
							peer->state = (context->mode == ADHOC_MATCHING_MODE_CHILD) ? (ADHOC_MATCHING_PEER_PARENT) : (ADHOC_MATCHING_PEER_P2P);
							
							// Remove Unneeded Peer Information
							_postAcceptCleanPeerList(context);
							
							// Add Sibling Peers
							if(context->mode == ADHOC_MATCHING_MODE_CHILD) _postAcceptAddSiblings(context, siblingcount, siblings);
							
							// IMPORTANT! The Event Order here is ok!
							// Internally the Event Stack appends to the front, so the order will be switched around.
							
							// Spawn Established Event
							_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_ESTABLISHED, sendermac, 0, NULL);
							
							// Spawn Accept Event
							_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_ACCEPT, sendermac, optlen, opt);
						}
					}
				}
			}
		}
	}
}
Beispiel #15
0
/**
 * Handle Join Packet
 * @param context Matching Context Pointer
 * @param sendermac Packet Sender MAC
 * @param length Packet Length
 */
void _actOnJoinPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * sendermac, uint32_t length)
{
	// Not a child mode context
	if(context->mode != ADHOC_MATCHING_MODE_CHILD)
	{
		// We still got a unoccupied slot in our room (Parent / P2P)
		if((context->mode == ADHOC_MATCHING_MODE_PARENT && _countChildren(context) < (context->maxpeers - 1)) || (context->mode == ADHOC_MATCHING_MODE_P2P && _findP2P(context) == NULL))
		{
			// Complete Packet Header available
			if(length >= 5)
			{
				// Extract Optional Data Length
				int optlen = 0; memcpy(&optlen, context->rxbuf + 1, sizeof(optlen));
				
				// Complete Valid Packet available
				if(optlen >= 0 && length >= (5 + optlen))
				{
					// Set Default Null Data
					void * opt = NULL;
					
					// Extract Optional Data Pointer
					if(optlen > 0) opt = context->rxbuf + 5;
					
					// Find Peer
					SceNetAdhocMatchingMemberInternal * peer = _findPeer(context, sendermac);
					
					// If we got the peer in the table already and are a parent, there is nothing left to be done.
					// This is because the only way a parent can know of a child is via a join request...
					// If we thus know of a possible child, then we already had a previous join request thus no need for double tapping.
					if(peer != NULL && context->mode == ADHOC_MATCHING_MODE_PARENT) return;
					
					// New Peer
					if(peer == NULL)
					{
						// Allocate Memory
						peer = (SceNetAdhocMatchingMemberInternal *)_malloc(sizeof(SceNetAdhocMatchingMemberInternal));
						
						// Allocated Memory
						if(peer != NULL)
						{
							// Clear Memory
							memset(peer, 0, sizeof(SceNetAdhocMatchingMemberInternal));
							
							// Copy Sender MAC
							peer->mac = *sendermac;
							
							// Set Peer State
							peer->state = ADHOC_MATCHING_PEER_INCOMING_REQUEST;
							
							// Initialize Ping Timer
							peer->lastping = sceKernelGetSystemTimeWide();
							
							// Link Peer into List
							peer->next = context->peerlist;
							context->peerlist = peer;
							
							// Spawn Request Event
							_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_REQUEST, sendermac, optlen, opt);
							
							// Return Success
							return;
						}
					}
					
					// Existing Peer (this case is only reachable for P2P mode)
					else
					{
						// Set Peer State
						peer->state = ADHOC_MATCHING_PEER_INCOMING_REQUEST;
						
						// Spawn Request Event
						_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_REQUEST, sendermac, optlen, opt);
						
						// Return Success
						return;
					}
				}
			}
		}
		
		// Auto-Reject Player
		_sendCancelPacket(context, sendermac, 0, NULL);
	}
}
Beispiel #16
0
/**
 * Send Accept Packet to Player
 * @param context Matching Context Pointer
 * @param mac Target Player MAC
 * @param optlen Optional Data Length
 * @param opt Optional Data
 */
void _sendAcceptPacket(SceNetAdhocMatchingContext * context, SceNetEtherAddr * mac, int optlen, void * opt)
{
	// Find Peer
	SceNetAdhocMatchingMemberInternal * peer = _findPeer(context, mac);
	
	// Found Peer
	if(peer != NULL && (peer->state == ADHOC_MATCHING_PEER_CHILD || peer->state == ADHOC_MATCHING_PEER_P2P))
	{
		// Required Sibling Buffer
		uint32_t siblingbuflen = 0;
		
		// Parent Mode
		if(context->mode == ADHOC_MATCHING_MODE_PARENT) siblingbuflen = sizeof(SceNetEtherAddr) * (_countConnectedPeers(context) - 2);
		
		// Sibling Count
		int siblingcount = siblingbuflen / sizeof(SceNetEtherAddr);
		
		// Allocate Accept Message Buffer
		uint8_t * accept = (uint8_t *)_malloc(9 + optlen + siblingbuflen);
	
		// Allocated Accept Message Buffer
		if(accept != NULL)
		{
			// Accept Opcode
			accept[0] = ADHOC_MATCHING_PACKET_ACCEPT;
			
			// Optional Data Length
			memcpy(accept + 1, &optlen, sizeof(optlen));
			
			// Sibling Count
			memcpy(accept + 5, &siblingcount, sizeof(siblingcount));
			
			// Copy Optional Data
			if(optlen > 0) memcpy(accept + 9, opt, optlen);
			
			// Parent Mode Extra Data required
			if(context->mode == ADHOC_MATCHING_MODE_PARENT && siblingcount > 0)
			{
				// Create MAC Array Pointer
				uint8_t * siblingmacs = (uint8_t *)(accept + 9 + optlen);
				
				// MAC Writing Pointer
				int i = 0;
				
				// Iterate Peer List
				SceNetAdhocMatchingMemberInternal * item = context->peerlist; for(; item != NULL; item = item->next)
				{
					// Ignore Target
					if(item == peer) continue;
					
					// Copy Child MAC
					if(item->state == ADHOC_MATCHING_PEER_CHILD)
					{
						// Clone MAC the stupid memcpy way to shut up PSP CPU
						memcpy(siblingmacs + sizeof(SceNetEtherAddr) * i++, &item->mac, sizeof(SceNetEtherAddr));
					}
				}
			}
			
			// Send Data
			sceNetAdhocPdpSend(context->socket, mac, context->port, accept, 9 + optlen + siblingbuflen, 0, ADHOC_F_NONBLOCK);
			
			// Free Memory
			_free(accept);
			
			// Spawn Local Established Event
			_spawnLocalEvent(context, ADHOC_MATCHING_EVENT_ESTABLISHED, mac, 0, NULL);
		}
	}
}