Beispiel #1
0
/*********************************************************************
 * @fn      OTA_ProcessZDOMsgs
 *
 * @brief   Process messages from the ZDO layer.
 *
 * @param   pMsg - The message from the server.
 *
 * @return  none
 */
void OTA_ProcessZDOMsgs(zdoIncomingMsg_t * pMsg)
{
    if (pMsg)
    {
        if (pMsg->clusterID == Match_Desc_rsp)
        {
            ZDO_ActiveEndpointRsp_t *pRsp = ZDO_ParseEPListRsp( pMsg );

            if (pRsp)
            {
                // Notify the console application of the client device's OTA endpoint
                if (pRsp->cnt)
                    OTA_Send_EndpointInd(pRsp->nwkAddr, pRsp->epList[0]);

                osal_mem_free(pRsp);
            }
        }
        else if (pMsg->clusterID == Device_annce)
        {
            cId_t otaCluster = ZCL_CLUSTER_ID_OTA;
            zAddrType_t dstAddr;

            ZDO_DeviceAnnce_t devAnnce;
            ZDO_ParseDeviceAnnce(pMsg, &devAnnce);
            OTA_Send_DeviceInd(devAnnce.nwkAddr);

            // Send out a match for the OTA cluster ID
            dstAddr.addrMode = Addr16Bit;
            dstAddr.addr.shortAddr = devAnnce.nwkAddr;
            ZDP_MatchDescReq( &dstAddr, devAnnce.nwkAddr, ZCL_OTA_SAMPLE_PROFILE_ID,
                              0, NULL, 1, &otaCluster, FALSE );
        }
    }
}
Beispiel #2
0
/*********************************************************************
 * @fn      GenericApp_HandleKeys
 *
 * @brief   Handles all key events for this device.
 *
 * @param   shift - true if in shift/alt.
 * @param   keys - bit field for key events. Valid entries:
 *                 HAL_KEY_SW_4
 *                 HAL_KEY_SW_3
 *                 HAL_KEY_SW_2
 *                 HAL_KEY_SW_1
 *
 * @return  none
 */
void GenericApp_HandleKeys( byte shift, byte keys )
{
  zAddrType_t dstAddr;
  
  // Shift is used to make each button/switch dual purpose.
  if ( shift )
  {
    if ( keys & HAL_KEY_SW_1 )
    {
    }
    if ( keys & HAL_KEY_SW_2 )
    {
    }
    if ( keys & HAL_KEY_SW_3 )
    {
    }
    if ( keys & HAL_KEY_SW_4 )
    {
    }
  }
  else
  {
    if ( keys & HAL_KEY_SW_1 )
    {
    }

    if ( keys & HAL_KEY_SW_2 )
    {
      HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );

      // Initiate an End Device Bind Request for the mandatory endpoint
      dstAddr.addrMode = Addr16Bit;
      dstAddr.addr.shortAddr = 0x0000; // Coordinator
      ZDP_EndDeviceBindReq( &dstAddr, NLME_GetShortAddr(), 
                            GenericApp_epDesc.endPoint,
                            GENERICAPP_PROFID,
                            GENERICAPP_MAX_CLUSTERS, (cId_t *)GenericApp_ClusterList,
                            GENERICAPP_MAX_CLUSTERS, (cId_t *)GenericApp_ClusterList,
                            FALSE );
    }

    if ( keys & HAL_KEY_SW_3 )
    {
    }

    if ( keys & HAL_KEY_SW_4 )
    {
      HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
      // Initiate a Match Description Request (Service Discovery)
      dstAddr.addrMode = AddrBroadcast;
      dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
      ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR,
                        GENERICAPP_PROFID,
                        GENERICAPP_MAX_CLUSTERS, (cId_t *)GenericApp_ClusterList,
                        GENERICAPP_MAX_CLUSTERS, (cId_t *)GenericApp_ClusterList,
                        FALSE );
    }
  }
}
Beispiel #3
0
/*********************************************************************
 * @fn      OTA_ProcessSysApp_DiscoveryReq
 *
 * @brief   Handles app messages from the console application.
 *
 * @param   pData - The data from the server.
 *
 * @return  none
 */
void OTA_ProcessSysApp_DiscoveryReq(uint8 *pData)
{

    cId_t otaCluster = ZCL_CLUSTER_ID_OTA;
    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_OTA_SAMPLE_PROFILE_ID,
                      0, NULL, 1, &otaCluster, FALSE );
}
Beispiel #4
0
/*********************************************************************
 * @fn      zclSampleSw_HandleKeys
 *
 * @brief   Handles all key events for this device.
 *
 * @param   shift - true if in shift/alt.
 * @param   keys - bit field for key events. Valid entries:
 *                 HAL_KEY_SW_4
 *                 HAL_KEY_SW_3
 *                 HAL_KEY_SW_2
 *                 HAL_KEY_SW_1
 *
 * @return  none
 */
static void zclSampleSw_HandleKeys( byte shift, byte keys )
{
  zAddrType_t dstAddr;
  (void)shift;  // Intentionally unreferenced parameter

  if ( keys & HAL_KEY_SW_1 )
  {
    // Using this as the "Light Switch"
#ifdef ZCL_ON_OFF
    zclGeneral_SendOnOff_CmdToggle( SAMPLESW_ENDPOINT, &zclSampleSw_DstAddr, false, 0 );
#endif
  }

  if ( keys & HAL_KEY_SW_2 )
  {
    HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );

    // Initiate an End Device Bind Request, this bind request will
    // only use a cluster list that is important to binding.
    dstAddr.addrMode = afAddr16Bit;
    dstAddr.addr.shortAddr = 0;   // Coordinator makes the match
    ZDP_EndDeviceBindReq( &dstAddr, NLME_GetShortAddr(),
                           SAMPLESW_ENDPOINT,
                           ZCL_HA_PROFILE_ID,
                           0, NULL,   // No incoming clusters to bind
                           ZCLSAMPLESW_BINDINGLIST, bindingOutClusters,
                           TRUE );
  }

  if ( keys & HAL_KEY_SW_3 )
  {
    #ifdef ZCL_LEVEL_CTRL
      uint16 potiVal =  HalAdcRead ( SAMPLESW_POTI_CHANNEL, HAL_ADC_RESOLUTION_8 );
      zclGeneral_SendLevelControlMoveToLevel( SAMPLESW_ENDPOINT, &zclSampleSw_DstAddr, potiVal, SAMPLESW_STD_TRANSTIME, false, 0 );
    #endif
  }

  if ( keys & HAL_KEY_SW_4 )
  {
    HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );

    // Initiate a Match Description Request (Service Discovery)
    dstAddr.addrMode = AddrBroadcast;
    dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
    ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR,
                       ZCL_HA_PROFILE_ID,
                       ZCLSAMPLESW_BINDINGLIST, bindingOutClusters,
                       0, NULL,   // No incoming clusters to bind
                       FALSE );
  }
}
Beispiel #5
0
void ReqMatchDesc(void)
{
      zAddrType_t dstAddr;
     // Initiate a Match Description Request (Service Discovery)
      dstAddr.addrMode = AddrBroadcast;
      dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
#ifdef ZDO_COORDINATOR
      ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR,
                        SERIALAPP_PROFID,
                        SERIALAPP_CENTER_OUT_MAX_CLUSTERS, 
                        (cId_t *)SerialApp_ClusterList,
                        SERIALAPP_CENTER_IN_MAX_CLUSTERS, 
                        (cId_t *)SerialApp_CenterIn_EndOut_ClusterList,
                        FALSE );
#else
      ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR,
                        SERIALAPP_PROFID,
                        SERIALAPP_CENTER_IN_MAX_CLUSTERS, 
                        (cId_t *)SerialApp_CenterIn_EndOut_ClusterList,
                        SERIALAPP_CENTER_OUT_MAX_CLUSTERS, 
                        (cId_t *)SerialApp_ClusterList,
                        FALSE );
#endif
}
/******************************************************************************
 * @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          rangeext_event_loop
 *
 * @brief       Event Loop Processor for rangeext.
 *
 * @param       uint8 task_id - the osal task id
 * @param       uint16 events - the event bitmask
 *
 * @return      none
 */
uint16 rangeext_event_loop( uint8 task_id, uint16 events )
{
  afIncomingMSGPacket_t *MSGpkt;

  if ( events & SYS_EVENT_MSG )
  {
    while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( rangeExtTaskID )) )
    {
      switch ( MSGpkt->hdr.event )
      {
        case ZDO_CB_MSG:
          rangeext_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
          break;

        case ZCL_INCOMING_MSG:
          // Incoming ZCL foundation command/response messages
          rangeext_ProcessZCLMsg( (zclIncomingMsg_t *)MSGpkt );
          break;

        case KEY_CHANGE:
          rangeext_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
          break;

        case ZDO_STATE_CHANGE:
          if (DEV_ROUTER == (devStates_t)(MSGpkt->hdr.status))
          {
#if SECURE
            {
              // check to see if link key had already been established
              linkKeyStatus = rangeext_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
          }
          break;

#if defined( ZCL_KEY_ESTABLISH )
        case ZCL_KEY_ESTABLISH_IND:
          if ((MSGpkt->hdr.status) == TermKeyStatus_Success)
          {
            ESPAddr.endPoint = RANGEEXT_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 & RANGEEXT_KEY_ESTABLISHMENT_REQUEST_EVT )
  {
    zclGeneral_KeyEstablish_InitiateKeyEstablishment(rangeExtTaskID, &ESPAddr, rangeExtTransID);

    return ( events ^ RANGEEXT_KEY_ESTABLISHMENT_REQUEST_EVT );
  }


  // handle processing of identify timeout event triggered by an identify command
  if ( events & RANGEEXT_IDENTIFY_TIMEOUT_EVT )
  {
    if ( rangeExtIdentifyTime > 0 )
    {
      rangeExtIdentifyTime--;
    }
    rangeext_ProcessIdentifyTimeChange();

    return ( events ^ RANGEEXT_IDENTIFY_TIMEOUT_EVT );
  }

  // Discard unknown events
  return 0;
}
/*********************************************************************
 * @fn          loadcontrol_event_loop
 *
 * @brief       Event Loop Processor for loadcontrol.
 *
 * @param       uint8 task id - load control task id
 * @param       uint16 events - event bitmask
 *
 * @return      none
 */
uint16 loadcontrol_event_loop( uint8 task_id, uint16 events )
{
  afIncomingMSGPacket_t *MSGpkt;

  if ( events & SYS_EVENT_MSG )
  {
    while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( loadControlTaskID )) )
    {
      switch ( MSGpkt->hdr.event )
      {
        case ZDO_CB_MSG:
          loadcontrol_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
          break;

        case ZCL_INCOMING_MSG:
          // Incoming ZCL foundation command/response messages
          loadcontrol_ProcessZCLMsg( (zclIncomingMsg_t *)MSGpkt );
          break;

        case KEY_CHANGE:
          loadcontrol_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
          break;

        case ZDO_STATE_CHANGE:
          if (DEV_ROUTER == (devStates_t)(MSGpkt->hdr.status))
          {
#if SECURE
            {
              // check to see if link key had already been established
              linkKeyStatus = loadcontrol_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
          }
          break;

#if defined( ZCL_KEY_ESTABLISH )
        case ZCL_KEY_ESTABLISH_IND:
          if ((MSGpkt->hdr.status) == TermKeyStatus_Success)
          {
            ESPAddr.endPoint = LOADCONTROL_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 & LOADCONTROL_KEY_ESTABLISHMENT_REQUEST_EVT )
  {
    zclGeneral_KeyEstablish_InitiateKeyEstablishment(loadControlTaskID, &ESPAddr, loadControlTransID);

    return ( events ^ LOADCONTROL_KEY_ESTABLISHMENT_REQUEST_EVT );
  }

  // handle processing of identify timeout event triggered by an identify command
  if ( events & LOADCONTROL_IDENTIFY_TIMEOUT_EVT )
  {
    if ( loadControlIdentifyTime > 0 )
    {
      loadControlIdentifyTime--;
    }
    loadcontrol_ProcessIdentifyTimeChange();

    return ( events ^ LOADCONTROL_IDENTIFY_TIMEOUT_EVT );
  }

  // event to get current time
  if ( events & LOADCONTROL_UPDATE_TIME_EVT )
  {
    loadControlTime = osal_getClock();
    osal_start_timerEx( loadControlTaskID, LOADCONTROL_UPDATE_TIME_EVT, LOADCONTROL_UPDATE_TIME_PERIOD );

    return ( events ^ LOADCONTROL_UPDATE_TIME_EVT );
  }

  // event to handle load control complete event
  if ( events & LOADCONTROL_LOAD_CTRL_EVT )
  {
    // 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( LOADCONTROL_ENDPOINT, &ESPAddr,
                                            &rsp, FALSE, loadControlTransID );

    HalLcdWriteString("Load Evt Complete", HAL_LCD_LINE_3);

    HalLedSet(HAL_LED_4, HAL_LED_MODE_OFF);

    return ( events ^ LOADCONTROL_LOAD_CTRL_EVT );

  }

  // Discard unknown events
  return 0;
}
Beispiel #9
0
/*********************************************************************
 * @fn      zcl_EZModeAction
 *
 * @brief   Called when the application needs to inform EZ-Mode of some action
 *          (now on the network, identify mode query, etc...)
 *
 * @param   action - which action has taken place
 *          pData  - the data unique to the action
 *
 * @return  none
 */
void zcl_EZModeAction(zclEzMode_Action_t action, zclEZMode_ActionData_t *pData)
{
  ZDO_MatchDescRsp_t *pMatchDescRsp;
  zAddrType_t dstAddr;

  // not in the EZ-Mode state machine, so do nothing
  if( zclEZModeState == EZMODE_STATE_READY )
    return;

  switch ( action )
  {
    case EZMODE_ACTION_PROCESS:
      zcl_ProcessEZMode();  // process next state
    break;

    case EZMODE_ACTION_NETWORK_STARTED:
      // once on the network, time to go on to the identify state
      if( zclEZModeState == EZMODE_STATE_JOINER )
      {
        // set local permit joining on locally only for joiners (openers turn it on across the network)
        NLME_PermitJoiningRequest( (byte)(EZMODE_TIME / 1000) ); // in seconds
        zcl_SetEZModeState( EZMODE_STATE_IDENTIFYING );
      }
    break;

    // received identify query
    case EZMODE_ACTION_IDENTIFY_QUERY:

      // targets just go to autoclose once they have been identified
      if ( !zclEZModeInvokeData.initiator )
      {
        zcl_SetEZModeState( EZMODE_STATE_AUTOCLOSE );
      }
    break;

    // received identify query response
    case EZMODE_ACTION_IDENTIFY_QUERY_RSP:

      // remember the node we found via identify query
      zclEZModeQueryRspNwkAddr = pData->pIdentifyQueryRsp->srcAddr->addr.shortAddr;
      zclEZModeQueryRspEP = pData->pIdentifyQueryRsp->srcAddr->endPoint;

      // initiate match descriptor request on the remote node
      dstAddr.addrMode = Addr16Bit;
      dstAddr.addr.shortAddr = zclEZModeQueryRspNwkAddr;
      ZDP_MatchDescReq( &dstAddr, zclEZModeQueryRspNwkAddr,
                        ZCL_HA_PROFILE_ID,
                        zclEZModeInvokeData.numActiveOutClusters, zclEZModeInvokeData.pActiveOutClusterIDs,
                        zclEZModeInvokeData.numActiveInClusters, zclEZModeInvokeData.pActiveInClusterIDs,
                        FALSE );
      zcl_SetEZModeState( EZMODE_STATE_WAITING_MATCHDESCRSP );
    break;

    // received match descriptor response, see if active clusters match
    case EZMODE_ACTION_MATCH_DESC_RSP:

      pMatchDescRsp = pData->pMatchDescRsp;
      if ( ( pMatchDescRsp && pMatchDescRsp->status == ZSuccess ) && ( pMatchDescRsp->cnt>0 ) )
      {
        zclEZModeMatched = TRUE;

        // BindingEntry_t *bindAddEntry( byte srcEpInt, zAddrType_t *dstAddr, byte dstEpInt, byte numClusterIds, uint16 *clusterIds )
        dstAddr.addr.shortAddr = zclEZModeQueryRspNwkAddr;
        dstAddr.addrMode = Addr16Bit;

        // bind each matching input cluster
        if ( zclEZModeInvokeData.numActiveInClusters )
        {
          bindAddEntry( zclEZModeInvokeData.endpoint, &dstAddr, zclEZModeQueryRspEP,
                        zclEZModeInvokeData.numActiveInClusters, zclEZModeInvokeData.pActiveInClusterIDs );
        }

        // bind each matching output cluster
        if ( zclEZModeInvokeData.numActiveOutClusters )
        {
          bindAddEntry( zclEZModeInvokeData.endpoint, &dstAddr, zclEZModeQueryRspEP,
                        zclEZModeInvokeData.numActiveOutClusters, zclEZModeInvokeData.pActiveOutClusterIDs );
        }
      }

      // time to close (wait a bit before finishing, to allow for multiple initiators)
      zcl_SetEZModeState( EZMODE_STATE_AUTOCLOSE );
    break;

    // timed out of EZ-Mode
    case EZMODE_ACTION_TIMED_OUT:
      // timed out
      if(zclEZModeState != EZMODE_STATE_READY)
      {
        zcl_SetEZModeError( EZMODE_ERR_TIMEDOUT );
        zcl_SetEZModeState( EZMODE_STATE_FINISH );
      }
    break;
  }   // switch ( action )

}
/*********************************************************************
 * @fn      GenericApp_HandleKeys
 *
 * @brief   Handles all key events for this device.
 *
 * @param   shift - true if in shift/alt.
 * @param   keys - bit field for key events. Valid entries:
 *                 HAL_KEY_SW_4
 *                 HAL_KEY_SW_3
 *                 HAL_KEY_SW_2
 *                 HAL_KEY_SW_1
 *
 * @return  none
 */
static void GenericApp_HandleKeys( uint8 shift, uint8 keys )
{
  zAddrType_t dstAddr;

  // Shift is used to make each button/switch dual purpose.
  if ( shift )
  {
    if ( keys & HAL_KEY_SW_1 )
    {
    }
    if ( keys & HAL_KEY_SW_2 )
    {
    }
    if ( keys & HAL_KEY_SW_3 )
    {
    }
    if ( keys & HAL_KEY_SW_4 )
    {
    }
  }
  else
  {
    if ( keys & HAL_KEY_SW_1 )
    {
      // Since SW1 isn't used for anything else in this application...
#if defined( SWITCH1_BIND )
      // we can use SW1 to simulate SW2 for devices that only have one switch,
      keys |= HAL_KEY_SW_2;
#elif defined( SWITCH1_MATCH )
      // or use SW1 to simulate SW4 for devices that only have one switch
      keys |= HAL_KEY_SW_4;
#endif
    }

    if ( keys & HAL_KEY_SW_2 )
    {
      HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );

      // Initiate an End Device Bind Request for the mandatory endpoint
      dstAddr.addrMode = Addr16Bit;
      dstAddr.addr.shortAddr = 0x0000; // Coordinator
      ZDP_EndDeviceBindReq( &dstAddr, NLME_GetShortAddr(),
                            GenericApp_epDesc.endPoint,
                            GENERICAPP_PROFID,
                            GENERICAPP_MAX_CLUSTERS, (cId_t *)GenericApp_ClusterList,
                            GENERICAPP_MAX_CLUSTERS, (cId_t *)GenericApp_ClusterList,
                            FALSE );
    }

    if ( keys & HAL_KEY_SW_3 )
    {
    }

    if ( keys & HAL_KEY_SW_4 )
    {
      HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
      // Initiate a Match Description Request (Service Discovery)
      dstAddr.addrMode = AddrBroadcast;
      dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
      ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR,
                        GENERICAPP_PROFID,
                        GENERICAPP_MAX_CLUSTERS, (cId_t *)GenericApp_ClusterList,
                        GENERICAPP_MAX_CLUSTERS, (cId_t *)GenericApp_ClusterList,
                        FALSE );
    }
  }
}
//Main function to proccess the timers and events 
uint16 ParkWay_ProcessEvent( uint8 task_id, uint16 events )
{
  afIncomingMSGPacket_t *MSGpkt;
  //afDataConfirm_t *afDataConfirm;
  zAddrType_t dstAddr;

  // Data Confirmation message fields
  //byte sentEP;
  //ZStatus_t sentStatus;
  //byte sentTransID;       // This should match the value sent
  (void)task_id;  // Intentionally unreferenced parameter

  if ( events & SYS_EVENT_MSG )
  {
    MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( ParkWay_TaskID );
    while ( MSGpkt )
    {
      switch ( MSGpkt->hdr.event )
      {
        case ZDO_CB_MSG: //Event trigger by ZigBee Device Object like connect, bind...etc
          ParkWay_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
          break;

        case AF_DATA_CONFIRM_CMD: //Event trigger by a confirmation of sent message
          // This message is received as a confirmation of a data packet sent.
          // The status is of ZStatus_t type [defined in ZComDef.h]
          // The message fields are defined in AF.h
          // afDataConfirm = (afDataConfirm_t *)MSGpkt;
          // sentEP = afDataConfirm->endpoint;
          // sentStatus = afDataConfirm->hdr.status;
          // sentTransID = afDataConfirm->transID;
          // (void)sentEP;
          // (void)sentTransID;

          // // Action taken when confirmation is received.
          // if ( sentStatus != ZSuccess )
          // {
          //   // The data wasn't delivered -- Do something
          // }
          break;

        case AF_INCOMING_MSG_CMD: //Event trigger by a receive message
          ParkWay_MessageMSGCB( MSGpkt );
          break;

        case ZDO_STATE_CHANGE: //Event trigger by a connection to the coordinator or Router
          ParkWay_NwkState = (devStates_t)(MSGpkt->hdr.status);
          if ( (ParkWay_NwkState == DEV_ZB_COORD)
              || (ParkWay_NwkState == DEV_ROUTER)
              || (ParkWay_NwkState == DEV_END_DEVICE) )
          {
            // Start sending the status message in a regular interval.
            osal_start_timerEx( ParkWay_TaskID,
                                ParkWay_SEND_MSG_EVT,
                                ParkWay_SEND_MSG_TIMEOUT );
            // Start reading ultrasonic in a regular interval.
            osal_start_timerEx( ParkWay_TaskID,
                                POLLING_ULTRASONIC,
                                TIME_ULTRA);
          }
          break;

        default:
          break;
      }

      // Release the memory
      osal_msg_deallocate( (uint8 *)MSGpkt );

      // Next
      MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( ParkWay_TaskID );
    }

    // return unprocessed events
    return (events ^ SYS_EVENT_MSG);
  }

  // Send to the coordinator the status of ultrasound
  if ( events & ParkWay_SEND_MSG_EVT )
  {
    // Send "the" message
    ParkWay_SendTheMessage();
    
    // Setup to send message again
    osal_start_timerEx( ParkWay_TaskID,
                        ParkWay_SEND_MSG_EVT,
                        ParkWay_SEND_MSG_TIMEOUT );

    // return unprocessed events
    return (events ^ ParkWay_SEND_MSG_EVT);
  }
  
  if(events & POLLING_ULTRASONIC)
  {
    osal_start_timerEx( ParkWay_TaskID,
                        POLLING_ULTRASONIC,
                        TIME_ULTRA);
    read_ultrasonic();
  }
  
  if(events & POLLING_OF_DEV_EVT) //This force the auto bind to the coordinator or Router
  {
    //HalLedSet ( HAL_LED_1, HAL_LED_MODE_ON);
    // Initiate a Match Description Request (Service Discovery)
    dstAddr.addrMode = AddrBroadcast;
    dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
    ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR,
                      ParkWay_PROFID,
                      ParkWay_MAX_CLUSTERS, (cId_t *)ParkWay_ClusterList,
                      ParkWay_MAX_CLUSTERS, (cId_t *)ParkWay_ClusterList,
                      FALSE );
    osal_start_timerEx( ParkWay_TaskID,
                        POLLING_OF_DEV_EVT,
                        TIME_TO_CONNECT_COORD);
  } 


  HalLedSet( HAL_LED_ALL, HAL_LED_MODE_OFF ); //Shutdown all LEDS to reduce consumption of power
  
  // Discard unknown events
  return 0;
}
Beispiel #12
0
void Serial_callBack(uint8 port, uint8 event)
{
  char theMessageData[] = "Hello";
  zAddrType_t dstAddr;
  zAddrType_t ZAddr;
  
  afAddrType_t myaddr; // use for p2p
  
  char pbuf[3];
  char pbuf1[3];
  uint16 cmd;
  
  uint8 buff[128];
  uint8 readBytes = 0;
  
  uint16 short_ddr;
  uint16 panid;
  uint8 *ieeeAddr;
  
  uint16 *p1;
  
  byte cnt = 0;
  uint8 yy1;
  uint8 yy2;
  
  uint8 i;
  byte nr;
  uint16 devlist[ NWK_MAX_DEVICES + 1];
  associated_devices_t *adp; // delete devices
  
  //short_ddr = GenericApp_DstAddr.addr.shortAddr;
  uint8 startOptions;    
  uint8 logicalType;
  
  logicalType = (uint8)ZDO_Config_Node_Descriptor.LogicalType;
  
            
  readBytes = HalUARTRead(SER_PORT, buff, 127);
  if (readBytes > 0)
  {
    //HalUARTWrite( SER_PORT, "DataRead: ",10);
    // HalUARTWrite( SER_PORT, buff, readBytes);
    if(readBytes == 4)
    {
      if(buff[0] == 'p' && buff[1] == 'i' && buff[2]=='n' && buff[3] == 'g')
      {
          UART_Send_String( "pong", 4 );
      }
    }
    
    if( readBytes == 1)
    {
        yy1 = 1;
        if(buff[0]== 's')
        {
          /// short address
          short_ddr = _NIB.nwkDevAddress;
          
          UART_Send_String( (uint8*)&short_ddr, 2);
          
        }
        if(buff[0] == 'p')
        {
          /// pan id
          panid = _NIB.nwkPanId;
          UART_Send_String( (uint8*)&panid, 2);          
        }
        if(buff[0] == 'c')/// channel
        {
            yy2 = _NIB.nwkLogicalChannel;
            UART_Send_String( (uint8*)&yy2, 1);
            
        }
        if(buff[0] =='m') // mac address
        {
            ieeeAddr = NLME_GetExtAddr();
            UART_Send_String( ieeeAddr, 8);
            
        }

        if( buff[0] ==0xc0) // coordinator 
        {

          set_coordi();       
          return;
        }

        if( buff[0] ==0xe0) // router
        {
          set_router();
          
          return;
        }
        
        if(buff[0] == 0xCA)
        {
          // 使命的招唤
          // read self AssociatedDevList
          for(i=0;i< NWK_MAX_DEVICES; i++)
          {
             nr = AssociatedDevList[ i ].nodeRelation;
             if(nr > 0 && nr < 5) //CHILD_RFD CHILD_RFD_RX_IDLE CHILD_FFD CHILD_FFD_RX_IDLE
             //if( nr != 0XFF)
             {
               //   myaddr.addrMode = (afAddrMode_t)Addr16Bit;
               //   myaddr.endPoint = GENERICAPP_ENDPOINT;
             //  if( AssociatedDevList[ i ].shortAddr != 0x0000)
             //  {
                  //if( AssocIsChild( AssociatedDevList[ i ].shortAddr ) != 1 || AssociatedDevList[ i ].age > NWK_ROUTE_AGE_LIMIT)
                  //if( AssocIsChild( AssociatedDevList[ i ].shortAddr ) == 1 && AssociatedDevList[ i ].age > NWK_ROUTE_AGE_LIMIT )
                 // {
                    //  myaddr.addr.shortAddr = AssociatedDevList[ i ].shortAddr;
                      /*
                      if ( AF_DataRequest( &myaddr, &GenericApp_epDesc, GENERICAPP_CLUSTERID,(byte)osal_strlen( theMessageData ) + 1,
                              (byte *)&theMessageData,
                              &GenericApp_TransID,
                              AF_ACK_REQUEST, AF_DEFAULT_RADIUS ) != afStatus_SUCCESS )
                        {
                          uprint("delete asso");
                        */
                   //       delete_asso( AssociatedDevList[ i ]. addrIdx);
                          
                  // }
                    //    else
                     //   {
                          devlist[yy1] = AssociatedDevList[ i ].shortAddr;
                          yy1++;
                     //   }
                  
                  // }
             }//else {break;}
          }
          devlist[0] = BUILD_UINT16(0xce,  AssocCount(1, 4) );
          UART_Send_String( (uint8*)&devlist[0], yy1*2);
            //p1 = AssocMakeList( &cnt );
            //UART_Send_String( (uint8*)p1,  AssocCount(1, 4)*2);
            //osal_mem_free(p1);
          return;
        }
    }
    
#if defined( ZDO_COORDINATOR )
    // only coordinator can have this function
    if(readBytes == 3)
    {
      
      if( buff[0] == 0xCA || buff[0] == 0x6d)
      {
        // CA xx xx ,send CA to a node ,with it's short address
        ///uprint("it's CA ");
        short_ddr = BUILD_UINT16( buff[1], buff[2] );
        myaddr.addrMode = (afAddrMode_t)Addr16Bit;
        myaddr.endPoint = GENERICAPP_ENDPOINT;
        myaddr.addr.shortAddr = short_ddr;
        
        if ( AF_DataRequest( &myaddr, &GenericApp_epDesc, GENERICAPP_CLUSTERID, 1,
                          (byte *)&buff,
                          &GenericApp_TransID,
                          AF_DISCV_ROUTE, AF_DEFAULT_RADIUS ) != afStatus_SUCCESS )
        {
             AF_DataRequest( &myaddr, &GenericApp_epDesc, GENERICAPP_CLUSTERID, 1,
                          (byte *)&buff,
                          &GenericApp_TransID,
                          AF_DISCV_ROUTE, AF_DEFAULT_RADIUS );
             // send twice only, if it is still not ok, f**k it
          
        }
       return;
      }
    }
          
#endif 
          
    if( readBytes >= 2)
    {
     
      if( buff[0] == 'e' && buff[1] == '#')
      {
          uprint("EndDevice match");
          HalLedSet ( HAL_LED_1, HAL_LED_MODE_OFF );

          dstAddr.addrMode = Addr16Bit;
          dstAddr.addr.shortAddr = 0x0000; // Coordinator
          ZDP_EndDeviceBindReq( &dstAddr, NLME_GetShortAddr(), GenericApp_epDesc.endPoint,
                            GENERICAPP_PROFID,
                            GENERICAPP_MAX_CLUSTERS, (cId_t *)GenericApp_ClusterList,
                            GENERICAPP_MAX_CLUSTERS, (cId_t *)GenericApp_ClusterList,
                            FALSE );
      
      }
 
      if( buff[0] == 'r' && buff[1] == '#')
      {
          uprint("Router Device match");
          
        HalLedSet ( HAL_LED_1, HAL_LED_MODE_FLASH );

      dstAddr.addrMode = AddrBroadcast;
      dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
      ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR,
                        GENERICAPP_PROFID,
                        GENERICAPP_MAX_CLUSTERS, (cId_t *)GenericApp_ClusterList,
                        GENERICAPP_MAX_CLUSTERS, (cId_t *)GenericApp_ClusterList,
                        FALSE );
      
      }
      if(readBytes == 6)
      {
        if(buff[0] == 'p' && buff[1]==':') // pan id
        {
            strncpy(pbuf, &buff[2],2); pbuf[2] = '\0';
            strncpy(pbuf1, &buff[4],2); pbuf1[2] = '\0';
            
            set_panid( BUILD_UINT16( strtol(pbuf1,NULL,16),strtol(pbuf,NULL,16) ));
            if(_NIB.nwkPanId == 0xffff)
            {
              zgWriteStartupOptions (ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_NETWORK_STATE);           
              SystemReset();
            }            
            //SystemResetSoft();
        }
        
        if(buff[0] == 's' && buff[1]==':') // short address
        {
            /*
            strncpy(pbuf, &buff[2],2); pbuf[2] = '\0';
            strncpy(pbuf1, &buff[4],2); pbuf1[2] = '\0';
            _NIB.nwkDevAddress = BUILD_UINT16( strtol(pbuf1,NULL,16),strtol(pbuf,NULL,16));
            */
            
        }
      }
      
      
      cmd = BUILD_UINT16(buff[ 1 + 1], buff[1]);
      if( ( buff[ 0 ] == CPT_SOP) && (cmd == SYS_PING_REQUEST) ) 
      {
        sysPingReqRcvd();
        return;
      }

      if( readBytes == 2)
      {        
        if( buff[0] == 0xcc )
        {
          if( buff[1] > 0x0a && buff[1] < 0x1b )
          {

            _NIB.nwkLogicalChannel = buff[1];
            NLME_UpdateNV(0x01);
            ZMacSetReq( ZMacChannel, &buff[1]);
            
            osal_nv_item_init( ZCD_NV_CHANLIST, sizeof(zgDefaultChannelList), &zgDefaultChannelList);
            
            if( buff[1] == 0x0b)
            {
              zgDefaultChannelList = 0x00000800;
              
            } 
            if (buff[1] == 0x0c )
            {
              zgDefaultChannelList = 0x00001000;
            }            
            if (buff[1] == 0x0d )
            {
              zgDefaultChannelList = 0x00002000;
            }
            if (buff[1] == 0x0e )
            {
              zgDefaultChannelList = 0x00004000;
            }
            if (buff[1] == 0x0f )
            {
              zgDefaultChannelList = 0x00008000;
            }
            if (buff[1] == 0x10 )
            {
              zgDefaultChannelList = 0x00010000;
            }
            if (buff[1] == 0x11 )
            {
              zgDefaultChannelList = 0x00020000;
            }
            if (buff[1] == 0x12 )
            {
              zgDefaultChannelList = 0x00040000;
            }            
            if (buff[1] == 0x13 )
            {
              zgDefaultChannelList = 0x00080000;
            }
            if (buff[1] == 0x14 )
            {
              zgDefaultChannelList = 0x00100000;
            }
            if (buff[1] == 0x15 )
            {
              zgDefaultChannelList = 0x00200000;
            }            
            if (buff[1] == 0x16 )
            {
              zgDefaultChannelList = 0x00400000;
            }
            if (buff[1] == 0x17 )
            {
              zgDefaultChannelList = 0x00800000;
            }
            if (buff[1] == 0x18 )
            {
              zgDefaultChannelList = 0x01000000;
            }

            if (buff[1] == 0x19 )
            {
              zgDefaultChannelList = 0x02000000;
            }
            if (buff[1] == 0x1a )
            {
              zgDefaultChannelList = 0x04000000;
            }
            
            osal_nv_write(  ZCD_NV_CHANLIST, 0 ,sizeof(zgDefaultChannelList), &zgDefaultChannelList);
            
            UART_Send_String( (uint8*)&zgDefaultChannelList, sizeof(zgDefaultChannelList) );

            /*
            _NIB.nwkLogicalChannel = buff[1];
            NLME_UpdateNV(0x01);
            if( osal_nv_write(ZCD_NV_CHANLIST, 0, osal_nv_item_len( ZCD_NV_CHANLIST ), &tmp32) !=  ZSUCCESS)
            {
              uprint("change channel to nv failed");
            }
            */
            /*
            _NIB.nwkLogicalChannel = buff[1];
            ZMacSetReq( ZMacChannel, &buff[1]);
            ZDApp_NwkStateUpdateCB();
            _NIB.nwkTotalTransmissions = 0;
            nwkTransmissionFailures( TRUE );
            */
          }
        }
        
      }// readBytes==2


      ser_process( buff,readBytes );// 中讯威易的协议最小也是2 字节
    }//if( readBytes >= 2)


    AF_DataRequest( &GenericApp_DstAddr, &GenericApp_epDesc,
                       GENERICAPP_CLUSTERID,
                       readBytes,
                       (byte *)&buff,
                       &GenericApp_TransID,
                       AF_DISCV_ROUTE, AF_DEFAULT_RADIUS );
    
      
  } //if (readBytes > 0) 
}
Beispiel #13
0
/*********************************************************************
 * @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 );
}