├── README.md ├── network_80211.h ├── smartlink.c └── user_main.c /README.md: -------------------------------------------------------------------------------- 1 | esp8266-smartlink 2 | ======= 3 | 4 | Instruction in English is followed by Chinese. 5 | 6 | ### 名词定义 7 | *Smartlink* 用于在物理网设备没有外部输入端时,使用手机对其进行配置的一种通用的说法。 8 | 9 | ### Definition of Smartlink 10 | *Smartlink* is a generic phrase when you configure your IoT devices by mobile phone, PC etc. instead of physical external devices. 11 | 12 | ### 使用方法 13 | 在需要使用 `smartlink` 的地方调用 14 | 15 | ```c 16 | smartlink_init(callback_func, callback_func_args, callback_failed_func, max_retry); 17 | ``` 18 | 19 | **手机端**: 设置完成后会调用 `(*callback_func)(callback_func_args)`,连接失败则会调用 `(*callback_failed_func)(callback_func_args)` 20 | 使用手机手动添加一个Wi-Fi网络,ssid为 ssidpassword,确定的几乎一瞬间 8266 就会收到并且开始配置。 21 | 22 | **SDK 版本**: 0.9.4 by Espressif 23 | 24 | ### Usage 25 | Call `smartlink_init(callback_func, callback_func_args, callback_failed_func, max_retry);` when you want to use Smarklink to configure. 26 | 27 | `callback_func`: callback function when connect target successfully. 28 | `callback_func_args`: arguments of success callback function. 29 | `callback_failed_func`: callback function when fail to connect target. 30 | `max_retry`: maximiun number of retry. 31 | 32 | **Mobile**: Add a ssid named `ssidpassword` manually, 8266 will receive this request almost immediately and finish configuration. 33 | 34 | **SDK Version**: 0.9.4 by Espressif 35 | 36 | ### 原理 37 | `Probe Request` 包的 `tagged parameter` 字段是不加密的,这个字段中的 `ssid` 可以每次最大传送 32 字节的数据。 38 | 39 | ### Principle 40 | `tagged parameter` in `Probe Request` packet is not encrypted, we can reuse this area to send data to our IoT devices. 41 | 42 | ### 协议 43 | The MIT License (MIT) 44 | 45 | Copyright (c) 2014 latyas 46 | 47 | Permission is hereby granted, free of charge, to any person obtaining a copy 48 | of this software and associated documentation files (the "Software"), to deal 49 | in the Software without restriction, including without limitation the rights 50 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 51 | copies of the Software, and to permit persons to whom the Software is 52 | furnished to do so, subject to the following conditions: 53 | 54 | The above copyright notice and this permission notice shall be included in 55 | all copies or substantial portions of the Software. 56 | 57 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 58 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 59 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 60 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 61 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 62 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 63 | THE SOFTWARE. 64 | 65 | 66 | ### License 67 | See above. 68 | 69 | ### Reference 70 | [Cisco Support Forums](https://supportforums.cisco.com/document/52391/80211-frames-starter-guide-learn-wireless-sniffer-traces) 71 | -------------------------------------------------------------------------------- /network_80211.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ly0/esp8266-smartlink/afb22864b60271d8054891a35c7f33c1fe98eada/network_80211.h -------------------------------------------------------------------------------- /smartlink.c: -------------------------------------------------------------------------------- 1 | #include "c_types.h" 2 | #include "osapi.h" 3 | #include "network_80211.h" 4 | #include "user_interface.h" 5 | 6 | #define SMARTLK_TOKEN "" 7 | #define SMARTLK_TOKEN_LEN (strlen(SMARTLK_TOKEN)) 8 | 9 | void smartlink_wifi_promiscuous_rx(uint8_t*, uint16); 10 | void smartlink_received(char*, char*); 11 | void delay_ms(uint16); 12 | void delay_s(uint16); 13 | 14 | void (*smartlink_received_cb)(void*) = NULL; 15 | void *smartlink_received_cb_args = NULL; 16 | void (*smartlink_failed_cb)() = NULL; 17 | 18 | uint8_t max_wait = 5; 19 | 20 | void delay_s(uint16 ss) 21 | { 22 | uint16 i; 23 | for(i = 0; i < ss; i++) 24 | { 25 | delay_ms(1000); 26 | } 27 | } 28 | void delay_ms(uint16 sms) 29 | { 30 | uint16 i; 31 | for(i = 0; i < sms; i++) 32 | { 33 | os_delay_us(1000); 34 | } 35 | } 36 | void ICACHE_FLASH_ATTR 37 | smartlink_init(void* cb, void* args, void* fail, uint8_t max) 38 | { 39 | os_printf("\n\n"); 40 | os_printf("[*] reset wifi config \n"); 41 | { 42 | wifi_station_disconnect(); 43 | wifi_station_set_config(NULL); 44 | } 45 | 46 | os_printf("[*] set opmode=0x01\n"); 47 | wifi_set_opmode(0x01); 48 | 49 | os_printf("[*] set smartlink_received callback function\n"); 50 | smartlink_received_cb = cb; 51 | smartlink_received_cb_args = args; 52 | smartlink_failed_cb = fail; 53 | max_wait = max; 54 | 55 | os_printf("[*] enable wifi promiscuous\n"); 56 | wifi_promiscuous_enable(1); 57 | wifi_set_promiscuous_rx_cb(smartlink_wifi_promiscuous_rx); 58 | } 59 | 60 | void ICACHE_FLASH_ATTR 61 | smartlink_wifi_promiscuous_rx(uint8_t *buf, uint16 len) 62 | { 63 | 64 | uint16 i; 65 | uint8_t type; 66 | 67 | // os_printf("smartlink_wifi_promiscuous_rx -----\n"); 68 | lpframectrl_80211 framectrl; 69 | struct router_info *info = NULL; 70 | if (len < 64) { 71 | return; 72 | } 73 | struct sniffer_buf *sniffer = (struct sniffer_buf*)buf; 74 | buf +=sizeof(struct RxControl); 75 | struct probe_request_80211 *probe_buf = (struct probe_request_80211*)buf; 76 | if (FRAME_TYPE_MANAGEMENT == probe_buf->framectrl.Type) { 77 | /* Management frame */ 78 | if (FRAME_SUBTYPE_PROBE_REQUEST == probe_buf->framectrl.Subtype) { 79 | 80 | /* Probe Request */ 81 | ptagged_parameter tag = (ptagged_parameter)(buf + sizeof(probe_request)); 82 | if (tag->tag_length != 0) 83 | { 84 | uint8_t ssid_buff[32]; 85 | os_memset(ssid_buff, 0, 32); 86 | os_memcpy(ssid_buff, (uint8_t *)tag + 2, tag->tag_length); 87 | char *pos = (char *)os_strstr(ssid_buff, SMARTLK_TOKEN); 88 | if (pos != NULL) 89 | { 90 | uint8_t ssid[40]; 91 | uint8_t password[40]; 92 | os_memset(ssid, 0, 32); 93 | os_memset(password, 0, 32); 94 | /* ssid */ 95 | os_memcpy(ssid, ssid_buff, pos - (char *)ssid_buff); 96 | /* password */ 97 | os_memcpy(password, pos + SMARTLK_TOKEN_LEN, tag->tag_length - SMARTLK_TOKEN_LEN - strlen(ssid)); 98 | smartlink_received(ssid, password); 99 | } 100 | } 101 | } 102 | } 103 | 104 | } 105 | void ICACHE_FLASH_ATTR 106 | smartlink_received(char* ssid, char* password) 107 | { 108 | os_printf("[*] received SSID:%s PASSWORD:%s\n", ssid, password); 109 | //wifi_promiscuous_enable(0); 110 | os_printf("[*] change mode: STATION \n"); 111 | wifi_set_opmode(0x01); 112 | { 113 | struct station_config config; 114 | os_strcpy(config.ssid, ssid); 115 | os_strcpy(config.password, password); 116 | wifi_station_set_config(&config); 117 | } 118 | system_restart(); 119 | #if 0 120 | os_printf("[*] connecting to %s ... \n", ssid); 121 | wifi_station_connect(); 122 | 123 | os_printf("[*] check connection to %s ... \n", ssid); 124 | { 125 | uint8_t status; 126 | uint8_t retry; 127 | for(retry = 0; retry < max_wait; ++retry) 128 | { 129 | status = wifi_station_get_connect_status(); 130 | if (STATION_IDLE == status || STATION_GOT_IP == status) 131 | { 132 | os_printf("[*] connected to %s", ssid); 133 | if (smartlink_received_cb) 134 | { 135 | (*smartlink_received_cb)(smartlink_received_cb_args); 136 | } 137 | } else { 138 | os_printf("[*] probing AP:%s\n", ssid); 139 | //vTaskDelay(1000 / portTICK_RATE_MS); 140 | } 141 | } 142 | 143 | } 144 | 145 | if (smartlink_failed_cb) 146 | { 147 | (*smartlink_failed_cb)(); 148 | } 149 | #endif 150 | } 151 | -------------------------------------------------------------------------------- /user_main.c: -------------------------------------------------------------------------------- 1 | #include "ets_sys.h" 2 | #include "osapi.h" 3 | #include "mem.h" 4 | #include "user_interface.h" 5 | 6 | 7 | void smartlink_success(void *args) 8 | { 9 | os_printf("smartlink_success"); 10 | } 11 | void smartlink_failed(void *args) 12 | { 13 | os_printf("smartlink_failed"); 14 | } 15 | SLIST_HEAD(router_info_head, router_info) router_list; 16 | 17 | void ICACHE_FLASH_ATTR 18 | test(void* args) 19 | { 20 | os_printf("Hi, this is a callback function!"); 21 | } 22 | //Init function 23 | void ICACHE_FLASH_ATTR 24 | user_init() 25 | { 26 | //uart_init(115200, 115200); 27 | smartlink_init(NULL, NULL, smartlink_failed, 5); 28 | } 29 | 30 | --------------------------------------------------------------------------------