Пример #1
0
/*********************************************************************
 * @fn          ZDP_SimpleDescReq
 *
 * @brief       This builds and send a NWK_Simple_Desc_req
 *              message.  This function sends unicast message to the
 *              destination device.
 *
 * @param       dstAddr - destination address
 * @param       nwkAddr - 16 bit address
 * @param       epIntf - endpoint/interface
 * @param       SecurityEnable - Security Options
 *
 * @return      afStatus_t
 */
afStatus_t ZDP_SimpleDescReq( zAddrType_t *dstAddr, uint16 nwkAddr,
                                    byte endPoint, byte SecurityEnable )

{
  uint8 *pBuf, rtrn;

  (void)SecurityEnable;

  pBuf = zap_msg_allocate(5, (uint8)MT_RPC_SYS_ZDO | (uint8)MT_RPC_CMD_SREQ,
                             (uint8)MT_ZDO_SIMPLE_DESC_REQ);
  if (NULL == pBuf)
  {
    return afStatus_MEM_FAIL;
  }

  pBuf[0] = LO_UINT16(dstAddr->addr.shortAddr);
  pBuf[1] = HI_UINT16(dstAddr->addr.shortAddr);
  pBuf[2] = LO_UINT16(nwkAddr);
  pBuf[3] = HI_UINT16(nwkAddr);
  pBuf[4] = endPoint;

  zapPhySend(zapAppPort, pBuf);
  rtrn = ZAP_SRSP_STATUS(pBuf);
  zap_msg_deallocate(&pBuf);

  return (afStatus_t)rtrn;
}
Пример #2
0
/**************************************************************************************************
 * @fn          sapiReq
 *
 * @brief       This function packs and sends an RPC SAPI request.
 *
 * input parameters
 *
 * @param       cmd - A valid SAPI command.
 * @param       arg - A valid argument corresponding to the SAPI command.
 * @param       req - A buffer containing the contents of the request, or NULL.
 * @param       len - The non-zero length of a non-NULL req buffer, or NULL.
 *
 * output parameters
 *
 * None.
 *
 * @return      SUCCESS or FAILURE.
 **************************************************************************************************
 */
static uint8 sapiReq(uint8 cmd, uint8 arg, uint8 *req, uint8 len)
{
  uint8 cmd0 = (MT_SAPI_SYS_RESET == cmd) ? ((uint8)MT_RPC_SYS_SAPI | (uint8)MT_RPC_CMD_AREQ):
                                            ((uint8)MT_RPC_SYS_SAPI | (uint8)MT_RPC_CMD_SREQ);
  uint8 *pBuf = zap_msg_allocate((uint8)(len + 2), cmd0, cmd);
  uint8 rtrn = FAILURE;

  if (NULL != pBuf)
  {
    pBuf[0] = arg;
    pBuf[1] = len;
    if (NULL != req)
    {
      (void)osal_memcpy(pBuf+2, req, len);
    }

    if (((rtrn = zapPhySend(zapAppPort, pBuf)) == SUCCESS) && (NULL != req))
    {
      (void)osal_memcpy(req, pBuf, ZAP_MSG_LEN(pBuf));
    }

    zap_msg_deallocate(&pBuf);
  }

  return rtrn;
}
Пример #3
0
/**************************************************************************************************
 * @fn          ZDP_EndDeviceBindReq
 *
 * @brief       This builds and sends a End_Device_Bind_req message.
 *              This function sends a unicast message.
 *
 * input parameters
 *
 * @param       dstAddr - destination address
 * @param       LocalCoordinator - short address of local coordinator
 * @param       epIntf - Endpoint/Interface of Simple Desc
 * @param       ProfileID - Profile ID
 *
 *   The Input cluster list is the opposite of what you would think.
 *   This is the output cluster list of this device
 * @param       NumInClusters - number of input clusters
 * @param       InClusterList - input cluster ID list
 *
 *   The Output cluster list is the opposite of what you would think.
 *   This is the input cluster list of this device
 * @param       NumOutClusters - number of output clusters
 * @param       OutClusterList - output cluster ID list
 *
 * @param       SecurityEnable - Security Options
 *
 * output parameters
 *
 * None.
 *
 * @return      afStatus_t
 **************************************************************************************************
 */
afStatus_t ZDP_EndDeviceBindReq(zAddrType_t *dstAddr,
                                uint16 LocalCoordinator,
                                byte endPoint,
                                uint16 ProfileID,
                                byte NumInClusters, cId_t *InClusterList,
                                byte NumOutClusters, cId_t *OutClusterList,
                                byte SecurityEnable)
{
  const uint8 len = 17 + ((NumInClusters + NumOutClusters) * 2);
  uint8 *pBuf, *pPtr, cnt;

  (void)SecurityEnable;

  if ((Addr16Bit != dstAddr->addrMode) && (AddrBroadcast != dstAddr->addrMode))
  {
    return afStatus_INVALID_PARAMETER;
  }

  pBuf = zap_msg_allocate(len, (uint8)MT_RPC_SYS_ZDO | (uint8)MT_RPC_CMD_SREQ,
                               (uint8)MT_ZDO_END_DEV_BIND_REQ);

  if (NULL == pBuf)
  {
    return afStatus_MEM_FAIL;
  }

  pPtr = pBuf;
  *pPtr++ = LO_UINT16(dstAddr->addr.shortAddr);
  *pPtr++ = HI_UINT16(dstAddr->addr.shortAddr);
  *pPtr++ = LO_UINT16(LocalCoordinator);
  *pPtr++ = HI_UINT16(LocalCoordinator);
  //(void)osal_memset(pPtr, 0, Z_EXTADDR_LEN);  // MT_ZDO ignores extended address.
  pPtr += Z_EXTADDR_LEN;
  *pPtr++ = endPoint;
  *pPtr++ = LO_UINT16(ProfileID);
  *pPtr++ = HI_UINT16(ProfileID);
  *pPtr++ = NumInClusters;
  for (cnt = 0; cnt < NumInClusters; cnt++)
  {
    *pPtr++ = LO_UINT16(*InClusterList);
    *pPtr++ = HI_UINT16(*InClusterList);
    InClusterList++;
  }
  *pPtr++ = NumOutClusters;
  for (cnt = 0; cnt < NumOutClusters; cnt++)
  {
    *pPtr++ = LO_UINT16(*OutClusterList);
    *pPtr++ = HI_UINT16(*OutClusterList);
    OutClusterList++;
  }

  zapPhySend(zapAppPort, pBuf);
  cnt = ZAP_SRSP_STATUS(pBuf);
  zap_msg_deallocate(&pBuf);

  return (afStatus_t)cnt;
}
Пример #4
0
/*********************************************************************
 * @fn          ZDO_RemoveRegisteredCB
 *
 * @brief       Call this function if you don't want to receive the
 *              incoming message.
 *
 * @param       taskID - Where the messages are being delivered.
 * @param       clusterID - What message?
 *
 * @return      ZSuccess - successful, ZFailure if not found
 */
ZStatus_t ZDO_RemoveRegisteredCB( uint8 taskID, uint16 clusterID )
{
  ZDO_MsgCB_t *pList;
  ZDO_MsgCB_t *pLast = NULL;

  pList = zdoMsgCBs;
  while ( pList )
  {
    if ( pList->taskID == taskID && pList->clusterID == clusterID )
    {
      uint8 *pBuf, rtrn;

      // Note that this could be sent AREQ to free up the host (but then no status.)
      if (NULL == (pBuf = zap_msg_allocate(2, (uint8)MT_RPC_SYS_ZDO | (uint8)MT_RPC_CMD_SREQ,
                                              (uint8)MT_ZDO_MSG_CB_REMOVE)))
      {
        return ZMemError;
      }

      pBuf[0] = LO_UINT16(clusterID);
      pBuf[1] = HI_UINT16(clusterID);

      zapPhySend(zapAppPort, pBuf);
      rtrn = ZAP_SRSP_STATUS(pBuf);
      zap_msg_deallocate(&pBuf);

      if (ZSuccess != rtrn)
      {
        return (ZStatus_t)rtrn;
      }

      if ( pLast )
      {
        // remove this one from the linked list
        pLast->next = pList->next;
      }
      else if ( pList->next )
      {
        // remove the first one from the linked list
        zdoMsgCBs = pList->next;
      }
      else
      {
        // remove the only item from the list
        zdoMsgCBs = (ZDO_MsgCB_t *)NULL;
      }
      osal_mem_free( pList );
      return ( ZSuccess );
    }
    pLast = pList;
    pList = pList->next;
  }

  return ( ZFailure );
}
Пример #5
0
/**************************************************************************************************
 * @fn          afRetrieve
 *
 * @brief       This function retrieves the data of a huge incoming message. On an failure during
 *              the retrieval, the incoming message is freed. Otherwise, the incoming message is
 *              forwarded to the corresponding task.
 *
 * input parameters
 *
 * @param       pMsg - Pointer to the incoming AF message.
 * @param       taskId - The task ID corresponding to the destination endpoint of the message.
 *
 * output parameters
 *
 * @param       pMsg->cmd.Data - The incoming message data buffer member is filled.
 *
 * @return      None.
 **************************************************************************************************
 */
static void afRetrieve(uint8 taskId, afIncomingMSGPacket_t *pMsg)
{
  #define ZAP_AF_RTV_MSG_HDR  7  // Retrieve message header length.
  #define ZAP_AF_RTV_RPY_HDR  2  // Retrieve-reply message header length.
  #define ZAP_AF_RTV_DAT_MAX (MT_RPC_DATA_MAX - ZAP_AF_RTV_RPY_HDR)

  uint16 idx = 0, len = pMsg->cmd.DataLength;
  uint8 *pBuf, rtrn, tmpLen = 0;

  do {
    /* This trick to pre-decrement (with zero on the first pass) allows the while() test to
     * succeed and loop to send a zero data length message which will trigger the ZNP to
     * de-allocate the huge incoming message being held.
     */
    len -= tmpLen;
    idx += tmpLen;

    if (len > ZAP_AF_RTV_DAT_MAX)
    {
      tmpLen = ZAP_AF_RTV_DAT_MAX;
    }
    else
    {
      tmpLen = len;
    }

    if ((pBuf = zap_msg_allocate(ZAP_AF_RTV_MSG_HDR, ((uint8)MT_RPC_SYS_AF | MT_RPC_CMD_SREQ),
                                                             MT_AF_DATA_RETRIEVE)) == NULL)
    {
      rtrn = afStatus_MEM_FAIL;
      break;
    }

    pBuf[0] = BREAK_UINT32(pMsg->timestamp, 0);
    pBuf[1] = BREAK_UINT32(pMsg->timestamp, 1);
    pBuf[2] = BREAK_UINT32(pMsg->timestamp, 2);
    pBuf[3] = BREAK_UINT32(pMsg->timestamp, 3);
    pBuf[4] = LO_UINT16(idx);
    pBuf[5] = HI_UINT16(idx);
    pBuf[6] = tmpLen;
    zapPhySend(zapAppPort, pBuf);
    rtrn = (afStatus_t)ZAP_SRSP_STATUS(pBuf);
    (void)osal_memcpy(pMsg->cmd.Data+idx, pBuf+ZAP_AF_RTV_RPY_HDR, tmpLen);
    zap_msg_deallocate(&pBuf);
  } while ((rtrn == afStatus_SUCCESS) && len);

  if (rtrn == afStatus_SUCCESS)
  {
    (void)osal_msg_send(taskId, (uint8 *)pMsg);
  }
  else
  {
    (void)osal_msg_deallocate((uint8 *)pMsg);
  }
}
Пример #6
0
/*********************************************************************
 * @fn      ZDOInitDevice
 *
 * @brief   Start the device in the network.  This function will read
 *   ZCD_NV_STARTUP_OPTION (NV item) to determine whether or not to
 *   restore the network state of the device.
 *
 * @param   startDelay - timeDelay to start device (in milliseconds).
 *      There is a jitter added to this delay:
 *              ((NWK_START_DELAY + startDelay)
 *              + (osal_rand() & EXTENDED_JOINING_RANDOM_MASK))
 *
 * NOTE:    If the application would like to force a "new" join, the
 *          application should set the ZCD_STARTOPT_DEFAULT_NETWORK_STATE
 *          bit in the ZCD_NV_STARTUP_OPTION NV item before calling
 *          this function. "new" join means to not restore the network
 *          state of the device. Use zgWriteStartupOptions() to set these
 *          options.
 *
 * @return
 *    ZDO_INITDEV_RESTORED_NETWORK_STATE  - The device's network state was
 *          restored.
 *    ZDO_INITDEV_NEW_NETWORK_STATE - The network state was initialized.
 *          This could mean that ZCD_NV_STARTUP_OPTION said to not restore, or
 *          it could mean that there was no network state to restore.
 *    ZDO_INITDEV_LEAVE_NOT_STARTED - Before the reset, a network leave was issued
 *          with the rejoin option set to TRUE.  So, the device was not
 *          started in the network (one time only).  The next time this
 *          function is called it will start.
 *    0xFF for failure.
 */
uint8 ZDOInitDevice(uint16 startDelay)
{
  uint8 *pBuf;
#if !ZAP_ZDO_STARTUP_AREQ
  uint8 rtrn;
#endif

  (void)startDelay;  // ZNP MT_ZDO_STARTUP_FROM_APP processing forces delay 0.

  zb_GetDeviceInfo(ZB_INFO_DEV_STATE, &devState);
  if ((DEV_HOLD != devState) && (DEV_INIT != devState) && (DEV_NWK_ORPHAN != devState))
  {
    return FAILURE;
  }

#if ZAP_ZDO_STARTUP_AREQ
  pBuf = zap_msg_allocate(0, (uint8)MT_RPC_SYS_ZDO | (uint8)MT_RPC_CMD_AREQ,
                             (uint8)MT_ZDO_STARTUP_FROM_APP);
#else
  pBuf = zap_msg_allocate(0, (uint8)MT_RPC_SYS_ZDO | (uint8)MT_RPC_CMD_SREQ,
                             (uint8)MT_ZDO_STARTUP_FROM_APP);
#endif

  if (NULL == pBuf)
  {
    return 0xFF;
  }

  zapPhySend(zapAppPort, pBuf);
#if !ZAP_ZDO_STARTUP_AREQ
  if (ZSuccess == (rtrn = ZAP_SRSP_STATUS(pBuf)))
#endif
  // Need to locally enter the discovery state to holdoff calls to ZDOInitDevice() until the ZAP
  // monitoring task requests the actual ZNP state.
  devState = DEV_NWK_DISC;
  zap_msg_deallocate(&pBuf);

  // Joining can take some time - especially with > 1 scan channel.
  if (ZSuccess != osal_start_timerEx(zapTaskId, ZAP_APP_TMR_EVT, ZAP_APP_JOIN_DLY))
  {
    (void)osal_set_event(zapTaskId, ZAP_APP_TMR_EVT);
  }

#if ZAP_ZDO_STARTUP_AREQ
  // Made into an AREQ after empirical results showed > 400 msec delay on SRSP.
#if ZAP_NV_RESTORE
  return ZDO_INITDEV_RESTORED_NETWORK_STATE;
#else
  return ZDO_INITDEV_NEW_NETWORK_STATE;
#endif
#else
  return rtrn;
#endif
}
Пример #7
0
/**************************************************************************************************
 * @fn          ZDP_MatchDescReq
 *
 * @brief       This builds and send a Match_Desc_req message.  This
 *              function sends a broadcast or unicast message
 *              requesting the list of endpoint/interfaces that
 *              match profile ID and cluster IDs.
 *
 * input parameters
 *
 * @param       dstAddr - destination address
 * @param       ProfileID - Profile ID
 * @param       NumInClusters - number of input clusters
 * @param       InClusterList - input cluster ID list
 * @param       NumOutClusters - number of output clusters
 * @param       OutClusterList - output cluster ID list
 * @param       SecurityEnable - Security Options
 *
 * output parameters
 *
 * None.
 *
 * @return      afStatus_t
 **************************************************************************************************
 */
afStatus_t ZDP_MatchDescReq(zAddrType_t *dstAddr, uint16 nwkAddr,
                            uint16 ProfileID,
                            byte NumInClusters, cId_t *InClusterList,
                            byte NumOutClusters, cId_t *OutClusterList,
                            byte SecurityEnable)
{
  const uint8 len = 8 + ((NumInClusters + NumOutClusters) * 2);
  uint8 *pBuf, *pPtr, cnt;

  (void)SecurityEnable;

  if ((Addr16Bit != dstAddr->addrMode) && (AddrBroadcast != dstAddr->addrMode))
  {
    return afStatus_INVALID_PARAMETER;
  }

  pBuf = zap_msg_allocate(len, (uint8)MT_RPC_SYS_ZDO | (uint8)MT_RPC_CMD_SREQ,
                               (uint8)MT_ZDO_MATCH_DESC_REQ);

  if (NULL == pBuf)
  {
    return afStatus_MEM_FAIL;
  }

  pPtr = pBuf;
  *pPtr++ = LO_UINT16(dstAddr->addr.shortAddr);
  *pPtr++ = HI_UINT16(dstAddr->addr.shortAddr);
  *pPtr++ = LO_UINT16(nwkAddr);
  *pPtr++ = HI_UINT16(nwkAddr);
  *pPtr++ = LO_UINT16(ProfileID);
  *pPtr++ = HI_UINT16(ProfileID);
  *pPtr++ = NumInClusters;
  for (cnt = 0; cnt < NumInClusters; cnt++)
  {
    *pPtr++ = LO_UINT16(*InClusterList);
    *pPtr++ = HI_UINT16(*InClusterList);
    InClusterList++;
  }
  *pPtr++ = NumOutClusters;
  for (cnt = 0; cnt < NumOutClusters; cnt++)
  {
    *pPtr++ = LO_UINT16(*OutClusterList);
    *pPtr++ = HI_UINT16(*OutClusterList);
    OutClusterList++;
  }

  zapPhySend(zapAppPort, pBuf);
  cnt = ZAP_SRSP_STATUS(pBuf);
  zap_msg_deallocate(&pBuf);

  return (afStatus_t)cnt;
}
Пример #8
0
/**************************************************************************************************
 * @fn          afStore
 *
 * @brief       This function stores a huge outgoing message data buffer on the ZNP.
 *
 * input parameters
 *
 * @param       buf - Pointer to the message data buffer.
 * @param       len - The length of the message data buffer 'buf'.
 *
 * output parameters
 *
 * None.
 *
 * @return      The AF-Status of storing the message data on the ZNP.
 **************************************************************************************************
 */
static afStatus_t afStore(uint8 *buf, uint16 len)
{
  #define ZAP_AF_STO_MSG_HDR  3
  #define ZAP_AF_STO_DAT_MAX (MT_RPC_DATA_MAX - ZAP_AF_STO_MSG_HDR)
  uint8 *pBuf;
  uint16 idx = 0;
  uint8 tmpLen = 0;
  afStatus_t rtrn;

  do {
    /* This trick to pre-decrement (with zero on the first pass) allows the while() test to
     * succeed and loop to send a zero data length message which will trigger the ZNP to send the
     * accumulated data OTA in an AF_DataRequest().
     */
    len -= tmpLen;
    idx += tmpLen;

    if (len > ZAP_AF_STO_DAT_MAX)
    {
      tmpLen = ZAP_AF_STO_DAT_MAX;
    }
    else
    {
      tmpLen = len;
    }

    if ((pBuf = zap_msg_allocate((uint8)(tmpLen + ZAP_AF_STO_MSG_HDR),
                                 (uint8)MT_RPC_SYS_AF | (uint8)MT_RPC_CMD_SREQ,
                                 (uint8)MT_AF_DATA_STORE)) == NULL)
    {
      rtrn = afStatus_MEM_FAIL;
      break;
    }

    pBuf[0] = LO_UINT16(idx);
    pBuf[1] = HI_UINT16(idx);
    pBuf[2] = tmpLen;
    (void)osal_memcpy(pBuf+3, buf+idx, tmpLen);
    zapPhySend(zapAppPort, pBuf);
    rtrn = (afStatus_t)ZAP_SRSP_STATUS(pBuf);
    zap_msg_deallocate(&pBuf);
  } while ((rtrn == afStatus_SUCCESS) && len);

  return rtrn;
}
Пример #9
0
/******************************************************************************
 * @fn          zb_PermitJoiningRequest
 *
 * @brief       The zb_PermitJoiningRequest function is used to control the
 *              joining permissions and thus allow or disallow new devices from
 *              joining the network.
 *
 * @param       destination - The destination parameter indicates the address
 *                            of the device for which the joining permissions
 *                            should be set. This is usually the local device
 *                            address or the special broadcast address that denotes
 *                            all routers and coordinator ( 0xFFFC ). This way
 *                            the joining permissions of a single device or the
 *                            whole network can be controlled.
 *              timeout -  Indicates the amount of time in seconds for which
 *                         the joining permissions should be turned on.
 *                         If timeout is set to 0x00, the device will turn off the
 *                         joining permissions indefinitely. If it is set to 0xFF,
 *                         the joining permissions will be turned on indefinitely.
 *
 *
 * @return      ZB_SUCCESS or a failure code
 *
 */
uint8 zb_PermitJoiningRequest(uint16 destination, uint8 timeout)
{
  uint8 rtrn = ZB_FAILURE;
  uint8 *pBuf = zap_msg_allocate(3, ((uint8)MT_RPC_SYS_SAPI | (uint8)MT_RPC_CMD_SREQ),
                                                                     MT_SAPI_PMT_JOIN_REQ);
  if (pBuf != NULL)
  {
    pBuf[0] = LO_UINT16(destination);
    pBuf[1] = HI_UINT16(destination);
    pBuf[2] = timeout;

    if (zapPhySend(zapAppPort, pBuf) == SUCCESS)
    {
      rtrn = pBuf[0];
    }

    zap_msg_deallocate(&pBuf);
  }

  return rtrn;
}
Пример #10
0
/**************************************************************************************************
 * @fn          zapSysReq
 *
 * @brief       This function packs and sends an RPC SYS request.
 *
 * input parameters
 *
 * @param       cmd - A valid SYS command.
 * @param       req - A buffer containing the contents of the request/response, or NULL.
 * @param       args - Valid argument(s) corresponding to the SYS 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 zapSysReq(uint8 cmd, uint8 *req, uint8 *args)
{
  uint8 len, cmd0 = (uint8)MT_RPC_CMD_SREQ;
  uint8 *pBuf;

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

  case MT_SYS_PING:
  case MT_SYS_RANDOM:
  case MT_SYS_ADC_READ:
    len = 2;
    break;

  case MT_SYS_VERSION:
    len = sizeof(MTVersionString);
    break;

  case MT_SYS_SET_EXTADDR:
  case MT_SYS_GET_EXTADDR:
    len = Z_EXTADDR_LEN;
    break;

  case MT_SYS_OSAL_NV_READ:
    len = 3;
    break;

  case MT_SYS_OSAL_NV_WRITE:
    len = args[3] + 4;
    break;

  case MT_SYS_OSAL_START_TIMER:
    len = 3;
    break;

  case MT_SYS_OSAL_STOP_TIMER:
    len = 1;
    break;
    
  case MT_SYS_GPIO:
    break;

  case MT_SYS_STACK_TUNE:
    len = args[1] + 1;
    break;

  // AREQ's to ZNP.

  case MT_SYS_RESET_REQ:
    cmd0 = (uint8)MT_RPC_CMD_AREQ;
    len = 1;
    break;
    
  default:
    len = 8;  // Biggest return buffer size besides NV access.
    break;
  }
  cmd0 |= (uint8)MT_RPC_SYS_SYS;

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

  switch (cmd)
  {
  case MT_SYS_SET_EXTADDR:
    (void)osal_memcpy(pBuf, req, Z_EXTADDR_LEN);
    break;

  case MT_SYS_OSAL_NV_WRITE:
    (void)osal_memcpy(pBuf+4, req, args[3]);
    pBuf[3] = args[3];  // NV Item len.
  case MT_SYS_OSAL_NV_READ:
  case MT_SYS_OSAL_START_TIMER:
    pBuf[2] = args[2];  // NV Item offset / Timer Period MSB.
  case MT_SYS_ADC_READ:
    pBuf[1] = args[1];  // NV Item Id MSB / Timer Period LSB / ADC Resolution.
  case MT_SYS_RESET_REQ:
  case MT_SYS_OSAL_STOP_TIMER:
    pBuf[0] = args[0];  // NV Item Id LSB / Timer Idx / ADC Chan.
    break;

  case MT_SYS_GPIO:
    break;

  case MT_SYS_STACK_TUNE:
    pBuf[0] = args[0];  // The MT_SYS_STACK_TUNE command from STK_Tune_t.
    (void)osal_memcpy(pBuf+1, req, args[1]);
    break;
    
  default:
    break;
  }

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

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

  case MT_SYS_PING:
  case MT_SYS_RANDOM:
  case MT_SYS_ADC_READ:
    (void)osal_memcpy(req, pBuf, 2);
    break;

  case MT_SYS_VERSION:
    (void)osal_memcpy(req, pBuf, sizeof(MTVersionString));
    break;
    
  case MT_SYS_SET_EXTADDR:
    // It is not intuitive to have non-NULL args just for return value that should always be TRUE.
    break;

  case MT_SYS_OSAL_NV_WRITE:
  case MT_SYS_OSAL_START_TIMER:
  case MT_SYS_OSAL_STOP_TIMER:
    args[0] = pBuf[0];
    break;

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

  case MT_SYS_OSAL_NV_READ:
    if ((SUCCESS == (args[0] = pBuf[0])) && (args[3] == (args[1] = pBuf[1])))
    {
      (void)osal_memcpy(req, pBuf+2, args[1]);
    }
    else
    {
      args[0] = NV_OPER_FAILED;
    }
    break;

  case MT_SYS_GPIO:
    break;

  case MT_SYS_STACK_TUNE:
    *req = *pBuf;
    break;
    
  default:
    break;
  }

  zap_msg_deallocate(&pBuf);
  return SUCCESS;
}
Пример #11
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;
}
Пример #12
0
/**************************************************************************************************
 * @fn      AF_DataRequest
 *
 * @brief   API definition to invoke AF_DataRequest on the ZNP.
 *
 * input parameters
 *
 * @param  *dstAddr - Full ZB destination address: Nwk Addr + End Point.
 * @param  *srcEP - Origination (i.e. respond to or ack to) End Point Descr.
 * @param   cID - A valid cluster ID as specified by the Profile.
 * @param   len - Number of bytes of data pointed to by next param.
 * @param  *buf - A pointer to the data bytes to send.
 * @param  *transID - A pointer to a byte which can be modified and which will
 *                    be used as the transaction sequence number of the msg.
 * @param   options - Valid bit mask of Tx options.
 * @param   radius - Normally set to AF_DEFAULT_RADIUS.
 *
 * output parameters
 *
 * @param  *transID - Incremented by one if the return value is success.
 *
 * @return  afStatus_t per declaration.
 **************************************************************************************************
 */
afStatus_t AF_DataRequest(afAddrType_t *dstAddr, endPointDesc_t *srcEP,
                          uint16 cID, uint16 len, uint8 *buf, uint8 *transID,
                          uint8 options, uint8 radius)
{
  #define ZAP_AF_REQ_MSG_HDR  20
  #define ZAP_AF_REQ_DAT_MAX (MT_RPC_DATA_MAX - ZAP_AF_REQ_MSG_HDR)
  uint8 *pBuf;

#if !ZAP_AF_DATA_REQ_AREQ
  afStatus_t rtrn;

#if ZAP_AF_DATA_REQ_FRAG
  if (len > ZAP_AF_REQ_DAT_MAX)
  {
    pBuf = zap_msg_allocate(ZAP_AF_REQ_MSG_HDR, (uint8)MT_RPC_SYS_AF | (uint8)MT_RPC_CMD_SREQ,
                                                (uint8)MT_AF_DATA_REQUEST_EXT);
  }
  else
#endif
  {
    pBuf = zap_msg_allocate((uint8)(len + ZAP_AF_REQ_MSG_HDR),
                            (uint8)MT_RPC_SYS_AF | (uint8)MT_RPC_CMD_SREQ,
                            (uint8)MT_AF_DATA_REQUEST_EXT);
  }
#else
  pBuf = zap_msg_allocate((uint8)(len + ZAP_AF_REQ_MSG_HDR),
                          (uint8)MT_RPC_SYS_AF | (uint8)MT_RPC_CMD_AREQ,
                          (uint8)MT_AF_DATA_REQUEST_EXT);
#endif

  if (NULL == pBuf)
  {
    return afStatus_MEM_FAIL;
  }

  *pBuf++ = dstAddr->addrMode;

  if (dstAddr->addrMode == afAddr64Bit)
  {
    (void)osal_memcpy(pBuf, dstAddr->addr.extAddr, Z_EXTADDR_LEN);
  }
  else
  {
    pBuf[0] = LO_UINT16(dstAddr->addr.shortAddr);
    pBuf[1] = HI_UINT16(dstAddr->addr.shortAddr);
  }
  pBuf += Z_EXTADDR_LEN;

  *pBuf++ = dstAddr->endPoint;
#if defined INTER_PAN
  *pBuf++ = LO_UINT16(dstAddr->panId);
  *pBuf++ = HI_UINT16(dstAddr->panId);
#else
  *pBuf++ = 0;
  *pBuf++ = 0;
#endif
  *pBuf++ = srcEP->endPoint;
  *pBuf++ = LO_UINT16(cID);
  *pBuf++ = HI_UINT16(cID);
  *pBuf++ = *transID;
  (*transID)++;
  *pBuf++ = options;
  *pBuf++ = radius;
  *pBuf++ = LO_UINT16(len);
  *pBuf++ = HI_UINT16(len);

#if ZAP_AF_DATA_REQ_FRAG
  if (len <= ZAP_AF_REQ_DAT_MAX)
#endif
  {
    (void)osal_memcpy(pBuf, buf, len);
  }

  pBuf -= ZAP_AF_REQ_MSG_HDR;
  zapPhySend(zapAppPort, pBuf);
#if !ZAP_AF_DATA_REQ_AREQ
  rtrn = (afStatus_t)ZAP_SRSP_STATUS(pBuf);
#endif
  zap_msg_deallocate(&pBuf);

#if ZAP_AF_DATA_REQ_FRAG
  if ((len > ZAP_AF_REQ_DAT_MAX) && (rtrn == afStatus_SUCCESS))
  {
    rtrn = afStore(buf, len);
  }
#endif

#if ZAP_AF_DATA_REQ_AREQ
  return SUCCESS;
#else
  return rtrn;
#endif
}