/*************************************************************************************************** * @fn MT_NlmeNetworkFormationRequest * * @brief Network Formation Request * * @param pBuf - pointer to the received buffer * * @return void ***************************************************************************************************/ void MT_NlmeNetworkFormationRequest(uint8 *pBuf) { uint8 retValue = ZFailure; uint16 panId; uint32 channelList; uint8 cmdId; /* parse header */ cmdId = pBuf[MT_RPC_POS_CMD1]; pBuf += MT_RPC_FRAME_HDR_SZ; /* Build panId */ panId = BUILD_UINT16( pBuf[0], pBuf[1]); pBuf += sizeof(uint16); /* Build the channel list */ channelList = osal_build_uint32(pBuf, 4); pBuf += sizeof(uint32); if ( ZG_BUILD_COORDINATOR_TYPE && ZG_DEVICE_COORDINATOR_TYPE ) { retValue = NLME_NetworkFormationRequest( panId, NULL, channelList, pBuf[0], pBuf[1], pBuf[2], pBuf[3] ); } else { retValue = ZUnsupportedMode; } /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), cmdId, 1, &retValue); }
/********************************************************************* * @fn GenericApp_ProcessRtosMessage * * @brief Receive message from RTOS queue, send response back. * * @param none * * @return none */ static void GenericApp_ProcessRtosMessage( void ) { osalQueue_t inMsg; if ( osal_queue_receive( OsalQueue, &inMsg, 0 ) == pdPASS ) { uint8 cmndId = inMsg.cmnd; uint32 counter = osal_build_uint32( inMsg.cbuf, 4 ); switch ( cmndId ) { case CMD_INCR: counter += 1; /* Increment the incoming counter */ /* Intentionally fall through next case */ case CMD_ECHO: { userQueue_t outMsg; outMsg.resp = RSP_CODE | cmndId; /* Response ID */ osal_buffer_uint32( outMsg.rbuf, counter ); /* Increment counter */ osal_queue_send( UserQueue1, &outMsg, 0 ); /* Send back to UserTask */ break; } default: break; /* Ignore unknown command */ } } }
/********************************************************************* * @fn macSrcMatchGetExtAddrEnBit * * @brief Return the SRCMATCH ExtAddr enable bitmap * * @param none * * @return uint24 - 24 bits bitmap */ static uint24 macSrcMatchGetExtAddrEnableBit( void ) { uint8 buf[MAC_SRCMATCH_ENABLE_BITMAP_LEN]; MAC_RADIO_GET_SRC_EXTEN( buf ); return osal_build_uint32( buf, MAC_SRCMATCH_ENABLE_BITMAP_LEN ); }
/********************************************************************* * @fn macSrcMatchGetShortAddrPendEnBit * * @brief Return the SRCMATCH ShortAddr Pend enable bitmap * * @param none * * @return uint24 - 24 bits bitmap */ static uint24 macSrcMatchGetShortAddrPendEnBit( void ) { uint8 buf[MAC_SRCMATCH_ENABLE_BITMAP_LEN]; MAC_RADIO_GET_SRC_SHORTPENDEN( buf ); return osal_build_uint32( buf, MAC_SRCMATCH_ENABLE_BITMAP_LEN ); }
/************************************************************************************************** * @fn znpBasicCfg * * @brief Process the Conglomerate Basic Configuration command. * * input parameters * * @param pBuf - Pointer to the MT buffer containing the conglomerated configuration. * * output parameters * * None. * * @return None. */ static void znpBasicCfg(uint8 *pBuf) { uint32 t32 = osal_build_uint32( &pBuf[0], 4 ); if (MT_PeriodicMsgRate != t32) { MT_PeriodicMsgRate = t32; (void)osal_start_reload_timer(MT_TaskID, MT_PERIODIC_MSG_EVENT, t32); } t32 = osal_build_uint32( &pBuf[4], 4 ); if (osal_memcmp(&zgDefaultChannelList, &t32, 4) == FALSE) { (void)osal_nv_write(ZCD_NV_CHANLIST, 0, 4, &t32); } uint16 t16 = osal_build_uint16( &pBuf[8] ); if (osal_memcmp(&zgConfigPANID, &t16, 2) == FALSE) { (void)osal_nv_write(ZCD_NV_PANID, 0, 2, &t16); } if (zgDeviceLogicalType != pBuf[10]) { (void)osal_nv_write(ZCD_NV_LOGICAL_TYPE, 0, 1, pBuf+10); } if (pBuf[11] & MT_ZNP_CMD_DISC_RESET_NWK) { pBuf[0] = ZCD_STARTOPT_DEFAULT_NETWORK_STATE; (void)osal_nv_write(ZCD_NV_STARTUP_OPTION, 0, 1, pBuf); #if defined CC2531ZNP SystemResetSoft(); #else SystemReset(); #endif } else if (pBuf[11] & MT_ZNP_CMD_DISC_ZDO_START) { if (devState == DEV_HOLD) { ZDOInitDevice(0); } } }
/*************************************************************************************************** * @fn MT_NlmeOrphanJoinRequest * * @brief Orphan Join Request * * @param pBuf - pointer to the received buffer * * @return void ***************************************************************************************************/ void MT_NlmeOrphanJoinRequest(uint8 *pBuf) { uint8 i, j, attr; uint8 retValue = ZFailure; uint32 channelList; uint8 cmdId; if ( ZSTACK_END_DEVICE_BUILD ) { /* parse header */ cmdId = pBuf[MT_RPC_POS_CMD1]; pBuf += MT_RPC_FRAME_HDR_SZ; /* Channel list bit mask */ channelList = osal_build_uint32(pBuf, 4); pBuf += sizeof(uint32); /* Count number of channels */ j = attr = 0; for (i = 0; i < ED_SCAN_MAXCHANNELS; i++) { if (channelList & (1 << i)) { j++; attr = i; } } /* If only one channel specified */ if (j == 1) { _NIB.scanDuration = *pBuf; _NIB.nwkLogicalChannel = attr; _NIB.channelList = channelList; if ( !_NIB.CapabilityInfo ) { _NIB.CapabilityInfo = ZDO_Config_Node_Descriptor.CapabilityFlags; } devState = DEV_NWK_ORPHAN; retValue = (uint8)NLME_OrphanJoinRequest(channelList, *pBuf); } else { retValue = ZNwkInvalidParam; } } else { retValue = ZUnsupportedMode; } /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), cmdId, 1, &retValue); }
/*************************************************************************************************** * @fn MT_SysSetUtcTime * * @brief Set the OSAL UTC Time. UTC rollover is: 06:28:16 02/07/2136 * * @param pBuf - pointer to time parameters * * @return None ***************************************************************************************************/ void MT_SysSetUtcTime(uint8 *pBuf) { uint8 cmdId; uint8 retStat; UTCTime utcSecs; /* Parse header */ cmdId = pBuf[MT_RPC_POS_CMD1]; pBuf += MT_RPC_FRAME_HDR_SZ; utcSecs = osal_build_uint32( pBuf, 4 ); if ( utcSecs == 0 ) { UTCTimeStruct utc; /* Skip past UTC time */ pBuf += 4; /* Get time and date parameters */ utc.hour = *pBuf++; utc.minutes = *pBuf++; utc.seconds = *pBuf++; utc.month = (*pBuf++) - 1; utc.day = (*pBuf++) - 1; utc.year = osal_build_uint16 ( pBuf ); if ((utc.hour < 24) && (utc.minutes < 60) && (utc.seconds < 60) && (utc.month < 12) && (utc.day < 31) && (utc.year > 1999) && (utc.year < 2136)) { /* Got past the course filter, now check for leap year */ if ((utc.month != 1) || (utc.day < (IsLeapYear( utc.year ) ? 29 : 28))) { /* Numbers look reasonable, convert to UTC */ utcSecs = osal_ConvertUTCSecs( &utc ); } } } if ( utcSecs == 0 ) { /* Bad parameter(s) */ retStat = ZInvalidParameter; } else { /* Parameters accepted, set the time */ osal_setClock( utcSecs ); retStat = ZSuccess; } /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), cmdId, 1, &retStat); }
/********************************************************************* * @fn macSrcMatchGetPendEnBit * * @brief Return the SRCMATCH Pend enable bitmap * * @param none * * @return uint24 - 24 bits bitmap */ static uint24 macSrcMatchGetPendEnBit( void ) { uint8 buf[MAC_SRCMATCH_ENABLE_BITMAP_LEN]; if( macSrcMatchAddrMode == SADDR_MODE_SHORT ) { MAC_RADIO_GET_SRC_SHORTPENDEN( buf ); } else { MAC_RADIO_GET_SRC_EXTENPEND( buf ); } return osal_build_uint32( buf, MAC_SRCMATCH_ENABLE_BITMAP_LEN ); }
/*************************************************************************************************** * @fn MT_NlmeNetworkDiscoveryRequest * * @brief Network Discovery Request * * @param pBuf - pointer to the received buffer * * @return void ***************************************************************************************************/ void MT_NlmeNetworkDiscoveryRequest(uint8 *pBuf) { uint8 retValue = ZFailure; uint8 cmdId; uint32 scanChannels; /* parse header */ cmdId = pBuf[MT_RPC_POS_CMD1]; pBuf += MT_RPC_FRAME_HDR_SZ; /* Scan channels */ scanChannels = osal_build_uint32(pBuf, 4); pBuf += sizeof(uint32); retValue = NLME_NetworkDiscoveryRequest(scanChannels, *pBuf); /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), cmdId, 1, &retValue ); }
/********************************************************************* * @fn MT_NwkCommandProcessing * * @brief * * Process all the NWK commands that are issued by test tool * * @param cmd_id - Command ID * @param len - Length of received SPI data message * @param pData - pointer to received SPI data message * * @return void */ void MT_NwkCommandProcessing( uint16 cmd_id , byte len , byte *pData ) { byte ret; #if defined ( MT_NWK_FUNC ) uint8 dummyExPANID[Z_EXTADDR_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; uint16 dstAddr; #endif #if defined ( MT_NWK_FUNC ) //NWK commands byte attr; byte index; byte dataLen; byte *dataPtr; uint32 channelList; byte databuf[SPI_RESP_LEN_NWK_DEFAULT + NWK_DEFAULT_GET_RESPONSE_LEN]; #if defined( ZDO_COORDINATOR ) uint16 panId; #else byte i,j; #endif #endif // MT_NWK_FUNC len = SPI_0DATA_MSG_LEN + SPI_RESP_LEN_NWK_DEFAULT; ret = (byte)ZSuccess; switch (cmd_id) { #if defined( RTR_NWK ) case SPI_CMD_NLME_PERMIT_JOINING_REQ: //The only information is PermitDuration ret = (byte)NLME_PermitJoiningRequest( *pData ); break; #endif #if defined ( MT_NWK_FUNC ) //NWK commands case SPI_CMD_NWK_INIT: nwk_init( NWK_TaskID ); break; case SPI_CMD_NLDE_DATA_REQ: //First read the DstAddr dstAddr = BUILD_UINT16( pData[1], pData[0] ); pData += sizeof( dstAddr ); //Get the NSDU details dataLen = *pData++; dataPtr = pData; /* For now, skip a length of ZTEST_DEFAULT_DATA_LEN, instead of dataLen. In future ZTOOL releases the data buffer will be only as long as dataLen */ //pData += dataLen; pData += ZTEST_DEFAULT_DATA_LEN; /* pData[0] = NSDUHandlde pData[1] = NSDUHandleOptions pData[3] = SecurityEnable pData[4] = DiscoverRoute pData[5] = RadiusCounter */ ret = (byte)MT_Nwk_DataRequest( dstAddr, dataLen, dataPtr, pData[0], BUILD_UINT16( pData[2], pData[1] ), pData[3], pData[4], pData[5]); break; #if defined( ZDO_COORDINATOR ) case SPI_CMD_NLME_INIT_COORD_REQ: panId = BUILD_UINT16( pData[1], pData[0] ); MT_ReverseBytes( &pData[2], 4 ); channelList = osal_build_uint32( &pData[2], 4 ); ret = (byte)NLME_NetworkFormationRequest( panId, channelList, pData[6], pData[7], pData[8], pData[9] ); break; #endif // ZDO #if defined( RTR_NWK ) case SPI_CMD_NLME_START_ROUTER_REQ: // NOTE: first two parameters are not used, see NLMEDE.h for details ret = (byte)NLME_StartRouterRequest( pData[0], pData[1], pData[2] ); break; #endif // RTR case SPI_CMD_NLME_JOIN_REQ: ret = (byte)NLME_JoinRequest( dummyExPANID, BUILD_UINT16( pData[1], pData[0] ), pData[2], pData[3] ); if ( pData[3] & CAPINFO_RCVR_ON_IDLE ) { // The receiver is on, turn network layer polling off. NLME_SetPollRate( 0 ); NLME_SetQueuedPollRate( 0 ); NLME_SetResponseRate( 0 ); } break; case SPI_CMD_NLME_LEAVE_REQ: { NLME_LeaveReq_t req; // if extAddr is all zeros, it means null pointer.. for( index = 0; ( ( index < Z_EXTADDR_LEN ) && ( pData[index] == 0 ) ) ; index++ ); if ( index == Z_EXTADDR_LEN ) { req.extAddr = NULL; } else { MT_ReverseBytes( pData, Z_EXTADDR_LEN ); req.extAddr = pData; } pData += Z_EXTADDR_LEN; req.removeChildren = FALSE; req.rejoin = FALSE; req.silent = FALSE; ret = (byte)NLME_LeaveReq( &req ); } break; case SPI_CMD_NLME_RESET_REQ: //Its a direct call to reset NWK ret = (byte)NLME_ResetRequest(); break; case SPI_CMD_NLME_GET_REQ: attr = *pData++; index = *pData; databuf[0] = (byte)NLME_GetRequest( (ZNwkAttributes_t )attr, index, &databuf[1] ); len = SPI_0DATA_MSG_LEN + SPI_RESP_LEN_NWK_DEFAULT + NWK_DEFAULT_GET_RESPONSE_LEN; MT_BuildAndSendZToolResponse( len, (SPI_RESPONSE_BIT | SPI_CMD_NLME_GET_REQ), (SPI_RESP_LEN_NWK_DEFAULT + NWK_DEFAULT_GET_RESPONSE_LEN), databuf ); return; // Don't return to this function case SPI_CMD_NLME_SET_REQ: ret = (byte)NLME_SetRequest( (ZNwkAttributes_t)pData[0], pData[1], &pData[2] ); osal_start_timerEx( ZDAppTaskID, ZDO_NWK_UPDATE_NV, 1000 ); break; case SPI_CMD_NLME_NWK_DISC_REQ: MT_ReverseBytes( pData, 4 ); ret = (byte)NLME_NetworkDiscoveryRequest( osal_build_uint32( pData, 4 ), pData[4] ); break; #if !defined( ZDO_COORDINATOR ) case SPI_CMD_NLME_ORPHAN_JOIN_REQ: // Channel list bit mask MT_ReverseBytes( pData, 4 ); channelList = osal_build_uint32( pData, 4 ); // Count number of channels j = attr = 0; for ( i = 0; i < ED_SCAN_MAXCHANNELS; i++ ) { if ( channelList & (1 << i) ) { j++; attr = i; } } // If only one channel specified... if ( j == 1 ) { _NIB.scanDuration = pData[4]; _NIB.nwkLogicalChannel = attr; _NIB.channelList = channelList; if ( !_NIB.CapabilityInfo ) _NIB.CapabilityInfo = ZDO_Config_Node_Descriptor.CapabilityFlags; devState = DEV_NWK_ORPHAN; ret = (byte)NLME_OrphanJoinRequest( channelList, pData[4] ); } else ret = ZNwkInvalidParam; break; #endif // !ZDO #if defined (RTR_NWK) case SPI_CMD_NLME_ROUTE_DISC_REQ: ret = (byte)NLME_RouteDiscoveryRequest( BUILD_UINT16( pData[1], pData[0] ), pData[2] ); break; case SPI_CMD_NLME_DIRECT_JOIN_REQ: MT_ReverseBytes( pData, 8 ); ret = (byte)NLME_DirectJoinRequest( pData, pData[8] ); break; #endif // RTR #endif // MT_NWK_FUNC default: ret = (byte)ZUnsupportedMode; break; } #if defined ( MT_NWK_FUNC ) MT_SendSPIRespMsg( ret, cmd_id, len, SPI_RESP_LEN_NWK_DEFAULT ); #endif (void)len; (void)ret; }