ESP8266 基础篇:国家码使用
2017-11-30 11:01
2016 查看
一:简介
WiFi 设备工作在 2.4G 频段或 5G 频段,由于无线信号的开放性,不同的无线设备间会存在相互干扰。因此,不同国家对 WiFi 设备都有一定的要求和限制。主要体现在频谱、射频功率、安全性及其他方面。因此,在不同国家销售的 WiFi 设备应遵循该国家或地区的要求。在 ESP8266 和 ESP32 中,国家码主要就是针对不同国家可使用的频率不同而设计的。因为 WiFi 协议中将可发射的频率划分为不同的信道,所以也可以理解为国家码就是针对不同国家的信道要求而设计。因为 ESP8266 和 ESP32 目前只支持 2.4G 频段,所以本文就以 2.4G 频段中的信道为例来说明。国家码
下图是主要国家对于 2.4G 频段的信道要求,不同的国家对信道要求不同,如中国和欧洲支持的信道为 1-13(所以欧洲的路由器在中国是可以直接使用的),而北美只支持 1-11,日本则支持 1-14。因为国内支持的信道为 1-13,所以在使用国内的路由器时,WiFi 信道只能在 1-13 之间任选;
美国所支持的信道是 1-11,那么路由器中只可以使用 1-11,12 和 13 即为非法信道。如果将国内的路由器带到美国,并设置信道为 12,那么用美国的手机将扫描不到这个路由器的信息。所以如果不能自由转换国家码,必然会对售往不同国家的 WiFi 设备产生影响。
二:国家码接口
在 ESP32 中,国家码相关的接口主要包含设置国家码和获取国家码/** * @brief configure country info * * @attention 1. The default country is {.cc="CN", .schan=1, .nchan=13, policy=WIFI_COUNTRY_POLICY_AUTO} * * @param wifi_country_t *country: the configured country info * * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init * - ESP_ERR_WIFI_ARG: invalid argument */ esp_err_t esp_wifi_set_country(const wifi_country_t *country); /** * @brief get the current country info * * @param country country info * * @return * - ESP_OK: succeed * - ESP_ERR_WIFI_NOT_INIT: WiFi is not initialized by esp_wifi_init * - ESP_ERR_WIFI_ARG: invalid argument */ esp_err_t esp_wifi_get_country(wifi_country_t *country);
其中 esp_wifi_set_country (ESP8266 中称为 wifi_set_country) 用来设置国家码信息,esp_wifi_get_country (ESP8266 中称为 wifi_get_country) 用来获取当前的国家码信息。国家码参数信息 wifi_country_t 主要由以下几部分组成:
typedef struct { char cc[3]; /**< country code string */ uint8_t schan; /**< start channel */ uint8_t nchan; /**< total channel number */ uint8_t policy; /**< country policy */ } wifi_country_t;
其中 cc 为国家代码,如中国的国家代码为 CN,美国为 US;schan 为起始信道,nchan 为总信道数,如美国的起始信道为 1,信道数为 11,policy 为国家码选项,目前只支持如下两种:
typedef enum { WIFI_COUNTRY_POLICY_AUTO, /**< Country policy is auto, use the country info of AP to which the station is connected */ WIFI_COUNTRY_POLICY_MANUAL, /**< Country policy is manual, always use the configured country info */ } WIFI_COUNTRY_POLICY;
如果选择 auto 那么将会使用所连接 AP 的国家码信息,而 manual 表示由用户配置信息决定。
三:国家码使用
3.1 STATION 模式
当国家码 policy 为 auto 时,STA 的国家码信息由所连接的 AP 决定,如果 AP 中不含国家码信息,则使用默认值 {“CN”, 1, 13}。比如国家码设置为 {“US”, 1, 11},连接中国的路由器后,其国家码会被自动更新为 {“CN”, 1, 13}。
当国家码 policy 为 manual 时,STA 的国家码信息由 esp_wifi_set_country 中配置信息决定,
仅扫描国家码规定的信道。
3.2 SOFTAP 模式
在 AP 模式下,国家码 policy 不会生效,可以省略,如果配置了国家为 {“US”, 1, 11},则AP可配置的信道范围为 1~11。默认的国家码信息为 {“CN”, 1, 13}。需要注意的是配置的国家码信息会对 AP 参数的配置有影响,例如在 ESP32 中,esp_wifi_set_config 能够配置的信道范围就是由配置的国家码决定的。
3.3 AP + STATION 模式
当国家码 policy 为 auto 时,AP 的国家码信息跟随 STA 所连接的外部 AP 的国家码信息,此时AP 会动态更新 beacon/probe response 中的国家码信息。当 STA 连接的外部 AP 的国家码信息
与 AP 配置的国家码信息不同时,会打出一条 Warning 信息,如果 STA 与连接的 AP 断开连接,
国家码依然使用最近连接过的 AP 的国家码。
当国家码 policy 为 manual 时,AP 的国家码信息由配置所决定
四:运行分析
本文以ESP8266 RTOS 的 AP + STATION 模式下的 一个 ConnectAP 的 Demo (Conn_AP_DEMO)来分析国家码的具体实现。根据这个 demo,主要修改代码如下:
void wifi_handle_event_cb(System_Event_t *evt) { switch (evt->event_id) { case EVENT_STAMODE_CONNECTED: printf("connect to ssid %s, channel %d\n", evt->event_info.connected.ssid, evt->event_info.connected.channel); wifi_country_t config_country; wifi_get_country(&config_country); printf("Country info:CC:%c%c,SC:%d,NC:%d\n",config_country.cc[0],config_country.cc[1],config_country.schan,config_country.nchan); break; case EVENT_STAMODE_DISCONNECTED: printf("disconnect from ssid %s, reason %d\n", evt->event_info.disconnected.ssid, evt->event_info.disconnected.reason); break; ...... } } void conn_ap_init(void) { // wifi_country_t config_country = {.cc="US", .schan=1, .nchan=11, WIFI_COUNTRY_POLICY_AUTO}; wifi_country_t config_country = {.cc="US", .schan=1, .nchan=11, WIFI_COUNTRY_POLICY_MANUAL}; wifi_set_country(&config_country); wifi_set_opmode(STATIONAP_MODE); struct station_config config; memset(&config, 0, sizeof(config)); //set value of config from address of &config to width of size to be value '0' sprintf(config.ssid, DEMO_AP_SSID); sprintf(config.password, DEMO_AP_PASSWORD); wifi_station_set_config(&config); wifi_set_event_handler_cb(wifi_handle_event_cb); wifi_station_connect(); }
代码中设置的国家码为美国,policy 为 manual,如果路由器的信道为 11,运行程序,程序可以正常连接到路由,并打印如下信息:
可以看到此时通过 wifi_get_country 获得的国家码为代码中设置的国家码。使用 OmniPeak 抓包,发现 ESP32 上 AP 的国家码信息也会设置为美国。
如果将路由器的信道更改为 12,此时重新运行程序,会发现无法连接到此路由器,串口会打印如下信息:
因为程序根据设置的国家码要求在信道 1-11 扫描,但路由器是在信道 12 上广播的,所以没有办法扫描到 SSID。
如果将国家码 policy 从 WIFI_COUNTRY_POLICY_MANUAL 设置为 WIFI_COUNTRY_POLICY_AUTO,重新运行程序,会发现即使路由器信道改为 12 依然可以连接上,在 wifi_get_country 中打印的信息为路由器中的国家码信息。
此时使用OmniPeek抓取空中包,发现 ESP32 上的 softap 回复的 Probe Rsp 包中的国家码信息已经变成路由器中的国家码信息。
相关文章推荐
- Struts2获取HTML表单元素与Struts表单标签的区别使用-基础篇
- 【Arduino】【ESP】使用Arduino(ESP8266版本)获取雅虎天气信息,并使用点阵显示......进行中
- 9. ESP8266使用esp-open-rtos的实践
- WPF Visifire使用 ---- 基础篇二
- 使用 MEAN 进行全栈开发基础篇——5、接着前面玩儿编辑
- Esp8266 使用 Arduino 开发(二)
- OpenCV基础篇之使用CMake管理工程
- OpenCV基础篇之使用CMake管理工程
- 任何国家都无法限制数字货币。为什么呢? 要想明白这个问题需要具备一点区块链的基础知识: 区块链使用的大致技术包括以下几种: a.点对点网络设计 b.加密技术应用 c.分布式算法的实现 d.数据存储技术 e.拜占庭算法 f.权益证明POW,POS,DPOS 原因一: 点对点网络设计 其中点对点的P2P网络是bittorent ,由于是点对点的网络,没有中心化,因此在全球分布式的网
- 02、老徐教你学C语言基础篇2——C语言摩拳擦掌齐上阵(环境篇)——简单工程的创建与使用
- Git使用基础篇
- linux教程:Git使用基础篇
- Git使用基础篇
- WIFI模块ESP8266的使用指南(客户端和服务器两种模式建立)
- WF4.0 基础篇 (二) Activity介绍及WriteLine Activity的使用
- 【OpenGL基础篇】——使用面向对象方法封装OpenGL函数(一)
- ESP8266的基本使用及透传编程
- 转载一个简单的lua展示【COCOS2DX-LUA 脚本开发之一】LUA语言基础在Cocos2dX游戏中使用Lua脚本进行游戏开发(基础篇)并介绍脚本在游戏中详细用途!
- Spark修炼之道(基础篇)——Linux大数据开发基础:第一节、Linux介绍、安装及使用初步
- 【ESP8266】使用ESP8266 NONOS SDK的JSON API