/* @fn LoacationApp_Sleep * @brief Sample Application set allow/disallow sleep mode. * @return none*/ void LoacationApp_Sleep( uint8 allow ) { #if defined( POWER_SAVING ) if ( allow ) { osal_pwrmgr_task_state( NWK_TaskID, PWRMGR_CONSERVE ); NLME_SetPollRate( 0 ); } else { osal_pwrmgr_task_state( NWK_TaskID, PWRMGR_HOLD ); NLME_SetPollRate( 1000 ); } #endif }
/************************************************************************************************** * @fn MHMSAfMsgRx * * @brief This function is called by MHMSSysEvtMsg() to process an incoming AF message. * * input parameters * * @param msg - A pointer to the afIncomingMSGPacket_t packet. * * output parameters * * None. * * @return None. ************************************************************************************************** */ static void MHMSAfMsgRx(afIncomingMSGPacket_t *msg) { uint8 *buf = msg->cmd.Data; if(PanEstablishedwithRouter == FALSE & devState == DEV_ZB_COORD){ if(zap_set_logicalType(ZG_DEVICETYPE_ROUTER)){ HalLcdWriteString("Ready",HAL_LCD_LINE_7); } PanEstablishedwithRouter = TRUE; if (ZSuccess != osal_start_timerEx(MHMSTaskId, MHMS_EVT_ANN, MHMS_DLY_ANN)) { (void)osal_set_event(MHMSTaskId, MHMS_EVT_ANN); } } else if(PanEstablishedwithRouter == FALSE & devState == DEV_ROUTER){ HalLcdWriteString("Ready",HAL_LCD_LINE_7); PanEstablishedwithRouter = TRUE; } else { switch (buf[MHMS_CMD_IDX]) { case MHMS_CMD_DAT: //msg cmd indicates that there is data to be rx MHMSDataRx(msg); break; case MHMS_CMD_BEG: //msg cmd indicates that gate way has sent start cmd to field devices if (INVALID_NODE_ADDR == MHMSAddr) { if(dev_gateway == FALSE){ NLME_SetPollRate(0); if(MHMSEvtDat_sync == FALSE){ (void)osal_set_event(MHMSTaskId, MHMS_EVT_DAT); //Sync Pulsedat event operation } } } MHMSAddr = msg->srcAddr.addr.shortAddr; break; case MHMS_CMD_END: NLME_SetPollRate(POLL_RATE); MHMSAddr = INVALID_NODE_ADDR; break; case MHMS_CMD_DAT_TEST: //This is used for testing different payload sizes. Not used in normal operation MHMSTestingDataRx(msg); break; default: break; } } //end else }
/************************************************************************************************** * @fn pulseAfMsgRx * * @brief This function is called by pulseSysEvtMsg() to process an incoming AF message. * * input parameters * * @param msg - A pointer to the afIncomingMSGPacket_t packet. * * output parameters * * None. * * @return None. ************************************************************************************************** */ static void pulseAfMsgRx(afIncomingMSGPacket_t *msg) { uint8 *buf = msg->cmd.Data; if(PanEstablishedwithRouter == FALSE & devState == DEV_ZB_COORD){ if(zap_set_logicalType(ZG_DEVICETYPE_ROUTER)){ HalLcdWriteString("Should be Router",HAL_LCD_LINE_7); } PanEstablishedwithRouter = TRUE; if (ZSuccess != osal_start_timerEx(pulseTaskId, PULSE_EVT_ANN, PULSE_DLY_ANN)) { (void)osal_set_event(pulseTaskId, PULSE_EVT_ANN); } } else{ switch (buf[PULSE_CMD_IDX]) { case PULSE_CMD_DAT: //Nodes will send this by default pulseDataRx(msg); break; case PULSE_CMD_BEG: if (INVALID_NODE_ADDR == pulseAddr) { NLME_SetPollRate(0); if(PulseEvtDat_sync == FALSE){ (void)osal_set_event(pulseTaskId, PULSE_EVT_DAT); //Sync Pulsedat event operation } } pulseAddr = msg->srcAddr.addr.shortAddr; // BUILD_UINT16(buf[PULSE_ADR_LSB], buf[PULSE_ADR_MSB]); break; case PULSE_CMD_END: NLME_SetPollRate(POLL_RATE); pulseAddr = INVALID_NODE_ADDR; break; case PULSE_CMD_DAT_TEST: //This is used for testing different payload sizes. Not used in normal operation pulseTestingDataRx(msg); break; default: break; } } //end else }
/********************************************************************* * @fn zclSampleSw_ProcessOTAMsgs * * @brief Called to process callbacks from the ZCL OTA. * * @param none * * @return none */ static void zclSampleSw_ProcessOTAMsgs( zclOTA_CallbackMsg_t* pMsg ) { uint8 RxOnIdle; switch(pMsg->ota_event) { case ZCL_OTA_START_CALLBACK: if (pMsg->hdr.status == ZSuccess) { // Speed up the poll rate RxOnIdle = TRUE; ZMacSetReq( ZMacRxOnIdle, &RxOnIdle ); NLME_SetPollRate( 2000 ); } break; case ZCL_OTA_DL_COMPLETE_CALLBACK: if (pMsg->hdr.status == ZSuccess) { // Reset the CRC Shadow and reboot. The bootloader will see the // CRC shadow has been cleared and switch to the new image HalOTAInvRC(); SystemReset(); } else { // slow the poll rate back down. RxOnIdle = FALSE; ZMacSetReq( ZMacRxOnIdle, &RxOnIdle ); NLME_SetPollRate(DEVICE_POLL_RATE); } break; default: break; } }
/*************************************************************************************************** * @fn MT_NlmeJoinRequest * * @brief Join Request * * @param pBuf - pointer to the received buffer * * @return void ***************************************************************************************************/ void MT_NlmeJoinRequest(uint8 *pBuf) { uint8 retValue = ZFailure; uint8 dummyExPANID[Z_EXTADDR_LEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; uint16 panID; uint8 cmdId; networkDesc_t *pNwkDesc; /* parse header */ cmdId = pBuf[MT_RPC_POS_CMD1]; pBuf += MT_RPC_FRAME_HDR_SZ; panID = BUILD_UINT16(pBuf[0], pBuf[1]); if((pNwkDesc = nwk_getNetworkDesc(dummyExPANID,panID, pBuf[2])) != NULL ) { if (pNwkDesc->chosenRouter == INVALID_NODE_ADDR ) { retValue = ZNwkNotPermitted; } else { retValue = NLME_JoinRequest( dummyExPANID, panID, pBuf[2], pBuf[3], pNwkDesc->chosenRouter, pNwkDesc->chosenRouterDepth ); } } else { retValue = ZNwkNotPermitted; } if ( pBuf[3] & CAPINFO_RCVR_ON_IDLE ) { /* The receiver is on, turn network layer polling off. */ NLME_SetPollRate( 0 ); NLME_SetQueuedPollRate( 0 ); NLME_SetResponseRate( 0 ); } /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), cmdId, 1, &retValue); }
/*************************************************************************************************** * @fn MT_NlmeJoinRequest * * @brief Join Request * * @param pBuf - pointer to the received buffer * * @return void ***************************************************************************************************/ void MT_NlmeJoinRequest(uint8 *pBuf) { uint8 retValue = ZFailure; uint8 dummyExPANID[Z_EXTADDR_LEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; uint8 cmdId; /* parse header */ cmdId = pBuf[MT_RPC_POS_CMD1]; pBuf += MT_RPC_FRAME_HDR_SZ; retValue = NLME_JoinRequest(dummyExPANID, BUILD_UINT16(pBuf[0], pBuf[1]), pBuf[2], pBuf[3]); if ( pBuf[6] & CAPINFO_RCVR_ON_IDLE ) { /* The receiver is on, turn network layer polling off. */ NLME_SetPollRate( 0 ); NLME_SetQueuedPollRate( 0 ); NLME_SetResponseRate( 0 ); } /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), cmdId, 1, &retValue); }
/********************************************************************* * @fn pct_event_loop * * @brief Event Loop Processor for PCT * * @param uint8 task_id - the osal task id * @param uint16 events - the event bitmask * * @return none */ uint16 pct_event_loop( uint8 task_id, uint16 events ) { afIncomingMSGPacket_t *MSGpkt; if ( events & SYS_EVENT_MSG ) { while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( pctTaskID )) ) { switch ( MSGpkt->hdr.event ) { case ZDO_CB_MSG: pct_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt ); break; case ZCL_INCOMING_MSG: // Incoming ZCL foundation command/response messages pct_ProcessZCLMsg( (zclIncomingMsg_t *)MSGpkt ); break; case KEY_CHANGE: pct_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys ); break; case ZDO_STATE_CHANGE: if (DEV_END_DEVICE == (devStates_t)(MSGpkt->hdr.status)) { #if SECURE { // check to see if link key had already been established linkKeyStatus = pct_KeyEstablish_ReturnLinkKey(ESPAddr.addr.shortAddr); if (linkKeyStatus != ZSuccess) { cId_t cbkeCluster = ZCL_CLUSTER_ID_GEN_KEY_ESTABLISHMENT; zAddrType_t dstAddr; // Send out a match for the key establishment dstAddr.addrMode = AddrBroadcast; dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR; ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR, ZCL_SE_PROFILE_ID, 1, &cbkeCluster, 0, NULL, FALSE ); } } #endif // Per smart energy spec end device polling requirement of not to poll < 7.5 seconds. NLME_SetPollRate ( SE_DEVICE_POLL_RATE ); } break; #if defined( ZCL_KEY_ESTABLISH ) case ZCL_KEY_ESTABLISH_IND: if ((MSGpkt->hdr.status) == TermKeyStatus_Success) { ESPAddr.endPoint = PCT_ENDPOINT; // set destination endpoint back to application endpoint } break; #endif default: break; } // Release the memory osal_msg_deallocate( (uint8 *)MSGpkt ); } // return unprocessed events return (events ^ SYS_EVENT_MSG); } // event to intiate key establishment request if ( events & PCT_KEY_ESTABLISHMENT_REQUEST_EVT ) { zclGeneral_KeyEstablish_InitiateKeyEstablishment(pctTaskID, &ESPAddr, pctTransID); return ( events ^ PCT_KEY_ESTABLISHMENT_REQUEST_EVT ); } // handle processing of identify timeout event triggered by an identify command if ( events & PCT_IDENTIFY_TIMEOUT_EVT ) { if ( pctIdentifyTime > 0 ) { pctIdentifyTime--; } pct_ProcessIdentifyTimeChange(); return ( events ^ PCT_IDENTIFY_TIMEOUT_EVT ); } // event to get current time if ( events & PCT_UPDATE_TIME_EVT ) { pctTime = osal_getClock(); osal_start_timerEx( pctTaskID, PCT_UPDATE_TIME_EVT, PCT_UPDATE_TIME_PERIOD ); return ( events ^ PCT_UPDATE_TIME_EVT ); } // event to handle pct load control complete event if ( events & PCT_LOAD_CTRL_EVT ) { // pct load control evt completed // Send response back // DisableDefaultResponse is set to FALSE - it is recommended to turn on // default response since Report Event Status Command does not have // a response. rsp.eventStatus = EVENT_STATUS_LOAD_CONTROL_EVENT_COMPLETED; zclSE_LoadControl_Send_ReportEventStatus( PCT_ENDPOINT, &ESPAddr, &rsp, FALSE, pctTransID ); HalLcdWriteString("PCT Evt Complete", HAL_LCD_LINE_3); HalLedSet(HAL_LED_4, HAL_LED_MODE_OFF); return ( events ^ PCT_LOAD_CTRL_EVT ); } // Discard unknown events return 0; }
/********************************************************************* * @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; }
/********************************************************************* * @fn ipd_event_loop * * @brief Event Loop Processor for ipd. * * @param uint8 task_id - ipd task id * @param uint16 events - event bitmask * * @return none */ uint16 ipd_event_loop( uint8 task_id, uint16 events ) { afIncomingMSGPacket_t *MSGpkt; if ( events & SYS_EVENT_MSG ) { while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( ipdTaskID )) ) { switch ( MSGpkt->hdr.event ) { case ZCL_INCOMING_MSG: // Incoming ZCL foundation command/response messages ipd_ProcessZCLMsg( (zclIncomingMsg_t *)MSGpkt ); break; case KEY_CHANGE: ipd_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys ); break; case ZDO_STATE_CHANGE: if (DEV_END_DEVICE == (devStates_t)(MSGpkt->hdr.status)) { #if SECURE { // check to see if link key had already been established linkKeyStatus = ipd_KeyEstablish_ReturnLinkKey(ESPAddr.addr.shortAddr); if (linkKeyStatus != ZSuccess) { // send out key establishment request osal_set_event( ipdTaskID, IPD_KEY_ESTABLISHMENT_REQUEST_EVT); } else { // link key already established, resume sending reports osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD ); } } #else { osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD ); } #endif // Per smart energy spec end device polling requirement of not to poll < 7.5 seconds. NLME_SetPollRate ( SE_DEVICE_POLL_RATE ); } break; #if defined( ZCL_KEY_ESTABLISH ) case ZCL_KEY_ESTABLISH_IND: if ((MSGpkt->hdr.status) == TermKeyStatus_Success) { osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD ); } break; #endif default: break; } // Release the memory osal_msg_deallocate( (uint8 *)MSGpkt ); } // return unprocessed events return (events ^ SYS_EVENT_MSG); } // event to intiate key establishment request if ( events & IPD_KEY_ESTABLISHMENT_REQUEST_EVT ) { zclGeneral_KeyEstablish_InitiateKeyEstablishment(ipdTaskID, &ESPAddr, ipdTransID); return ( events ^ IPD_KEY_ESTABLISHMENT_REQUEST_EVT ); } // event to get current price if ( events & IPD_GET_PRICING_INFO_EVT ) { zclSE_Pricing_Send_GetCurrentPrice( IPD_ENDPOINT, &ESPAddr, option, TRUE, 0 ); osal_start_timerEx( ipdTaskID, IPD_GET_PRICING_INFO_EVT, IPD_GET_PRICING_INFO_PERIOD ); return ( events ^ IPD_GET_PRICING_INFO_EVT ); } // handle processing of identify timeout event triggered by an identify command if ( events & IPD_IDENTIFY_TIMEOUT_EVT ) { if ( ipdIdentifyTime > 0 ) { ipdIdentifyTime--; } ipd_ProcessIdentifyTimeChange(); return ( events ^ IPD_IDENTIFY_TIMEOUT_EVT ); } // event to get current time if ( events & IPD_UPDATE_TIME_EVT ) { ipdTime = osal_getClock(); osal_start_timerEx( ipdTaskID, IPD_UPDATE_TIME_EVT, IPD_UPDATE_TIME_PERIOD ); return ( events ^ IPD_UPDATE_TIME_EVT ); } // Discard unknown events return 0; }