/****************************************************************************** * @fn zb_StartRequest * * @brief The zb_StartRequest function starts the ZigBee stack. When the * ZigBee stack starts, the device reads configuration parameters * from Nonvolatile memory and the device joins its network. The * ZigBee stack calls the zb_StartConrifm callback function when * the startup process completes. * * @param none * * @return none */ void zb_StartRequest() { uint8 logicalType; zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType ); // Check for bad combinations of compile flag definitions and device type setting. if ((logicalType > ZG_DEVICETYPE_ENDDEVICE) || #if !ZG_BUILD_ENDDEVICE_TYPE // Only RTR or Coord possible. (logicalType == ZG_DEVICETYPE_ENDDEVICE) || #endif #if !ZG_BUILD_RTR_TYPE // Only End Device possible. (logicalType == ZG_DEVICETYPE_ROUTER) || (logicalType == ZG_DEVICETYPE_COORDINATOR) || #elif ZG_BUILD_RTRONLY_TYPE // Only RTR possible. (logicalType == ZG_DEVICETYPE_COORDINATOR) || #elif !ZG_BUILD_JOINING_TYPE // Only Coord possible. (logicalType == ZG_DEVICETYPE_ROUTER) || #endif (0)) { logicalType = ZB_INVALID_PARAMETER; SAPI_SendCback(SAPICB_START_CNF, logicalType, 0); } else { logicalType = ZB_SUCCESS; ZDOInitDevice(zgStartDelay); } return; }
/****************************************************************************** * @fn zb_StartRequest * * @brief The zb_StartRequest function starts the ZigBee stack. When the * ZigBee stack starts, the device reads configuration parameters * from Nonvolatile memory and the device joins its network. The * ZigBee stack calls the zb_StartConrifm callback function when * the startup process completes. * * @param none * * @return none */ void zb_StartRequest() { uint8 logicalType; // Start the device // start delay = min(NWK_START_DELAY, zgStartDelay) + rand() - only for fresh start, not restore if ( zgStartDelay < NWK_START_DELAY ) zgStartDelay = 0; else zgStartDelay -= NWK_START_DELAY; // check that bad combinations of compile flag definitions and device type zb_ReadConfiguration( ZCD_NV_LOGICAL_TYPE, sizeof(uint8), &logicalType ); if ( ( logicalType > ZG_DEVICETYPE_ENDDEVICE ) || #if defined( RTR_NWK ) #if defined( ZDO_COORDINATOR ) // Only RTR or Coord possible ( logicalType == ZG_DEVICETYPE_ENDDEVICE ) || #else // Only RTR possible ( logicalType != ZG_DEVICETYPE_ROUTER ) || #endif #else #if defined( ZDO_COORDINATOR ) // Error ( 1 ) || #else // only ED possible ( logicalType != ZG_DEVICETYPE_ENDDEVICE ) || #endif #endif ( 0 ) ) { // error configuration SAPI_SendCback( SAPICB_START_CNF, ZInvalidParameter, 0 ); } else { ZDOInitDevice(zgStartDelay); } return; }
/****************************************************************************** * @fn zb_SendDataRequest * * @brief The zb_SendDataRequest function initiates transmission of data * to a peer device * * @param destination - The destination of the data. The destination can * be one of the following: * - 16-Bit short address of device [0-0xfffD] * - ZB_BROADCAST_ADDR sends the data to all devices * in the network. * - ZB_BINDING_ADDR sends the data to a previously * bound device. * * commandId - The command ID to send with the message. If the * ZB_BINDING_ADDR destination is used, this parameter * also indicates the binding to use. * * len - The size of the pData buffer in bytes * handle - A handle used to identify the send data request. * txOptions - TRUE if requesting acknowledgement from the destination. * radius - The max number of hops the packet can travel through * before it is dropped. * * @return none */ void zb_SendDataRequest ( uint16 destination, uint16 commandId, uint8 len, uint8 *pData, uint8 handle, uint8 txOptions, uint8 radius ) { afStatus_t status; afAddrType_t dstAddr; txOptions |= AF_DISCV_ROUTE; // Set the destination address if (destination == ZB_BINDING_ADDR) { // Binding dstAddr.addrMode = afAddrNotPresent; } else { // Use short address dstAddr.addr.shortAddr = destination; dstAddr.addrMode = afAddr16Bit; if ( ADDR_NOT_BCAST != NLME_IsAddressBroadcast( destination ) ) { txOptions &= ~AF_ACK_REQUEST; } } dstAddr.panId = 0; // Not an inter-pan message. dstAddr.endPoint = sapi_epDesc.simpleDesc->EndPoint; // Set the endpoint. // Send the message status = AF_DataRequest(&dstAddr, &sapi_epDesc, commandId, len, pData, &handle, txOptions, radius); if (status != afStatus_SUCCESS) { SAPI_SendCback( SAPICB_DATA_CNF, status, handle ); } }
/****************************************************************************** * @fn zb_BindDevice * * @brief The zb_BindDevice function establishes or removes a ‘binding’ * between two devices. Once bound, an application can send * messages to a device by referencing the commandId for the * binding. * * @param create - TRUE to create a binding, FALSE to remove a binding * commandId - The identifier of the binding * pDestination - The 64-bit IEEE address of the device to bind to * * @return The status of the bind operation is returned in the * zb_BindConfirm callback. */ void zb_BindDevice ( uint8 create, uint16 commandId, uint8 *pDestination ) { zAddrType_t destination; uint8 ret = ZB_ALREADY_IN_PROGRESS; if ( create ) { if (sapi_bindInProgress == 0xffff) { if ( pDestination ) { destination.addrMode = Addr64Bit; osal_cpyExtAddr( destination.addr.extAddr, pDestination ); ret = APSME_BindRequest( sapi_epDesc.endPoint, commandId, &destination, sapi_epDesc.endPoint ); if ( ret == ZSuccess ) { // Find nwk addr ZDP_NwkAddrReq(pDestination, ZDP_ADDR_REQTYPE_SINGLE, 0, 0 ); osal_start_timerEx( ZDAppTaskID, ZDO_NWK_UPDATE_NV, 250 ); } } else { ret = ZB_INVALID_PARAMETER; destination.addrMode = Addr16Bit; destination.addr.shortAddr = NWK_BROADCAST_SHORTADDR; if ( ZDO_AnyClusterMatches( 1, &commandId, sapi_epDesc.simpleDesc->AppNumOutClusters, sapi_epDesc.simpleDesc->pAppOutClusterList ) ) { // Try to match with a device in the allow bind mode ret = ZDP_MatchDescReq( &destination, NWK_BROADCAST_SHORTADDR, sapi_epDesc.simpleDesc->AppProfId, 1, &commandId, 0, (cId_t *)NULL, 0 ); } else if ( ZDO_AnyClusterMatches( 1, &commandId, sapi_epDesc.simpleDesc->AppNumInClusters, sapi_epDesc.simpleDesc->pAppInClusterList ) ) { ret = ZDP_MatchDescReq( &destination, NWK_BROADCAST_SHORTADDR, sapi_epDesc.simpleDesc->AppProfId, 0, (cId_t *)NULL, 1, &commandId, 0 ); } if ( ret == ZB_SUCCESS ) { // Set a timer to make sure bind completes #if ( ZG_BUILD_RTR_TYPE ) osal_start_timerEx(sapi_TaskID, ZB_BIND_TIMER, AIB_MaxBindingTime); #else // AIB_MaxBindingTime is not defined for an End Device osal_start_timerEx(sapi_TaskID, ZB_BIND_TIMER, zgApsDefaultMaxBindingTime); #endif sapi_bindInProgress = commandId; return; // dont send cback event } } } SAPI_SendCback( SAPICB_BIND_CNF, ret, commandId ); } else { // Remove local bindings for the commandId BindingEntry_t *pBind; // Loop through bindings an remove any that match the cluster while ( pBind = bindFind( sapi_epDesc.simpleDesc->EndPoint, commandId, 0 ) ) { bindRemoveEntry(pBind); } osal_start_timerEx( ZDAppTaskID, ZDO_NWK_UPDATE_NV, 250 ); } return; }