[文章]

鸿蒙第4节 Hi3861 Wifi操作,热点连接

2020-9-30 19:47:00  305 鸿蒙
分享
5
本帖最后由 jf_39160458 于 2020-9-30 19:49 编辑

Hi3861 WiFi操作,热点连接
之前我们使用Hi3861的时候,是使用AT指令连接到WiFi热点的。例如:


但是很多时候,我们需要实现开机后自动连接到某个热点,光靠AT指令不行。
Hi3861 为我们提供了WiFi操作的相关API,方便我们编写代码,实现热点连接。

1.代码实现
先直接上代码和操作演示。
跟我们最早的hello world代码一样,在app下新增业务wifi_demo,其中hello_world.c为业务代码,BUILD.gn为编译脚本,具体规划目录结构如下:
.
└── applications
    └── sample
        └── wifi-iot
            └── app
                │── wifi_demo
                │  │── wifi_demo.c
                │  └── BUILD.gn
                └── BUILD.gn

Wifi_demo.c 代码如下:
  1. #include <stdio.h>

  2. #include <unistd.h>

  3. #include "ohos_init.h"
  4. #include "cmsis_os2.h"

  5. #include <unistd.h>
  6. #include "hi_wifi_api.h"
  7. //#include "wifi_sta.h"
  8. #include "lwip/ip_addr.h"
  9. #include "lwip/netifapi.h"

  10. #define APP_INIT_VAP_NUM    2
  11. #define APP_INIT_USR_NUM    2

  12. static struct netif *g_lwip_netif = NULL;

  13. /* clear netif's ip, gateway and netmask */
  14. void hi_sta_reset_addr(struct netif *pst_lwip_netif)
  15. {
  16.     ip4_addr_t st_gw;
  17.     ip4_addr_t st_ipaddr;
  18.     ip4_addr_t st_netmask;
  19.     printf("%s %d \r\n", __FILE__, __LINE__);
  20.     if (pst_lwip_netif == NULL) {
  21.         printf("hisi_reset_addr::Null param of netdev\r\n");
  22.         return;
  23.     }

  24.     IP4_ADDR(&st_gw, 0, 0, 0, 0);
  25.     IP4_ADDR(&st_ipaddr, 0, 0, 0, 0);
  26.     IP4_ADDR(&st_netmask, 0, 0, 0, 0);

  27.     netifapi_netif_set_addr(pst_lwip_netif, &st_ipaddr, &st_netmask, &st_gw);
  28. }

  29. void wifi_wpa_event_cb(const hi_wifi_event *hisi_event)
  30. {
  31.     if (hisi_event == NULL)
  32.         return;

  33.     switch (hisi_event->event) {
  34.         case HI_WIFI_EVT_SCAN_DONE:
  35.             printf("WiFi: Scan results available\n");
  36.             break;
  37.         case HI_WIFI_EVT_CONNECTED:
  38.             printf("WiFi: Connected\n");
  39.             netifapi_dhcp_start(g_lwip_netif);
  40.             break;
  41.         case HI_WIFI_EVT_DISCONNECTED:
  42.             printf("WiFi: Disconnected\n");
  43.             netifapi_dhcp_stop(g_lwip_netif);
  44.             hi_sta_reset_addr(g_lwip_netif);
  45.             break;
  46.         case HI_WIFI_EVT_WPS_TIMEOUT:
  47.             printf("WiFi: wps is timeout\n");
  48.             break;
  49.         default:
  50.             break;
  51.     }
  52. }

  53. int hi_wifi_start_connect(void)
  54. {
  55.     int ret;
  56.     errno_t rc;
  57.     hi_wifi_assoc_request assoc_req = {0};

  58.     /* copy SSID to assoc_req */
  59.     //热点名称
  60.     rc = memcpy_s(assoc_req.ssid, HI_WIFI_MAX_SSID_LEN + 1, "15919500", 8); /* 9:ssid length */
  61.     if (rc != EOK) {
  62.         printf("%s %d \r\n", __FILE__, __LINE__);
  63.         return -1;
  64.     }

  65.     /*
  66.      * OPEN mode
  67.      * for WPA2-PSK mode:
  68.      * set assoc_req.auth as HI_WIFI_SECURITY_WPA2PSK,
  69.      * then memcpy(assoc_req.key, "12345678", 8).
  70.      */
  71.     //热点加密方式
  72.     assoc_req.auth = HI_WIFI_SECURITY_WPA2PSK;

  73.     /* 热点密码 */
  74.     memcpy(assoc_req.key, "11206582488", 11);


  75.     ret = hi_wifi_sta_connect(&assoc_req);
  76.     if (ret != HISI_OK) {
  77.         printf("%s %d \r\n", __FILE__, __LINE__);
  78.         return -1;
  79.     }
  80.     printf("%s %d \r\n", __FILE__, __LINE__);
  81.     return 0;
  82. }

  83. int hi_wifi_start_sta(void)
  84. {
  85.     int ret;
  86.     char ifname[WIFI_IFNAME_MAX_SIZE + 1] = {0};
  87.     int len = sizeof(ifname);
  88.     const unsigned char wifi_vap_res_num = APP_INIT_VAP_NUM;
  89.     const unsigned char wifi_user_res_num = APP_INIT_USR_NUM;
  90.     unsigned int  num = WIFI_SCAN_AP_LIMIT;

  91.     printf("%s %d \r\n", __FILE__, __LINE__);

  92.     ret = hi_wifi_init(wifi_vap_res_num, wifi_user_res_num);
  93.     if (ret != HISI_OK) {
  94.         printf("%s %d \r\n", __FILE__, __LINE__);
  95.         //return -1;
  96.     }

  97.     printf("%s %d \r\n", __FILE__, __LINE__);
  98.     ret = hi_wifi_sta_start(ifname, &len);
  99.     if (ret != HISI_OK) {
  100.         printf("%s %d \r\n", __FILE__, __LINE__);
  101.         return -1;
  102.     }

  103.     /* register call back function to receive wifi event, etc scan results event,
  104.      * connected event, disconnected event.
  105.      */
  106.     ret = hi_wifi_register_event_callback(wifi_wpa_event_cb);
  107.     if (ret != HISI_OK) {
  108.         printf("register wifi event callback faiLED\n");
  109.     }

  110.     /* acquire netif for IP operation */
  111.     g_lwip_netif = netifapi_netif_find(ifname);
  112.     if (g_lwip_netif == NULL) {
  113.         printf("%s: get netif failed\n", __FUNCTION__);
  114.         return -1;
  115.     }

  116.     /* start scan, scan results event will be received soon */
  117.     ret = hi_wifi_sta_scan();
  118.     if (ret != HISI_OK) {
  119.         printf("%s %d \r\n", __FILE__, __LINE__);
  120.         return -1;
  121.     }

  122.     sleep(5);   /* sleep 5s, waiting for scan result. */

  123.     hi_wifi_ap_info *pst_results = malloc(sizeof(hi_wifi_ap_info) * WIFI_SCAN_AP_LIMIT);
  124.     if (pst_results == NULL) {
  125.         printf("%s %d \r\n", __FILE__, __LINE__);
  126.         return -1;
  127.     }

  128.     ret = hi_wifi_sta_scan_results(pst_results, &num);
  129.     if (ret != HISI_OK) {
  130.         printf("%s %d \r\n", __FILE__, __LINE__);
  131.         free(pst_results);
  132.         return -1;
  133.     }

  134.     for (unsigned int loop = 0; (loop < num) && (loop < WIFI_SCAN_AP_LIMIT); loop++) {
  135.         printf("SSID: %s\n", pst_results[loop].ssid);
  136.     }
  137.     free(pst_results);

  138.     /* if received scan results, select one SSID to connect */
  139.     ret = hi_wifi_start_connect();
  140.     if (ret != 0) {
  141.         printf("%s %d \r\n", __FILE__, __LINE__);
  142.         return -1;
  143.     }


  144.     return 0;
  145. }

  146. void hi_wifi_stop_sta(void)
  147. {
  148.     int ret;

  149.     ret = hi_wifi_sta_stop();
  150.     if (ret != HISI_OK) {
  151.         printf("failed to stop sta\n");
  152.     }

  153.     ret = hi_wifi_deinit();
  154.     if (ret != HISI_OK) {
  155.         printf("failed to deinit wifi\n");
  156.     }

  157.     g_lwip_netif = NULL;

  158.    
  159. }


  160. void WiFiExampleEntry(void)
  161. {
  162.     hi_wifi_start_sta();
  163. }

  164. SYS_RUN(WiFiExampleEntry);
复制代码


Wifi_demo目录下的BUILD.gn文件内容如下:
static_library("wifi_demo") {
    sources = [
        "wifi_demo.c"
    ]

    include_dirs = [
        "//utils/native/lite/include",
        "//kernel/liteos_m/components/cmsis/2.0",
        "//base/iot_hardware/inteRFaces/kits/wifiiot_lite",
        "//vendor/hisi/hi3861/hi3861/third_party/lwip_sack/include",
        "//foundation/communication/interfaces/kits/wifi_lite/wifiservice",
        
    ]
}

app目录下的BUILD.gn文件内容修改如下:
import("//build/lite/config/component/lite_component.gni")

lite_component("app") {
    features = [
        "wifi_demo:wifi_demo",
    ]
}


编译烧录,查看串口数据:





可以看到有打印扫描到的热点名称:

SSID: 15919500

SSID: Netcore_FD55A7

同时最后打印:WiFi: Connected 成功连接上热点。



2.wifi api接口说明

Hi3861 提供了非常多的wifi相关API,主要文件是 hi_wifi_api.h

我们这里只列举最重要的几个API



(1)开启STA

int hi_wifi_sta_start(char *ifname, int *len);



(2)停止STA

int hi_wifi_sta_stop(void);



  • 扫描附件的热点
int hi_wifi_sta_scan(void);



(4)连接热点

int hi_wifi_sta_connect(hi_wifi_assoc_request *req);

其中hi_wifi_assoc_request *req 结构的定义如下:







这里需要注意的是,通常加密方式是:HI_WIFI_SECURITY_WPA2PSK

例如我家的热点的连接方式的代码实现如下:
  1.     /* copy SSID to assoc_req */
  2.     //热点名称
  3.     rc = memcpy_s(assoc_req.ssid, HI_WIFI_MAX_SSID_LEN + 1, "15919500", 8); /* 9:ssid length */
  4.     if (rc != EOK) {
  5.         printf("%s %d \r\n", __FILE__, __LINE__);
  6.         return -1;
  7.     }

  8.     /*
  9.      * OPEN mode
  10.      * for WPA2-PSK mode:
  11.      * set assoc_req.auth as HI_WIFI_SECURITY_WPA2PSK,
  12.      * then memcpy(assoc_req.key, "12345678", 8).
  13.      */
  14.     //热点加密方式
  15.     assoc_req.auth = HI_WIFI_SECURITY_WPA2PSK;

  16.     /* 热点密码 */
  17.     memcpy(assoc_req.key, "11206582488", 11);
复制代码


7771c37c9acdf8c21b47d235199a1a4.jpg

评论

您需要登录后才可以回帖 登录 | 注册

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
发文章