# WiFi网络

  - [概要](#概要)
  - [什么是WLAN](#什么是wlan)
    - [WLAN架构](#wlan架构)
    - [waffle nano网络模式](#waffle-nano网络模式)
      - [热点模式(AP)](#热点模式ap)
      - [站点模式(STA)](#站点模式sta)
  - [WLAN引脚定义](#wlan引脚定义)
  - [network.WLAN API详解](#networkwlan-api详解)
    - [宏定义](#宏定义)
    - [类](#类)
      - [构造WLAN](#构造wlan)
    - [函数](#函数)
      - [查询状态](#查询状态)
      - [扫描网络](#扫描网络)
      - [设置网络](#设置网络)
      - [连接网络](#连接网络)
      - [断开网络连接](#断开网络连接)
  - [示例](#示例)

## 概要

  waffle nano自带了WiFi模块,因此可以很容易的让waffle nano接入网络。

  在MicroPython下,使用 [`network`](https://docs.micropython.org/en/latest/library/network.html#module-network)模块来配置waffle nano的网络模式:

- `STA` 作为站点接入WiFi网络
- `AP` 作为热点,允许其他设备接入waffle nano

## 什么是WLAN

WLAN 包括如下能力:建立/关闭WLAN热点、扫描、关联WLAN热点等。

### WLAN架构

  WLAN模块框架图如下:

![](Image/zh-cn_image_0000001055299108.png)

  WLAN模块有三部分对外开放的API接口,如下图所示:

1. 对HDI层提供的能力接口。
2. 驱动直接调用WLAN模块能力接口。
3. 提供给各厂商实现的能力接口。

![](Image/接口分布图4.png)

### waffle nano网络模式

#### 热点模式(AP)

  热点模式允许用户将自己的waffle nano配置为热点,这让多个waffle nano芯片之间的无线连接在不借助外部路由器网络的情况下成为可能。

  热点模式通过把本机设备创建成一个热点,在激活热点和为热点配置热点名称后,使本机成为一个开放的AP热点,其他设备在WiFi列表中找到它,连接此热点实现无线连接。

#### 站点模式(STA)

  更多的情况下,会将waffle nano连接到WiFi网络。

  站点模式通过创建一个Wifi站点,在激活该站点和扫描周围的可用网络后,本机在WiFi列表中找到可用网络名,输入正确密码实现无线连接。连接成功后还可以获取当前WiFi连接的IP、子网掩码、网关、DNS等信息

## WLAN引脚定义

  有1个引脚可以用作WLAN

| 引脚  | 功能        |
| ----- | ----------- |
| pin 8 | WLAN ACTIVE |

## network.WLAN API详解

  使用`import network`导入`network`模块

  再使用`TAB` 按键来查看`network`中所包含的内容:

```python
>>>import network
>>>network.
__name__        AP_IF           AUTH_OPEN       AUTH_PSK
AUTH_SAE        AUTH_WEP        BAND_2G         BAND_5G
STA_IF          WLAN
```

### 宏定义

  下面的宏定义用于配置network,设置对应网络模式。

| 宏定义            | 含义                                                         |
| :---------------- | :----------------------------------------------------------- |
| network.AP_IF     | 热点模式                                                     |
| network.AUTH_OPEN | 完全不认证也不加密                                           |
| network.AUTH_PSK  | 预共享密钥,为每个客户分配唯一的密钥而工作,比WEP难被破解,更加安全 |
| network.AUTH_SAE  | 对等实体同时验证,通过证实密码信息,用密码进行身份验证,而不是进行密钥导出 |
| network.AUTH_WEP  | 有线等效加密,拥有相同的网络金钥,才能解读互相传递的数据     |
| network.BAND_2G   | 2G频段                                                       |
| network.STA_IF    | 站点模式                                                     |
| network.WLAN      | WLAN类                                                       |

### 类

  `class network.WLAN(mode)`

  `mode`:模式

- `network.STA_IF`— 站点模式,连接到上游WiFi接入点
- `network.AP_IF`—— 热点模式,允许其他WiFi客户端连接

#### 构造WLAN

  用WLAN对象的构造器函数

  示例:

```python
>>> import network
>>> sta_wlan = network.WLAN(network.STA_IF)#创建一个站点模式的WLAN对象
>>> ap_wlan = network.WLAN(network.AP_IF)#创建一个热点模式的WLAN对象
```

### 函数

#### 查询状态

  wlan.active(is_active)

  函数说明:带有参数时,为是否激活WiFi,不带参数为查询当前状态。

  `is_active`:是否激活

- `Pin(8)`激活网络接口
- `True` 激活网络接口
- `False` 停用网络接口

  示例:

```python
>>> import network
>>> sta_wlan = network.WLAN(network.STA_IF)#创建一个站点模式的WLAN对象
>>>sta_wlan.active(True)#激活网络
RegisterWifiEvent: Success
EnableWifi: Success
True
```

#### 扫描网络

  wlan.scan()

  函数说明:扫描可用的无线网络(仅在STA接口上进行扫描),必须先激活WiFi,返回有关WiFi接入点信息的元组列表。

  示例:

```python
>>> import network
>>> sta_wlan = network.WLAN(network.STA_IF)#创建一个站点模式的WLAN对象
>>> ap_wlan = network.WLAN(network.AP_IF)#创建一个热点模式的WLAN对象
>>> ap_wlan.scan()#AP模式扫描不了无线网络
Traceback (most recent call last):
  File "<stdin>", in <module>
OSError: STA required
>>> sta_wlan.scan()#STA模式,未激活网络,依旧无法扫描无线网络
Traceback (most recent call last):
  File "<stdin>", in <module>
OSError: STA must be active
>>>sta_wlan.active(True)#激活网络
RegisterWifiEvent: Success
EnableWifi: Success
True
>>> sta_wlan.scan()#扫描网络
OnWifiScanStateChanged: state = 0, size = 0
OnWifiScanStateChanged: state = 1, size = 10
WaitSacnResult:wait success[1]s
[('Noah-BlackWalnut', b'<|?W\x84h', -1, -5600, 2452), ('tingchechang', b'\x0c\xd8lLL\xb0', 2, -6300, 2467), ('sunking', b'\xacau\xe2\xa1\x80', 2, -6800, 2437), ('GU', b'\x80\x8f\x1d9\x1c\xfa', 2, -7200, 2412), ('zykj', b'l\xe8s\xafq\xcc', 2, -7400, 2437), ('ZYKJ_202012', b'dn\x97\xdf\xce\xfe', 2, -7600, 2462), ('zykj_sw', b'D\x97Z\x90\xe0\xae', 2, -7600, 2412), ('zykj_28', b'\xd4\xf7\x86\x82P\xdd', -1, -7700, 2472), ('ChinaNet-QufH', b'\xa8\xad=\xb1\xdax', -1, -7900, 2462), ('zykj2020', b'`\x14f\xbb\x90(', -1, -8300, 2442)]
```

#### 设置网络

&emsp;&emsp;wlan.config('ssid'[,password=[,security=])

&emsp;&emsp;函数说明:设置热点(仅在AP接口上进行设置),必须先停用创建的热点对象,设置完成后再激活热点对象,就能在网络列表中找到设置的热点。

&emsp;&emsp;`ssid`:WiFi名称

&emsp;&emsp;`password`:WiFi密码

&emsp;&emsp;`security`:WiFi安全类型

&emsp;&emsp;示例:

```python
>>> import network
>>> ap_wlan = network.WLAN(network.AP_IF)#创建一个热点模式的WLAN对象
>>> ap.config('abc')#热点在使用,无法修改配置
RegisterWifiEvent: Invalid parameters
SetHotspotConfig: Success
>>> ap_wlan.active(False)#停用热点
netifapi_dhcps_stop: success
UnRegisterWifiEvent: Success
EnableHotspot: Success
False
>>> ap_wlan.config("waffle_nano", password="waffle_nano", security=network.AUTH_PSK)
RegisterWifiEvent: Success
SetHotspotConfig: Success
>>> ap_wlan.active(True)#激活热点
HotspotState: Active.
Active AP...
Enable: success
netifapi_netif_set_addr: success
netifapi_dhcp_start: success
True
```

#### 连接网络

&emsp;&emsp;`wlan.connect('ssid'[,'password'[,security=]])`

&emsp;&emsp;函数说明:连接到无线网络(仅在STA接口上进行扫描),必须先激活站点网络才能连接

&emsp;&emsp;`ssid`:WiFi名称

&emsp;&emsp;`password`:WiFi密码

&emsp;&emsp;`security`:WiFi安全类型

&emsp;&emsp;示例:

```python
>>> import network
>>> sta_wlan = network.WLAN(network.STA_IF)#创建一个热点模式的WLAN对象
>>> sta_wlan.active(True)#激活站点模式的WLAN对象
RegisterWifiEvent: Success
EnableWifi: Success
True
>>> sta_wlan.scan()#扫描可用的WIFI网络
OnWifiScanStateChanged: state = 0, size = 0
OnWifiScanStateChanged: state = 1, size = 12
WaitSacnResult:wait success[1]s
[('Noah-BlackWalnut', b'<|?W\x84h', -1, -4800, 2427), ('tingchechang', b'\x0c\xd8lLL\xb0', 2, -6600, 2467), ('sunking', b'\xacau\xe2\xa1\x80', 2, -6600, 2437), ('yzk5T', b'\xa6\x02\xb9\xb0\x90}', -1, -6800, 2437), ('GU', b'\x80\x8f\x1d9\x1c\xfa', 2, -6900, 2412), ('ZYKJ_202012', b'dn\x97\xdf\xce\xfe', 2, -7100, 2462), ('zykj_28', b'\xd4\xf7\x86\x82P\xdd', -1, -7200, 2472), ('zykj2020', b'`\x14f\xbb\x90(', -1, -7900, 2442), ('ChinaNet-QufH', b'\xa8\xad=\xb1\xdax', -1, -8100, 2462), ('zykj', b'l\xe8s\xafq\xcc', 2, -8100, 2437), ('Redmi', b'\x8a7!&\x83\x85', 0, -3200, 2412), ('', b'\x9aP\xe9(Q\xae', 0, -8700, 2437)]
>>> sta_wlan.connect('sunking','sunking100',security=network.AUTH_PSK)
Connecting............OnWifiConnectionChanged: state = 1, info = 
bssid: B8:F8:83:07:A1:F0, rssi: 0, connState: 0, reason: 0, ssid: sunking

connect: success
netifapi_dhcp_start: success
netifapi_netif_common: success
True
```

#### 断开网络连接

&emsp;&emsp;`wlan.disconnect()`

&emsp;&emsp;函数说明:断开与当前连接的无线网络的连接,没有网络连接时会报错

​		示例:

```python
>>> import network
>>> sta_wlan = network.WLAN(network.STA_IF)#创建一个站点模式的WLAN对象
>>> sta_wlan.active(True)#激活网络
RegisterWifiEvent: Success
EnableWifi: Success
True
>>>sta_wlan.disconnect()#断开网络连接
netifapi_dhcp_stop: success
Disconnect: Success
RemoveDevice: Success
```

## 示例

&emsp;&emsp;对waffle nano创建Wifi热点。

```python
import network
ap_wlan = network.WLAN(network.AP_IF)
ap_wlan.active(False)
ap.config('WIFI-AP')
ap_wlan.active(True)
```

&emsp;&emsp;第一行导入`machine`模块的类`network`

&emsp;&emsp;第二行创建热点

&emsp;&emsp;第三行停用创建的热点

&emsp;&emsp;第四行修改热点名字

&emsp;&emsp;第五行重新激活该热点,此时可在WIFI列表中通过热点名找到创建的热点