/***************************************************************************
deal with the HA discover request
*****************************************************************************/
void AT_AF_Cmd_HA_DISC_req(afIncomingMSGPacket_t *pkt  ){
  AT_AF_Cmd_HA_DISC_req_t *req = (AT_AF_Cmd_HA_DISC_req_t *)pkt->cmd.Data;
  AT_AF_Cmd_HA_DISC_rsp_t *rsp;
  uint8 zcl_epCount =0;
  
  uint8 AT_CMD_EP_ARRAY[]=AT_CMD_EPs;
  uint8 i;
  uint8 buf_temp[sizeof(AT_AF_Cmd_HA_DISC_rsp_t)+sizeof(AT_CMD_EP_ARRAY)*sizeof(AT_AF_Cmd_HA_DISC_item_t)];
  rsp = (AT_AF_Cmd_HA_DISC_rsp_t *) buf_temp;
  
  for(i=0;i<sizeof(AT_CMD_EP_ARRAY);i++){
    epList_t* epList = AT_af_get_ep(AT_CMD_EP_ARRAY[i]);
    SimpleDescriptionFormat_t* simDesc=epList->epDesc->simpleDesc;
    
    //find the CID
    bool found=false;
    uint8 j;
    for(j=0;j<simDesc->AppNumOutClusters;j++){
      if(simDesc->pAppOutClusterList[j]==req->CID) {
        if(req->option==0){
          if(afFindEndPointDesc(AT_CMD_EP_ARRAY[i])) found=true;
        }else{
          found=true;
        }
        break;
      }
    }
    if(!found){
      for(j=0;j<simDesc->AppNumInClusters;j++){
        if(simDesc->pAppInClusterList[j]==req->CID) {
          if(req->option==0){
            if(afFindEndPointDesc(AT_CMD_EP_ARRAY[i])) found=true;
          }else{
            found=true;
          }
          break;
        }
      }
    }
    
    //if found the CID
    if(found){
      rsp->item[zcl_epCount].ep = AT_CMD_EP_ARRAY[i];
      rsp->item[zcl_epCount].status = afFindEndPointDesc(AT_CMD_EP_ARRAY[i]) ? AT_AF_enable : AT_AF_disable;
      zcl_epCount++;
    }
  }
  if(zcl_epCount!=0){
    rsp->hdr.numItem=zcl_epCount;
    rsp->hdr.cmd=AT_AF_Cmd_rsp;
    AF_DataRequest( & (pkt->srcAddr), & AT_AF_epDesc,
                         AT_AF_Cmd_HA_DISC_CLUSTERID,
                         sizeof(AT_AF_Cmd_HA_DISC_rsp_t)+zcl_epCount*sizeof(AT_AF_Cmd_HA_DISC_item_t),
                         (uint8*)rsp,
                         &AT_AF_TransID,
                         AF_DISCV_ROUTE,
                         AF_DEFAULT_RADIUS );
      
  }
}
Example #2
0
/***************************************************************************************************
 * @fn      MT_AppPB_ZCLCfg
 *
 * @brief   Process MT_APP_PB_ZCL_CFG command
 *
 * @param   pBuf - pointer to the received buffer
 *
 * @return  void
 ***************************************************************************************************/
static void MT_AppPB_ZCLCfg( uint8 *pBuf )
{
  uint8 retValue = ZFailure;
  uint8 appEP;
  endPointDesc_t *epDesc;
  mtAppPB_ZCLCfg_t *cmd;
  uint8 cmdId;

  /* Parse the RPC header */
  cmdId = pBuf[MT_RPC_POS_CMD1];
  pBuf += MT_RPC_FRAME_HDR_SZ;

  /* Application End Point */
  appEP = *pBuf++;

  /* Look up the endpoint */
  epDesc = afFindEndPointDesc( appEP );

  if ( epDesc )
  {
    /* Build and send the message to the APP */
    cmd = (mtAppPB_ZCLCfg_t *)osal_msg_allocate( sizeof( mtAppPB_ZCLCfg_t ) );

    if ( cmd )
    {
      /* Build and send message to the app */
      cmd->hdr.event = MT_SYS_APP_PB_ZCL_CMD;

      /* PB ZCL command type*/
      cmd->type = MT_APP_PB_ZCL_CMD_CFG;

      /* PB ZCL Config Mode */
      cmd->mode = *pBuf++;

      /* Send the message */
      osal_msg_send( *(epDesc->task_id), (uint8 *)cmd );

      /* Info for response */
      retValue = ZSuccess;
    }
  }

  /* Build and send back the response */
  MT_BuildAndSendZToolResponse( ( (uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_APP ),
                                cmdId, 1, &retValue );
}
Example #3
0
/***************************************************************************************************
 * @fn      MT_AfInterPanCtl
 *
 * @brief   Process the AF Inter Pan control command.
 *
 * @param   pBuf - pointer to the received buffer
 *
 * @return  none
 ***************************************************************************************************/
static void MT_AfInterPanCtl(uint8 *pBuf)
{
  uint8 cmd, rtrn;
  uint16 panId;
  endPointDesc_t *pEP;

  cmd = pBuf[MT_RPC_POS_CMD1];
  pBuf += MT_RPC_FRAME_HDR_SZ;

  switch (*pBuf++)  // Inter-pan request parameter.
  {
  case InterPanClr:
    rtrn = StubAPS_SetIntraPanChannel();           // Switch channel back to the NIB channel.
    break;

  case InterPanSet:
    rtrn = StubAPS_SetInterPanChannel(*pBuf);      // Set channel for inter-pan communication.
    break;

  case InterPanReg:
    if ((pEP = afFindEndPointDesc(*pBuf)))
    {
      StubAPS_RegisterApp(pEP);
      rtrn = SUCCESS;
    }
    else
    {
      rtrn = FAILURE;
    }
    break;

  case InterPanChk:
    panId = BUILD_UINT16(pBuf[0], pBuf[1]);
    rtrn = (StubAPS_InterPan(panId, pBuf[2])) ? ZSuccess : ZFailure;
    break;

  default:
    rtrn = afStatus_INVALID_PARAMETER;
    break;
  }

  MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_AF), cmd, 1, &rtrn);
}
Example #4
0
/***************************************************************************************************
 * @fn      MT_AppMsg
 *
 * @brief   Process APP_MSG command
 *
 * @param   pBuf - pointer to the received buffer
 *
 * @return  void
 ***************************************************************************************************/
static void MT_AppMsg(uint8 *pBuf)
{
  uint8 retValue = ZFailure;
  uint8 endpoint;
  endPointDesc_t *epDesc;
  mtSysAppMsg_t *msg;
  uint8 cmdId, dataLen;

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

  /* Get the endpoint and skip past it.*/
  endpoint = *pBuf++;
  dataLen--;

  /* Look up the endpoint */
  epDesc = afFindEndPointDesc( endpoint );

  if (epDesc)
  {
    /* Build and send the message to the APP */
    msg = (mtSysAppMsg_t *)osal_msg_allocate(sizeof(mtSysAppMsg_t) + (dataLen));
    if ( msg )
    {
      /* Build and send message up the app */
      msg->hdr.event = MT_SYS_APP_MSG;
      msg->endpoint = endpoint;
      msg->appDataLen = dataLen;
      msg->appData = (uint8*)(msg+1);
      osal_memcpy( msg->appData, pBuf, dataLen);
      osal_msg_send( *(epDesc->task_id), (uint8 *)msg );

      /* Info for response */
      retValue = ZSuccess;
    }
  }

  /* Build and send back the response */
  MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_APP), cmdId, 1, &retValue);
}
Example #5
0
File: AF.c Project: LILCMU/WRATIOT
/*********************************************************************
 * @fn          afReflectError
 *
 * @brief       This function will generate the Reflect Error message to
 *              the application.
 *
 * @param       srcEP - Source Endpoint
 * @param       dstAddrMode - mode of dstAdd - 0 - normal short addr, 1 - group Address
 * @param       dstAddr - intended destination
 * @param       dstEP - Destination Endpoint
 * @param       transID - transaction ID from APSDE_DATA_REQUEST
 * @param       status - status of APSDE_DATA_REQUEST
 *
 * @return      none
 */
void afReflectError( uint8 srcEP, uint8 dstAddrMode, uint16 dstAddr, uint8 dstEP,
                     uint8 transID, ZStatus_t status )
{
  endPointDesc_t *epDesc;
  afReflectError_t *msgPtr;

  // Find the endpoint description
  epDesc = afFindEndPointDesc( srcEP );
  if ( epDesc == NULL )
    return;

  // Determine the incoming command type
  msgPtr = (afReflectError_t *)osal_msg_allocate( sizeof(afReflectError_t) );
  if ( msgPtr )
  {
    // Build the Data Confirm message
    msgPtr->hdr.event = AF_REFLECT_ERROR_CMD;
    msgPtr->hdr.status = status;
    msgPtr->endpoint = dstEP;
    msgPtr->transID = transID;
    msgPtr->dstAddrMode = dstAddrMode;
    msgPtr->dstAddr = dstAddr;

#if defined ( MT_AF_CB_FUNC )
    /* If MT has subscribed for this callback, don't send as a message. */
    if ( AFCB_CHECK( CB_ID_AF_REFLECT_ERROR, *(epDesc->task_id) ) )
    {
      /* Send callback if it's subscribed */
      MT_AfReflectError( (void *)msgPtr );
      /* Release the memory. */
      osal_msg_deallocate( (void *)msgPtr );
    }
    else
#endif
    {
      /* send message through task message */
      osal_msg_send( *(epDesc->task_id), (uint8 *)msgPtr );
    }
  }
}
Example #6
0
/*********************************************************************
 * @fn          afDataConfirm
 *
 * @brief       This function will generate the Data Confirm back to
 *              the application.
 *
 * @param       endPoint - confirm end point
 * @param       transID - transaction ID from APSDE_DATA_REQUEST
 * @param       status - status of APSDE_DATA_REQUEST
 *
 * @return      none
 */
void afDataConfirm( uint8 endPoint, uint8 transID, ZStatus_t status )
{
  endPointDesc_t *epDesc;
  afDataConfirm_t *msgPtr;

  // Find the endpoint description
  epDesc = afFindEndPointDesc( endPoint );
  if ( epDesc == NULL )
    return;

  // Determine the incoming command type
  msgPtr = (afDataConfirm_t *)osal_msg_allocate( sizeof(afDataConfirm_t) );
  if ( msgPtr )
  {
    // Build the Data Confirm message
    msgPtr->hdr.event = AF_DATA_CONFIRM_CMD;
    msgPtr->hdr.status = status;
    msgPtr->endpoint = endPoint;
    msgPtr->transID = transID;

#if defined ( MT_AF_CB_FUNC )
    /* If MT has subscribed for this callback, don't send as a message. */
    if ( AFCB_CHECK(CB_ID_AF_DATA_CNF,*(epDesc->task_id)) )
    {
      /* Send callback if it's subscribed */
      MT_AfDataConfirm ((void *)msgPtr);
      /* Release the memory. */
      osal_msg_deallocate( (void *)msgPtr );
    }
    else
#endif
    {
      /* send message through task message */
      osal_msg_send( *(epDesc->task_id), (byte *)msgPtr );
    }
  }
}
Example #7
0
/*********************************************************************
 * @fn          afIncomingData
 *
 * @brief       Transfer a data PDU (ASDU) from the APS sub-layer to the AF.
 *
 * @param       aff  - pointer to APS frame format
 * @param       SrcAddress  - Source address
 * @param       sig - incoming message's link quality
 * @param       SecurityUse - Security enable/disable
 *
 * @return      none
 */
void afIncomingData( aps_FrameFormat_t *aff, zAddrType_t *SrcAddress, uint16 SrcPanId,
                     NLDE_Signal_t *sig, byte SecurityUse, uint32 timestamp )
{
  endPointDesc_t *epDesc = NULL;
  uint16 epProfileID = 0xFFFF;  // Invalid Profile ID
  epList_t *pList = epList;
#if !defined ( APS_NO_GROUPS )    
  uint8 grpEp = APS_GROUPS_EP_NOT_FOUND;
#endif  

  if ( ((aff->FrmCtrl & APS_DELIVERYMODE_MASK) == APS_FC_DM_GROUP) )
  {
#if !defined ( APS_NO_GROUPS )    
    // Find the first endpoint for this group
    grpEp = aps_FindGroupForEndpoint( aff->GroupID, APS_GROUPS_FIND_FIRST );
    if ( grpEp == APS_GROUPS_EP_NOT_FOUND )
      return;   // No endpoint found

    epDesc = afFindEndPointDesc( grpEp );
    if ( epDesc == NULL )
      return;   // Endpoint descriptor not found

    pList = afFindEndPointDescList( epDesc->endPoint );
#else
    return; // Not supported
#endif    
  }
  else if ( aff->DstEndPoint == AF_BROADCAST_ENDPOINT )
  {
    // Set the list
    if ( pList != NULL )
    {
      epDesc = pList->epDesc;
    }
  }
  else if ( (epDesc = afFindEndPointDesc( aff->DstEndPoint )) )
  {
    pList = afFindEndPointDescList( epDesc->endPoint );
  }

  while ( epDesc )
  {
    if ( pList->pfnDescCB )
    {
      uint16 *pID = (uint16 *)(pList->pfnDescCB(
                                 AF_DESCRIPTOR_PROFILE_ID, epDesc->endPoint ));
      if ( pID )
      {
        epProfileID = *pID;
        osal_mem_free( pID );
      }
    }
    else if ( epDesc->simpleDesc )
    {
      epProfileID = epDesc->simpleDesc->AppProfId;
    }

    if ( (aff->ProfileID == epProfileID) ||
         ((epDesc->endPoint == ZDO_EP) && (aff->ProfileID == ZDO_PROFILE_ID)) )
    {
      {
        afBuildMSGIncoming( aff, epDesc, SrcAddress, SrcPanId, sig, SecurityUse, timestamp );
      }
    }

    if ( ((aff->FrmCtrl & APS_DELIVERYMODE_MASK) == APS_FC_DM_GROUP) )
    {
#if !defined ( APS_NO_GROUPS )      
      // Find the next endpoint for this group
      grpEp = aps_FindGroupForEndpoint( aff->GroupID, grpEp );
      if ( grpEp == APS_GROUPS_EP_NOT_FOUND )
        return;   // No endpoint found

      epDesc = afFindEndPointDesc( grpEp );
      if ( epDesc == NULL )
        return;   // Endpoint descriptor not found

      pList = afFindEndPointDescList( epDesc->endPoint );
#else
      return;
#endif      
    }
    else if ( aff->DstEndPoint == AF_BROADCAST_ENDPOINT )
    {
      pList = pList->nextDesc;
      if ( pList )
        epDesc = pList->epDesc;
      else
        epDesc = NULL;
    }
    else
      epDesc = NULL;
  }
}
Example #8
0
/***************************************************************************************************
 * @fn      MT_AfDataRequestSrcRtg
 *
 * @brief   Process AF Register command
 *
 * @param   pBuf - pointer to the received buffer
 *
 * @return  none
 ***************************************************************************************************/
void MT_AfDataRequestSrcRtg(uint8 *pBuf)
{
  uint8 cmdId, dataLen = 0;
  uint8 retValue = ZFailure;
  endPointDesc_t *epDesc;
  byte transId;
  afAddrType_t dstAddr;
  cId_t cId;
  byte txOpts, radius, srcEP, relayCnt;
  uint16 *pRelayList;
  uint8 i;

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

  /* Destination address */
  /* Initialize the panID field to zero to avoid inter-pan */
  osal_memset( &dstAddr, 0, sizeof(afAddrType_t) );
  dstAddr.addrMode = afAddr16Bit;
  dstAddr.addr.shortAddr = BUILD_UINT16(pBuf[0], pBuf[1]);
  pBuf += 2;

  /* Destination endpoint */
  dstAddr.endPoint = *pBuf++;

  /* Source endpoint */
  srcEP = *pBuf++;
  epDesc = afFindEndPointDesc( srcEP );

  /* ClusterId */
  cId = BUILD_UINT16(pBuf[0], pBuf[1]);
  pBuf +=2;

  /* TransId */
  transId = *pBuf++;

  /* TxOption */
  txOpts = *pBuf++;

  /* Radius */
  radius = *pBuf++;

  /* Source route relay count */
  relayCnt = *pBuf++;

  /* Convert the source route relay list */
  if( (pRelayList = osal_mem_alloc( relayCnt * sizeof( uint16 ))) != NULL )
  {
    for( i = 0; i < relayCnt; i++ )
    {
      pRelayList[i]  = BUILD_UINT16( pBuf[0], pBuf[1] );
      pBuf += 2;
    }

    /* Data payload Length */
    dataLen = *pBuf++;

    if ( epDesc == NULL )
    {
      retValue = afStatus_INVALID_PARAMETER;
    }
    else
    {
      retValue = AF_DataRequestSrcRtg( &dstAddr, epDesc, cId, dataLen, pBuf,
                                     &transId, txOpts, radius, relayCnt, pRelayList );
    }

    /* Free the memory allocated */
    osal_mem_free( pRelayList );
  }
  else
  {
    retValue = afStatus_MEM_FAIL;
  }


  /* Build and send back the response */
  MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_AF), cmdId, 1, &retValue);
}
Example #9
0
/***************************************************************************************************
 * @fn      MT_AfDataRequest
 *
 * @brief   Process AF Register command
 *
 * @param   pBuf - pointer to the received buffer
 *
 * @return  none
 ***************************************************************************************************/
void MT_AfDataRequest(uint8 *pBuf)
{
  #define MT_AF_REQ_MSG_LEN  10
  #define MT_AF_REQ_MSG_EXT  10

  endPointDesc_t *epDesc;
  afAddrType_t dstAddr;
  cId_t cId;
  uint8 transId, txOpts, radius;
  uint8 cmd0, cmd1;
  uint8 retValue = ZFailure;
  uint16 dataLen, tempLen;

  /* Parse header */
  cmd0 = pBuf[MT_RPC_POS_CMD0];
  cmd1 = pBuf[MT_RPC_POS_CMD1];
  pBuf += MT_RPC_FRAME_HDR_SZ;

  if (cmd1 == MT_AF_DATA_REQUEST_EXT)
  {
    dstAddr.addrMode = (afAddrMode_t)*pBuf++;

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

    dstAddr.endPoint = *pBuf++;
    dstAddr.panId = BUILD_UINT16(pBuf[0], pBuf[1]);
    pBuf += 2;
  }
  else
  {
    /* Destination address */
    dstAddr.addrMode = afAddr16Bit;
    dstAddr.addr.shortAddr = BUILD_UINT16(pBuf[0], pBuf[1]);
    pBuf += 2;

    /* Destination endpoint */
    dstAddr.endPoint = *pBuf++;
    dstAddr.panId = 0;
  }

  /* Source endpoint */
  epDesc = afFindEndPointDesc(*pBuf++);

  /* ClusterId */
  cId = BUILD_UINT16(pBuf[0], pBuf[1]);
  pBuf +=2;

  /* TransId */
  transId = *pBuf++;

  /* TxOption */
  txOpts = *pBuf++;

  /* Radius */
  radius = *pBuf++;

  /* Length */
  if (cmd1 == MT_AF_DATA_REQUEST_EXT)
  {
    dataLen = BUILD_UINT16(pBuf[0], pBuf[1]);
    tempLen = dataLen + MT_AF_REQ_MSG_LEN + MT_AF_REQ_MSG_EXT;
    pBuf += 2;
  }
  else
  {
    dataLen = *pBuf++;
    tempLen = dataLen + MT_AF_REQ_MSG_LEN;
  }

  if ( epDesc == NULL )
  {
    retValue = afStatus_INVALID_PARAMETER;
  }
  else if (tempLen > (uint16)MT_RPC_DATA_MAX)
  {
    if (pMtAfDataReq != NULL)
    {
      retValue = afStatus_INVALID_PARAMETER;
    }
    else if ((pMtAfDataReq = osal_mem_alloc(sizeof(mtAfDataReq_t) + dataLen)) == NULL)
    {
      retValue = afStatus_MEM_FAIL;
    }
    else
    {
      retValue = afStatus_SUCCESS;

      pMtAfDataReq->data = (uint8 *)(pMtAfDataReq+1);
      (void)osal_memcpy(&(pMtAfDataReq->dstAddr), &dstAddr, sizeof(afAddrType_t));
      pMtAfDataReq->epDesc = epDesc;
      pMtAfDataReq->cId = cId;
      pMtAfDataReq->dataLen = dataLen;
      pMtAfDataReq->transId = transId;
      pMtAfDataReq->txOpts = txOpts;
      pMtAfDataReq->radius = radius;

      // Setup to time-out the huge outgoing item if host does not MT_AF_DATA_STORE it.
      pMtAfDataReq->tick = MT_AF_EXEC_CNT;
      if (ZSuccess != osal_start_timerEx(MT_TaskID, MT_AF_EXEC_EVT, MT_AF_EXEC_DLY))
      {
        (void)osal_set_event(MT_TaskID, MT_AF_EXEC_EVT);
      }
    }
  }
  else
  {
    retValue = AF_DataRequest(&dstAddr, epDesc, cId, dataLen, pBuf, &transId, txOpts, radius);
  }

  if (MT_RPC_CMD_SREQ == (cmd0 & MT_RPC_CMD_TYPE_MASK))
  {
    MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP|(uint8)MT_RPC_SYS_AF), cmd1, 1, &retValue);
  }
}
Example #10
0
/*********************************************************************
 * @fn      MT_afCommandProcessing
 *
 * @brief
 *
 *   Process all the AF commands that are issued by test tool
 *
 * @param   cmd_id - Command ID
 * @param   len    - Length of received SPI data message
 * @param   data   - pointer to received SPI data message
 *
 * @return  none
 */
void MT_afCommandProcessing( uint16 cmd_id , byte len , byte *pData )
{
  byte i;
  endPointDesc_t *epDesc;
  uint8 af_stat = afStatus_FAILED;

  switch (cmd_id)
  {
    case SPI_CMD_AF_INIT:

      afInit();

      //No response for this command
      break;

    case SPI_CMD_AF_REGISTER:

      // First allocate memory for the AF structure epIntDesc
      epDesc = ( endPointDesc_t * )
                  osal_mem_alloc( sizeof( endPointDesc_t ) );

      if ( epDesc )
      {
        //Assemble the AF structures with the data received
        //First the Endpoint
        epDesc->simpleDesc = ( SimpleDescriptionFormat_t * )
                    osal_mem_alloc( sizeof( SimpleDescriptionFormat_t ) );

        if ( epDesc->simpleDesc )
        {
          epDesc->endPoint = *pData++;
          epDesc->simpleDesc->EndPoint = epDesc->endPoint;

          epDesc->task_id = &MT_TaskID;

          //Now for the simple description part
          epDesc->simpleDesc->AppProfId = BUILD_UINT16( pData[1],pData[0]);
          pData += sizeof( uint16 );
          epDesc->simpleDesc->AppDeviceId = BUILD_UINT16( pData[1],pData[0]);
          pData += sizeof( uint16 );
          epDesc->simpleDesc->AppDevVer = (*pData++) & AF_APP_DEV_VER_MASK ;
          epDesc->simpleDesc->Reserved = (*pData++) & AF_APP_FLAGS_MASK ;

          epDesc->simpleDesc->AppNumInClusters = *pData++;

          if (epDesc->simpleDesc->AppNumInClusters)
          {
            epDesc->simpleDesc->pAppInClusterList = (uint16 *)
            osal_mem_alloc(ZTEST_DEFAULT_PARAM_LEN*sizeof(uint16));

            for (i=0; i<ZTEST_DEFAULT_PARAM_LEN; i++)  {
              epDesc->simpleDesc->pAppInClusterList[i] = BUILD_UINT16(*pData, 0);
              pData++;
            }
          }
          else
          {
            pData += ZTEST_DEFAULT_PARAM_LEN;
          }

          epDesc->simpleDesc->AppNumOutClusters = *pData++;

          if (epDesc->simpleDesc->AppNumOutClusters)
          {
            epDesc->simpleDesc->pAppOutClusterList = (uint16 *)
            osal_mem_alloc(ZTEST_DEFAULT_PARAM_LEN*sizeof(uint16));

            for (i=0; i<ZTEST_DEFAULT_PARAM_LEN; i++)  {
              epDesc->simpleDesc->pAppOutClusterList[i] = BUILD_UINT16(*pData, 0);
              pData++;
            }
          }
          else
          {
            pData += ZTEST_DEFAULT_PARAM_LEN;
          }

          epDesc->latencyReq = (afNetworkLatencyReq_t)*pData;

          if ( afFindEndPointDesc( epDesc->endPoint ) == NULL )
          {
            af_stat = afRegister( epDesc );
          }
        }
        else
        {
          osal_mem_free( epDesc );
          af_stat = afStatus_MEM_FAIL;
        }
      }

      len = SPI_0DATA_MSG_LEN + SPI_RESP_LEN_AF_DEFAULT;
      MT_SendSPIRespMsg( af_stat, SPI_CMD_AF_REGISTER, len, SPI_RESP_LEN_AF_DEFAULT );

      break;

    case SPI_CMD_AF_SENDMSG:
    {
#if ( AF_KVP_SUPPORT )
      afKVPCommandFormat_t kvp;
      afAddOrSend_t addOrSend;
      byte frameType;
#else
      endPointDesc_t *epDesc;
      byte transId;
#endif
      afAddrType_t dstAddr;
      cId_t cId;
      byte txOpts, radius, srcEP;

#if ( AF_KVP_SUPPORT )
      frameType = *pData;
#endif
      pData++;
      txOpts = *pData++;
      radius = *pData++;

      // Fill the AF structures with the data received.
      dstAddr.addrMode = afAddr16Bit;
      dstAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] );
      pData += 2;
      dstAddr.endPoint = *pData++;

      srcEP = *pData++;
      cId = BUILD_UINT16( pData[1], pData[0] );
      pData += 2;
#if ( AF_KVP_SUPPORT )
      addOrSend = (afAddOrSend_t)(*pData++);
      kvp.TransSeqNumber = *pData++;
      kvp.CommandType = *pData++;
      kvp.AttribDataType = *pData++;
      kvp.AttribId = BUILD_UINT16( pData[1], pData[0] );
      pData += 2;
      kvp.ErrorCode = *pData++;
      kvp.DataLength = *pData++;
      kvp.Data = pData;

      af_stat = afAddOrSendMessage( &dstAddr, srcEP, cId,
          addOrSend, frameType, &kvp.TransSeqNumber,
          kvp.CommandType, kvp.AttribDataType, kvp.AttribId, kvp.ErrorCode,
          kvp.DataLength, kvp.Data, (txOpts & ~AF_DISCV_ROUTE),
                                    (txOpts &  AF_DISCV_ROUTE), radius );
#else
      pData++;
      transId = *pData++;
      pData += 5;
      len = *pData++;
      epDesc = afFindEndPointDesc( srcEP );
      if ( epDesc == NULL )
      {
        af_stat = afStatus_INVALID_PARAMETER;
      }
      else
      {
        af_stat = AF_DataRequest( &dstAddr, epDesc, cId, len, pData,
                                  &transId, txOpts, radius );
      }
#endif

      len = SPI_0DATA_MSG_LEN + SPI_RESP_LEN_AF_DEFAULT;
      MT_SendSPIRespMsg( af_stat, SPI_CMD_AF_SENDMSG,
                             len, SPI_RESP_LEN_AF_DEFAULT );
    }
    break;
  }
}
Example #11
0
/***************************************************************************************************
 * @fn      MT_BuildEndpointDesc
 *
 * @brief   Build endpoint descriptor and simple descriptor structure from incoming buffer
 *
 * @param   pBuf - byte array
 *
 * @return  epDesc - pointer to the endpoint descriptor
 ***************************************************************************************************/
uint8 MT_BuildEndpointDesc( uint8 *pBuf, void *param )
{
    uint8 i;
    uint8 ret = ZSuccess;
    endPointDesc_t *epDesc;

    epDesc = (endPointDesc_t *)param;
    /* check if this endpoint is already registered */
    if ( afFindEndPointDesc( *pBuf ) != NULL )
    {
        ret = ZApsDuplicateEntry;
    }
    else if ( epDesc )
    {
        epDesc->endPoint = *pBuf;

        /* Ignore the latency reqs */
        epDesc->latencyReq = noLatencyReqs;

        /* allocate memory for the simple descriptor */
        epDesc->simpleDesc = (SimpleDescriptionFormat_t *) osal_mem_alloc(sizeof(SimpleDescriptionFormat_t));
        if (epDesc->simpleDesc)
        {
            /* Endpoint */
            epDesc->simpleDesc->EndPoint = *pBuf++;

            /* AppProfId */
            epDesc->simpleDesc->AppProfId = BUILD_UINT16(pBuf[0], pBuf[1]);
            pBuf += sizeof(uint16);

            /* AppDeviceId */
            epDesc->simpleDesc->AppDeviceId = BUILD_UINT16(pBuf[0],pBuf[1]);
            pBuf += sizeof(uint16);

            /* AppDevVer */
            epDesc->simpleDesc->AppDevVer = (*pBuf++) & AF_APP_DEV_VER_MASK ;

            /* LatencyReq */
            pBuf++;

            /* AppNumInClusters */
            epDesc->simpleDesc->AppNumInClusters = *pBuf++;
            if (epDesc->simpleDesc->AppNumInClusters)
            {
                epDesc->simpleDesc->pAppInClusterList = (uint16 *)
                                                        osal_mem_alloc((epDesc->simpleDesc->AppNumInClusters)*sizeof(uint16));
                if ( epDesc->simpleDesc->pAppInClusterList )
                {
                    for (i=0; i<(epDesc->simpleDesc->AppNumInClusters); i++)
                    {
                        epDesc->simpleDesc->pAppInClusterList[i] = BUILD_UINT16(*pBuf, *(pBuf+1));
                        pBuf += 2;
                    }
                }
                else
                {
                    ret = ZMemError;
                }
            }

            /* AppNumOutClusters */
            epDesc->simpleDesc->AppNumOutClusters = *pBuf++;
            if (epDesc->simpleDesc->AppNumOutClusters)
            {
                epDesc->simpleDesc->pAppOutClusterList = (uint16 *)
                        osal_mem_alloc((epDesc->simpleDesc->AppNumOutClusters)*sizeof(uint16));
                if (epDesc->simpleDesc->pAppOutClusterList)
                {
                    for (i=0; i<(epDesc->simpleDesc->AppNumOutClusters); i++)
                    {
                        epDesc->simpleDesc->pAppOutClusterList[i] = BUILD_UINT16(*pBuf, *(pBuf+1));
                        pBuf += 2;
                    }
                }
                else
                {
                    ret = ZMemError;
                }
            }

            /* if any list cannot be allocated...free all */
            if ( ret == ZMemError )
            {
                if (epDesc->simpleDesc->pAppInClusterList)
                {
                    osal_mem_free(epDesc->simpleDesc->pAppInClusterList);
                }

                if (epDesc->simpleDesc->AppNumOutClusters)
                {
                    osal_mem_free(epDesc->simpleDesc->pAppOutClusterList);
                }

                osal_mem_free(epDesc->simpleDesc);
            }
        }
        else
        {
            ret = ZMemError;
        }
    }

    return ret;
}
Example #12
0
/***************************************************************************************************
 * @fn      MT_AppPB_ZCLMsg
 *
 * @brief   Process MT_APP_PB_ZCL_MSG command
 *
 * @param   pBuf - pointer to the received buffer
 *
 * @return  void
 ***************************************************************************************************/
static void MT_AppPB_ZCLMsg( uint8 *pBuf )
{
  uint8 retValue = ZFailure;
  uint8 appEP;
  endPointDesc_t *epDesc;
  mtAppPB_ZCLMsg_t *cmd;
  uint8 cmdId;
  uint8 dataLen;

  /* Parse the RPC header */
  dataLen = pBuf[MT_RPC_POS_LEN] - MT_APP_PB_ZCL_MSG_HDR_LEN;
  cmdId = pBuf[MT_RPC_POS_CMD1];
  pBuf += MT_RPC_FRAME_HDR_SZ;

  /* Application End Point */
  appEP = *pBuf++;

  /* Look up the endpoint */
  epDesc = afFindEndPointDesc( appEP );

  if ( epDesc )
  {
    /* Build and send the message to the APP */
    cmd = (mtAppPB_ZCLMsg_t *)osal_msg_allocate( sizeof( mtAppPB_ZCLMsg_t ) + dataLen );
    if ( cmd )
    {
      /* Build and send message to the app */
      cmd->hdr.event = MT_SYS_APP_PB_ZCL_CMD;

      /* PB ZCL command type */
      cmd->type = MT_APP_PB_ZCL_CMD_MSG;

      /* Application End Point */
      cmd->appEP = appEP;

      /* Destination Address */
      cmd->dstAddr.addr.shortAddr = osal_build_uint16( pBuf );
      pBuf += sizeof(uint16);

      /* Destination Address Mode */
      cmd->dstAddr.addrMode = afAddr16Bit;

      /* Destination End Point */
      cmd->dstAddr.endPoint = *pBuf++;;

      /* Use Default PAN ID */
      cmd->dstAddr.panId = 0xFFFF;

      /* Cluster ID */
      cmd->clusterID = osal_build_uint16( pBuf );
      pBuf += sizeof( uint16 );

      /* Command ID */
      cmd->commandID = *pBuf++;

      /* Cluster Specific Command */
      cmd->specific = *pBuf++;

      /* Command Direction */
      cmd->direction = *pBuf++;

      /* Disable Default Response */
      cmd->disableDefRsp = *pBuf++;

      /* Manufacturer Code */
      cmd->manuCode = osal_build_uint16( pBuf );
      pBuf += sizeof( uint16 );

      /* ZCL Transaction Sequence Number */
      cmd->transSeqNum  = *pBuf++;

      /* Application Data Length */
      cmd->appPBDataLen = dataLen;

      /* Application Data */
      cmd->appPBData = (uint8 *)( cmd + 1 );
      osal_memcpy( cmd->appPBData, pBuf, dataLen );

      /* Send the message */
      osal_msg_send( *(epDesc->task_id), (uint8 *)cmd );

      /* Info for response */
      retValue = ZSuccess;
    }
  }

  /* Build and send back the response */
  MT_BuildAndSendZToolResponse( ( (uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_APP ),
                                cmdId, 1, &retValue);
}
Example #13
0
/***************************************************************************************************
 * @fn      MT_AfDataRequest
 *
 * @brief   Process AF Register command
 *
 * @param   pBuf - pointer to the received buffer
 *
 * @return  none
 ***************************************************************************************************/
void MT_AfDataRequest(uint8 *pBuf)
{
  uint8 cmd0, cmd1, tempLen = 0;
  uint8 retValue = ZFailure;
  endPointDesc_t *epDesc;
  byte transId;
  afAddrType_t dstAddr;
  cId_t cId;
  byte txOpts, radius, srcEP;

  /* Parse header */
  cmd0 = pBuf[MT_RPC_POS_CMD0];
  cmd1 = pBuf[MT_RPC_POS_CMD1];
  pBuf += MT_RPC_FRAME_HDR_SZ;

  if (cmd1 == MT_AF_DATA_REQUEST_EXT)
  {
    dstAddr.addrMode = (afAddrMode_t)*pBuf++;

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

    dstAddr.endPoint = *pBuf++;
    dstAddr.panId = BUILD_UINT16(pBuf[0], pBuf[1]);
    pBuf += 2;
  }
  else
  {
    /* Destination address */
    dstAddr.addrMode = afAddr16Bit;
    dstAddr.addr.shortAddr = BUILD_UINT16(pBuf[0], pBuf[1]);
    pBuf += 2;

    /* Destination endpoint */
    dstAddr.endPoint = *pBuf++;
    dstAddr.panId = 0;
  }

  /* Source endpoint */
  srcEP = *pBuf++;
  epDesc = afFindEndPointDesc( srcEP );

  /* ClusterId */
  cId = BUILD_UINT16(pBuf[0], pBuf[1]);
  pBuf +=2;

  /* TransId */
  transId = *pBuf++;

  /* TxOption */
  txOpts = *pBuf++;

  /* Radius */
  radius = *pBuf++;

  /* Length */
  tempLen = *pBuf++;

  if ( epDesc == NULL )
  {
    retValue = afStatus_INVALID_PARAMETER;
  }
  else
  {
    retValue = AF_DataRequest( &dstAddr, epDesc, cId, tempLen, pBuf, &transId, txOpts, radius );
  }

  if (MT_RPC_CMD_SREQ == (cmd0 & MT_RPC_CMD_TYPE_MASK))
  {
    MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP|(uint8)MT_RPC_SYS_AF), cmd1, 1, &retValue);
  }
}
Example #14
0
/*********************************************************************
 * @fn          afIncomingData
 *
 * @brief       Transfer a data PDU (ASDU) from the APS sub-layer to the AF.
 *
 * @param       aff  - pointer to APS frame format
 * @param       SrcAddress  - Source address
 * @param       SrcPanId  - Source PAN ID
 * @param       sig - incoming message's link quality
 * @param       nwkSeqNum - incoming network sequence number (from nwk header frame)
 * @param       SecurityUse - Security enable/disable
 * @param       timestamp - the MAC Timer2 timestamp at Rx.
 * @param       radius - incoming messages received radius
 *
 * @return      none
 */
void afIncomingData( aps_FrameFormat_t *aff, zAddrType_t *SrcAddress, uint16 SrcPanId,
                     NLDE_Signal_t *sig, uint8 nwkSeqNum, uint8 SecurityUse,
                     uint32 timestamp, uint8 radius )
{
  endPointDesc_t *epDesc = NULL;
  epList_t *pList = epList;
#if !defined ( APS_NO_GROUPS )
  uint8 grpEp = APS_GROUPS_EP_NOT_FOUND;
#endif

  if ( ((aff->FrmCtrl & APS_DELIVERYMODE_MASK) == APS_FC_DM_GROUP) )
  {
#if !defined ( APS_NO_GROUPS )
    // Find the first endpoint for this group
    grpEp = aps_FindGroupForEndpoint( aff->GroupID, APS_GROUPS_FIND_FIRST );
    if ( grpEp == APS_GROUPS_EP_NOT_FOUND )
      return;   // No endpoint found

    epDesc = afFindEndPointDesc( grpEp );
    if ( epDesc == NULL )
      return;   // Endpoint descriptor not found

    pList = afFindEndPointDescList( epDesc->endPoint );
#else
    return; // Not supported
#endif
  }
  else if ( aff->DstEndPoint == AF_BROADCAST_ENDPOINT )
  {
    // Set the list
    if ( pList != NULL )
    {
      epDesc = pList->epDesc;
    }
  }
  else if ( (epDesc = afFindEndPointDesc( aff->DstEndPoint )) )
  {
    pList = afFindEndPointDescList( epDesc->endPoint );
  }

  while ( epDesc )
  {
    uint16 epProfileID = 0xFFFE;  // Invalid Profile ID

    if ( pList->pfnDescCB )
    {
      uint16 *pID = (uint16 *)(pList->pfnDescCB(
                                 AF_DESCRIPTOR_PROFILE_ID, epDesc->endPoint ));
      if ( pID )
      {
        epProfileID = *pID;
        osal_mem_free( pID );
      }
    }
    else if ( epDesc->simpleDesc )
    {
      epProfileID = epDesc->simpleDesc->AppProfId;
    }

    // First part of verification is to make sure that:
    // the local Endpoint ProfileID matches the received ProfileID OR
    // the message is specifically send to ZDO (this excludes the broadcast endpoint) OR
    // if the Wildcard ProfileID is received the message should not be sent to ZDO endpoint
    if ( (aff->ProfileID == epProfileID) ||
         ((epDesc->endPoint == ZDO_EP) && (aff->ProfileID == ZDO_PROFILE_ID)) ||
         ((epDesc->endPoint != ZDO_EP) && ( aff->ProfileID == ZDO_WILDCARD_PROFILE_ID )) )
    {
      // Save original endpoint
      uint8 endpoint = aff->DstEndPoint;

      // overwrite with descriptor's endpoint
      aff->DstEndPoint = epDesc->endPoint;

      afBuildMSGIncoming( aff, epDesc, SrcAddress, SrcPanId, sig,
                         nwkSeqNum, SecurityUse, timestamp, radius );

      // Restore with original endpoint
      aff->DstEndPoint = endpoint;
    }

    if ( ((aff->FrmCtrl & APS_DELIVERYMODE_MASK) == APS_FC_DM_GROUP) )
    {
#if !defined ( APS_NO_GROUPS )
      // Find the next endpoint for this group
      grpEp = aps_FindGroupForEndpoint( aff->GroupID, grpEp );
      if ( grpEp == APS_GROUPS_EP_NOT_FOUND )
        return;   // No endpoint found

      epDesc = afFindEndPointDesc( grpEp );
      if ( epDesc == NULL )
        return;   // Endpoint descriptor not found

      pList = afFindEndPointDescList( epDesc->endPoint );
#else
      return;
#endif
    }
    else if ( aff->DstEndPoint == AF_BROADCAST_ENDPOINT )
    {
      pList = pList->nextDesc;
      if ( pList )
        epDesc = pList->epDesc;
      else
        epDesc = NULL;
    }
    else
      epDesc = NULL;
  }
}