wifi_ifx_cyw43012.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-07-25 11714 the first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <rthw.h>
  13. #include <string.h>
  14. #define DBG_ENABLE
  15. #define DBG_SECTION_NAME "[wifi_ifx]"
  16. #define DBG_LEVEL DBG_WARNING
  17. #define DBG_COLOR
  18. #include <rtdbg.h>
  19. #include <FreeRTOS.h>
  20. #include <task.h>
  21. /* Wi-Fi driver header files */
  22. #include <whd_wifi_api.h>
  23. #include "whd_network_types.h"
  24. #include "cy_network_buffer.h"
  25. #include "whd_buffer_api.h"
  26. #include "whd_wlioctl.h"
  27. #include "whd_int.h"
  28. #include <cybsp_wifi.h>
  29. #define EAPOL_PACKET_TYPE (0x888E)
  30. struct ifx_wifi
  31. {
  32. /* inherit from ethernet device */
  33. struct rt_wlan_device *wlan;
  34. /* spi transfer layer handle */
  35. whd_interface_t whd_if;
  36. };
  37. static struct ifx_wifi wifi_sta, wifi_ap;
  38. static rt_bool_t inited = RT_FALSE;
  39. static whd_scan_result_t scan_result;
  40. rt_inline struct ifx_wifi *_GET_DEV(struct rt_wlan_device *wlan)
  41. {
  42. if (wlan == wifi_sta.wlan)
  43. {
  44. return &wifi_sta;
  45. }
  46. if (wlan == wifi_ap.wlan)
  47. {
  48. return &wifi_ap;
  49. }
  50. return RT_NULL;
  51. }
  52. static whd_security_t get_security(rt_wlan_security_t security)
  53. {
  54. /* security type */
  55. switch (security)
  56. {
  57. case SECURITY_OPEN:
  58. return WHD_SECURITY_OPEN;
  59. case SECURITY_WEP_PSK:
  60. return WHD_SECURITY_WEP_PSK;
  61. case SECURITY_WEP_SHARED:
  62. return WHD_SECURITY_WEP_SHARED;
  63. case SECURITY_WPA_TKIP_PSK:
  64. return WHD_SECURITY_WPA_TKIP_PSK;
  65. case SECURITY_WPA_AES_PSK:
  66. return WHD_SECURITY_WPA_AES_PSK;
  67. case SECURITY_WPA2_AES_PSK:
  68. return WHD_SECURITY_WPA2_AES_PSK;
  69. case SECURITY_WPA2_TKIP_PSK:
  70. return WHD_SECURITY_WPA2_TKIP_PSK;
  71. case SECURITY_WPA2_MIXED_PSK:
  72. return WHD_SECURITY_WPA2_MIXED_PSK;
  73. case SECURITY_WPS_SECURE:
  74. return WHD_SECURITY_WPS_SECURE;
  75. default:
  76. return WHD_SECURITY_UNKNOWN;
  77. }
  78. }
  79. static int _ifx_scan_info2rtt(whd_scan_result_t *result_ptr, struct rt_wlan_info *wlan_info)
  80. {
  81. /* security type */
  82. switch (result_ptr->security)
  83. {
  84. case WHD_SECURITY_OPEN:
  85. wlan_info->security = SECURITY_OPEN;
  86. break;
  87. case WHD_SECURITY_WEP_PSK:
  88. wlan_info->security = SECURITY_WEP_PSK;
  89. break;
  90. case WHD_SECURITY_WEP_SHARED:
  91. wlan_info->security = SECURITY_WEP_SHARED;
  92. break;
  93. case WHD_SECURITY_WPA_TKIP_PSK:
  94. wlan_info->security = SECURITY_WPA_TKIP_PSK;
  95. break;
  96. case WHD_SECURITY_WPA_AES_PSK:
  97. wlan_info->security = SECURITY_WPA_AES_PSK;
  98. break;
  99. case WHD_SECURITY_WPA2_AES_PSK:
  100. wlan_info->security = SECURITY_WPA2_AES_PSK;
  101. break;
  102. case WHD_SECURITY_WPA2_TKIP_PSK:
  103. wlan_info->security = SECURITY_WPA2_TKIP_PSK;
  104. break;
  105. case WHD_SECURITY_WPA2_MIXED_PSK:
  106. wlan_info->security = SECURITY_WPA2_MIXED_PSK;
  107. break;
  108. case WHD_SECURITY_WPS_SECURE:
  109. wlan_info->security = SECURITY_WPS_SECURE;
  110. break;
  111. default:
  112. wlan_info->security = SECURITY_UNKNOWN;
  113. break;
  114. }
  115. /* 2.4G/5G */
  116. switch (result_ptr->band)
  117. {
  118. case WHD_802_11_BAND_5GHZ:
  119. wlan_info->band = RT_802_11_BAND_5GHZ;
  120. break;
  121. case WHD_802_11_BAND_2_4GHZ:
  122. wlan_info->band = RT_802_11_BAND_2_4GHZ;
  123. break;
  124. default:
  125. wlan_info->band = RT_802_11_BAND_UNKNOWN;
  126. break;
  127. }
  128. /* maximal data rate */
  129. wlan_info->datarate = result_ptr->max_data_rate;
  130. /* radio channel */
  131. wlan_info->channel = result_ptr->channel;
  132. /* signal strength */
  133. wlan_info->rssi = result_ptr->signal_strength;
  134. /* ssid */
  135. rt_strncpy(wlan_info->ssid.val, result_ptr->SSID.value, RT_WLAN_SSID_MAX_LENGTH);
  136. wlan_info->ssid.len =
  137. result_ptr->SSID.length > RT_WLAN_SSID_MAX_LENGTH ? RT_WLAN_SSID_MAX_LENGTH : result_ptr->SSID.length;
  138. /* hwaddr */
  139. rt_strncpy(wlan_info->bssid, result_ptr->BSSID.octet, RT_WLAN_BSSID_MAX_LENGTH);
  140. wlan_info->hidden = RT_TRUE;
  141. return 0;
  142. }
  143. #define SCAN_BSSI_ARR_MAX 30
  144. #define CMP_MAC( a, b ) (((((unsigned char*)a)[0])==(((unsigned char*)b)[0]))&& \
  145. ((((unsigned char*)a)[1])==(((unsigned char*)b)[1]))&& \
  146. ((((unsigned char*)a)[2])==(((unsigned char*)b)[2]))&& \
  147. ((((unsigned char*)a)[3])==(((unsigned char*)b)[3]))&& \
  148. ((((unsigned char*)a)[4])==(((unsigned char*)b)[4]))&& \
  149. ((((unsigned char*)a)[5])==(((unsigned char*)b)[5])))
  150. static whd_mac_t mac_addr_arr[SCAN_BSSI_ARR_MAX];
  151. rt_uint8_t current_bssid_arr_length = 0;
  152. bool scan_bssi_has(whd_mac_t *BSSID)
  153. {
  154. whd_mac_t *mac_iter = NULL;
  155. /* Check for duplicate SSID */
  156. for (mac_iter = mac_addr_arr; (mac_iter < mac_addr_arr + current_bssid_arr_length); ++mac_iter)
  157. {
  158. if (CMP_MAC(mac_iter->octet, BSSID->octet))
  159. {
  160. /* The scanned result is a duplicate; just return */
  161. return true;
  162. }
  163. }
  164. /* If scanned Wi-Fi is not a duplicate then populate the array */
  165. if (current_bssid_arr_length < SCAN_BSSI_ARR_MAX)
  166. {
  167. memcpy(&mac_iter->octet, &BSSID->octet, sizeof(whd_mac_t));
  168. current_bssid_arr_length++;
  169. }
  170. return false;
  171. }
  172. void scan_callback(whd_scan_result_t **result_ptr, void *user_data, whd_scan_status_t status)
  173. {
  174. whd_scan_result_t *whd_scan_result = *result_ptr;
  175. uint32_t scan_status = status;
  176. /* Check if we don't have a scan result to send to the user */
  177. if ((result_ptr == NULL) || (*result_ptr == NULL))
  178. {
  179. /* Check for scan complete */
  180. if (status == WHD_SCAN_COMPLETED_SUCCESSFULLY || status == WHD_SCAN_ABORTED)
  181. {
  182. /* Notify scan complete */
  183. rt_wlan_dev_indicate_event_handle(wifi_sta.wlan, RT_WLAN_DEV_EVT_SCAN_DONE, 0);
  184. }
  185. return;
  186. }
  187. if (whd_scan_result->SSID.length != 0)
  188. {
  189. /* parse scan report event data */
  190. struct rt_wlan_buff buff;
  191. struct rt_wlan_info wlan_info;
  192. if (scan_bssi_has(&whd_scan_result->BSSID) == false)
  193. {
  194. _ifx_scan_info2rtt(whd_scan_result, &wlan_info);
  195. buff.data = &wlan_info;
  196. buff.len = sizeof(struct rt_wlan_info);
  197. /* indicate scan report event */
  198. rt_wlan_dev_indicate_event_handle(wifi_sta.wlan, RT_WLAN_DEV_EVT_SCAN_REPORT, &buff);
  199. }
  200. }
  201. return;
  202. }
  203. void cy_network_process_ethernet_data(whd_interface_t iface, whd_buffer_t buf)
  204. {
  205. LOG_D("get wlan data");
  206. uint8_t *data = whd_buffer_get_current_piece_data_pointer(iface->whd_driver, buf);
  207. uint16_t ethertype;
  208. struct netif *net_interface = NULL;
  209. if (iface->role == WHD_STA_ROLE)
  210. {
  211. }
  212. else if (iface->role == WHD_AP_ROLE)
  213. {
  214. }
  215. else
  216. {
  217. cy_buffer_release(buf, WHD_NETWORK_RX);
  218. return;
  219. }
  220. ethertype = (uint16_t) (data[12] << 8 | data[13]);
  221. if (ethertype == EAPOL_PACKET_TYPE)
  222. {
  223. LOG_D("EAPOL_PACKET_TYPE");
  224. }
  225. else
  226. {
  227. /* If the interface is not yet set up, drop the packet */
  228. LOG_D("Send data up to wlan");
  229. rt_wlan_dev_report_data(wifi_sta.wlan, data, whd_buffer_get_current_piece_size(iface->whd_driver, buf));
  230. cy_buffer_release(buf, WHD_NETWORK_RX);
  231. }
  232. }
  233. static whd_netif_funcs_t _netif_if =
  234. {
  235. .whd_network_process_ethernet_data = cy_network_process_ethernet_data,
  236. };
  237. static rt_err_t wlan_init(struct rt_wlan_device *wlan)
  238. {
  239. cy_rslt_t result = CY_RSLT_SUCCESS;
  240. if (inited == RT_FALSE)
  241. {
  242. inited = RT_TRUE;
  243. /* Initialize the Wi-Fi device, Wi-Fi transport*/
  244. cybsp_wifi_init_primary_extended(&(_GET_DEV(wlan)->whd_if), NULL, NULL, NULL, &_netif_if);
  245. RT_ASSERT(result == 0 && "cy_wcm_init failed...!\n");
  246. }
  247. if (wlan == wifi_ap.wlan)
  248. {
  249. LOG_D("softap init");
  250. cybsp_wifi_init_secondary(&(_GET_DEV(wlan)->whd_if), NULL);
  251. }
  252. return RT_EOK;
  253. }
  254. static rt_err_t wlan_scan(struct rt_wlan_device *wlan, struct rt_scan_info *scan_info)
  255. {
  256. current_bssid_arr_length = 0;
  257. memset(mac_addr_arr, sizeof(whd_mac_t) * SCAN_BSSI_ARR_MAX, 0);
  258. whd_wifi_scan(_GET_DEV(wlan)->whd_if, WHD_SCAN_TYPE_ACTIVE, WHD_BSS_TYPE_ANY,
  259. NULL, NULL, NULL, NULL, scan_callback, &scan_result, NULL);
  260. return 0;
  261. }
  262. static rt_err_t wlan_scan_stop(struct rt_wlan_device *wlan)
  263. {
  264. whd_wifi_stop_scan(_GET_DEV(wlan)->whd_if);
  265. return 0;
  266. }
  267. static rt_err_t wlan_join(struct rt_wlan_device *wlan, struct rt_sta_info *sta_info)
  268. {
  269. uint32_t res;
  270. whd_ssid_t ssid;
  271. strncpy(ssid.value, sta_info->ssid.val, sta_info->ssid.len);
  272. ssid.length = sta_info->ssid.len;
  273. ssid.value[sta_info->ssid.len] = '\0';
  274. whd_wifi_set_ioctl_value(_GET_DEV(wlan)->whd_if, WLC_SET_BAND, WLC_BAND_2G);
  275. /** Join to Wi-Fi AP **/
  276. res = whd_wifi_join(_GET_DEV(wlan)->whd_if, &ssid, WHD_SECURITY_WPA2_AES_PSK, sta_info->key.val, sta_info->key.len);
  277. if (res == WHD_SUCCESS)
  278. {
  279. rt_wlan_dev_indicate_event_handle(wifi_sta.wlan, RT_WLAN_DEV_EVT_CONNECT, 0);
  280. }
  281. else
  282. {
  283. rt_wlan_dev_indicate_event_handle(wifi_sta.wlan, RT_WLAN_DEV_EVT_CONNECT_FAIL, 0);
  284. }
  285. return 0;
  286. }
  287. int _wlan_send(struct rt_wlan_device *wlan, void *buff, int len)
  288. {
  289. whd_buffer_t buffer;
  290. if (whd_wifi_is_ready_to_transceive(_GET_DEV(wlan)->whd_if) != WHD_SUCCESS)
  291. {
  292. return -1;
  293. }
  294. if (whd_host_buffer_get(_GET_DEV(wlan)->whd_if->whd_driver, &buffer, WHD_NETWORK_TX, len + WHD_LINK_HEADER, 1000) != 0)
  295. {
  296. LOG_D("err whd_host_buffer_get failed\n");
  297. return -1;
  298. }
  299. whd_buffer_add_remove_at_front(_GET_DEV(wlan)->whd_if->whd_driver, &buffer, WHD_LINK_HEADER);
  300. memcpy(whd_buffer_get_current_piece_data_pointer(_GET_DEV(wlan)->whd_if->whd_driver, buffer), buff, len);
  301. whd_network_send_ethernet_data(_GET_DEV(wlan)->whd_if, buffer);
  302. return 0;
  303. }
  304. rt_err_t wlan_mode(struct rt_wlan_device *wlan, rt_wlan_mode_t mode)
  305. {
  306. switch (mode)
  307. {
  308. case RT_WLAN_STATION:
  309. LOG_D("wlan_mode RT_WLAN_STATION\n");
  310. break;
  311. case RT_WLAN_AP:
  312. LOG_D("wlan_mode RT_WLAN_AP\n");
  313. break;
  314. }
  315. return 0;
  316. }
  317. rt_err_t wlan_softap(struct rt_wlan_device *wlan, struct rt_ap_info *ap_info)
  318. {
  319. uint32_t res;
  320. whd_interface_t *ifx = &(_GET_DEV(wlan)->whd_if);
  321. LOG_D("wlan_softap");
  322. res = whd_wifi_init_ap(*ifx, (whd_ssid_t*)&ap_info->ssid, get_security(ap_info->security), (const uint8_t *) ap_info->key.val,
  323. ap_info->key.len, ap_info->channel);
  324. res = whd_wifi_start_ap(*ifx);
  325. if (res == WHD_SUCCESS)
  326. {
  327. LOG_D("ap start ok");
  328. rt_wlan_dev_indicate_event_handle(wifi_ap.wlan, RT_WLAN_DEV_EVT_AP_START, 0);
  329. }
  330. else
  331. {
  332. rt_wlan_dev_indicate_event_handle(wifi_ap.wlan, RT_WLAN_DEV_EVT_AP_STOP, 0);
  333. }
  334. return 0;
  335. }
  336. rt_err_t wlan_disconnect(struct rt_wlan_device *wlan)
  337. {
  338. LOG_D("wlan_disconnect");
  339. whd_wifi_leave(_GET_DEV(wlan)->whd_if);
  340. return 0;
  341. }
  342. rt_err_t wlan_ap_stop(struct rt_wlan_device *wlan)
  343. {
  344. LOG_D("wlan_ap_stop");
  345. whd_wifi_stop_ap(_GET_DEV(wlan)->whd_if);
  346. return 0;
  347. }
  348. rt_err_t wlan_ap_deauth(struct rt_wlan_device *wlan, rt_uint8_t mac[])
  349. {
  350. whd_mac_t _mac;
  351. LOG_D("wlan_ap_deauth");
  352. memcpy(&_mac, mac, sizeof(whd_mac_t));
  353. whd_wifi_deauth_sta(_GET_DEV(wlan)->whd_if, &_mac, 0);
  354. return 0;
  355. }
  356. int wlan_get_rssi(struct rt_wlan_device *wlan)
  357. {
  358. int32_t rssi;
  359. whd_wifi_get_rssi(_GET_DEV(wlan)->whd_if, &rssi);
  360. return rssi;
  361. }
  362. rt_err_t wlan_set_channel(struct rt_wlan_device *wlan, int channel)
  363. {
  364. LOG_D("wlan_set_channel");
  365. whd_wifi_set_channel(_GET_DEV(wlan)->whd_if, channel);
  366. return 0;
  367. }
  368. int wlan_get_channel(struct rt_wlan_device *wlan)
  369. {
  370. uint32_t channel;
  371. LOG_D("wlan_get_channel");
  372. whd_wifi_get_channel(_GET_DEV(wlan)->whd_if, &channel);
  373. return channel;
  374. }
  375. rt_err_t wlan_set_mac(struct rt_wlan_device *wlan, rt_uint8_t mac[])
  376. {
  377. whd_mac_t _mac;
  378. memcpy(&_mac, mac, sizeof(whd_mac_t));
  379. whd_wifi_set_mac_address(_GET_DEV(wlan)->whd_if, _mac);
  380. return 0;
  381. }
  382. rt_err_t wlan_get_mac(struct rt_wlan_device *wlan, rt_uint8_t mac[])
  383. {
  384. whd_mac_t *_mac = (whd_mac_t *) mac;
  385. if (whd_wifi_get_mac_address(_GET_DEV(wlan)->whd_if, _mac) == WHD_SUCCESS)
  386. {
  387. LOG_D("WLAN MAC Address : %02X:%02X:%02X:%02X:%02X:%02X", _mac->octet[0], _mac->octet[1], _mac->octet[2],
  388. _mac->octet[3], _mac->octet[4], _mac->octet[5]);
  389. }
  390. return 0;
  391. }
  392. const static struct rt_wlan_dev_ops ops =
  393. {
  394. .wlan_init = wlan_init,
  395. .wlan_mode = wlan_mode,
  396. .wlan_scan = wlan_scan,
  397. .wlan_join = wlan_join,
  398. .wlan_softap = wlan_softap,
  399. .wlan_disconnect = wlan_disconnect,
  400. .wlan_ap_stop = wlan_ap_stop,
  401. .wlan_ap_deauth = wlan_ap_deauth,
  402. .wlan_scan_stop = wlan_scan_stop,
  403. .wlan_get_rssi = wlan_get_rssi,
  404. .wlan_set_channel = wlan_set_channel,
  405. .wlan_get_channel = wlan_get_channel,
  406. .wlan_set_mac = wlan_set_mac,
  407. .wlan_get_mac = wlan_get_mac,
  408. .wlan_send = _wlan_send,
  409. };
  410. int wifi_ifx_init(void)
  411. {
  412. static struct rt_wlan_device wlan_sta, wlan_ap;
  413. rt_err_t ret;
  414. wifi_sta.wlan = &wlan_sta;
  415. wifi_ap.wlan = &wlan_ap;
  416. /* register wlan device for ap */
  417. ret = rt_wlan_dev_register(&wlan_ap, RT_WLAN_DEVICE_AP_NAME, &ops, 0, &wifi_ap);
  418. if (ret != RT_EOK)
  419. {
  420. return ret;
  421. }
  422. /* register wlan device for sta */
  423. ret = rt_wlan_dev_register(&wlan_sta, RT_WLAN_DEVICE_STA_NAME, &ops, 0, &wifi_sta);
  424. if (ret != RT_EOK)
  425. {
  426. return ret;
  427. }
  428. }
  429. INIT_DEVICE_EXPORT(wifi_ifx_init);