Skip to content

3.3 数据发送API简介 ​

一句话理解

AF 层所有发送数据的工作,最终都汇到一个函数:AF_DataRequest()。点对点、广播、组播,不过是它的三种"填法"。

核心 API:AF_DataRequest() ​

打开配套工程,在 Profile 文件夹下找到 AF.h,可以看到 AF 层的数据发送 API——AF_DataRequest():

c
/*
 * @param dstAddr  目标设备地址(网络地址 + 端点号)
 * @param srcEP    发送设备的简单描述符
 * @param cID      Cluster ID(后续章节详细讲解)
 * @param len      待发送数据的长度
 * @param buf      待发送的数据
 * @param transID  传输 ID,给每一次发送的数据包编号
 * @param options  附加选项,给这次发送添加说明
 * @param radius   最大路由跳转级数
 */
afStatus_t AF_DataRequest(
    afAddrType_t *dstAddr,
    endPointDesc_t *srcEP,
    uint16 cID,
    uint16 len,
    uint8 *buf,
    uint8 *transID,
    uint8 options,
    uint8 radius );

参数速记

AF_DataRequest( 发给谁, 用哪个名片, 什么业务, 多长, 什么内容, 编号, 选项, 跳数 )

协议栈里的 SampleSwitch 例程,基于这个 API 封装出了三种通信 API:点对点 / 广播 / 组播。下面逐个看。

① 点对点通信 API ​

在 zcl_samplesw.c 中可以找到点对点通信 API:

c
/*
 * @param destNwkAddr 目标设备的网络地址
 * @param cid         Cluster ID
 * @param len         数据长度
 * @param data        数据内容
 */
static void zclSampleSw_AF_P2P(
    uint16 destNwkAddr,
    uint16 cid,
    uint8 len,
    uint8 *data)
{
  afAddrType_t dstAddr;              // 寻址信息配置
  static uint8 transferId = 0;       // 传输 ID,是数据包的标识符

  /* Destination */
  dstAddr.addrMode = afAddr16Bit;             // 16 位网络地址 → 点对点方式
  dstAddr.addr.shortAddr = destNwkAddr;       // 目标设备的网络地址
  dstAddr.endPoint = SAMPLESW_ENDPOINT;       // 目标设备的端点号

  transferId++;
  AF_DataRequest(&dstAddr,
                 &sampleSw_TestEp,            // 已经创建好的简单描述符
                 cid,
                 len,
                 data,
                 &transferId,
                 AF_DISCV_ROUTE,              // 路由扫描,建立通信路径(保持例程默认即可)
                 AF_DEFAULT_RADIUS);          // 最大路由跳转级数
}

用到的两个关键类型 ​

afAddrType_t:寻址信息结构体,用于配置"发给谁":

c
typedef struct
{
  union
  {
    uint16      shortAddr;   // 16 位短地址(网络地址)
    ZLongAddr_t extAddr;     // 64 位扩展地址
  } addr;
  afAddrMode_t addrMode;     // 地址模式:点对点 / 广播 / 组播
  uint8        endpoint;     // 目标端点号
  uint16       panId;        // 用于 INTER_PAN 特性
} afAddrType_t;

afAddrMode_t:地址模式枚举,说明用哪种通信方式:

c
typedef enum
{
  afAddrNotPresent = AddrNotPresent,  // 地址不存在(间接寻址)
  afAddr16Bit      = Addr16Bit,       // 16 位网络地址 → 点对点
  afAddr64Bit      = Addr64Bit,       // 64 位扩展地址
  afAddrGroup      = AddrGroup,       // 组地址 → 组播
  afAddrBroadcast  = AddrBroadcast    // 广播地址 → 广播
} afAddrMode_t;

观察

点对点 API 最后一步还是调用 AF_DataRequest() 发送数据。你也可以基于 AF_DataRequest() 写自己的通信 API,不必非用例程自带的这个。

② 广播通信 API ​

在 zcl_samplesw.c 中可以找到广播通信 API:

c
/*
 * @param cid   Cluster ID
 * @param len   待发送数据的长度
 * @param data  待发送数据的内容
 */
static void zclSampleSw_AF_Broadcast(
    uint16 cid,
    uint8 len,
    uint8 *data)
{
  afAddrType_t dstAddr;
  static uint8 transferId = 0;

  /* Destination */
  dstAddr.addrMode = afAddrBroadcast;         // 使用广播模式
  dstAddr.addr.shortAddr = 0xFFFF;            // 广播地址
  dstAddr.endPoint = SAMPLESW_ENDPOINT;       // 目标设备的端点号

  /* Transfer id */
  transferId++;

  /* Send */
  AF_DataRequest(&dstAddr,
                 &sampleSw_TestEp,
                 cid,
                 len,
                 data,
                 &transferId,
                 AF_TX_OPTIONS_NONE,
                 AF_DEFAULT_RADIUS);
}

它和点对点 API 结构几乎一样,区别就在:地址模式设为 afAddrBroadcast,目标地址填广播地址 0xFFFF。

ZigBee 的广播地址一共有 3 个:

📢
0xFFFF
广播给该网络中所有设备
🔔
0xFFFD
只广播给网络中打开收听功能的设备
📡
0xFFFC
只广播给网络中的协调器和路由设备

③ 组播通信 API ​

组播可以只给指定的一组设备发数据。在 zcl_samplesw.c 中可以找到组播通信 API:

c
/*
 * @param groupId 组 ID
 * @param cid     Cluster ID
 * @param len     待发送数据的长度
 * @param data    待发送数据的内容
 */
static void zclSampleSw_AF_Groupcast(
    uint16 groupId,
    uint16 cid,
    uint8 len,
    uint8 *data)
{
  afAddrType_t dstAddr;
  static uint8 transferId = 0;

  /* Destination */
  dstAddr.addrMode = afAddrGroup;             // 使用组播通信模式
  dstAddr.addr.shortAddr = groupId;           // 组 ID
  dstAddr.endPoint = SAMPLESW_ENDPOINT;       // 组中设备的端点号

  /* Transfer id */
  transferId++;

  /* Send */
  AF_DataRequest(&dstAddr,
                 &sampleSw_TestEp,
                 cid,
                 len,
                 data,
                 &transferId,
                 AF_TX_OPTIONS_NONE,
                 AF_DEFAULT_RADIUS);
}

组播的关键就是:地址模式设为 afAddrGroup,目标地址填组 ID(groupId)。后续章节会以实验的方式讲解如何让设备加入指定组。

三种通信方式对比 ​

🔗
点对点
afAddr16Bit
目标 = 设备网络地址
例:zclSampleSw_AF_P2P
·
📢
广播
afAddrBroadcast
目标 = 0xFFFF 等广播地址
例:zclSampleSw_AF_Broadcast
·
👥
组播
afAddrGroup
目标 = 组 ID
例:zclSampleSw_AF_Groupcast

小结

三种 API 长得像、结构同——都是把"地址模式 + 目标地址"填好,然后调用 AF_DataRequest()。理解这一个函数,三种通信方式就都掌握了。

内容来源:紫甲 IoT《ZigBee 3.0 开发指南》第四部分·3.3 数据发送API简介,原站链接


本章自测 ​

一、单项选择题(每题 4 分,共 40 分) ​

  1. AF 层所有发送数据的工作,最终都汇到的一个核心函数是(A. zcl_SendCommand() B. AF_DataRequest() C. afRegister() D. bdb_StartCommissioning()) 答案:B

  2. 在 AF_DataRequest() 的参数中,radius 参数的含义是(A. 待发送数据的长度 B. 传输 ID C. 最大路由跳转级数 D. 附加选项) 答案:C

  3. 实现点对点通信时,dstAddr.addrMode 应设置为(A. afAddrBroadcast B. afAddrGroup C. afAddr16Bit D. afAddrNotPresent) 答案:C

  4. 广播通信时,目标地址 dstAddr.addr.shortAddr 应填写(A. 0x0000 B. 0xFFFF C. 0x0EF1 D. 组 ID) 答案:B

  5. 组播通信的关键配置是(A. addrMode 设为 afAddrGroup,目标地址填组 ID(groupId) B. addrMode 设为 afAddrBroadcast C. addrMode 设为 afAddr16Bit D. 目标地址填 0xFFFF) 答案:A

  6. ZigBee 的广播地址 0xFFFD 的含义是(A. 广播给网络中所有设备 B. 只广播给网络中打开收听功能的设备 C. 只广播给协调器和路由设备 D. 广播给 ZDO) 答案:B

  7. ZigBee 的广播地址 0xFFFC 的含义是(A. 广播给网络中所有设备 B. 只广播给网络中打开收听功能的设备 C. 只广播给网络中的协调器和路由设备 D. 广播给终端设备) 答案:C

  8. 在 afAddrMode_t 枚举中,表示"组地址 → 组播"的是(A. afAddr16Bit B. afAddr64Bit C. afAddrGroup D. afAddrBroadcast) 答案:C

  9. afAddrType_t 结构体中的 addr 是一个 union,其成员不包括(A. shortAddr(16 位短地址) B. extAddr(64 位扩展地址) C. endpoint(目标端点号)) 答案:C(endpoint 是结构体的独立成员,不是 addr union 的成员)

  10. 关于三种通信 API(点对点 / 广播 / 组播),下列说法正确的是(A. 三者内部实现完全不同的发送机制 B. 结构几乎相同,都是把"地址模式 + 目标地址"填好后调用 AF_DataRequest() C. 广播不需要调用 AF_DataRequest() D. 组播只能由协调器发起) 答案:B

二、问答题(每题 20 分,共 60 分) ​

  1. 题干:写出 AF_DataRequest() 的各主要参数含义(可用书中的速记口诀)。 参考答案要点:
  • dstAddr:目标设备地址(网络地址 + 端点号);srcEP:发送设备的简单描述符。
  • cID:Cluster ID;len:待发送数据长度;buf:待发送数据内容。
  • transID:传输 ID,给每次发送的数据包编号;options:附加选项;radius:最大路由跳转级数。
  • 速记口诀:发给谁、用哪个名片、什么业务、多长、什么内容、编号、选项、跳数。
  1. 题干:点对点、广播、组播三种方式在配置 afAddrType_t 时有何区别?请分别写出 addrMode 与目标地址的填法。 参考答案要点:
  • 点对点:addrMode = afAddr16Bit,目标 shortAddr = 目标设备网络地址。
  • 广播:addrMode = afAddrBroadcast,目标 shortAddr = 0xFFFF 等广播地址。
  • 组播:addrMode = afAddrGroup,目标 shortAddr = 组 ID(groupId)。
  • 三者都还需指定 dstAddr.endPoint(目标端点号),最后统一调用 AF_DataRequest()。
  1. 题干:ZigBee 的广播地址共有哪几个?各自的接收范围是什么? 参考答案要点:
  • 0xFFFF:广播给该网络中的所有设备。
  • 0xFFFD:只广播给网络中打开收听功能的设备。
  • 0xFFFC:只广播给网络中的协调器和路由设备。

aioteer · 物联网专业课程群

💬AI 伴学配置