/**************************************************************************************** * @fn nwk_processFreq * * @brief Process a Frequency application frame. * * input parameters * @param frame - pointer to frame * * @return Disposition for frame: either release (FHS_RELEASE) or replay (FHS_REPLAY). */ fhStatus_t nwk_processFreq(mrfiPacket_t *frame) { fhStatus_t rc = FHS_RELEASE; uint8_t replyType; /* Make sure this is a reply and see if we sent this. Validate the * packet for reception by client app. */ if (SMPL_MY_REPLY == (replyType=nwk_isValidReply(frame, sTid, FB_APP_INFO_OS, FB_TID_OS))) { /* It's a match and it's a reply. Validate the received packet by * returning a 1 so it can be received by the client app. */ MRFI_PostKillSem(); rc = FHS_KEEP; } #if !defined( END_DEVICE ) else if (SMPL_A_REPLY == replyType) { /* no match. if i'm not an ED this is a reply that should be passed on. */ rc = FHS_REPLAY; } #endif /* !END_DEVICE */ else if (SMPL_NOT_REPLY == replyType) { rc = handle_freq_cmd(frame); } return rc; }
fhStatus_t nwk_processPing(mrfiPacket_t *frame) { fhStatus_t rc; uint8_t replyType; /* If we sent this then this is the reply. Validate the * packet for reception by client app. If we didn't send * it then we are the target. Send the reply. */ replyType = nwk_isValidReply(frame, sTid, PB_REQ_OS, PB_TID_OS); if (SMPL_MY_REPLY == replyType) { /* It's a match and it's a reply. Validate the received packet by * returning a 1 so it can be received by the client app. */ MRFI_PostKillSem(); rc = FHS_KEEP; } #if !defined(END_DEVICE) else if (SMPL_A_REPLY == replyType) { /* no match. If I'm not an ED this is a reply that should be passed on. */ rc = FHS_REPLAY; } #endif /* !END_DEVICE */ else { /* No, we didn't send it. Send reply assuming it's a Ping intended for us. */ handlePingRequest(frame); rc = FHS_RELEASE; } return rc; }
/****************************************************************************** * @fn nwk_processMgmt * * @brief Process Management frame. Just save the frame for the Management * app it it is a reply. If it isn't a reply, send the reply in this * thread. * * input parameters * @param frame - pointer to frame to be processed * * output parameters * * @return Keep frame for application, release frame, or replay frame. */ fhStatus_t nwk_processMgmt(mrfiPacket_t *frame) { fhStatus_t rc; uint8_t replyType; /* If we sent this then this is the reply. Validate the * packet for reception by client app. If we didn't send * it then we are the target. send the reply. */ if (SMPL_MY_REPLY == (replyType=nwk_isValidReply(frame, sTid, MB_APP_INFO_OS, MB_TID_OS))) { /* It's a match and it's a reply. Validate the received packet by * returning a 1 so it can be received by the client app. */ MRFI_PostKillSem(); rc = FHS_KEEP; } #if !defined( END_DEVICE ) else if (SMPL_A_REPLY == replyType) { /* no match. if i'm not an ED this is a reply that should be passed on. */ rc = FHS_REPLAY; } #endif /* !END_DEVICE */ else { /* no, we didn't send it. send reply if it's intended for us */ if (!memcmp(MRFI_P_DST_ADDR(frame), nwk_getMyAddress(), NET_ADDR_SIZE)) { smpl_send_mgmt_reply(frame); /* we're done with the frame. */ rc = FHS_RELEASE; } else { rc = FHS_REPLAY; } } (void) replyType; /* keep compiler happy */ return rc; }
fhStatus_t nwk_processLink(mrfiPacket_t *frame) { fhStatus_t rc; uint8_t replyType; /* If we sent this then this is the reply. Validate the * packet for reception by client app. If we didn't send * it then we are the target. send the reply. */ if (SMPL_MY_REPLY == (replyType = nwk_isValidReply(frame, sTid, LB_REQ_OS, LB_TID_OS))) { /* It's a match and it's a reply. Validate the received packet by * returning a 1 so it can be received by the client app. */ MRFI_PostKillSem(); rc = FHS_KEEP; } #if !defined(END_DEVICE) else if (SMPL_A_REPLY == replyType) { /* no match. if i'm not an ED this is a reply that should be passed on. */ rc = FHS_REPLAY; } #endif /* !END_DEVICE */ else { /* No, we didn't send it. Process request assuming it's * intended for us. */ rc = handleLinkRequest(frame); } (void) replyType; /* keep compiler happy when ED built... */ return rc; }
/****************************************************************************** * @fn nwk_join * * @brief Join functioanlity for non-AP devices. Send the Join token * and wait for the reply. * * input parameters * * output parameters * * @return Status of operation. */ smplStatus_t nwk_join(void) { uint8_t msg[JOIN_FRAME_SIZE]; uint32_t linkToken; addr_t apAddr; uint8_t radioState = MRFI_GetRadioState(); smplStatus_t rc = SMPL_NO_JOIN; union { ioctlRawSend_t send; ioctlRawReceive_t recv; } ioctl_info; #if defined( FREQUENCY_AGILITY ) uint8_t i, numChan; freqEntry_t channels[NWK_FREQ_TBL_SIZE]; if (!(numChan=nwk_scanForChannels(channels))) { return SMPL_NO_CHANNEL; } for (i=0; i<numChan; ++i) { nwk_setChannel(&channels[i]); #else { #endif ioctl_info.send.addr = (addr_t *)nwk_getBCastAddress(); ioctl_info.send.msg = msg; ioctl_info.send.len = sizeof(msg); ioctl_info.send.port = SMPL_PORT_JOIN; /* Put join token in */ nwk_putNumObjectIntoMsg((void *)&sJoinToken, msg+J_JOIN_TOKEN_OS, sizeof(sJoinToken)); /* set app info byte */ msg[JB_REQ_OS] = JOIN_REQ_JOIN; msg[JB_TID_OS] = sTid; /* Set number of connections supported. Used only by AP if it is * a data hub. */ msg[J_NUMCONN_OS] = NUM_CONNECTIONS; /* protocol version number */ msg[J_PROTOCOL_VERSION_OS] = nwk_getProtocolVersion(); SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_WRITE, &ioctl_info.send); ioctl_info.recv.port = SMPL_PORT_JOIN; ioctl_info.recv.msg = msg; ioctl_info.recv.addr = &apAddr; /* save AP address from reply */ NWK_CHECK_FOR_SETRX(radioState); NWK_REPLY_DELAY(); NWK_CHECK_FOR_RESTORE_STATE(radioState); if (SMPL_SUCCESS == SMPL_Ioctl(IOCTL_OBJ_RAW_IO, IOCTL_ACT_READ, &ioctl_info.recv)) { uint8_t firstByte = msg[JB_REQ_OS] & (~NWK_APP_REPLY_BIT); /* Sanity check for correct reply frame. Older version * has the length instead of the request as the first byte. */ if ((firstByte == JOIN_REQ_JOIN) || (firstByte == JOIN_REPLY_LEGACY_MSG_LENGTH) ) { /* join reply returns link token */ memcpy(&linkToken, msg+JR_LINK_TOKEN_OS, sizeof(linkToken)); nwk_setLinkToken(linkToken); /* save AP address */ nwk_setAPAddress(&apAddr); sTid++; /* guard against duplicates */ rc = SMPL_SUCCESS; #if defined( FREQUENCY_AGILITY ) break; #endif } } /* TODO: process encryption stuff */ } return rc; } #endif /* ACCESS_POINT */ /****************************************************************************** * @fn nwk_processJoin * * @brief Processes a Join frame. If this is a reply let it go to the * application. Otherwise generate and send the reply. * * input parameters * @param frame - Pointer to Join frame * * output parameters * * @return Keep frame for application, release frame, or replay frame. */ fhStatus_t nwk_processJoin(mrfiPacket_t *frame) { fhStatus_t rc = FHS_RELEASE; uint8_t replyType; /* Make sure this is a reply and see if we sent this. Validate the * packet for reception by client app. */ if (SMPL_MY_REPLY == (replyType=nwk_isValidReply(frame, sTid, JB_REQ_OS, JB_TID_OS))) { /* It's a match and it's a reply. Validate the received packet by * returning a 1 so it can be received by the client app. */ MRFI_PostKillSem(); rc = FHS_KEEP; } #if defined(ACCESS_POINT) else if (SMPL_A_REPLY == replyType) { /* No match. If I'm not an ED this is a reply that should be passed on. */ rc = FHS_REPLAY; } else { /* Send reply if we're an Access Point otherwise ignore the frame. */ if ((SMPL_NOT_REPLY == replyType) && sJoinOK) { handleJoinRequest(frame); } } #elif defined(RANGE_EXTENDER) else {