did_GB2025_wifi.cpp 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. /*
  2. Copyright (C) 2020 Simon Wunderlich, Marek Sobe
  3. Copyright (C) 2020 Doodle Labs
  4. SPDX-License-Identifier: Apache-2.0
  5. Open Drone ID C Library
  6. Maintainer:
  7. Simon Wunderlich
  8. sw@simonwunderlich.de
  9. */
  10. /*该文件是对开源wifi修改适配国产标准*/
  11. #if defined(ARDUINO_ARCH_ESP32)
  12. #include <Arduino.h>
  13. int clock_gettime(clockid_t, struct timespec *);
  14. #else
  15. #include <string.h>
  16. #include <stddef.h>
  17. #include <stdio.h>
  18. #endif
  19. #include <errno.h>
  20. #include <time.h>
  21. #include "did_GB2025_wifi.h"
  22. #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
  23. #define cpu_to_le16(x) (x)
  24. #define cpu_to_le64(x) (x)
  25. #else
  26. #define cpu_to_le16(x) (bswap_16(x))
  27. #define cpu_to_le64(x) (bswap_64(x))
  28. #endif
  29. #define IEEE80211_FCTL_FTYPE 0x000c
  30. #define IEEE80211_FCTL_STYPE 0x00f0
  31. #define IEEE80211_FTYPE_MGMT 0x0000
  32. #define IEEE80211_STYPE_ACTION 0x00D0
  33. #define IEEE80211_STYPE_BEACON 0x0080
  34. /* IEEE 802.11-2016 capability info */
  35. #define IEEE80211_CAPINFO_ESS 0x0001
  36. #define IEEE80211_CAPINFO_IBSS 0x0002
  37. #define IEEE80211_CAPINFO_CF_POLLABLE 0x0004
  38. #define IEEE80211_CAPINFO_CF_POLLREQ 0x0008
  39. #define IEEE80211_CAPINFO_PRIVACY 0x0010
  40. #define IEEE80211_CAPINFO_SHORT_PREAMBLE 0x0020
  41. /* bits 6-7 reserved */
  42. #define IEEE80211_CAPINFO_SPECTRUM_MGMT 0x0100
  43. #define IEEE80211_CAPINFO_QOS 0x0200
  44. #define IEEE80211_CAPINFO_SHORT_SLOTTIME 0x0400
  45. #define IEEE80211_CAPINFO_APSD 0x0800
  46. #define IEEE80211_CAPINFO_RADIOMEAS 0x1000
  47. /* bit 13 reserved */
  48. #define IEEE80211_CAPINFO_DEL_BLOCK_ACK 0x4000
  49. #define IEEE80211_CAPINFO_IMM_BLOCK_ACK 0x8000
  50. /* IEEE 802.11 Element IDs */
  51. #define IEEE80211_ELEMID_SSID 0x00
  52. #define IEEE80211_ELEMID_RATES 0x01
  53. #define IEEE80211_ELEMID_VENDOR 0xDD
  54. /* 《邻居感知网络规范》v3.1第2.8.2节
  55. * NAN集群ID是一个MAC地址,其取值范围为50-6F-9A-01-00-00至50-6F-9A-01-FF-FF,
  56. * 承载于部分NAN帧的A3字段中。NAN集群ID由发起NAN集群的设备随机选择。
  57. * 然而,《ASTM远程ID规范》v1.1规定,NAN集群ID必须固定为50-6F-9A-01-00-FF这一值。
  58. */
  59. static const uint8_t *get_nan_cluster_id(void)
  60. {
  61. static const uint8_t cluster_id[6] = { 0x50, 0x6F, 0x9A, 0x01, 0x00, 0xFF };
  62. return cluster_id;
  63. }
  64. static int buf_fill_ieee80211_mgmt(uint8_t *buf, size_t *len, size_t buf_size,
  65. const uint16_t subtype,
  66. const uint8_t *dst_addr,
  67. const uint8_t *src_addr,
  68. const uint8_t *bssid)
  69. {
  70. if (*len + sizeof(struct ieee80211_mgmt) > buf_size)
  71. return -ENOMEM;
  72. struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)(buf + *len);
  73. mgmt->frame_control = (uint16_t) cpu_to_le16(IEEE80211_FTYPE_MGMT | subtype);
  74. mgmt->duration = cpu_to_le16(0x0000);
  75. memcpy(mgmt->da, dst_addr, sizeof(mgmt->da));
  76. memcpy(mgmt->sa, src_addr, sizeof(mgmt->sa));
  77. memcpy(mgmt->bssid, bssid, sizeof(mgmt->bssid));
  78. mgmt->seq_ctrl = cpu_to_le16(0x0000);
  79. *len += sizeof(*mgmt);
  80. return 0;
  81. }
  82. static int buf_fill_ieee80211_beacon(uint8_t *buf, size_t *len, size_t buf_size, uint16_t interval_tu)
  83. {
  84. if (*len + sizeof(struct ieee80211_beacon) > buf_size)
  85. return -ENOMEM;
  86. struct ieee80211_beacon *beacon = (struct ieee80211_beacon *)(buf + *len);
  87. struct timespec ts;
  88. uint64_t mono_us = 0;
  89. #if defined(CLOCK_MONOTONIC)
  90. clock_gettime(CLOCK_MONOTONIC, &ts);
  91. mono_us = (uint64_t)((double) ts.tv_sec * 1e6 + (double) ts.tv_nsec * 1e-3);
  92. #elif defined(CLOCK_REALTIME)
  93. clock_gettime(CLOCK_REALTIME, &ts);
  94. mono_us = (uint64_t)((double) ts.tv_sec * 1e6 + (double) ts.tv_nsec * 1e-3);
  95. #elif defined(ARDUINO)
  96. #warning "No REALTIME or MONOTONIC clock, using micros()."
  97. mono_us = micros();
  98. #else
  99. #warning "Unable to set wifi timestamp."
  100. #endif
  101. beacon->timestamp = cpu_to_le64(mono_us);
  102. beacon->beacon_interval = cpu_to_le16(interval_tu);
  103. beacon->capability = cpu_to_le16(IEEE80211_CAPINFO_SHORT_SLOTTIME | IEEE80211_CAPINFO_SHORT_PREAMBLE);
  104. *len += sizeof(*beacon);
  105. return 0;
  106. }
  107. /* void* 不能用 可能是编译器版本的问题 改成uint8_t* 了*/
  108. int did_GB2025_message_build_pack(UavIdentificationData *UAS_Data, uint8_t *pack, size_t buflen)
  109. {
  110. if (UAS_Data == NULL || pack == NULL || buflen == 0) {
  111. return -1; // 参数错误
  112. }
  113. UavIdentificationPacket *msg_pack_enc = (UavIdentificationPacket *)pack;
  114. // 1. 调用组包函数
  115. int8_t ret = uav_identification_pack(msg_pack_enc, UAS_Data);
  116. if (ret != 0) {
  117. return -2; // 组包失败
  118. }
  119. // 2. 计算实际包大小(头部 + 内容)
  120. // 数据包总大小 = 固定头部(1+1+1+3) + 内容长度
  121. size_t total_len = sizeof(msg_pack_enc->data_type) +
  122. sizeof(msg_pack_enc->version) +
  123. sizeof(msg_pack_enc->content_len) +
  124. sizeof(msg_pack_enc->data_flag) +
  125. msg_pack_enc->content_len;
  126. // 3. 检查缓冲区大小
  127. if (total_len > buflen) {
  128. return -3; // 缓冲区不足
  129. }
  130. return (int)total_len; // 返回实际使用的字节数
  131. }
  132. // 里面的服务id可能后面要改 还有一些指向 open droneid的
  133. int did_GB2025_wifi_build_nan_sync_beacon_frame(char *mac, uint8_t *buf, size_t buf_size)
  134. {
  135. /* Broadcast address */
  136. uint8_t target_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
  137. uint8_t wifi_alliance_oui[3] = { 0x50, 0x6F, 0x9A };
  138. /* "org.opendroneid.remoteid" hash */
  139. uint8_t service_id[6] = { 0x88, 0x69, 0x19, 0x9D, 0x92, 0x09 };
  140. const uint8_t *cluster_id = get_nan_cluster_id();
  141. struct ieee80211_vendor_specific *vendor;
  142. struct nan_master_indication_attribute *master_indication_attr;
  143. struct nan_cluster_attribute *cluster_attr;
  144. struct nan_service_id_list_attribute *nsila;
  145. int ret;
  146. size_t len = 0;
  147. /* IEEE 802.11 Management Header */
  148. ret = buf_fill_ieee80211_mgmt(buf, &len, buf_size, IEEE80211_STYPE_BEACON, target_addr, (uint8_t *)mac, cluster_id);
  149. if (ret <0)
  150. return ret;
  151. /* Beacon */
  152. ret = buf_fill_ieee80211_beacon(buf, &len, buf_size, 0x0200);
  153. if (ret <0)
  154. return ret;
  155. /* Vendor Specific */
  156. if (len + sizeof(*vendor) > buf_size)
  157. return -ENOMEM;
  158. vendor = (struct ieee80211_vendor_specific *)(buf + len);
  159. memset(vendor, 0, sizeof(*vendor));
  160. vendor->element_id = IEEE80211_ELEMID_VENDOR;
  161. vendor->length = 0x22;
  162. memcpy(vendor->oui, wifi_alliance_oui, sizeof(vendor->oui));
  163. vendor->oui_type = 0x13;
  164. len += sizeof(*vendor);
  165. /* NAN Master Indication attribute */
  166. if (len + sizeof(*master_indication_attr) > buf_size)
  167. return -ENOMEM;
  168. master_indication_attr = (struct nan_master_indication_attribute *)(buf + len);
  169. memset(master_indication_attr, 0, sizeof(*master_indication_attr));
  170. master_indication_attr->header.attribute_id = 0x00;
  171. master_indication_attr->header.length = cpu_to_le16(0x0002);
  172. /* Information that is used to indicate a NAN Device’s preference to serve
  173. * as the role of Master, with a larger value indicating a higher
  174. * preference. Values 1 and 255 are used for testing purposes only.
  175. */
  176. master_indication_attr->master_preference = 0xFE;
  177. /* Random factor value 0xEA is recommended by the European Standard */
  178. master_indication_attr->random_factor = 0xEA;
  179. len += sizeof(*master_indication_attr);
  180. /* NAN Cluster attribute */
  181. if (len + sizeof(*cluster_attr) > buf_size)
  182. return -ENOMEM;
  183. cluster_attr = (struct nan_cluster_attribute *)(buf + len);
  184. memset(cluster_attr, 0, sizeof(*cluster_attr));
  185. cluster_attr->header.attribute_id = 0x1;
  186. cluster_attr->header.length = cpu_to_le16(0x000D);
  187. memcpy(cluster_attr->device_mac, mac, sizeof(cluster_attr->device_mac));
  188. cluster_attr->random_factor = 0xEA;
  189. cluster_attr->master_preference = 0xFE;
  190. cluster_attr->hop_count_to_anchor_master = 0x00;
  191. memset(cluster_attr->anchor_master_beacon_transmission_time, 0, sizeof(cluster_attr->anchor_master_beacon_transmission_time));
  192. len += sizeof(*cluster_attr);
  193. /* NAN attributes */
  194. if (len + sizeof(*nsila) > buf_size)
  195. return -ENOMEM;
  196. nsila = (struct nan_service_id_list_attribute *)(buf + len);
  197. memset(nsila, 0, sizeof(*nsila));
  198. nsila->header.attribute_id = 0x02;
  199. nsila->header.length = cpu_to_le16(0x0006);
  200. memcpy(nsila->service_id, service_id, sizeof(service_id));
  201. len += sizeof(*nsila);
  202. return (int) len;
  203. }
  204. int did_GB2025_wifi_build_message_pack_nan_action_frame(UavIdentificationData *UAS_Data, char *mac,
  205. uint8_t send_counter,
  206. uint8_t *buf, size_t buf_size)
  207. {
  208. /* Neighbor Awareness Networking Specification v3.0 in section 2.8.1
  209. * NAN网络ID要求目标MAC地址为51-6F-9A-01-00-00*/
  210. uint8_t target_addr[6] = { 0x51, 0x6F, 0x9A, 0x01, 0x00, 0x00 };
  211. /* "org.opendroneid.remoteid 哈希值 国际通用的*/
  212. uint8_t service_id[6] = { 0x88, 0x69, 0x19, 0x9D, 0x92, 0x09 };
  213. uint8_t wifi_alliance_oui[3] = { 0x50, 0x6F, 0x9A };
  214. const uint8_t *cluster_id = get_nan_cluster_id();
  215. struct nan_service_discovery *nsd;
  216. struct nan_service_descriptor_attribute *nsda;
  217. struct nan_service_descriptor_extension_attribute *nsdea;
  218. struct DID_GB2025_service_info *si;
  219. int ret;
  220. size_t len = 0;
  221. /* IEEE 802.11 Management Header */
  222. ret = buf_fill_ieee80211_mgmt(buf, &len, buf_size, IEEE80211_STYPE_ACTION, target_addr, (uint8_t *)mac, cluster_id);
  223. if (ret <0)
  224. return ret;
  225. /* NAN Service Discovery header */
  226. if (len + sizeof(*nsd) > buf_size)
  227. return -ENOMEM;
  228. nsd = (struct nan_service_discovery *)(buf + len);
  229. memset(nsd, 0, sizeof(*nsd));
  230. nsd->category = 0x04; /* IEEE 802.11 Public Action frame */
  231. nsd->action_code = 0x09; /* IEEE 802.11 Public Action frame Vendor Specific*/
  232. memcpy(nsd->oui, wifi_alliance_oui, sizeof(nsd->oui));
  233. nsd->oui_type = 0x13; /* Identify Type and version of the NAN */
  234. len += sizeof(*nsd);
  235. /* NAN Attribute for Service Descriptor header */
  236. if (len + sizeof(*nsda) > buf_size)
  237. return -ENOMEM;
  238. nsda = (struct nan_service_descriptor_attribute *)(buf + len);
  239. nsda->header.attribute_id = 0x3; /* Service Descriptor Attribute type */
  240. memcpy(nsda->service_id, service_id, sizeof(service_id));
  241. /* always 1 */
  242. nsda->instance_id = 0x01; /* always 1 */
  243. nsda->requestor_instance_id = 0x00; /* from triggering frame */
  244. nsda->service_control = 0x10; /* follow up */
  245. len += sizeof(*nsda);
  246. /* CNDID Service Info Attribute header */
  247. if (len + sizeof(*si) > buf_size)
  248. return -ENOMEM;
  249. si = (struct DID_GB2025_service_info *)(buf + len);
  250. memset(si, 0, sizeof(*si));
  251. si->message_counter = send_counter;
  252. len += sizeof(*si);
  253. ret = did_GB2025_message_build_pack(UAS_Data, buf + len, buf_size - len);
  254. if (ret < 0)
  255. return ret;
  256. len += ret;
  257. /* set the lengths according to the message pack lengths */
  258. nsda->service_info_length = sizeof(*si) + ret;
  259. nsda->header.length = cpu_to_le16(sizeof(*nsda) - sizeof(struct nan_attribute_header) + nsda->service_info_length);
  260. /* NAN Attribute for Service Descriptor extension header */
  261. if (len + sizeof(*nsdea) > buf_size)
  262. return -ENOMEM;
  263. nsdea = (struct nan_service_descriptor_extension_attribute *)(buf + len);
  264. nsdea->header.attribute_id = 0xE;
  265. nsdea->header.length = cpu_to_le16(0x0004);
  266. nsdea->instance_id = 0x01;
  267. nsdea->control = cpu_to_le16(0x0200);
  268. nsdea->service_update_indicator = send_counter;
  269. len += sizeof(*nsdea);
  270. return (int) len;
  271. }
  272. int did_GB2025_wifi_build_message_pack_beacon_frame(UavIdentificationData *UAS_Data, char *mac,
  273. const char *SSID, size_t SSID_len,
  274. uint16_t interval_tu, uint8_t send_counter,
  275. uint8_t *buf, size_t buf_size)
  276. {
  277. /* Broadcast address */
  278. uint8_t target_addr[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
  279. uint8_t asd_stan_oui[3] = { 0xFA, 0x0B, 0xBC }; // 国标也是0xFA0BBC
  280. /* Mgmt Beacon frame mandatory fields + IE 221 */
  281. struct ieee80211_ssid *ssid_s;
  282. struct ieee80211_supported_rates *rates;
  283. struct ieee80211_vendor_specific *vendor;
  284. /* Message Pack */
  285. struct DID_GB2025_service_info *si;
  286. int ret;
  287. size_t len = 0;
  288. /* IEEE 802.11 Management Header */
  289. ret = buf_fill_ieee80211_mgmt(buf, &len, buf_size, IEEE80211_STYPE_BEACON, target_addr, (uint8_t *)mac, (uint8_t *)mac);
  290. if (ret <0)
  291. return ret;
  292. /* Mandatory Beacon as of 802.11-2016 Part 11 */
  293. ret = buf_fill_ieee80211_beacon(buf, &len, buf_size, interval_tu);
  294. if (ret <0)
  295. return ret;
  296. /* SSID: 1-32 bytes */
  297. if (len + sizeof(*ssid_s) > buf_size)
  298. return -ENOMEM;
  299. ssid_s = (struct ieee80211_ssid *)(buf + len);
  300. if(!SSID || (SSID_len ==0) || (SSID_len > 32))
  301. return -EINVAL;
  302. ssid_s->element_id = IEEE80211_ELEMID_SSID;
  303. ssid_s->length = (uint8_t) SSID_len;
  304. memcpy(ssid_s->ssid, SSID, ssid_s->length);
  305. len += sizeof(*ssid_s) + SSID_len;
  306. /* Supported Rates: 1 record at minimum */
  307. if (len + sizeof(*rates) > buf_size)
  308. return -ENOMEM;
  309. rates = (struct ieee80211_supported_rates *)(buf + len);
  310. rates->element_id = IEEE80211_ELEMID_RATES;
  311. rates->length = 1; // One rate only
  312. rates->supported_rates = 0x8C; // 6 Mbps
  313. len += sizeof(*rates);
  314. /* Vendor Specific Information Element (IE 221) */
  315. if (len + sizeof(*vendor) > buf_size)
  316. return -ENOMEM;
  317. vendor = (struct ieee80211_vendor_specific *)(buf + len);
  318. vendor->element_id = IEEE80211_ELEMID_VENDOR;
  319. vendor->length = 0x00; // Length updated at end of function
  320. memcpy(vendor->oui, asd_stan_oui, sizeof(vendor->oui));
  321. vendor->oui_type = 0x0D;
  322. len += sizeof(*vendor);
  323. /* DID GB2025 Service Info Attribute header */
  324. if (len + sizeof(*si) > buf_size)
  325. return -ENOMEM;
  326. si = (struct DID_GB2025_service_info *)(buf + len);
  327. memset(si, 0, sizeof(*si));
  328. si->message_counter = send_counter;
  329. len += sizeof(*si);
  330. ret = did_GB2025_message_build_pack(UAS_Data, buf + len, buf_size - len);
  331. if (ret < 0)
  332. return ret;
  333. len += ret;
  334. /* set the lengths according to the message pack lengths */
  335. vendor->length = sizeof(vendor->oui) + sizeof(vendor->oui_type) + sizeof(*si) + ret; // ret 是个负的表示空闲字节数
  336. return (int) len;
  337. }
  338. // 解包
  339. int did_GB2025_message_process_pack(UavIdentificationData *UAS_Data, uint8_t *pack, size_t buflen)
  340. {
  341. if (UAS_Data == NULL || pack == NULL || buflen == 0) {
  342. return -1;
  343. }
  344. UavIdentificationPacket *msg_pack_enc = (UavIdentificationPacket *) pack;
  345. // 固定头部大小:data_type(1) + version(1) + content_len(1) + data_flag(3) = 6字节
  346. const size_t FIXED_HEADER_SIZE = 6;
  347. // 1. 首先检查是否能安全读取固定头部
  348. if (buflen < FIXED_HEADER_SIZE) {
  349. return -2; // 缓冲区太小,连头部都不够
  350. }
  351. // 2. 现在可以安全地读取 content_len
  352. uint8_t content_len = msg_pack_enc->content_len;
  353. // 3. 检查 content_len 是否合理
  354. if (content_len > MAX_CONTENT_BYTES) {
  355. return -3; // 内容长度超限
  356. }
  357. // 4. 计算完整的包大小
  358. size_t total_size = FIXED_HEADER_SIZE + content_len;
  359. // 5. 验证整个包是否在缓冲区范围内
  360. if (total_size > buflen) {
  361. return -4; // 包不完整
  362. }
  363. // 6. 检查数据类型(可选)
  364. if (msg_pack_enc->data_type != PACKET_DATA_TYPE) {
  365. return -5; // 数据类型错误
  366. }
  367. // 7. 初始化解包目标
  368. uav_identification_data_init(UAS_Data);
  369. // 8. 执行解包
  370. if (uav_identification_unpack(UAS_Data, msg_pack_enc) != 0) {
  371. return -6; // 解包失败
  372. }
  373. // 9. 返回实际处理的字节数
  374. return (int)total_size;
  375. }
  376. int did_GB2025_wifi_receive_message_pack_nan_action_frame(UavIdentificationData *UAS_Data,
  377. char *mac, uint8_t *buf, size_t buf_size)
  378. {
  379. struct ieee80211_mgmt *mgmt; // 802.11管理帧头
  380. struct nan_service_discovery *nsd; // NAN服务发现帧头
  381. struct nan_service_descriptor_attribute *nsda; // NAN服务描述符属性
  382. struct nan_service_descriptor_extension_attribute *nsdea; // NAN服务描述符扩展属性
  383. struct DID_GB2025_service_info *si; // 中国远程ID服务信息
  384. uint8_t target_addr[6] = { 0x51, 0x6F, 0x9A, 0x01, 0x00, 0x00 }; // 远程ID(Remote ID)分配的专用组播地址
  385. uint8_t wifi_alliance_oui[3] = { 0x50, 0x6F, 0x9A }; // Wi-Fi联盟OUI
  386. uint8_t service_id[6] = { 0x88, 0x69, 0x19, 0x9D, 0x92, 0x09 }; // 远程ID服务ID 国际通用的 不需要改
  387. int ret;
  388. size_t len = 0;
  389. /* IEEE 802.11 Management Header */
  390. if (len + sizeof(*mgmt) > buf_size) // 检查缓冲区是否足够容纳一个管理帧头
  391. return -EINVAL;
  392. mgmt = (struct ieee80211_mgmt *)(buf + len);
  393. if ((mgmt->frame_control & cpu_to_le16(IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) !=
  394. cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION))
  395. return -EINVAL;
  396. if (memcmp(mgmt->da, target_addr, sizeof(mgmt->da)) != 0)
  397. return -EINVAL;
  398. memcpy(mac, mgmt->sa, sizeof(mgmt->sa));
  399. len += sizeof(*mgmt);
  400. /* NAN Service Discovery header */
  401. if (len + sizeof(*nsd) > buf_size)
  402. return -EINVAL;
  403. nsd = (struct nan_service_discovery *)(buf + len);
  404. if (nsd->category != 0x04)
  405. return -EINVAL;
  406. if (nsd->action_code != 0x09)
  407. return -EINVAL;
  408. if (memcmp(nsd->oui, wifi_alliance_oui, sizeof(wifi_alliance_oui)) != 0)
  409. return -EINVAL;
  410. if (nsd->oui_type != 0x13)
  411. return -EINVAL;
  412. len += sizeof(*nsd);
  413. /* NAN Attribute for Service Descriptor header */
  414. if (len + sizeof(*nsda) > buf_size)
  415. return -EINVAL;
  416. nsda = (struct nan_service_descriptor_attribute *)(buf + len);
  417. if (nsda->header.attribute_id != 0x3)
  418. return -EINVAL;
  419. if (memcmp(nsda->service_id, service_id, sizeof(service_id)) != 0)
  420. return -EINVAL;
  421. if (nsda->instance_id != 0x01)
  422. return -EINVAL;
  423. if (nsda->service_control != 0x10)
  424. return -EINVAL;
  425. len += sizeof(*nsda);
  426. // 在读取 si 之前应该检查空间
  427. if (len + sizeof(*si) > buf_size)
  428. return -EINVAL;
  429. si = (struct DID_GB2025_service_info *)(buf + len);
  430. ret = did_GB2025_message_process_pack(UAS_Data, buf + len + sizeof(*si), buf_size - len - sizeof(*nsdea));
  431. if (ret < 0)
  432. return -EINVAL;
  433. if (nsda->service_info_length != (sizeof(*si) + ret))
  434. return -EINVAL;
  435. if (nsda->header.length != (cpu_to_le16(sizeof(*nsda) - sizeof(struct nan_attribute_header) + nsda->service_info_length)))
  436. return -EINVAL;
  437. len += sizeof(*si) + ret;
  438. /* NAN Attribute for Service Descriptor extension header */
  439. if (len + sizeof(*nsdea) > buf_size)
  440. return -ENOMEM;
  441. nsdea = (struct nan_service_descriptor_extension_attribute *)(buf + len);
  442. if (nsdea->header.attribute_id != 0xE)
  443. return -EINVAL;
  444. if (nsdea->header.length != cpu_to_le16(0x0004))
  445. return -EINVAL;
  446. if (nsdea->instance_id != 0x01)
  447. return -EINVAL;
  448. if (nsdea->control != cpu_to_le16(0x0200))
  449. return -EINVAL;
  450. return 0;
  451. }