/****************************************************************************** * @fn zb_FindDeviceRequest * * @brief The zb_FindDeviceRequest function is used to determine the * short address for a device in the network. The device initiating * a call to zb_FindDeviceRequest and the device being discovered * must both be a member of the same network. When the search is * complete, the zv_FindDeviceConfirm callback function is called. * * @param searchType - The type of search to perform. Can be one of following: * ZB_IEEE_SEARCH - Search for 16-bit addr given IEEE addr. * searchKey - Value to search on. * * @return none */ void zb_FindDeviceRequest( uint8 searchType, void *searchKey ) { if (searchType == ZB_IEEE_SEARCH) { ZDP_NwkAddrReq((uint8*) searchKey, ZDP_ADDR_REQTYPE_SINGLE, 0, 0 ); } }
/****************************************************************************** * @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; }
/********************************************************************* * @fn MT_ZdoCommandProcessing * * @brief * * Process all the ZDO 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_ZdoCommandProcessing( uint16 cmd_id , byte len , byte *pData ) { byte i; byte x; byte ret; byte attr; byte attr1; uint16 cID; uint16 shortAddr; uint16 uAttr; byte *ptr; byte *ptr1; zAddrType_t devAddr; zAddrType_t dstAddr; byte respLen; #if defined ( ZDO_MGMT_NWKDISC_REQUEST ) uint32 scanChans; #endif #if defined ( ZDO_USERDESCSET_REQUEST ) UserDescriptorFormat_t userDesc; #endif ret = UNSUPPORTED_COMMAND; len = SPI_0DATA_MSG_LEN + SPI_RESP_LEN_ZDO_DEFAULT; respLen = SPI_RESP_LEN_ZDO_DEFAULT; switch (cmd_id) { case SPI_CMD_ZDO_AUTO_ENDDEVICEBIND_REQ: i = *pData; // Get the endpoint/interface ZDApp_SendEndDeviceBindReq( i ); //Since function type is void, report a succesful operation to the test tool ret = ZSUCCESS; break; case SPI_CMD_ZDO_AUTO_FIND_DESTINATION_REQ: i = *pData; // Get the endpoint/interface ZDApp_AutoFindDestination( i ); //Since function type is void, report a succesful operation to the test tool ret = ZSUCCESS; break; #if defined ( ZDO_NWKADDR_REQUEST ) case SPI_CMD_ZDO_NWK_ADDR_REQ: // Copy and flip incoming 64-bit address pData = zdo_MT_MakeExtAddr( &devAddr, pData ); ptr = (byte*)&devAddr.addr.extAddr; attr = *pData++; // RequestType attr1 = *pData++; // StartIndex x = *pData; ret = (byte)ZDP_NwkAddrReq( ptr, attr, attr1, x ); break; #endif #if defined ( ZDO_IEEEADDR_REQUEST ) case SPI_CMD_ZDO_IEEE_ADDR_REQ: shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += sizeof( shortAddr ); attr = *pData++; // RequestType attr1 = *pData++; // StartIndex x = *pData; // SecuritySuite ret = (byte)ZDP_IEEEAddrReq( shortAddr, attr, attr1, x ); break; #endif #if defined ( ZDO_NODEDESC_REQUEST ) case SPI_CMD_ZDO_NODE_DESC_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData; ret = (byte)ZDP_NodeDescReq( &devAddr, shortAddr, attr ); break; #endif #if defined ( ZDO_POWERDESC_REQUEST ) case SPI_CMD_ZDO_POWER_DESC_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData; ret = (byte)ZDP_PowerDescReq( &devAddr, shortAddr, attr ); break; #endif #if defined ( ZDO_SIMPLEDESC_REQUEST ) case SPI_CMD_ZDO_SIMPLE_DESC_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData++; // endpoint/interface attr1 = *pData; // SecuritySuite ret = (byte)ZDP_SimpleDescReq( &devAddr, shortAddr, attr, attr1 ); break; #endif #if defined ( ZDO_ACTIVEEP_REQUEST ) case SPI_CMD_ZDO_ACTIVE_EPINT_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData; // SecuritySuite ret = (byte)ZDP_ActiveEPReq( &devAddr, shortAddr, attr ); break; #endif #if defined ( ZDO_MATCH_REQUEST ) case SPI_CMD_ZDO_MATCH_DESC_REQ: { uint16 inC[16], outC[16]; // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; uAttr = BUILD_UINT16( pData[1], pData[0] ); // Profile ID pData += 2; attr = *pData++; // NumInClusters for (i=0; i<16; ++i) { inC[i] = BUILD_UINT16(pData[1], pData[0]); pData += 2; } attr1 = *pData++; // NumOutClusters for (i=0; i<16; ++i) { outC[i] = BUILD_UINT16(pData[1], pData[0]); pData += 2; } i = *pData; // SecuritySuite ret = (byte)ZDP_MatchDescReq( &devAddr, shortAddr, uAttr, attr, inC, attr1, outC, i ); } break; #endif #if defined ( ZDO_COMPLEXDESC_REQUEST ) case SPI_CMD_ZDO_COMPLEX_DESC_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData; // SecuritySuite ret = (byte)ZDP_ComplexDescReq( &devAddr, shortAddr, attr ); break; #endif #if defined ( ZDO_USERDESC_REQUEST ) case SPI_CMD_ZDO_USER_DESC_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData; // SecuritySuite ret = (byte)ZDP_UserDescReq( &devAddr, shortAddr, attr ); break; #endif #if defined ( ZDO_ENDDEVICEBIND_REQUEST ) case SPI_CMD_ZDO_END_DEV_BIND_REQ: //TODO: When ZTool supports 16 bits the code below will need to take it into account { uint16 inC[16], outC[16]; // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; x = *pData++; // EPInt uAttr = BUILD_UINT16( pData[1], pData[0] ); // Profile ID pData += 2; attr = *pData++; // NumInClusters for (i=0; i<16; ++i) { inC[i] = BUILD_UINT16(pData[1], pData[0]); pData += 2; } attr1 = *pData++; // NumOutClusters for (i=0; i<16; ++i) { outC[i] = BUILD_UINT16(pData[1], pData[0]); pData += 2; } i = *pData; // SecuritySuite ret = (byte)ZDP_EndDeviceBindReq( &devAddr, shortAddr, x, uAttr, attr, inC, attr1, outC, i ); } break; #endif #if defined ( ZDO_BIND_UNBIND_REQUEST ) case SPI_CMD_ZDO_BIND_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; MT_ReverseBytes( pData, Z_EXTADDR_LEN ); ptr = pData; // SrcAddress pData += Z_EXTADDR_LEN; attr = *pData++; // SrcEPInt cID = BUILD_UINT16( pData[1], pData[0]); // ClusterID pData += 2; dstAddr.addrMode = *pData++; if ( NLME_GetProtocolVersion() == ZB_PROT_V1_0 ) dstAddr.addrMode = Addr64Bit; MT_ReverseBytes( pData, Z_EXTADDR_LEN ); if ( dstAddr.addrMode == Addr64Bit ) { ptr1 = pData; // DstAddress osal_cpyExtAddr( dstAddr.addr.extAddr, ptr1 ); } else { dstAddr.addr.shortAddr = BUILD_UINT16( pData[0], pData[1] ); } // The short address occupies lsb two bytes pData += Z_EXTADDR_LEN; attr1 = *pData++; // DstEPInt x = *pData; // SecuritySuite #if defined ( REFLECTOR ) if ( devAddr.addr.shortAddr == _NIB.nwkDevAddress ) { ZDApp_BindReqCB( 0, &devAddr, ptr, attr, cID, &dstAddr, attr1, x ); ret = ZSuccess; } else #endif ret = (byte)ZDP_BindReq( &devAddr, ptr, attr, cID, &dstAddr, attr1, x ); break; #endif #if defined ( ZDO_BIND_UNBIND_REQUEST ) case SPI_CMD_ZDO_UNBIND_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; MT_ReverseBytes( pData, Z_EXTADDR_LEN ); ptr = pData; // SrcAddress pData += Z_EXTADDR_LEN; attr = *pData++; // SrcEPInt cID = BUILD_UINT16( pData[1], pData[0]); // ClusterID pData += 2; dstAddr.addrMode = *pData++; if ( NLME_GetProtocolVersion() == ZB_PROT_V1_0 ) dstAddr.addrMode = Addr64Bit; MT_ReverseBytes( pData, Z_EXTADDR_LEN ); if ( dstAddr.addrMode == Addr64Bit ) { ptr1 = pData; // DstAddress osal_cpyExtAddr( dstAddr.addr.extAddr, ptr1 ); } else { dstAddr.addr.shortAddr = BUILD_UINT16( pData[0], pData[1] ); } pData += Z_EXTADDR_LEN; attr1 = *pData++; // DstEPInt x = *pData; // SecuritySuite #if defined ( REFLECTOR ) if ( devAddr.addr.shortAddr == _NIB.nwkDevAddress ) { ZDApp_UnbindReqCB( 0, &devAddr, ptr, attr, cID, &dstAddr, attr1, x ); ret = ZSuccess; } else #endif { ret = (byte)ZDP_UnbindReq( &devAddr, ptr, attr, cID, &dstAddr, attr1, x ); } break; #endif #if defined ( ZDO_MGMT_NWKDISC_REQUEST ) case SPI_CMD_ZDO_MGMT_NWKDISC_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; scanChans = BUILD_UINT32( pData[3], pData[2], pData[1], pData[0] ); ret = (byte)ZDP_MgmtNwkDiscReq( &devAddr, scanChans, pData[4], pData[5], false ); break; #endif #if defined ( ZDO_MGMT_LQI_REQUEST ) case SPI_CMD_ZDO_MGMT_LQI_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); ret = (byte)ZDP_MgmtLqiReq( &devAddr, pData[2], false ); break; #endif #if defined ( ZDO_MGMT_RTG_REQUEST ) case SPI_CMD_ZDO_MGMT_RTG_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); ret = (byte)ZDP_MgmtRtgReq( &devAddr, pData[2], false ); break; #endif #if defined ( ZDO_MGMT_BIND_REQUEST ) case SPI_CMD_ZDO_MGMT_BIND_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); ret = (byte)ZDP_MgmtBindReq( &devAddr, pData[2], false ); break; #endif #if defined ( ZDO_MGMT_JOINDIRECT_REQUEST ) case SPI_CMD_ZDO_MGMT_DIRECT_JOIN_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); MT_ReverseBytes( &pData[2], Z_EXTADDR_LEN ); ret = (byte)ZDP_MgmtDirectJoinReq( &devAddr, &pData[2], pData[2 + Z_EXTADDR_LEN], false ); break; #endif #if defined ( ZDO_MGMT_LEAVE_REQUEST ) case SPI_CMD_ZDO_MGMT_LEAVE_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); MT_ReverseBytes( &pData[2], Z_EXTADDR_LEN ); ret = (byte)ZDP_MgmtLeaveReq( &devAddr, &pData[2], false ); break; #endif #if defined ( ZDO_MGMT_PERMIT_JOIN_REQUEST ) case SPI_CMD_ZDO_MGMT_PERMIT_JOIN_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); ret = (byte)ZDP_MgmtPermitJoinReq( &devAddr, pData[2], pData[3], false ); break; #endif #if defined ( ZDO_USERDESCSET_REQUEST ) case SPI_CMD_ZDO_USER_DESC_SET: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // User descriptor userDesc.len = *pData++; osal_memcpy( userDesc.desc, pData, userDesc.len ); pData += 16; // len of user desc ret =(byte)ZDP_UserDescSet( &devAddr, shortAddr, &userDesc, pData[0] ); break; #endif #if defined ( ZDO_ENDDEVICE_ANNCE_REQUEST ) case SPI_CMD_ZDO_END_DEV_ANNCE: // network address shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // extended address ptr = pData; MT_ReverseBytes( ptr, Z_EXTADDR_LEN ); pData += Z_EXTADDR_LEN; // security attr = *pData++; ret = (byte)ZDP_EndDeviceAnnce( shortAddr, ptr, *pData, attr ); break; #endif #if defined (ZDO_SERVERDISC_REQUEST ) case SPI_CMD_ZDO_SERVERDISC_REQ: // Service Mask uAttr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData++; // Security suite ret = (byte) ZDP_ServerDiscReq( uAttr, attr ); break; #endif #if defined (ZDO_NETWORKSTART_REQUEST ) case SPI_CMD_ZDO_NETWORK_START_REQ: ret = ZDApp_StartUpFromApp( ZDAPP_STARTUP_AUTO ); break; #endif default: break; } MT_SendSPIRespMsg( ret, cmd_id, len, respLen ); }