/********************************************************************* * @fn nwk_adjustDelay() * * @brief Adjust the retransmit delay. Modify this function to * change the default delay behavior. * * @param existingDelay - default delay * @param confirmStatus - data confirm status * @param bufOptions - network buffer options * * @return delay value - this number is the number of * network event ticks (~2ms). */ uint16 nwk_adjustDelay( uint16 existingDelay, uint8 confirmStatus, uint16 bufOptions ) { uint16 result = existingDelay; uint16 mask; // Random mask uint16 startValue; // Start value switch ( confirmStatus ) { case ZMacTransactionOverFlow: case ZMacChannelAccessFailure: if ( bufOptions & (HANDLE_DELAY | HANDLE_HI_DELAY) ) { // Delay 4 - 18 ms mask = 0x0007; startValue = 2; } break; case ZNwkNoRoute: case ZMAC_NO_RESOURCES: case ZMacNoACK: default: // leave default delay mask = 0; startValue = 0; break; } if ( (mask > 0) && (startValue > 0) ) { result = (osal_rand() & mask) + startValue; } return ( result ); }
/********************************************************************* * @fn SampleApp_ProcessEvent * @brief Generic Application Task event processor. This function * is called to process all events for the task. Events * include timers, messages and any other user defined events. * @param task_id - The OSAL assigned task ID. * @param events - events to process. This is a bit map and can * contain more than one event. * @return none */ uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ) { afIncomingMSGPacket_t *MSGpkt; (void)task_id; // Intentionally unreferenced parameter if ( events & SYS_EVENT_MSG ) { MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); //Databuf = osal_mem_alloc(MSGpkt->cmd.DataLength); while ( MSGpkt ) { switch ( MSGpkt->hdr.event ) { // Received when a messages is received (OTA) for this endpoint case AF_INCOMING_MSG_CMD: SampleApp_MessageMSGCB( MSGpkt ); break; default: break; } // Release the memory osal_msg_deallocate((uint8 *)MSGpkt ); // Next - if one is available MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); } // return unprocessed events return (events ^ SYS_EVENT_MSG); } // Send a message out - This event is generated by a timer // (setup in SampleApp_Init()). if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT ) { SampleApp_SendPeriodicMessage(); //发送数据函数 // Setup to send message again in normal period (+ a little jitter) osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, (SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) ); // return unprocessed events return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT); } // Discard unknown events return 0; }
// << Wayne >> << Digits To Ascii >> -- // << Wayne >> << Random Number Generator 20 bytes >> ++ uint8 *randomGen_Max20bytes(uint8 len) { uint16 randomNum; static uint8 num[20]; uint8 *pNum = num; for( uint8 i = 0; i < len; i++ ) { do{ randomNum = osal_rand(); }while(!(randomNum & 0x00FF)); *pNum++ = randomNum & 0xFF; //randomNum = randomNum>>4; } return num; }
/********************************************************************* * @fn TransmitApp_SendTheMessage * * @brief Send "the" message. * * @param none * * @return none */ void TransmitApp_SendTheMessage( void ) { uint16 len; uint8 tmp; // put the sequence number in the message tmp = HI_UINT8( TransmitApp_TransID ); tmp += (tmp <= 9) ? ('0') : ('A' - 0x0A); TransmitApp_Msg[2] = tmp; tmp = LO_UINT8( TransmitApp_TransID ); tmp += (tmp <= 9) ? ('0') : ('A' - 0x0A); TransmitApp_Msg[3] = tmp; len = TransmitApp_MaxDataLength; #if defined ( TRANSMITAPP_RANDOM_LEN ) len = (uint8)(osal_rand() & 0x7F); if( len > TransmitApp_MaxDataLength || len == 0 ) len = TransmitApp_MaxDataLength; #endif do { tmp = AF_DataRequest( &TransmitApp_DstAddr, &TransmitApp_epDesc, TRANSMITAPP_CLUSTERID_TESTMSG, len, TransmitApp_Msg, &TransmitApp_TransID, TRANSMITAPP_TX_OPTIONS, AF_DEFAULT_RADIUS ); if ( timesToSend ) { timesToSend--; } } while ( (timesToSend != 0) && (afStatus_SUCCESS == tmp) ); if ( afStatus_SUCCESS == tmp ) { pktCounter++; } else { // Error, so wait (10 mSec) and try again. osal_start_timerEx( TransmitApp_TaskID, TRANSMITAPP_SEND_ERR_EVT, 10 ); } }
/********************************************************************* * @fn SampleApp_ProcessEvent * * @brief Generic Application Task event processor. This function * is called to process all events for the task. Events * include timers, messages and any other user defined events. * * @param task_id - The OSAL assigned task ID. * @param events - events to process. This is a bit map and can * contain more than one event. * * @return none */ uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ) { afIncomingMSGPacket_t *MSGpkt; (void)task_id; // Intentionally unreferenced parameter if ( events & SYS_EVENT_MSG ) { MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); while ( MSGpkt ) { switch ( MSGpkt->hdr.event ) { // Received when a key is pressed case KEY_CHANGE: SampleApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys ); break; // Received when a messages is received (OTA) for this endpoint case AF_INCOMING_MSG_CMD: SampleApp_MessageMSGCB( MSGpkt ); break; // Received whenever the device changes state in the network case ZDO_STATE_CHANGE: SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status); if ( //(SampleApp_NwkState == DEV_ZB_COORD)|| //协调器不给自己点播 (SampleApp_NwkState == DEV_ROUTER) || (SampleApp_NwkState == DEV_END_DEVICE) ) { #ifdef MODE_ED //开机或断网后测一次 #endif // Start sending the periodic message in a regular interval. osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT ); } else { // Device is no longer in the network } break; default: break; } // Release the memory osal_msg_deallocate( (uint8 *)MSGpkt ); // Next - if one is available MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); } // return unprocessed events return (events ^ SYS_EVENT_MSG); } // Send a message out - This event is generated by a timer // (setup in SampleApp_Init()). if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT ) { // Send the periodic message //SampleApp_SendPeriodicMessage();//周期性发送函数 //SampleApp_SendPointToPointMessage();//此处替换成点播函数 // Setup to send message again in normal period (+ a little jitter) osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, (SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) ); // return unprocessed events return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT); } // Discard unknown events return 0; }
/********************************************************************* * @fn NIB_init() * * @brief * * Initialize attribute values in NIB * * @param none * * @return none */ void NIB_init() { _NIB.SequenceNum = LO_UINT16(osal_rand()); _NIB.nwkProtocolVersion = ZB_PROT_VERS; _NIB.MaxDepth = MAX_NODE_DEPTH; #if ( NWK_MODE == NWK_MODE_MESH ) _NIB.beaconOrder = BEACON_ORDER_NO_BEACONS; _NIB.superFrameOrder = BEACON_ORDER_NO_BEACONS; #endif // BROADCAST SETTINGS: // ******************* // Broadcast Delivery Time // - set to multiples of 100ms // - should be 500ms more than the retry time // - "retry time" = PassiveAckTimeout * (MaxBroadcastRetries + 1) // Passive Ack Timeout // - set to multiples of 100ms _NIB.BroadcastDeliveryTime = zgBcastDeliveryTime; _NIB.PassiveAckTimeout = zgPassiveAckTimeout; _NIB.MaxBroadcastRetries = zgMaxBcastRetires; _NIB.ReportConstantCost = 0; _NIB.RouteDiscRetries = 0; _NIB.SecureAllFrames = USE_NWK_SECURITY; _NIB.nwkAllFresh = NWK_ALL_FRESH; if ( ZG_SECURE_ENABLED ) { _NIB.SecurityLevel = SECURITY_LEVEL; } else { _NIB.SecurityLevel = 0; } #if defined ( ZIGBEEPRO ) _NIB.SymLink = FALSE; #else _NIB.SymLink = TRUE; #endif _NIB.CapabilityFlags = ZDO_Config_Node_Descriptor.CapabilityFlags; _NIB.TransactionPersistenceTime = zgIndirectMsgTimeout; _NIB.RouteDiscoveryTime = zgRouteDiscoveryTime; _NIB.RouteExpiryTime = zgRouteExpiryTime; _NIB.nwkDevAddress = INVALID_NODE_ADDR; _NIB.nwkLogicalChannel = 0; _NIB.nwkCoordAddress = INVALID_NODE_ADDR; osal_memset( _NIB.nwkCoordExtAddress, 0, Z_EXTADDR_LEN ); _NIB.nwkPanId = INVALID_NODE_ADDR; osal_cpyExtAddr( _NIB.extendedPANID, zgExtendedPANID ); _NIB.nwkKeyLoaded = FALSE; #if defined ( ZIGBEE_STOCHASTIC_ADDRESSING ) _NIB.nwkAddrAlloc = NWK_ADDRESSING_STOCHASTIC; _NIB.nwkUniqueAddr = FALSE; #else _NIB.nwkAddrAlloc = NWK_ADDRESSING_DISTRIBUTED; _NIB.nwkUniqueAddr = TRUE; #endif _NIB.nwkLinkStatusPeriod = NWK_LINK_STATUS_PERIOD; _NIB.nwkRouterAgeLimit = NWK_ROUTE_AGE_LIMIT; //MTO and source routing _NIB.nwkConcentratorDiscoveryTime = zgConcentratorDiscoveryTime; _NIB.nwkIsConcentrator = zgConcentratorEnable; _NIB.nwkConcentratorRadius = zgConcentratorRadius; #if defined ( ZIGBEE_MULTICAST ) _NIB.nwkUseMultiCast = TRUE; #else _NIB.nwkUseMultiCast = FALSE; #endif #if defined ( NV_RESTORE ) if ( osal_nv_read( ZCD_NV_NWKMGR_ADDR, 0, sizeof( _NIB.nwkManagerAddr ), &_NIB.nwkManagerAddr ) != SUCCESS ) #endif { _NIB.nwkManagerAddr = 0x0000; } _NIB.nwkUpdateId = 0; _NIB.nwkTotalTransmissions = 0; if ( ZSTACK_ROUTER_BUILD ) { #if defined ( ZIGBEE_STOCHASTIC_ADDRESSING ) NLME_InitStochasticAddressing(); #else NLME_InitTreeAddressing(); #endif } }
/********************************************************************* * @fn SampleApp_ProcessEvent * * @brief Generic Application Task event processor. This function * is called to process all events for the task. Events * include timers, messages and any other user defined events. * * @param task_id - The OSAL assigned task ID. * @param events - events to process. This is a bit map and can * contain more than one event. * * @return none */ uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ) { afIncomingMSGPacket_t *MSGpkt; (void)task_id; // Intentionally unreferenced parameter if ( events & SYS_EVENT_MSG ) { MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); // ³z¹Losal_msg_receive function ±µ¦¬SampleApp_TaskID¼Ð»x while ( MSGpkt ) { switch ( MSGpkt->hdr.event ) { case KEY_CHANGE: // Received when a key is pressed(·í«ö¤Ukey®É¶i¦æ±µ¦¬) SampleApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys ); break; case AF_INCOMING_MSG_CMD: // Received when a messages is received (OTA) for this endpoint(·íendpoint±µ¦¬¨ìmessage¶i¦æ±µ¦¬) SampleApp_MessageMSGCB( MSGpkt ); break; case ZDO_STATE_CHANGE: // Received whenever the device changes state in the network(¥[¤Jºô¸ô«áª¬ºA§ïÅܮɶi¦æ±µ¦¬) SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status); if ((SampleApp_NwkState == DEV_ZB_COORD) || (SampleApp_NwkState == DEV_ROUTER) || (SampleApp_NwkState == DEV_END_DEVICE) ) { // Start sending the periodic message in a regular interval. ¶}©l¦b©w´Áªº®É¶¡¶¡¹j¶Ç°e©w´Á°T®§ osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT ); } else { /* Device is no longer in the network(device¤£¦b¦¹ºô¸ô¤¤) */ } break; default: break; } // Release the memory osal_msg_deallocate( (uint8 *)MSGpkt ); // Next - if one is available MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID ); } // return unprocessed events return (events ^ SYS_EVENT_MSG); } // Send a message out - This event is generated by a timer (setup in SampleApp_Init()). if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT ) { // Send the periodic message SampleApp_SendPeriodicMessage(); // Setup to send message again in normal period (+ a little jitter) osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT, (SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) ); // return unprocessed events return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT); } // Discard unknown events return 0; }
/********************************************************************* * @fn zclCCServer_Restart_DeviceCB * * @brief Callback from the ZCL commissioning Cluster Library when * it received a Restart Device for this application. * * @param pCmd - restart command * @param srcAddr - source address * @param seqNum - message sequence number * * @return none */ static void zclCCServer_Restart_DeviceCB( zclCCRestartDevice_t *pCmd, afAddrType_t *srcAddr, uint8 seqNum ) { zclCCServerParamsRsp_t rsp; // Make sure the device is not in the Operational Network if ( osal_ExtAddrEqual( _NIB.extendedPANID, zbaGlobalCommissioningEPID ) ) { // If form network or associate from scratch, set the default network state. // Only Coordiunator can form (Option 1) and Router or EndDevices can // associate (Option 3). if ( ( ( zclCCServer_StartUpControl == CC_STARTUP_CONTROL_OPTION_1 ) && // (form && ( zgDeviceLogicalType == ZG_DEVICETYPE_COORDINATOR ) ) || // Coord) || ( ( zclCCServer_StartUpControl == CC_STARTUP_CONTROL_OPTION_3 ) && // (associate && ( ( zgDeviceLogicalType == ZG_DEVICETYPE_ROUTER ) || // (RTR || ( zgDeviceLogicalType == ZG_DEVICETYPE_ENDDEVICE ) ) ) ) // ED)) { // Form or Join a new network rsp.status = SUCCESS; } else { // Startup state is currently not supported rsp.status = ZCL_STATUS_INCONSISTENT_STARTUP_STATE; } } else { // No access to Commissioning cluster in the Operational Network rsp.status = ZCL_STATUS_NOT_AUTHORIZED; } zclCC_Send_RestartDeviceRsp( CCSERVER_ENDPOINT, srcAddr, &rsp, TRUE, seqNum ); if ( rsp.status == SUCCESS ) { uint16 delay; // If restart immediately is specified the should restart at a convienent // time when all messages have been sent. Give 1s for response to be sent // and then restart. Else, calculate the delay time. if ( zcl_CCImmediate( pCmd->options ) ) { delay = 1000; } else { delay = ( pCmd->delay * 1000 ) + ( osal_rand() % ( pCmd->jitter * 80 ) ); } if ( zcl_CCStartupMode( pCmd->options ) == CC_STARTUP_MODE_REPLACE_RESTART ) { zclCCServer_UseStartupParameters(); } // Save the received command for later restartDevice = *pCmd; osal_start_timerEx( zclCCServer_TaskID, CCSERVER_LEAVE_TIMER_EVT, delay ); } }