CDNET 协议中文版 - dukelec/cdnet GitHub Wiki

CDNET:面向 CDBUS 的可选高层协议

协议状态: 稳定 [版本 v2.0]

CDBUS 包含 CDNET 数据包的帧格式如下:
[src, dst, len] + [CDNET package] + [crc_l, crc_h]
或者:
[src, dst, len] + [CDNET header, payload] + [crc_l, crc_h]

CDNET Levels

CDNET 协议提供两个级别,由协议头的第一个字节的第 7 位决定:

Bit7 DESCRIPTION
0 Level 0: 简化版通信
1 Level 1: 标准版通信

根据需要,您可以选择一个或多个 levels 应用于您的程序。

CDNET 是小端模式的。

Level 0 格式

Header 始终为 2 个字节。

第一个字节:

位段 描述
[7] 总是 0 (表示 level 0)
[6:0] src_port, 范围 0 ~ 127

第二个字节:

位段 描述
[7] 保留为 0
[6:0] dst_port, 范围 0 ~ 127

备注:端口类似于 UDP 端口,也可以看作是命令号。

Level 1 格式

头部的第一个字节:

位段 描述
[7] 总是 1 (表示 level 1)
[6] 保留为 0
[5] MULTI_NET
[4] MULTICAST
[3:2] 保留为 0
[1] SRC_PORT_SIZE
[0] DST_PORT_SIZE

MULTI_NET & MULTICAST

MULTI_NET MULTICAST 描述
0 0 本地网络:追加 0 字节
0 1 本地网络多播:追加 2 字节 [mh, ml]
1 0 跨网络:追加 4 字节 [src_net, src_mac, dst_net, dst_mac]
1 1 跨网络多播:追加 4 字节 [src_net, src_mac, mh, ml]

备注:

  • mh/ml:多播 ID,ml 映射到 mac 层的多播地址(h:高字节,l:低字节);
  • 可以简单地使用 MULTI_NET = 0 和 MULTICAST = 0 用于本地网络的多播和广播。
  • MULTI_NET 和 MULTICAST 的实现是可选的。

PORT_SIZE:

Bit1 SRC_PORT
0 1 字节
1 2 字节
Bit0 DST_PORT
0 1 字节
1 2 字节

备注:

  • 先追加 src_port 字节,后追加 dst_port 字节。
  • 2 字节端口的实现是可选的。

端口分配建议

建议将端口 0 到 15 用于一般目的。 具体而言,端口 1 用于设备信息查询。
虽然此范围中的所有端口都是可选的,但建议实现端口 1 的基本功能(读取 device_info)。

端口号 ≥ 64 通常用作临时端口。

端口 1

提供设备信息。

数据类型:
 - mac_start 和 mac_end: uint8_t
 - max_time: uint16_t (单位毫秒)
 - "string": 变长字符串,包含空字符串 (字串不含 '\0' 结尾)


读取 device_info 字符串:
  写入 None
  返回 ["device_info"]

使用过滤器搜索设备 (为了处理 mac 地址冲突):
  写入 [0x10, max_time, mac_start, mac_end, "string"]
  返回 ["device_info"] 等待一个随机时间且满足以下两个条件才返回,随机时间范围为 [0, max_time]
    当 "device_info" 字符串内包含 "string" (空字符也当作包含)
    当前本机 mac 地址在此返回内 [mac_start, mac_end] (首尾也包含)
  其它情形不返回
    并且拒绝执行后续任何修改 mac 地址(或保存配置)的命令

device_info 的示例:
M: model; S: serial id; HW: hardware version; SW: software version ...

内容顺序不做要求,建议内容至少包含 model 型号。

CDNET 字符串地址格式

           localhost      local link     unique local    multicast
            10:00:00
level0:                    00:NN:MM
level1:                    80:NN:MM        a0:NN:MM       f0:MH:ML

备注:

  • NN: net_id, MM: mac_addr, MH/ML: multicast_id (H: 高位字节, L: 低位字节)。
  • 该字符串地址类似 IPv6 的地址。

示例

请求设备 info 字符串:
(本地网络、请求方 mac 地址: 0x0c、目标 mac 地址: 0x0d

返回设备 info 字符串示范:"M: c1; S: 1234", 该字符串用十六进制表示:[0x4d, 0x3a, 0x20, 0x63, 0x31, 0x3b, 0x20, 0x53, 0x3a, 0x20, 0x31, 0x32, 0x33, 0x34].

Level 0 格式:

  • 请求:
    • CDNET socket: [00:00:0c]:64 -> [00:00:0d]:1: None
    • CDNET packet: [0x40, 0x01] (src_port: 0x40, dst_port: 0x01)
    • CDBUS frame: [0x0c, 0x0d, 0x02, 0x40, 0x01, crc_l, crc_h]
  • 回复:
    • CDNET socket: [00:00:0d]:1 -> [00:00:0c]:64: "M: c1; S: 1234"
    • CDNET packet: [0x01, 0x40, 0x4d, 0x3a, 0x20 ... 0x34]
    • CDBUS frame: [0x0d, 0x0c, 0x10, 0x01, 0x40, 0x4d, 0x3a, 0x20 ... 0x34, crc_l, crc_h]

Level 1 格式:

  • 请求:
    • CDNET socket: [80:00:0c]:64 -> [80:00:0d]:1: None
    • CDNET packet: [0x80, 0x40, 0x01] (src_port: 0x40, dst_port: 0x01)
    • CDBUS frame: [0x0c, 0x0d, 0x03, 0x80, 0x40, 0x01, crc_l, crc_h]
  • 回复:
    • CDNET socket: [80:00:0d]:1 -> [80:00:0c]:64: "M: c1; S: 1234"
    • CDNET packet: [0x80, 0x01, 0x40, 0x4d, 0x3a, 0x20 ... 0x34] (src_port: 0x01, dst_port: 0x40)
    • CDBUS frame: [0x0d, 0x0c, 0x11, 0x80, 0x01, 0x40, 0x4d, 0x3a, 0x20 ... 0x34, crc_l, crc_h]

序列 和 流控

不同命令的 SRC_PORT 可以在一个范围内依次递增,当遇到丢包重传,接收方可避免重复执行命令。返回的回复和命令的对应关系也不会错乱。

分段传输大数据时,可规定 SRC_PORT 的某个高位为 not_reply 标记,置位时接收方不回复。(SRC_PORT 低位依次递增用做校验。)
可以先传输两组数据包,每组仅最后一个包需要回复。每当收到一个回复就再追加传输一组数据。每组包含多个数据包。