Exemplo n.º 1
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);
					}
				}
			}
		}
	}
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
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);
						}
					}
				}
			}
		}
	}
}