/****************************************************************************** * @fn nwk_joinInit * * @brief Initialize Join application. * * input parameters * * output parameters * * @return void */ void nwk_joinInit(uint8_t (*pf)(linkID_t)) { //-----MSP-EXP430F5137 Edit //-----To modify link token //---before if (!sJoinToken) { sJoinToken = DEFAULT_JOIN_TOKEN; } //---after // sJoinToken = (*(uint32_t *)0x01A0E); spCallback = pf; (void) spCallback; /* keep compiler happy if we don't use this */ sTid = MRFI_RandomByte() ; #ifdef ACCESS_POINT /* set link token to something other than deafult if desired */ nwk_setLinkToken(generateLinkToken()); #if defined(STARTUP_JOINCONTEXT_ON) sJoinOK = 1; #elif defined(STARTUP_JOINCONTEXT_OFF) sJoinOK = 0; #else #error ERROR: Must define either STARTUP_JOINCONTEXT_ON or STARTUP_JOINCONTEXT_OFF #endif spSandFContext = nwk_getSFInfoPtr(); #endif return; }
/****************************************************************************** * @fn SMPL_Ioctl * * @brief This routine supplies the SimpliciTI IOCTL support. * * input parameters * @param object - The IOCTL target object * @param action - The IOCTL target action on the object * @param val - pointer to value. exact forn depends on object type. * * output parameters * * @return Status of action. Value depends on object, action, and result. * * SMPL_BAD_PARAM is returned if this API is called before * initialization and the object is not one of * the valid exceptions. */ smplStatus_t SMPL_Ioctl(ioctlObject_t object, ioctlAction_t action, void *val) { smplStatus_t rc; /* if init hasn't occurred see if access is still valid */ if (!sInit_done && !ioctlPreInitAccessIsOK(object)) { return SMPL_BAD_PARAM; } switch (object) { #if defined(EXTENDED_API) case IOCTL_OBJ_TOKEN: { ioctlToken_t *t = (ioctlToken_t *)val; rc = SMPL_SUCCESS; if (TT_LINK == t->tokenType) { if (IOCTL_ACT_SET == action) { nwk_setLinkToken(t->token.linkToken); } else if (IOCTL_ACT_GET == action) { nwk_getLinkToken(&t->token.linkToken); } else { rc = SMPL_BAD_PARAM; } } else if (TT_JOIN == t->tokenType) { if (IOCTL_ACT_SET == action) { nwk_setJoinToken(t->token.joinToken); } else if (IOCTL_ACT_GET == action) { nwk_getJoinToken(&t->token.joinToken); } else { rc = SMPL_BAD_PARAM; } } else { rc = SMPL_BAD_PARAM; } } break; case IOCTL_OBJ_NVOBJ: rc = nwk_NVObj(action, (ioctlNVObj_t *)val); break; #endif /* EXTENDED_API */ case IOCTL_OBJ_CONNOBJ: rc = nwk_connectionControl(action, val); break; case IOCTL_OBJ_ADDR: if ((IOCTL_ACT_GET == action) || (IOCTL_ACT_SET == action)) { rc = nwk_deviceAddress(action, (addr_t *)val); } else { rc = SMPL_BAD_PARAM; } break; case IOCTL_OBJ_RAW_IO: if (IOCTL_ACT_WRITE == action) { rc = nwk_rawSend((ioctlRawSend_t *)val); } else if (IOCTL_ACT_READ == action) { rc = nwk_rawReceive((ioctlRawReceive_t *)val); } else { rc = SMPL_BAD_PARAM; } break; case IOCTL_OBJ_RADIO: rc = nwk_radioControl(action, val); break; #if defined(ACCESS_POINT) case IOCTL_OBJ_AP_JOIN: rc = nwk_joinContext(action); break; #endif #if defined(FREQUENCY_AGILITY) case IOCTL_OBJ_FREQ: rc = nwk_freqControl(action, val); break; #endif case IOCTL_OBJ_FWVER: if (IOCTL_ACT_GET == action) { memcpy(val, nwk_getFWVersion(), SMPL_FWVERSION_SIZE); rc = SMPL_SUCCESS; } else { rc = SMPL_BAD_PARAM; } break; case IOCTL_OBJ_PROTOVER: if (IOCTL_ACT_GET == action) { *((uint8_t *)val) = nwk_getProtocolVersion(); rc = SMPL_SUCCESS; } else { rc = SMPL_BAD_PARAM; } break; default: rc = SMPL_BAD_PARAM; break; } 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 {