⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 af.c

📁 Zigbee2006入门源代码,包括了Zigbee的入门介绍,和源代码
💻 C
📖 第 1 页 / 共 4 页
字号:

  if ( hdr == NULL )
  {
    hdr = multiInit( dstAddr, srcEndPoint, clusterID, FrameType,
                     txOptions, DiscoverRoute, RadiusCounter );
    if ( hdr == NULL )
    {
      return afStatus_MEM_FAIL;
    }
  }

  if ( FALSE == multiAppend( hdr, (byte)DataLength, Data,
                           CommandType, AttribDataType, AttribId, ErrorCode ) )
  {
    if ( hdr->msg != NULL )
    {
      multiSend( hdr, TransSeqNumber, RadiusCounter );
    }
    else
    {
      osal_mem_free( hdr );
    }
    hdr = NULL;
    return afStatus_MEM_FAIL;
  }

  // Only supporting up to 16 concatenated messages.
  if ( (AddOrSend == SEND_MESSAGE) || (hdr->transCount >= 16) )
  {
    stat = multiSend( hdr, TransSeqNumber, RadiusCounter );
    hdr = NULL;
  }
  else
  {
    stat = afStatus_SUCCESS;
    (*TransSeqNumber)++;
  }

  return stat;
}
#endif

#if ( AF_V1_SUPPORT || AF_KVP_SUPPORT )
/*********************************************************************
 * @fn      afFillAndSendMessage
 *
 * @brief   Fills in the cmd format structure and sends the out-going message.
 *
 * input parameters
 *
 * @param  *dstAddr         - Full ZB destination address: Nwk Addr + End Point.
 * @param   srcEndPoint     - Origination (i.e. respond to or ack to) End Point.
 * @param   clusterID       - A valid cluster ID as specified by the Profile.
 * @param   TransCount      - Set to 1.
 * @param   FrameType       - A valid frame type (see prev def of FRAMETYPE_...)
 * @param  *TransSeqNumber  - A pointer to a byte which can be modified and
 *          which will be used as the transaction sequence number of the msg.
 * @param   CommandType     -
 *          KVP Frame Type  : A valid command type (see prev def of CMDTYPE_...)
 *          MSG Frame Type  : Set to 0.
 * @param   AttribDataType  -
 *          KVP Frame Type  : A valid data type (see prev def of DATATYPE_...)
 *          MSG Frame Type  : Set to 0.
 * @param   AttribId        -
 *          KVP Frame Type  : A valid Attribute ID as specified by the Profile.
 *            (e.g. see OnOffSRC_OnOff in HomeControlLighting.h).
 *          MSG Frame Type  : Set to 0.
 * @param   ErrorCode       -
 *          KVP Frame Type  : A valid error code (see prev def of ERRORCODE_...)
 *          Note: Set to 0 unless the CommandType is one of the CMDTYPE_..._ACK.
 *          MSG Frame Type  : Set to 0.
 * @param   DataLength      - Number of bytes of data pointed to by next param.
 *          KVP Frame Type  : This must match value expected for the
 *          AttributeDataType specified above or the send will fail.
 *          MSG Frame Type  : No restriction or checks.
 * @param  *Data            - A pointer to the data bytes to send.
 * @param   txOptions       - A valid bit mask (see prev def of APS_TX_OPTIONS_)
 * @param   DiscoverRoute   - Normally set to FALSE. Perhaps set to TRUE after
 *          receiving an AF_DATA_CONFIRM_CMD with status other than ZSuccess.
 * @param   RadiusCounter   - Normally set to AF_DEFAULT_RADIUS.
 *
 * output parameters
 *
 * @param  *TransSeqNumber  - Incremented by one if the return value is success.
 *
 * @return  afStatus_t      - See previous definition of afStatus_... types.
 */
afStatus_t afFillAndSendMessage (
  afAddrType_t *dstAddr, byte srcEndPoint, cId_t clusterID,
  byte TransCount, byte FrameType, byte *TransSeqNumber,
  byte CommandType, byte AttribDataType, uint16 AttribId, byte ErrorCode,
  byte DataLength, byte *Data,
  byte txOptions, byte DiscoverRoute, byte RadiusCounter )
{
  const byte proVer = NLME_GetProtocolVersion();
  afStatus_t stat = afStatus_FAILED;
  byte *buf = Data;

#if ( AF_KVP_SUPPORT )
  if ( FrameType == FRAMETYPE_KVP )
  {
    return afAddOrSendMessage( dstAddr, srcEndPoint, clusterID,
      SEND_MESSAGE, FrameType, TransSeqNumber,
      CommandType, AttribDataType, AttribId, ErrorCode,
      DataLength, Data, txOptions, DiscoverRoute, RadiusCounter );
  }
#endif

  if ( FrameType != FRAMETYPE_MSG )
  {
    return afStatus_INVALID_PARAMETER;
  }

  if ( TransCount != 1 )
  {
    return afStatus_INVALID_PARAMETER;
  }

  if ( proVer == ZB_PROT_V1_0 )
  {
    buf = osal_mem_alloc( (short)(DataLength+3) );
    if ( buf == NULL )
    {
      return afStatus_MEM_FAIL;
    }

    buf[0] = BUILD_UINT8( FRAMETYPE_MSG, 1 );
    buf[1] = *TransSeqNumber;
    buf[2] = (byte)DataLength;

    // Copy the data portion of the packet.
    if ( Data && DataLength )
    {
      osal_memcpy( buf+3, Data, DataLength );
      DataLength += 3;
    }
    else
    {
      DataLength = 3;
    }
  }

  stat = afSend( dstAddr, srcEndPoint, clusterID,
                 DataLength, buf, TransSeqNumber, txOptions, RadiusCounter );

  if ( proVer == ZB_PROT_V1_0 )
  {
    osal_mem_free( buf );
  }

  return stat;
}
#endif

/*********************************************************************
 * @fn      AF_DataRequest
 *
 * @brief   Common functionality for invoking APSDE_DataReq() for both
 *          KVP-Send/SendMulti and MSG-Send.
 *
 * 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 - See previous definition of afStatus_... types.
 */
#if ( AF_V1_SUPPORT )
static afStatus_t afDataRequest( afAddrType_t *dstAddr, endPointDesc_t *srcEP,
                           uint16 cID, uint16 len, uint8 *buf, uint8 *transID,
                           uint8 options, uint8 radius )
#else
afStatus_t AF_DataRequest( afAddrType_t *dstAddr, endPointDesc_t *srcEP,
                           uint16 cID, uint16 len, uint8 *buf, uint8 *transID,
                           uint8 options, uint8 radius )
#endif
{
  pDescCB pfnDescCB;
  ZStatus_t stat;
  APSDE_DataReq_t req;
  afDataReqMTU_t mtu;


  if ( srcEP == NULL )
  {
    return afStatus_INVALID_PARAMETER;
  }

  // Enforce consistent values on the destination address / address mode.
  if ( dstAddr->addrMode == afAddrNotPresent )
  {
    dstAddr->endPoint = ZDO_EP;
    req.dstAddr.addr.shortAddr = afGetReflector( srcEP->endPoint );
  }
  else // Handle types: afAddr16Bit
  {    //               afAddrBroadcast
       //               afAddrGroup
    req.dstAddr.addr.shortAddr = dstAddr->addr.shortAddr;

    if ( ( dstAddr->addrMode == afAddr16Bit     ) ||
         ( dstAddr->addrMode == afAddrBroadcast )    )
    {
      // Check for valid broadcast values
      if( ADDR_NOT_BCAST != NLME_IsAddressBroadcast( dstAddr->addr.shortAddr )  )
      {
        // Force mode to broadcast
        dstAddr->addrMode = afAddrBroadcast;
      }
      else
      {
        // Address is not a valid broadcast type
        if ( dstAddr->addrMode == afAddrBroadcast )
        {
          return afStatus_INVALID_PARAMETER;
        }
      }
    }
    else if ( dstAddr->addrMode != afAddrGroup )
    {
      return afStatus_INVALID_PARAMETER;
    }
  }
  req.dstAddr.addrMode = dstAddr->addrMode;
  req.profileID = ZDO_PROFILE_ID;

  if ( (pfnDescCB = afGetDescCB( srcEP )) )
  {
    uint16 *pID = (uint16 *)(pfnDescCB(
                                 AF_DESCRIPTOR_PROFILE_ID, srcEP->endPoint ));
    if ( pID )
    {
      req.profileID = *pID;
      osal_mem_free( pID );
    }
  }
  else if ( srcEP->simpleDesc )
  {
    req.profileID = srcEP->simpleDesc->AppProfId;
  }

  req.txOptions = 0;

  if ( ( options & AF_ACK_REQUEST              ) &&
       ( req.dstAddr.addrMode != AddrBroadcast ) &&
       ( req.dstAddr.addrMode != AddrGroup     )    )
  {
    req.txOptions |=  APS_TX_OPTIONS_ACK;
  }

  if ( options & AF_SKIP_ROUTING )
  {
    req.txOptions |=  APS_TX_OPTIONS_SKIP_ROUTING;
  }

  if ( options & AF_EN_SECURITY )
  {
    req.txOptions |= APS_TX_OPTIONS_SECURITY_ENABLE;
    mtu.aps.secure = TRUE;
  }
  else
  {
    mtu.aps.secure = FALSE;
  }

  mtu.kvp = FALSE;

  req.transID       = *transID;
  req.srcEP         = srcEP->endPoint;
  req.dstEP         = dstAddr->endPoint;
  req.clusterID     = cID;
  req.asduLen       = len;
  req.asdu          = buf;
  req.discoverRoute = (uint8)((options & AF_DISCV_ROUTE) ? 1 : 0);
  req.radiusCounter = radius;

  if (len > afDataReqMTU( &mtu ) )
  {
    if (apsfSendFragmented)
    {
      req.txOptions |= AF_FRAGMENTED | APS_TX_OPTIONS_ACK;
      stat = (*apsfSendFragmented)( &req );
    }
    else
    {
      stat = afStatus_INVALID_PARAMETER;
    }
  } 
  else
  {
    stat = APSDE_DataReq( &req );
  }

  /*
   * If this is an EndPoint-to-EndPoint message on the same device, it will not
   * get added to the NWK databufs. So it will not go OTA and it will not get
   * a MACCB_DATA_CONFIRM_CMD callback. Thus it is necessary to generate the
   * AF_DATA_CONFIRM_CMD here. Note that APSDE_DataConfirm() only generates one
   * message with the first in line TransSeqNumber, even on a multi message.
   */
  if ( (req.dstAddr.addrMode == Addr16Bit) &&
       (req.dstAddr.addr.shortAddr == NLME_GetShortAddr()) )
  {
    afDataConfirm( srcEP->endPoint, *transID, stat );
  }

  if ( stat == afStatus_SUCCESS )
  {
    (*transID)++;
  }

  return (afStatus_t)stat;
}

/*********************************************************************
 * @fn      afFindEndPointDescList
 *
 * @brief   Find the endpoint description entry from the endpoint
 *          number.
 *
 * @param   EndPoint - Application Endpoint to look for
 *
 * @return  the address to the endpoint/interface description entry
 */
static epList_t *afFindEndPointDescList( byte EndPoint )
{
  epList_t *epSearch;

  // Start at the beginning
  epSearch = epList;

  // Look through the list until the end
  while ( epSearch )
  {
    // Is there a match?
    if ( epSearch->epDesc->endPoint == EndPoint )
    {
      return ( epSearch );
    }
    else
      epSearch = epSearch->nextDesc;  // Next entry
  }

  return ( (epList_t *)NULL );
}

/*********************************************************************
 * @fn      afFindEndPointDesc
 *
 * @brief   Find the endpoint description entry from the endpoint
 *          number.
 *
 * @param   EndPoint - Application Endpoint to look for
 *
 * @return  the address to the endpoint/interface description entry
 */
endPointDesc_t *afFindEndPointDesc( byte EndPoint )
{
  epList_t *epSearch;

  // Look for the endpoint
  epSearch = afFindEndPointDescList( EndPoint );

  if ( epSearch )
    return ( epSearch->epDesc );
  else
    return ( (endPointDesc_t *)NULL );
}

/*********************************************************************
 * @fn      afFindSimpleDesc
 *
 * @brief   Find the Simple Descriptor from the endpoint number.
 *
 * @param   EP - Application Endpoint to look for.
 *
 * @return  Non-zero to indicate that the descriptor memory must be freed.
 */
byte afFindSimpleDesc( SimpleDescriptionFormat_t **ppDesc, byte EP )
{
  epList_t *epItem = afFindEndPointDescList( EP );
  byte rtrn = FALSE;

  if ( epItem )
  {
    if ( epItem->pfnDescCB )
    {
      *ppDesc = epItem->pfnDescCB( AF_DESCRIPTOR_SIMPLE, EP );
      rtrn = TRUE;
    }
    else
    {
      *ppDesc = epItem->epDesc->simpleDesc;
    }
  }
  else
  {
    *ppDesc = NULL;
  }

  return rtrn;
}

/*********************************************************************
 * @fn      afGetDescCB
 *
 * @brief   Get the Descriptor callback function.
 *
 * @param   epDesc - pointer to the endpoint descriptor
 *
 * @return  function pointer or NULL
 */
static pDescCB afGetDescCB( endPointDesc_t *epDesc )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -