/** * 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; }
/** * 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; }
/** * Start Matching Context * @param id Matching Context ID * @param event_th_prio Event Thread Priority * @param event_th_stack Event Thread Stack * @param input_th_prio IO Thread Priority * @param input_th_stack IO Thread Stack * @param hello_optlen Hello Data Length * @param hello_opt Hello Data * @return 0 on success or... ADHOC_MATCHING_NOT_INITIALIZED, ADHOC_MATCHING_STACKSIZE_TOO_SHORT, ADHOC_MATCHING_INVALID_ID, ADHOC_MATCHING_IS_RUNNING, ADHOC_MATCHING_INVALID_OPTLEN, ADHOC_MATCHING_NO_SPACE */ int proNetAdhocMatchingStart(int id, int event_th_prio, int event_th_stack, int input_th_prio, int input_th_stack, int hello_optlen, const void * hello_opt) { // Library initialized if(_init == 1) { // Find Matching Context for ID SceNetAdhocMatchingContext * context = _findMatchingContext(id); // Found Matching Context if(context != NULL) { // Context not running yet if(!context->running) { // Valid Hello Data Length if((hello_optlen == 0 && hello_opt == NULL) || (hello_optlen > 0 && hello_opt != NULL)) { // Thread-Safe Hello Data void * safe_hello_opt = NULL; // Cloning Required if(hello_optlen > 0) { // Allocate Memory safe_hello_opt = _malloc(hello_optlen); // Clone Data if(safe_hello_opt != NULL) memcpy(safe_hello_opt, hello_opt, hello_optlen); // Out of Memory else return ADHOC_MATCHING_NO_SPACE; } // Save Hello Data context->hellolen = hello_optlen; context->hello = safe_hello_opt; // Setup Threads if(_setupMatchingThreads(context, event_th_prio, event_th_stack, input_th_prio, input_th_stack) == 0) { // Set Running Bit context->running = 1; // Start Success return 0; } // Clean up Memory on Thread Setup Failure else { // Free Hello Data Buffer _free(context->hello); // Delete Hello Data Information context->hellolen = 0; context->hello = NULL; } // Out of Memory return ADHOC_MATCHING_NO_SPACE; } // Invalid Hello Data Length return ADHOC_MATCHING_INVALID_OPTLEN; } // Already started return ADHOC_MATCHING_IS_RUNNING; } // Invalid Matching ID return ADHOC_MATCHING_INVALID_ID; } // Uninitialized Library return ADHOC_MATCHING_NOT_INITIALIZED; }
/** * Get Member List * @return 0 on success or... ADHOC_MATCHING_NOT_INITIALIZED, ADHOC_MATCHING_INVALID_ARG, ADHOC_MATCHING_INVALID_ID, ADHOC_MATCHING_NOT_RUNNING */ int proNetAdhocMatchingGetMembers(int id, int * buflen, SceNetAdhocMatchingMember * buf) { // Initialized Library if(_init == 1) { // Find Matching Context SceNetAdhocMatchingContext * context = _findMatchingContext(id); // Found Context if(context != NULL) { // Running Context if(context->running) { // Length Buffer available if(buflen != NULL) { // Number of Connected Peers uint32_t peercount = _countConnectedPeers(context); // Calculate Connected Peer Bytesize int available = sizeof(SceNetAdhocMatchingMember) * peercount; // Length Returner Mode if(buf == NULL) { // Get Connected Peer Count *buflen = available; } // Normal Mode else { // Fix Negative Length if((*buflen) < 0) *buflen = 0; // Fix Oversize Request if((*buflen) > available) *buflen = available; // Clear Memory memset(buf, 0, *buflen); // Calculate Requested Peer Count int requestedpeers = (*buflen) / sizeof(SceNetAdhocMatchingMember); // Filled Request Counter int filledpeers = 0; // Add Self-Peer if(requestedpeers > 0) { // Add Local MAC buf[filledpeers++].addr = context->mac; // Room for more than local peer if(requestedpeers > 1) { // P2P Mode if(context->mode == ADHOC_MATCHING_MODE_P2P) { // Find P2P Brother SceNetAdhocMatchingMemberInternal * p2p = _findP2P(context); // P2P Brother found if(p2p != NULL) { // Add P2P Brother MAC buf[filledpeers++].addr = p2p->mac; } } // Parent or Child Mode else { // Iterate Peer List SceNetAdhocMatchingMemberInternal * peer = context->peerlist; for(; peer != NULL && filledpeers < requestedpeers; peer = peer->next) { // Parent Mode if(context->mode == ADHOC_MATCHING_MODE_PARENT) { // Interested in Children (Michael Jackson Style) if(peer->state == ADHOC_MATCHING_PEER_CHILD) { // Add Child MAC buf[filledpeers++].addr = peer->mac; } } // Children Mode else { // Interested in Parent & Siblings if(peer->state == ADHOC_MATCHING_PEER_CHILD || peer->state == ADHOC_MATCHING_PEER_PARENT) { // Add Peer MAC buf[filledpeers++].addr = peer->mac; } } } } // Link Result List int i = 0; for(; i < filledpeers - 1; i++) { // Link Next Element buf[i].next = &buf[i + 1]; } } } // Fix Buffer Size *buflen = sizeof(SceNetAdhocMatchingMember) * filledpeers; } // Return Success return 0; } // Invalid Arguments return ADHOC_MATCHING_INVALID_ARG; } // Context not running return ADHOC_MATCHING_NOT_RUNNING; } // Invalid Matching ID return ADHOC_MATCHING_INVALID_ID; } // Uninitialized Library return ADHOC_MATCHING_NOT_INITIALIZED; }