예제 #1
0
/*********************************************************************
 * @fn      zclApplianceStatistics_LogNotification_OtaToNative
 *
 * @brief   Converts from native to OTA format.
 *
 * @param   pCmd - native format (destination)
 * @param   pZclPayloadLen - OTA ZCL payload (source)
 *
 * @return  none
*/
void zclApplianceStatistics_LogNotification_OtaToNative( zclCmdApplianceStatisticsLogNotificationPayload_t *pCmd, uint8 *pData )
{
  pCmd->timeStamp = BUILD_UINT32( pData[0], pData[1], pData[2], pData[3] );
  pCmd->logID     = BUILD_UINT32( pData[4], pData[5], pData[6], pData[7] );
  pCmd->logLength = BUILD_UINT32( pData[8], pData[9], pData[10], pData[11] );
  pCmd->pLogPayload = &pData[12];
}
예제 #2
0
/******************************************************************************
 * @fn      modbus_single_write
 */
void modbus_single_write( uint8 *data_buffer, uint8 len)
{
  uint8 address;
  
  address = BUILD_UINT16( data_buffer[3], data_buffer[2]);
  
  if( address == MODBUS_PANID)
  {
    zgConfigPANID = BUILD_UINT16( data_buffer[5], data_buffer[4]);
    osal_nv_write( ZCD_NV_PANID, 0, sizeof(zgConfigPANID), &zgConfigPANID);
  }
  else if( address == MODBUS_DEVICE_TYPE)
  {
    zgDeviceLogicalType = data_buffer[5];
    osal_nv_write( ZCD_NV_LOGICAL_TYPE, 0, sizeof(zgDeviceLogicalType), &zgDeviceLogicalType);
    restore_factory_setting();
  }
  else if( address == MODBUS_CHANNEL_LIST_HI)
  {
    zgDefaultChannelList = BUILD_UINT32( 0, 0, data_buffer[5], data_buffer[4]);
  }
  else if( address == MODBUS_CHANNEL_LIST_LO)
  {
    zgDefaultChannelList = BUILD_UINT32( data_buffer[5], data_buffer[4], 0, 0 );
    osal_nv_write( ZCD_NV_CHANLIST, 0, sizeof(zgDefaultChannelList), &zgDefaultChannelList);
  }
  else if( address == MODBUS_FACTORY_RESTORE)
  {
    if(data_buffer[5] == 1)
    {
      restore_factory_setting();
    }
  }
}
예제 #3
0
/*********************************************************************
 * @fn      osal_build_uint32
 *
 * @brief
 *
 *   Build a uint32 out of sequential bytes.
 *
 * @param   swapped - sequential bytes
 * @param   len - number of bytes in the uint8 array
 *
 * @return  uint32
 */
uint32 osal_build_uint32( uint8 *swapped, uint8 len )
{
  if ( len == 2 )
    return ( BUILD_UINT32( swapped[0], swapped[1], 0L, 0L ) );
  else if ( len == 3 )
    return ( BUILD_UINT32( swapped[0], swapped[1], swapped[2], 0L ) );
  else if ( len == 4 )
    return ( BUILD_UINT32( swapped[0], swapped[1], swapped[2], swapped[3] ) );
  else
    return ( (uint32)swapped[0] );
}
예제 #4
0
/*=================================================================================================
 * @fn          rxSecurityHdrIsr
 *
 * @brief       Receive ISR state for reading out and storing the auxiliary security header.
 *
 * @param       none
 *
 * @return      none
 *=================================================================================================
 */
static void rxSecurityHdrIsr(void)
{
  uint8 buf[MAC_FRAME_COUNTER_LEN + MAC_KEY_ID_8_LEN];

  /* read out frame counter and key ID */
  MAC_RADIO_READ_RX_FIFO(buf, rxNextLen);

  /* Incoming frame counter */
  pRxBuf->frameCounter = BUILD_UINT32(buf[0], buf[1], buf[2], buf[3]);
  if (rxNextLen - MAC_FRAME_COUNTER_LEN > 0)
  {
    /* Explicit mode */
    osal_memcpy(pRxBuf->sec.keySource, &buf[MAC_FRAME_COUNTER_LEN], rxNextLen - MAC_FRAME_COUNTER_LEN - 1);
    pRxBuf->sec.keyIndex = buf[rxNextLen - MAC_KEY_INDEX_LEN];
  }

  /* Copy security fields to RX buffer */
  osal_memcpy(pRxBuf->mhr.p, buf, rxNextLen);
  pRxBuf->mhr.p   += rxNextLen;
  pRxBuf->mhr.len += rxNextLen;

  /* Update payload pointer and payload length. The rxPayloadLen includes security header length
   * and SCF byte. The security header and SCF length must be deducted from the rxPayloadLen.
   */
  rxPayloadLen    -= (rxNextLen + MAC_SEC_CONTROL_FIELD_LEN);
  pRxBuf->msdu.len = rxPayloadLen;
  pRxBuf->mhr.len += rxPayloadLen;

  /*-------------------------------------------------------------------------------
   *  Prepare for payload interrupts.
   */
  pFuncRxState = &rxPayloadIsr;
  rxPrepPayload();
}
예제 #5
0
/**************************************************************************************************
 * @fn          afIncMsgPktParse
 *
 * @brief       This function parses an incoming AF data buffer into an afIncomingMSGPacket_t
 *              structure.
 *
 * input parameters
 *
 * @param       cmd1 - The RPC command type: MT_AF_INCOMING_MSG or MT_AF_INCOMING_MSG_EXT.
 * @param       pMsg - Pointer to the afIncomingMSGPacket_t structure.
 * @param       pMsg - Pointer to the afIncomingMSGPacket_t structure.
 *
 * output parameters
 *
 * None.
 *
 * @return      None.
 **************************************************************************************************
 */
static uint8 *afIncMsgPktParse(uint8 cmd1, uint8 *pBuf, afIncomingMSGPacket_t *pMsg)
{
  pMsg->groupId = BUILD_UINT16(pBuf[0], pBuf[1]);
  pBuf += 2;
  pMsg->clusterId = BUILD_UINT16(pBuf[0], pBuf[1]);
  pBuf += 2;

  if (cmd1 == MT_AF_INCOMING_MSG)
  {
    pMsg->srcAddr.addrMode = afAddr16Bit;
    pMsg->srcAddr.addr.shortAddr = BUILD_UINT16(pBuf[0], pBuf[1]);
    pMsg->macDestAddr = pMsg->srcAddr.addr.shortAddr;
    pBuf += 2;
    pMsg->srcAddr.endPoint = *pBuf++;
    pMsg->srcAddr.panId = znpPanId;
  }
  else
  {
    pMsg->srcAddr.addrMode = (afAddrMode_t)*pBuf++;

    if (pMsg->srcAddr.addrMode == afAddr64Bit)
    {
      (void)osal_memcpy(pMsg->srcAddr.addr.extAddr, pBuf, Z_EXTADDR_LEN);
      pMsg->macDestAddr = 0xFFFF;
    }
    else
    {
      pMsg->srcAddr.addr.shortAddr = BUILD_UINT16(pBuf[0], pBuf[1]);
      pMsg->macDestAddr = pMsg->srcAddr.addr.shortAddr;
    }
    pBuf += Z_EXTADDR_LEN;

    pMsg->srcAddr.endPoint = *pBuf++;
    pMsg->srcAddr.panId = BUILD_UINT16(pBuf[0], pBuf[1]);
    pBuf += 2;
  }
  pMsg->endPoint = *pBuf++;
  pMsg->wasBroadcast = *pBuf++;
  pMsg->LinkQuality = *pBuf++;
  pMsg->correlation = pMsg->rssi = 0;
  pMsg->SecurityUse = *pBuf++;
  pMsg->timestamp = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
  pBuf += 4;
  pMsg->cmd.TransSeqNumber = *pBuf++;

  if (cmd1 == MT_AF_INCOMING_MSG)
  {
    pMsg->cmd.DataLength = *pBuf++;
  }
  else
  {
    pMsg->cmd.DataLength = BUILD_UINT16(pBuf[0], pBuf[1]);
    pBuf += 2;
  }
  pMsg->cmd.Data = (uint8 *)(pMsg+1);
  return pBuf;
}
예제 #6
0
파일: ota_common.c 프로젝트: LILCMU/WRATIOT
/******************************************************************************
 * @fn      OTA_StreamToFileId
 *
 * @brief   Reads a file ID from a stream
 *
 * @param   pFileId - File ID
 *          pStream - Stream
 *
 * @return  new stream pointer
 */
uint8 *OTA_StreamToFileId(zclOTA_FileID_t *pFileId, uint8 *pStream)
{
  if (pStream)
  {
    pFileId->manufacturer = BUILD_UINT16(pStream[0], pStream[1]);
    pStream += 2;
    pFileId->type = BUILD_UINT16(pStream[0], pStream[1]);
    pStream += 2;
    pFileId->version = BUILD_UINT32(pStream[0], pStream[1], pStream[2], pStream[3]);
    pStream += 4;
  }

  return pStream;
}
예제 #7
0
/*********************************************************************
 * @fn      zclApplianceStatistics_ProcessInCmd_LogReq
 *
 * @brief   Process in the received Appliance Statistics Notification cmd
 *
 * @param   pInMsg - pointer to the incoming message
 * @param   pCBs - pointer to the application callback
 *
 * @return  ZStatus_t
 */
static ZStatus_t zclApplianceStatistics_ProcessInCmd_LogReq( zclIncoming_t *pInMsg,
                                                             zclApplianceStatistics_AppCallbacks_t *pCBs )
{
  zclApplianceStatisticsLogReq_t cmd;

  if ( pCBs->pfnApplianceStatistics_LogReq )
  {
    // convert from OTA format to native format (note: log data is not converted)
    cmd.logID = BUILD_UINT32( pInMsg->pData[0], pInMsg->pData[1], pInMsg->pData[2], pInMsg->pData[3] );

    // call user callback
    return ( pCBs->pfnApplianceStatistics_LogReq( pInMsg, &cmd ) );
  }

  return ( ZFailure );
}
예제 #8
0
/*********************************************************************
 * @fn      zclElectricalMeasurement_ProcessInCmd_GetMeasurementProfile
 *
 * @brief   Process in the received Electrical Measurement Get Measurement Profile cmd
 *
 * @param   pInMsg - pointer to the incoming message
 * @param   pCBs - pointer to the application callbacks
 *
 * @return  ZStatus_t
 */
static ZStatus_t zclElectricalMeasurement_ProcessInCmd_GetMeasurementProfile( zclIncoming_t *pInMsg,
                                                                              zclElectricalMeasurement_AppCallbacks_t *pCBs )
{
  if ( pCBs->pfnElectricalMeasurement_GetMeasurementProfile )
  {
    zclElectricalMeasurementGetMeasurementProfile_t cmd;

    cmd.attributeID = BUILD_UINT16( pInMsg->pData[0], pInMsg->pData[1] );
    cmd.startTime = BUILD_UINT32(pInMsg->pData[2], pInMsg->pData[3], pInMsg->pData[4], pInMsg->pData[5]);
    cmd.numberOfIntervals = pInMsg->pData[6];

    return ( pCBs->pfnElectricalMeasurement_GetMeasurementProfile( &cmd ) );
  }

  return ( ZFailure );
}
/***************************************************************************************************
 * @fn      MT_UtilSetChannels
 *
 * @brief   Set Channels
 *
 * @param   pBuf - pointer to the data
 *
 * @return  void
 ***************************************************************************************************/
void MT_UtilSetChannels(uint8 *pBuf)
{
  uint32 tmp32;
  uint8 retValue = ZFailure;
  uint8 cmdId;

  /* parse header */
  cmdId = pBuf[MT_RPC_POS_CMD1];
  pBuf += MT_RPC_FRAME_HDR_SZ;

  tmp32 = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]);

  retValue = osal_nv_write(ZCD_NV_CHANLIST, 0, osal_nv_item_len( ZCD_NV_CHANLIST ), &tmp32);

  /* Build and send back the response */
  MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, 1, &retValue);
}
예제 #10
0
/**************************************************************************************************
 * @fn          zapUtilParseAssocDevT
 *
 * @brief       This function parses a packed associated_devices_t.
 *
 * input parameters
 *
 * @param       pBuf - A buffer containing a packed associated_devices_t.
 *
 * output parameters
 *
 * None.
 *
 * @return      SUCCESS if the parsed shortAddr is not invalid, otherwise FAILURE.
 **************************************************************************************************
 */
static uint8 zapUtilParseAssocDevT(uint8 *pBuf)
{
    assocDevT.shortAddr = BUILD_UINT16(pBuf[0], pBuf[1]);
    assocDevT.addrIdx = BUILD_UINT16(pBuf[2], pBuf[3]);
    pBuf += 4;
    assocDevT.nodeRelation = *pBuf++;
    assocDevT.devStatus = *pBuf++;
    assocDevT.assocCnt = *pBuf++;
    assocDevT.age = *pBuf++;
    assocDevT.linkInfo.txCounter = *pBuf++;
    assocDevT.linkInfo.txCost = *pBuf++;
    assocDevT.linkInfo.rxLqi = *pBuf++;
    assocDevT.linkInfo.inKeySeqNum = *pBuf++;
    assocDevT.linkInfo.inFrmCntr = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
    assocDevT.linkInfo.txFailure = BUILD_UINT16(pBuf[4], pBuf[5]);

    return ((INVALID_NODE_ADDR != assocDevT.shortAddr) ? SUCCESS : FAILURE);
}
예제 #11
0
/*********************************************************************
 * @fn      OTA_ProcessSysApp_ImageNotifyReq
 *
 * @brief   Handles app messages from the console application.
 *
 * @param   pData - The data from the server.
 *
 * @return  none
 */
void OTA_ProcessSysApp_ImageNotifyReq(uint8 *pData)
{
    zclOTA_ImageNotifyParams_t imgNotifyParams;
    afAddrType_t dstAddr;

    // Setup the destination address
    dstAddr.addr.shortAddr = BUILD_UINT16(pData[0], pData[1]);
    dstAddr.endPoint = pData[2];
    dstAddr.addrMode = afAddr16Bit;
    dstAddr.panId = _NIB.nwkPanId;

    // Fill the Send Image Notify Parameters
    imgNotifyParams.payloadType = pData[3];
    imgNotifyParams.queryJitter = pData[4];
    imgNotifyParams.fileId.manufacturer = BUILD_UINT16(pData[5], pData[6]);
    imgNotifyParams.fileId.type = BUILD_UINT16(pData[7], pData[8]);
    imgNotifyParams.fileId.version = BUILD_UINT32(pData[9], pData[10], pData[11], pData[12]);

    // Send the command
    zclOTA_SendImageNotify(&dstAddr, &imgNotifyParams);
}
예제 #12
0
/*********************************************************************
 * @fn      zclApplianceStatistics_LogQueueRsp_OtaToNative
 *
 * @brief   Converts from native to OTA format. Make sure to free pCmd->pLogID if ZSuccess.
 *
 * @param   pCmd - native format (destination)
 * @param   pZclPayloadLen - OTA ZCL payload (source)
 *
 * @return  ZSuccess if worked
*/
ZStatus_t zclApplianceStatistics_LogQueueRsp_OtaToNative( zclCmdApplianceStatisticsLogQueueRspPayload_t *pCmd, uint8 *pData )
{
  uint8  offset;
  uint8  i;

  // convert from OTA (stream) format to native format
  pCmd->logQueueSize = pData[0];
  pCmd->pLogID = zcl_mem_alloc( pCmd->logQueueSize * sizeof(uint32) );
  if( !pCmd->pLogID )
  {
    return ( ZMemError );
  }

  offset = 1;
  for( i = 0; i < pCmd->logQueueSize; ++i )
  {
    pCmd->pLogID[i] = BUILD_UINT32( pData[offset], pData[offset+1], pData[offset+2], pData[offset+3] );
    offset += sizeof(uint32);
  }

  return ( ZSuccess );
}
예제 #13
0
/*********************************************************************
 * @fn      zclElectricalMeasurement_ProcessInCmd_GetMeasurementProfileRsp
 *
 * @brief   Process in the received Electrical Measurement Get Measurement Profile Response cmd
 *
 * @param   pInMsg - pointer to the incoming message
 * @param   pCBs - pointer to the application callbacks
 *
 * @return  ZStatus_t
 */
static ZStatus_t zclElectricalMeasurement_ProcessInCmd_GetMeasurementProfileRsp( zclIncoming_t *pInMsg,
                                                                                 zclElectricalMeasurement_AppCallbacks_t *pCBs )
{
  uint8 i;
  uint8 offset;
  uint16 calculatedIntervalSize;
  zclElectricalMeasurementGetMeasurementProfileRsp_t cmd;
  ZStatus_t status;

  if ( pCBs->pfnElectricalMeasurement_GetMeasurementProfileRsp )
  {
    // determine size of intervals by subtracting size of startTime, status,
    // profileIntervalPeriod, numberOfIntervalsDelivered, and attributeID from message length
    calculatedIntervalSize = pInMsg->pDataLen - 9;

    cmd.pIntervals = zcl_mem_alloc( calculatedIntervalSize );
    if ( !cmd.pIntervals )
    {
      return ( ZMemError );  // no memory, return failure
    }

    cmd.startTime = BUILD_UINT32( pInMsg->pData[0], pInMsg->pData[1], pInMsg->pData[2], pInMsg->pData[3] );
    cmd.status = pInMsg->pData[4];
    cmd.profileIntervalPeriod = pInMsg->pData[5];
    cmd.numberOfIntervalsDelivered = pInMsg->pData[6];
    cmd.attributeID = BUILD_UINT16( pInMsg->pData[7], pInMsg->pData[8] );
    offset = 9;
    for ( i = 0; i < calculatedIntervalSize; i++ )
    {
      cmd.pIntervals[i] = pInMsg->pData[offset++];
    }

    status = ( pCBs->pfnElectricalMeasurement_GetMeasurementProfileRsp( &cmd ) );
    zcl_mem_free( cmd.pIntervals );
    return status;
  }

  return ( ZFailure );
}
예제 #14
0
/**************************************************************************************************
 * @fn          MT_AfDataRetrieve
 *
 * @brief   Process AF Data Retrieve command to incrementally read out a very large
 *          incoming AF message.
 *
 * input parameters
 *
 * @param pBuf - pointer to the received buffer
 *
 * output parameters
 *
 * @param rtrn - AF-Status of the operation.
 *
 * @return      None.
 **************************************************************************************************
 */
void MT_AfDataRetrieve(uint8 *pBuf)
{
  #define MT_AF_RTV_HDR_SZ  2

  uint32 timestamp;
  mtAfInMsgList_t *pPrev, *pItem = pMtAfInMsgList;
  uint8 rtrn = afStatus_FAILED;
  uint8 len = 0;

  pBuf += MT_RPC_FRAME_HDR_SZ;
  timestamp = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]);

  while (pItem != NULL)
  {
    pPrev = pItem;
    if (pItem->timestamp == timestamp)
    {
      break;
    }
    pItem = pItem->next;
  }

  if (pItem != NULL)
  {
    uint16 idx;
    uint8 *pRsp;

    pBuf += 4;
    idx = BUILD_UINT16(pBuf[0], pBuf[1]);
    len = pBuf[2];

    if (len == 0)  // Indication to delete the afIncomingMSGPacket.
    {
      if (pMtAfInMsgList == pItem)
      {
        pMtAfInMsgList = pItem->next;
      }
      else
      {
        pPrev->next = pItem->next;
      }
      (void)osal_mem_free(pItem);
      rtrn = afStatus_SUCCESS;
    }
    else if ((pRsp = osal_mem_alloc(len + MT_AF_RTV_HDR_SZ)) == NULL)
    {
      rtrn = afStatus_MEM_FAIL;
      len = 0;
    }
    else
    {
      pRsp[0] = ZSuccess;
      pRsp[1] = len;
      (void)osal_memcpy(pRsp + MT_AF_RTV_HDR_SZ, pItem->data+idx, len);
      MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_AF),
                                           MT_AF_DATA_RETRIEVE, len + MT_AF_RTV_HDR_SZ, pRsp);
      (void)osal_mem_free(pRsp);
      return;
    }
  }

  pBuf[0] = rtrn;
  pBuf[1] = len;
  MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_AF),
                                       MT_AF_DATA_RETRIEVE, MT_AF_RTV_HDR_SZ, pBuf);
}
// -----------------------------------------------------------------------------
//! \brief      Call back function provided to NPI Task. All incoming NPI
//!             received by NPI Task with the subsystem ID of this subsystem
//!             will be sent to this call back through the NPI routing system
//!
//!             *** This function MUST free pNPIMsg
//!
//! \param[in]  pNPIMsg    Pointer to a "framed" NPI message
//!
//! \return     void
// -----------------------------------------------------------------------------
void NPISS_BLE_SNP_msgFromSNP(_npiFrame_t *pNPIMsg)
{
  uint16_t msgLen = pNPIMsg->dataLen;

  switch(SNP_GET_OPCODE_HDR_CMD1(pNPIMsg->cmd1))
  {
    /* Device group */
    case SNP_DEVICE_GRP:
      {
        switch( pNPIMsg->cmd1 )
        {
#ifndef SNP_LOCAL
          // NP is powered up indication.
          case SNP_POWER_UP_IND:
            // Device has restarted.
            if (SNP_asyncCB)
            {
              SNP_asyncCB(pNPIMsg->cmd1, NULL, msgLen);
            }
            break;


          // Mask Events response.
          case SNP_MASK_EVENT_RSP:
            if ( npiRetMsg.pMsg )
            {
              npiRetMsg.len = msgLen;

              // Explicitly copy response
              npiRetMsg.pMsg->maskEventCnf.maskedEvent =
                BUILD_UINT16(pNPIMsg->pData[0],pNPIMsg->pData[1]);
            }
            break;

          case SNP_GET_REVISION_RSP:
            if ( npiRetMsg.pMsg )
            {
              npiRetMsg.len = msgLen;

              // Explicitly copy response
              npiRetMsg.pMsg->revisionRsp.status = pNPIMsg->pData[0];
              npiRetMsg.pMsg->revisionRsp.snpVer =
                      BUILD_UINT16(pNPIMsg->pData[1],pNPIMsg->pData[2]);
              memcpy(npiRetMsg.pMsg->revisionRsp.stackBuildVer,
                     &pNPIMsg->pData[3],
                     sizeof(npiRetMsg.pMsg->revisionRsp.stackBuildVer));
            }
            break;

          case SNP_GET_RAND_RSP:
            if ( npiRetMsg.pMsg )
            {
              npiRetMsg.len = msgLen;

              // Explicitly copy response
              npiRetMsg.pMsg->randRsp.rand = BUILD_UINT32(pNPIMsg->pData[0],
                                                          pNPIMsg->pData[1],
                                                          pNPIMsg->pData[2],
                                                          pNPIMsg->pData[3]);

            }
            break;

          // HCI command response
          case SNP_HCI_CMD_RSP:
            {
              snpHciCmdRsp_t hciRsp;

              // Initialize Response Struct
              hciRsp.status = pNPIMsg->pData[0];
              hciRsp.opcode = BUILD_UINT16(pNPIMsg->pData[1],pNPIMsg->pData[2]);
              hciRsp.pData = (uint8_t *)&pNPIMsg->pData[3];

              if (SNP_asyncCB)
              {
                SNP_asyncCB(pNPIMsg->cmd1, (snp_msg_t *)&hciRsp, msgLen);
              }
            }
            break;
#endif //SNP_LOCAL

          case SNP_EVENT_IND:
            {
              snpEvt_t pEvt;

              // Copy non-Pointer members of Event Struct
              pEvt.event = BUILD_UINT16(pNPIMsg->pData[0],pNPIMsg->pData[1]);

              // Send event back up to NP.
              switch(pEvt.event)
              {
                case SNP_CONN_EST_EVT:
                  {
                    snpConnEstEvt_t connEstEvt;

                    // Initialize Event
                    connEstEvt.connHandle =
                      BUILD_UINT16(pNPIMsg->pData[2],pNPIMsg->pData[3]);
                    connEstEvt.connInterval =
                      BUILD_UINT16(pNPIMsg->pData[4],pNPIMsg->pData[5]);
                    connEstEvt.slaveLatency =
                      BUILD_UINT16(pNPIMsg->pData[6],pNPIMsg->pData[7]);
                    connEstEvt.supervisionTimeout =
                      BUILD_UINT16(pNPIMsg->pData[8],pNPIMsg->pData[9]);
                    connEstEvt.addressType = pNPIMsg->pData[10];

                    memcpy(connEstEvt.pAddr, &pNPIMsg->pData[11],
                           sizeof(connEstEvt.pAddr));

                    pEvt.pEvtParams = (snpEventParam_t *)&connEstEvt;
                  }
                  break;

                case SNP_CONN_TERM_EVT:
                  {
                    snpConnTermEvt_t connTermEvt;

                    // Initialize Event
                    connTermEvt.connHandle =
                      BUILD_UINT16(pNPIMsg->pData[2],pNPIMsg->pData[3]);
                    connTermEvt.reason = pNPIMsg->pData[4];

                    pEvt.pEvtParams = (snpEventParam_t *)&connTermEvt;
                  }
                  break;

                case SNP_CONN_PARAM_UPDATED_EVT:
                  {
                    snpUpdateConnParamEvt_t event;

                    // Initialize Event
                    event.connHandle =
                      BUILD_UINT16(pNPIMsg->pData[2],pNPIMsg->pData[3]);
                    event.connInterval =
                      BUILD_UINT16(pNPIMsg->pData[4],pNPIMsg->pData[5]);
                    event.slaveLatency =
                      BUILD_UINT16(pNPIMsg->pData[6],pNPIMsg->pData[7]);
                    event.supervisionTimeout =
                      BUILD_UINT16(pNPIMsg->pData[8],pNPIMsg->pData[9]);

                    pEvt.pEvtParams = (snpEventParam_t *)&event;
                  }
                  break;

                case SNP_ADV_STARTED_EVT:
                case SNP_ADV_ENDED_EVT:
                  {
                    snpAdvStatusEvt_t event;

                    // Initialize Event
                    event.status = pNPIMsg->pData[2];

                    pEvt.pEvtParams = (snpEventParam_t *)&event;
                  }
                  break;

                case SNP_ATT_MTU_EVT:
                  {
                    snpATTMTUSizeEvt_t event;

                    // Initialize Event
                    event.connHandle =
                      BUILD_UINT16(pNPIMsg->pData[2],pNPIMsg->pData[3]);
                    event.attMtuSize =
                      BUILD_UINT16(pNPIMsg->pData[4],pNPIMsg->pData[5]);

                    pEvt.pEvtParams = (snpEventParam_t *)&event;
                  }
                  break;

                case SNP_SECURITY_EVT:
                  {
                    snpSecurityEvt_t event;

                    // Initialize Event
                    event.state = pNPIMsg->pData[2];
                    event.status = pNPIMsg->pData[3];

                    pEvt.pEvtParams = (snpEventParam_t *)&event;
                  }
                  break;

                case SNP_AUTHENTICATION_EVT:
                  {
                    snpAuthenticationEvt_t event;

                    // Initialize Event
                    event.display = pNPIMsg->pData[2];
                    event.input   = pNPIMsg->pData[3];
                    event.numCmp = BUILD_UINT32(pNPIMsg->pData[4],
                                                pNPIMsg->pData[5],
                                                pNPIMsg->pData[6],
                                                pNPIMsg->pData[7]);

                    pEvt.pEvtParams = (snpEventParam_t *)&event;
                  }
                  break;
              }
              // Send to NP layer.
              if ( SNP_eventCB )
              {
                SNP_eventCB(&pEvt);
              }
            }
            break;

          case SNP_GET_STATUS_RSP:
          if ( npiRetMsg.pMsg )
          {
            npiRetMsg.len = msgLen;

            // Explicitly copy response
            npiRetMsg.pMsg->getStatusRsp.gapRoleStatus = pNPIMsg->pData[0];
            npiRetMsg.pMsg->getStatusRsp.advStatus = pNPIMsg->pData[1];
            npiRetMsg.pMsg->getStatusRsp.ATTstatus = pNPIMsg->pData[2];
            npiRetMsg.pMsg->getStatusRsp.ATTmethod = pNPIMsg->pData[3];
          }
          break;

#ifndef SNP_LOCAL
        case SNP_TEST_RSP:
          {
            snpTestCmdRsp_t rsp;

            // Initialize Response Struct
            rsp.memAlo = BUILD_UINT16(pNPIMsg->pData[0],pNPIMsg->pData[1]);
            rsp.memMax = BUILD_UINT16(pNPIMsg->pData[2],pNPIMsg->pData[3]);
            rsp.memSize = BUILD_UINT16(pNPIMsg->pData[4],pNPIMsg->pData[5]);

            if (SNP_asyncCB)
            {
              SNP_asyncCB(pNPIMsg->cmd1, (snp_msg_t *)&rsp, msgLen);
            }
          }
          break;
#endif //SNP_LOCAL

          default:
            // Unknown command
            break;
        }
      }
      break;

    /* GAP group */
    case SNP_GAP_GRP:
      {
        switch(pNPIMsg->cmd1)
        {
#ifndef SNP_LOCAL
          // GAP Role initialized.
          case SNP_INIT_DEVICE_CNF:
            // RFU
            break;

          // Advertisement data confirmation
          case SNP_SET_ADV_DATA_CNF:
            {
              snpSetAdvDataCnf_t cnf;

              cnf.status = pNPIMsg->pData[0];

              if (SNP_asyncCB)
              {
                SNP_asyncCB(pNPIMsg->cmd1, (snp_msg_t *)&cnf, msgLen);
              }
            }

          case SNP_UPDATE_CONN_PARAM_CNF:
            {
              snpUpdateConnParamCnf_t cnf;

              cnf.status = pNPIMsg->pData[0];
              cnf.connHandle =
                BUILD_UINT16(pNPIMsg->pData[1], pNPIMsg->pData[2]);

              if (SNP_asyncCB)
              {
                SNP_asyncCB(pNPIMsg->cmd1, (snp_msg_t *)&cnf, msgLen);
              }
            }
            break;
#endif //SNP_LOCAL

          // Set GAP parameter response.
          case SNP_SET_GAP_PARAM_RSP:
            if ( npiRetMsg.pMsg )
            {
              npiRetMsg.len = msgLen;

              // Explicitly copy response
              npiRetMsg.pMsg->setGapParamRsp.status = pNPIMsg->pData[0];
            }
            break;

          // Get GAP parameter response.
          case SNP_GET_GAP_PARAM_RSP:
            if ( npiRetMsg.pMsg )
            {
              npiRetMsg.len = msgLen;

              // Explicitly copy response
              npiRetMsg.pMsg->getGapParamRsp.status = pNPIMsg->pData[0];
              npiRetMsg.pMsg->getGapParamRsp.paramId =
                BUILD_UINT16(pNPIMsg->pData[1],pNPIMsg->pData[2]);
              npiRetMsg.pMsg->getGapParamRsp.status =
                BUILD_UINT16(pNPIMsg->pData[3],pNPIMsg->pData[4]);
            }
            break;

#ifdef SNP_LOCAL
          case SNP_SET_SECURITY_PARAM_RSP:
            if ( npiRetMsg.pMsg )
            {
              npiRetMsg.len = msgLen;

              // Explicitly copy response
              npiRetMsg.pMsg->setSecParamRsp.status = pNPIMsg->pData[0];
            }
            break;

          case SNP_SEND_AUTHENTICATION_DATA_RSP:
            if ( npiRetMsg.pMsg )
            {
              npiRetMsg.len = msgLen;

              // Explicitly copy response
              npiRetMsg.pMsg->setAuthDataRsp.status = pNPIMsg->pData[0];
            }
            break;

          case SNP_SET_WHITE_LIST_POLICY_RSP:
            if ( npiRetMsg.pMsg )
            {
              npiRetMsg.len = msgLen;

              //Explicitly copy reponse
              npiRetMsg.pMsg->setWhiteListRsp.status = pNPIMsg->pData[0];
            }
            break;
#endif //!SNP_LOCAL
          default:
            // Unknown command
            break;
        }
      }
      break;

    /* GATT group */
    case SNP_GATT_GRP:
      {
        switch(pNPIMsg->cmd1)
        {
#ifndef SNP_LOCAL
          case SNP_ADD_SERVICE_RSP:
            if ( npiRetMsg.pMsg )
            {
              npiRetMsg.len = msgLen;

              // Explicitly copy response
              npiRetMsg.pMsg->addServiceRsp.status = pNPIMsg->pData[0];
            }
            break;

          case SNP_ADD_CHAR_VAL_DECL_RSP:
            if ( npiRetMsg.pMsg )
            {
              npiRetMsg.len = msgLen;

              // Explicitly copy response
              npiRetMsg.pMsg->addCharValueDecRsp.status = pNPIMsg->pData[0];
              npiRetMsg.pMsg->addCharValueDecRsp.attrHandle =
                BUILD_UINT16(pNPIMsg->pData[1],pNPIMsg->pData[2]);
            }
            break;

          case SNP_ADD_CHAR_DESC_DECL_RSP:
            if ( npiRetMsg.pMsg )
            {
              uint8_t i = 0;
              npiRetMsg.len = msgLen;

              // Explicitly copy response
              npiRetMsg.pMsg->addCharDescDeclRsp.status = pNPIMsg->pData[0];
              npiRetMsg.pMsg->addCharDescDeclRsp.header = pNPIMsg->pData[1];

              // Remaining Msg contents are uint16 handles
              while(i < (msgLen - 2))
              {
                npiRetMsg.pMsg->addCharDescDeclRsp.handles[(i/2)] =
                  BUILD_UINT16(pNPIMsg->pData[2 + i],pNPIMsg->pData[3 + i]);
                i += 2;
              }
            }
            break;

          case SNP_REGISTER_SERVICE_RSP:
            if ( npiRetMsg.pMsg )
            {
              npiRetMsg.len = msgLen;

              // Explicitly copy response
              npiRetMsg.pMsg->addCharValueDecRsp.status = pNPIMsg->pData[0];
              npiRetMsg.pMsg->addCharValueDecRsp.attrHandle =
                BUILD_UINT16(pNPIMsg->pData[1],pNPIMsg->pData[2]);
            }
            break;

          case SNP_SET_GATT_PARAM_RSP:
            if ( npiRetMsg.pMsg )
            {
              npiRetMsg.len = msgLen;

              // Explicitly copy response
              npiRetMsg.pMsg->setGattParamRsp.status = pNPIMsg->pData[0];
            }
            break;

          // Get GATT parameter of predefined NP service response.
          case SNP_GET_GATT_PARAM_RSP:
            if ( npiRetMsg.pMsg )
            {
              npiRetMsg.len = msgLen;

              // Explicitly copy response
              npiRetMsg.pMsg->getGattParamRsp.serviceID = pNPIMsg->pData[0];
              npiRetMsg.pMsg->getGattParamRsp.paramID = pNPIMsg->pData[1];
              npiRetMsg.pMsg->getGattParamRsp.pData =
                (uint8_t *)&pNPIMsg->pData[2];
            }
            break;

          // Get attribute value from NP response.
          case SNP_GET_ATTR_VALUE_RSP:
            //RFU
            break;

          // Set attribute value on NP response.
          case SNP_SET_ATTR_VALUE_RSP:
            //RFU
            break;
#endif //!SNP_LOCAL

          case SNP_CHAR_READ_IND:
            if (SNP_asyncCB)
            {
              snpCharReadInd_t readInd;

              readInd.connHandle =
                BUILD_UINT16(pNPIMsg->pData[0], pNPIMsg->pData[1]);
              readInd.attrHandle =
                BUILD_UINT16(pNPIMsg->pData[2], pNPIMsg->pData[3]);
              readInd.offset =
                BUILD_UINT16(pNPIMsg->pData[4], pNPIMsg->pData[5]);
              readInd.maxSize =
                BUILD_UINT16(pNPIMsg->pData[6], pNPIMsg->pData[7]);

              SNP_asyncCB(pNPIMsg->cmd1, (snp_msg_t *)&readInd, msgLen);
            }
            break;

          // Characteristic write indication.
          case SNP_CHAR_WRITE_IND:
            {
              snpCharWriteInd_t writeInd;

              writeInd.connHandle =
                BUILD_UINT16(pNPIMsg->pData[0], pNPIMsg->pData[1]);
              writeInd.attrHandle =
                BUILD_UINT16(pNPIMsg->pData[2], pNPIMsg->pData[3]);
              writeInd.rspNeeded = pNPIMsg->pData[4];
              writeInd.offset =
                BUILD_UINT16(pNPIMsg->pData[5], pNPIMsg->pData[6]);
              writeInd.pData = (uint8_t *)&pNPIMsg->pData[7];

              if (SNP_asyncCB)
              {
                SNP_asyncCB(pNPIMsg->cmd1, (snp_msg_t *)&writeInd, msgLen);
              }
            }
            break;

          case SNP_SEND_NOTIF_IND_CNF:
            if (SNP_asyncCB)
            {
              snpNotifIndCnf_t notifCnf;

              notifCnf.status = pNPIMsg->pData[0];
              notifCnf.connHandle =
                BUILD_UINT16(pNPIMsg->pData[1], pNPIMsg->pData[2]);

              SNP_asyncCB(pNPIMsg->cmd1, (snp_msg_t *)&notifCnf, msgLen);
            }
            break;

          case SNP_CCCD_UPDATED_IND:
            if (SNP_asyncCB)
            {
              snpCharCfgUpdatedInd_t cccdInd;

              cccdInd.connHandle =
                BUILD_UINT16(pNPIMsg->pData[0], pNPIMsg->pData[1]);
              cccdInd.cccdHandle =
                BUILD_UINT16(pNPIMsg->pData[2], pNPIMsg->pData[3]);
              cccdInd.rspNeeded = pNPIMsg->pData[4];
              cccdInd.value =
                BUILD_UINT16(pNPIMsg->pData[5], pNPIMsg->pData[6]);

              SNP_asyncCB(pNPIMsg->cmd1, (snp_msg_t *)&cccdInd, msgLen);
            }
            break;

          default:
            // Unknown command
            break;
        }
      }
      break;

    default:
      // Unknown.
      break;
  }

#ifndef SNP_LOCAL
  if (pNPIMsg->cmd0 == SNP_NPI_SYNC_RSP_TYPE)
  {
    // This is a synchronous response, signal the application who requested this.
    SNP_responseReceived();
  }
#endif //SNP_LOCAL

  // Ok to deallocate
  SNP_free(pNPIMsg);
}
예제 #16
0
파일: ota_common.c 프로젝트: LILCMU/WRATIOT
/******************************************************************************
 * @fn      OTA_ParseHeader
 *
 * @brief   Reads the OTA header from the input buffer.
 *
 * @param   pHdr - pointer to the header information
 * @param   pBuf - pointer to the input buffer
 *
 * @return  new buffer pointer
 */
uint8 *OTA_ParseHeader(OTA_ImageHeader_t *pHdr, uint8 *pBuf)
{
  uint8 i;

  // Get the Magic Number
  pHdr->magicNumber = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
  pBuf += 4;

  // Get the Header Version
  pHdr->headerVersion = BUILD_UINT16(pBuf[0], pBuf[1]);
  pBuf += 2;

  // Get the Header Length
  pHdr->headerLength = BUILD_UINT16(pBuf[0], pBuf[1]);
  pBuf += 2;

  // Get the Field Control
  pHdr->fieldControl = BUILD_UINT16(pBuf[0], pBuf[1]);
  pBuf += 2;

  // Get the Manufacturer ID
  pHdr->fileId.manufacturer = BUILD_UINT16(pBuf[0], pBuf[1]);
  pBuf += 2;

  // Get the Image Type
  pHdr->fileId.type = BUILD_UINT16(pBuf[0], pBuf[1]);
  pBuf += 2;

  // Get the File Version
  pHdr->fileId.version = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
  pBuf += 4;

  // Get the Stack Version
  pHdr->stackVersion = BUILD_UINT16(pBuf[0], pBuf[1]);
  pBuf += 2;

  // Get the Header string
  for (i=0; i<OTA_HEADER_STR_LEN; i++)
  {
    pHdr->headerString[i] = *pBuf++;
  }

  // Get the Image Size
  pHdr->imageSize = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
  pBuf += 4;

  // Get the Security Credential Version
  if (pHdr->fieldControl & OTA_FC_SCV_PRESENT)
  {
    pHdr->secCredentialVer = *pBuf++;
  }

  // Get the Upgrade File Destination
  if (pHdr->fieldControl & OTA_FC_DSF_PRESENT)
  {
    for (i=0; i<Z_EXTADDR_LEN; i++)
    {
      pHdr->destIEEE[i] = *pBuf++;
    }
  }

  // Get the Min and Max Hardware Versions
  if (pHdr->fieldControl & OTA_FC_HWV_PRESENT)
  {
    pHdr->minHwVer = BUILD_UINT16(pBuf[0], pBuf[1]);
    pBuf += 2;
    pHdr->maxHwVer = BUILD_UINT16(pBuf[0], pBuf[1]);
    pBuf += 2;
  }

  return pBuf;
}
예제 #17
0
/**************************************************************************************************
 * @fn          zapUtilReq
 *
 * @brief       This function packs and sends an RPC NWK request.
 *
 * input parameters
 *
 * @param       cmd - A valid NWK command.
 * @param       req - A buffer containing the contents of the request/response, or NULL.
 * @param       args - Valid argument(s) corresponding to the NWK command.
 *
 * output parameters
 *
 * @param       req - The buffer filled with the contents or success of a response.
 * @param       args - The buffer filled with the contents or success of a response.
 *
 * @return      SUCCESS or FAILURE.
 **************************************************************************************************
 */
uint8 zapUtilReq(uint8 cmd, uint8 *req, uint8 *args)
{
    uint8 len, cmd0 = (uint8)MT_RPC_CMD_SREQ;
    uint8 rtrn = SUCCESS;
    uint8 *pBuf;

    if (DEV_STATE_INVALID <= devState)
    {
        return FAILURE;
    }

    switch (cmd)
    {
    // SREQ's to ZNP.

    case MT_UTIL_ASSOC_GET_WITH_ADDRESS:
        len = Z_EXTADDR_LEN + 2;
        break;

    case MT_UTIL_ADDRMGR_NWK_ADDR_LOOKUP:
    case MT_UTIL_ASSOC_COUNT:
        len = 2;
        break;

#if SECURE
    case MT_UTIL_APSME_LINK_KEY_DATA_GET:
        len = Z_EXTADDR_LEN;
        break;

    case MT_UTIL_APSME_LINK_KEY_NV_ID_GET:
        len = Z_EXTADDR_LEN;
        break;
#endif

    case MT_UTIL_ASSOC_FIND_DEVICE:
        len = 1;
        break;

#if defined ZCL_KEY_ESTABLISH
    case MT_UTIL_ZCL_KEY_EST_INIT_EST:
        len = 12;
        break;

    case MT_UTIL_ZCL_KEY_EST_SIGN:
        len = *args +1;
        break;
#endif

    // AREQ's to ZNP.

    case MT_UTIL_SYNC_REQ:
        cmd0 = (uint8)MT_RPC_CMD_AREQ;
        len = 0;
        break;

    default:
        return FAILURE;
    }
    cmd0 |= (uint8)MT_RPC_SYS_UTIL;

    if (NULL == (pBuf = zap_msg_allocate(len, cmd0, cmd)))
    {
        return FAILURE;
    }

    switch (cmd)
    {
    // SREQ's to ZNP.

    case MT_UTIL_ADDRMGR_NWK_ADDR_LOOKUP:
        pBuf[0] = *args++;
        pBuf[1] = *args;
        break;

#if SECURE
    case MT_UTIL_APSME_LINK_KEY_DATA_GET:
        (void)osal_memcpy(pBuf, req, Z_EXTADDR_LEN);
        break;

    case MT_UTIL_APSME_LINK_KEY_NV_ID_GET:
        (void)osal_memcpy(pBuf, req, Z_EXTADDR_LEN);
        break;
#endif

    case MT_UTIL_ASSOC_COUNT:
        (void)osal_memcpy(pBuf, req, 2);
        break;

    case MT_UTIL_ASSOC_FIND_DEVICE:
        pBuf[0] = *args;
        break;

    case MT_UTIL_ASSOC_GET_WITH_ADDRESS:
        if (NULL == args)
        {
            (void)osal_memset(pBuf, 0, Z_EXTADDR_LEN);
        }
        else
        {
            (void)osal_memcpy(pBuf, args, Z_EXTADDR_LEN);
        }
        pBuf[Z_EXTADDR_LEN] = LO_UINT16(assocDevT.shortAddr);
        pBuf[Z_EXTADDR_LEN+1] = HI_UINT16(assocDevT.shortAddr);
        break;

#if defined ZCL_KEY_ESTABLISH
    case MT_UTIL_ZCL_KEY_EST_INIT_EST:
        (void)osal_memcpy(pBuf, req, 12);
        break;

    case MT_UTIL_ZCL_KEY_EST_SIGN:
        *pBuf = *args;
        (void)osal_memcpy(pBuf+1, req, *args);
        break;
#endif

    // AREQ's to ZNP.

    default:
        break;
    }

    if (zapPhySend(zapAppPort, pBuf) == FAILURE)
    {
        zap_msg_deallocate(&pBuf);
        return FAILURE;
    }

    switch (cmd)
    {
    // SREQ's to ZNP.

    case MT_UTIL_ADDRMGR_NWK_ADDR_LOOKUP:
        (void)osal_memcpy(req, pBuf, Z_EXTADDR_LEN);
        break;

#if SECURE
    case MT_UTIL_APSME_LINK_KEY_DATA_GET:
        if (SUCCESS == (rtrn = *pBuf))
        {
            APSME_LinkKeyData_t *pData = (APSME_LinkKeyData_t *)args;
            uint8 *ptr = pBuf+1;

            // copy key data
            (void)osal_memcpy(pData->key, ptr, SEC_KEY_LEN);
            ptr += SEC_KEY_LEN;
            pData->txFrmCntr = BUILD_UINT32(ptr[0], ptr[1], ptr[2], ptr[3]);
            ptr += 4;
            pData->rxFrmCntr = BUILD_UINT32(ptr[0], ptr[1], ptr[2], ptr[3]);
        }
        break;

    case MT_UTIL_APSME_LINK_KEY_NV_ID_GET:
        if (SUCCESS == (rtrn = *pBuf))
        {
            uint16 *pNvId = (uint16 *)args;
            uint8 *ptr = pBuf+1;

            *pNvId = BUILD_UINT16(ptr[0], ptr[1]);
        }
        break;
#endif

    case MT_UTIL_ASSOC_COUNT:
        (void)osal_memcpy(req, pBuf, 2);
        break;

    case MT_UTIL_ASSOC_FIND_DEVICE:
    case MT_UTIL_ASSOC_GET_WITH_ADDRESS:
        (void)osal_memcpy(req, pBuf, sizeof(associated_devices_t));
        break;

#if defined ZCL_KEY_ESTABLISH
    case MT_UTIL_ZCL_KEY_EST_SIGN:
#if defined SECURE
        (void)osal_memcpy(req, pBuf+1, SE_PROFILE_SIGNATURE_LENGTH);
#endif
    case MT_UTIL_ZCL_KEY_EST_INIT_EST:
        rtrn = *pBuf;
        break;
#endif

    // AREQ's to ZNP.

    default:
        break;
    }

    zap_msg_deallocate(&pBuf);
    return rtrn;
}
예제 #18
0
파일: MT_ZDO.c 프로젝트: gothame/ZigbeeComm
/*********************************************************************
 * @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 );
}
예제 #19
0
 /*********************************************************************
 * @fn      cycling_ProcessCSCCmd
 *
 * @brief   process an incoming CSC command.
 *
 * @param   attrHandle - attribute handle
 * @param   pValue - pointer to data to be written
 * @param   len - length of data
 *
 * @return  none
 */
static void cycling_ProcessCSCCmd( uint16 attrHandle, uint8 *pValue, uint8 len )
{
  uint8 cscStatus = CSC_SUCCESS;

  // See if need to alloc payload for new indication.
  if (cscCmdInd.pValue == NULL)
  {
    cscCmdInd.pValue = GATT_bm_alloc(connectionHandle, ATT_HANDLE_VALUE_IND, 
                                     CSC_CMD_LEN, NULL);
    if (cscCmdInd.pValue == NULL)
    {
      return; // failed to allocate space!
    }
  }
  
  // Set Control Point Cfg in progress
  scOpInProgress = TRUE;

  // Set indication info to be sent out
  cscCmdInd.handle = attrHandle;

  cscCmdInd.len = 3;
  cscCmdInd.pValue[0] = CSC_COMMAND_RSP;
  cscCmdInd.pValue[1] = pValue[0];

  switch ( pValue[0] )
  {
    case CSC_SET_CUMM_VAL:
      // If wheel revolutions is a feature
      if ( ( len <= 5 ) && ( cyclingFeatures & CSC_WHEEL_REV_SUPP ) )
      {
        uint32 cummWheelRevolutions;

        // full 32 bits were specified.
        if (( len - 1 ) == 4)
        {
          cummWheelRevolutions = BUILD_UINT32( pValue[1], pValue[2], pValue[3], pValue[4]);
        }
        else
        {
          cummWheelRevolutions = 0;

          // In case only lower bits were specified and upper bits remain zero.
          for( int i = 0; i < (len - 1); ++i )
          {
            cummWheelRevolutions += pValue[i + 1] << (i*8);
          }
        }

        // Notify app
        if ( cyclingServiceCB != NULL )
        {
          (*cyclingServiceCB)( CSC_CMD_SET_CUMM_VAL, &cummWheelRevolutions );
        }
      }
      else // characteristic not supported.
      {
        cscStatus = CSC_INVALID_PARAMETER;
      }
      break;

    case CSC_UPDATE_SENS_LOC:
      // If multiple sensor locations is supported and that this is a valid location.
      if ( ( len == 2 )                              &&
           ( cyclingFeatures & CSC_MULTI_SENS_SUPP ) &&
           ( cycling_SensorLocSupported( pValue[1] ) == TRUE ) )
      {
        // Update sensor location
        cyclingSensLoc = pValue[1];

        // Notify app
        if ( cyclingServiceCB != NULL )
        {
          (*cyclingServiceCB)( CSC_CMD_UPDATE_SENS_LOC, NULL );
        }
      }
      else // characteristic not supported.
      {
        cscStatus = CSC_INVALID_PARAMETER;
      }
      break;

    case CSC_REQ_SUPP_SENS_LOC:
      // If multiple sensor locations are supported and list requested
      if ( ( len == 1 ) && ( cyclingFeatures & CSC_MULTI_SENS_SUPP ) )
      {
        cscCmdInd.len += supportedSensors;
        osal_memcpy( &(cscCmdInd.pValue[3]), supportedSensorLocations, supportedSensors );
      }
      else // characteristic not supported.
      {
        // Send an indication with the list.
        cscStatus = CSC_INVALID_PARAMETER;
      }
      break;

     default:
      // Send an indication with opcode not suported response
      cscStatus = CSC_OPCODE_NOT_SUPPORTED;
      break;
  }

  // Send indication of operation result
  cscCmdInd.pValue[2] = cscStatus;

  // Ask our task to send out indication
  osal_set_event( cyclingService_TaskID, CSC_CMD_IND_SEND_EVT );
}