|
| 1 | +#include <string.h> |
| 2 | + |
| 3 | +#include "py/runtime.h" |
| 4 | + |
| 5 | +#include "freertos/FreeRTOS.h" |
| 6 | +#include "freertos/task.h" |
| 7 | +#include "freertos/event_groups.h" |
| 8 | + |
| 9 | +#include "esp_wifi.h" |
| 10 | +#include "esp_event.h" |
| 11 | +#include "esp_log.h" |
| 12 | +#include "esp_smartconfig.h" |
| 13 | + |
| 14 | +#include "mphalport.h" |
| 15 | +#include "modsmartconfig.h" |
| 16 | + |
| 17 | +static EventGroupHandle_t wifi_event_group; |
| 18 | + |
| 19 | +static bool smartconfig_process_done = false; |
| 20 | + |
| 21 | +/* info variables */ |
| 22 | +static uint8_t ssid[33] = {0}; |
| 23 | +static uint8_t bssid[6] = {0}; |
| 24 | +static uint8_t password[65] = {0}; |
| 25 | +static uint8_t rvd_data[33] = {0}; |
| 26 | +static int type = SC_TYPE_ESPTOUCH_AIRKISS; |
| 27 | + |
| 28 | +/* event_handler used for esp_event_handler_register() */ |
| 29 | +static void event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { |
| 30 | + if (event_base == WIFI_EVENT && |
| 31 | + event_id == WIFI_EVENT_STA_START) { |
| 32 | + xTaskCreate(smartconfig_task, "smartconfig_task", 4096, NULL, 3, NULL); |
| 33 | + } else if (event_base == WIFI_EVENT && |
| 34 | + event_id == WIFI_EVENT_STA_DISCONNECTED) { |
| 35 | + // wrong password or other situations may occurs this event |
| 36 | + xEventGroupSetBits(wifi_event_group, SMARTCONFIG_DONE_BIT); |
| 37 | + } else if (event_base == IP_EVENT && |
| 38 | + event_id == IP_EVENT_STA_GOT_IP) { |
| 39 | + xEventGroupSetBits(wifi_event_group, CONNECTED_BIT); |
| 40 | + } else if (event_base == SC_EVENT && |
| 41 | + event_id == SC_EVENT_SCAN_DONE) { |
| 42 | + ESP_LOGI(TAG, "Scan done"); |
| 43 | + } else if (event_base == SC_EVENT && |
| 44 | + event_id == SC_EVENT_GOT_SSID_PSWD) { |
| 45 | + smartconfig_event_got_ssid_pswd_t *evt = (smartconfig_event_got_ssid_pswd_t *)event_data; |
| 46 | + wifi_config_t wifi_config; |
| 47 | + |
| 48 | + bzero(&wifi_config, sizeof(wifi_config_t)); |
| 49 | + memcpy(wifi_config.sta.ssid, evt->ssid, sizeof(wifi_config.sta.ssid)); |
| 50 | + memcpy(wifi_config.sta.password, evt->password, sizeof(wifi_config.sta.password)); |
| 51 | + wifi_config.sta.bssid_set = evt->bssid_set; |
| 52 | + |
| 53 | + if (wifi_config.sta.bssid_set == true) { |
| 54 | + memcpy(wifi_config.sta.bssid, evt->bssid, sizeof(wifi_config.sta.bssid)); |
| 55 | + } |
| 56 | + |
| 57 | + memcpy(ssid, evt->ssid, sizeof(evt->ssid)); |
| 58 | + memcpy(bssid, evt->bssid, sizeof(evt->bssid)); |
| 59 | + memcpy(password, evt->password, sizeof(evt->password)); |
| 60 | + type = evt->type; |
| 61 | + |
| 62 | + if (evt->type == SC_TYPE_ESPTOUCH_V2) { |
| 63 | + check_esp_err(esp_smartconfig_get_rvd_data(rvd_data, sizeof(rvd_data))); |
| 64 | + } |
| 65 | + |
| 66 | + check_esp_err(esp_wifi_disconnect()); |
| 67 | + check_esp_err(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); |
| 68 | + |
| 69 | + ESP_LOGI(TAG, "Try to connect to ap"); |
| 70 | + |
| 71 | + esp_wifi_connect(); |
| 72 | + } else if (event_base == SC_EVENT && |
| 73 | + event_id == SC_EVENT_SEND_ACK_DONE) { |
| 74 | + xEventGroupSetBits(wifi_event_group, SMARTCONFIG_DONE_BIT); |
| 75 | + ESP_LOGI(TAG, "Send ack done"); |
| 76 | + } |
| 77 | +} |
| 78 | + |
| 79 | +/* task function used for xTaskCreate() */ |
| 80 | +static void smartconfig_task(void *param) { |
| 81 | + check_esp_err(esp_smartconfig_set_type(type)); |
| 82 | + smartconfig_start_config_t cfg = SMARTCONFIG_START_CONFIG_DEFAULT(); |
| 83 | + check_esp_err(esp_smartconfig_start(&cfg)); |
| 84 | + |
| 85 | + EventBits_t uxBits; |
| 86 | + |
| 87 | + while (1) { |
| 88 | + uxBits = xEventGroupWaitBits( |
| 89 | + wifi_event_group, |
| 90 | + CONNECTED_BIT | SMARTCONFIG_DONE_BIT, |
| 91 | + true, false, portMAX_DELAY |
| 92 | + ); |
| 93 | + |
| 94 | + if (uxBits & CONNECTED_BIT) { |
| 95 | + ESP_LOGI(TAG, "Connected to ap"); |
| 96 | + } |
| 97 | + |
| 98 | + if (uxBits & SMARTCONFIG_DONE_BIT) { |
| 99 | + ESP_LOGI(TAG, "Smartconfig done"); |
| 100 | + smartconfig_process_done = true; |
| 101 | + smartconfig_stop(); |
| 102 | + vTaskDelete(NULL); |
| 103 | + } |
| 104 | + } |
| 105 | +} |
| 106 | + |
| 107 | +/* |
| 108 | + * initialize info variables, |
| 109 | + * register event handlers and restart wifi |
| 110 | + */ |
| 111 | +static void smartconfig_init(void) { |
| 112 | + smartconfig_process_done = false; |
| 113 | + |
| 114 | + memset(ssid, 0, sizeof(ssid)); |
| 115 | + memset(bssid, 0, sizeof(bssid)); |
| 116 | + memset(password, 0, sizeof(password)); |
| 117 | + memset(rvd_data, 0, sizeof(rvd_data)); |
| 118 | + |
| 119 | + wifi_event_group = xEventGroupCreate(); |
| 120 | + |
| 121 | + esp_err_t err = esp_wifi_stop(); |
| 122 | + if (err == ESP_ERR_WIFI_NOT_INIT) { |
| 123 | + return; |
| 124 | + } |
| 125 | + check_esp_err(err); |
| 126 | + |
| 127 | + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); |
| 128 | + check_esp_err(esp_wifi_init(&cfg)); |
| 129 | + |
| 130 | + check_esp_err(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)); |
| 131 | + check_esp_err(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL)); |
| 132 | + check_esp_err(esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL)); |
| 133 | + |
| 134 | + check_esp_err(esp_wifi_set_mode(WIFI_MODE_STA)); |
| 135 | + check_esp_err(esp_wifi_start()); |
| 136 | +} |
| 137 | + |
| 138 | +/* |
| 139 | + * get/set smartconfig protocol type |
| 140 | + * |
| 141 | + * smartconfig.type([type]) |
| 142 | + */ |
| 143 | +STATIC mp_obj_t smartconfig_type(size_t n_args, const mp_obj_t *args) { |
| 144 | + if (n_args == 0 || args[0] == mp_const_none) { |
| 145 | + return mp_obj_new_int(type); |
| 146 | + } else { |
| 147 | + if (mp_obj_is_integer(args[0])) { |
| 148 | + type = mp_obj_get_int(args[0]); |
| 149 | + |
| 150 | + if (type > SC_TYPE_ESPTOUCH_V2 || type < SC_TYPE_ESPTOUCH) { |
| 151 | + type = SC_TYPE_ESPTOUCH_AIRKISS; |
| 152 | + } |
| 153 | + } else { |
| 154 | + mp_raise_ValueError(MP_ERROR_TEXT("invalid arguments")); |
| 155 | + } |
| 156 | + } |
| 157 | + |
| 158 | + return mp_const_none; |
| 159 | +} |
| 160 | +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(smartconfig_type_obj, 0, 1, smartconfig_type); |
| 161 | + |
| 162 | +STATIC mp_obj_t smartconfig_start(void) { |
| 163 | + smartconfig_stop(); |
| 164 | + smartconfig_init(); |
| 165 | + |
| 166 | + return mp_const_none; |
| 167 | +} |
| 168 | +STATIC MP_DEFINE_CONST_FUN_OBJ_0(smartconfig_start_obj, smartconfig_start); |
| 169 | + |
| 170 | +STATIC mp_obj_t smartconfig_stop(void) { |
| 171 | + esp_smartconfig_stop(); |
| 172 | + |
| 173 | + check_esp_err(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler)); |
| 174 | + check_esp_err(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler)); |
| 175 | + check_esp_err(esp_event_handler_unregister(SC_EVENT, ESP_EVENT_ANY_ID, &event_handler)); |
| 176 | + |
| 177 | + return mp_const_none; |
| 178 | +} |
| 179 | +STATIC MP_DEFINE_CONST_FUN_OBJ_0(smartconfig_stop_obj, smartconfig_stop); |
| 180 | + |
| 181 | +STATIC mp_obj_t smartconfig_done(void) { |
| 182 | + return mp_obj_new_bool(smartconfig_process_done); |
| 183 | +} |
| 184 | +STATIC MP_DEFINE_CONST_FUN_OBJ_0(smartconfig_done_obj, smartconfig_done); |
| 185 | + |
| 186 | +/* |
| 187 | + * get smartconfig info |
| 188 | + * |
| 189 | + * return: tuple(ssid, password, bssid, type[, rvd_data]) |
| 190 | + * rvd_data - EspTouch V2 reserved data |
| 191 | + */ |
| 192 | +STATIC mp_obj_t smartconfig_info(void) { |
| 193 | + mp_obj_t info[] = { |
| 194 | + mp_obj_new_str((const char *)ssid, strlen((const char *)ssid)), |
| 195 | + mp_obj_new_str((const char *)password, strlen((const char *)password)), |
| 196 | + mp_obj_new_bytes(bssid, sizeof(bssid)), |
| 197 | + mp_obj_new_int(type), |
| 198 | + mp_obj_new_bytes(rvd_data, strlen((const char *)rvd_data)) |
| 199 | + }; |
| 200 | + |
| 201 | + if (rvd_data[0] == 0x00) { |
| 202 | + return mp_obj_new_tuple(4, info); |
| 203 | + } |
| 204 | + |
| 205 | + return mp_obj_new_tuple(5, info); |
| 206 | +} |
| 207 | +STATIC MP_DEFINE_CONST_FUN_OBJ_0(smartconfig_info_obj, smartconfig_info); |
| 208 | + |
| 209 | +/* get ssid */ |
| 210 | +STATIC mp_obj_t smartconfig_ssid(void) { |
| 211 | + return mp_obj_new_str((const char *)ssid, strlen((const char *)ssid)); |
| 212 | +} |
| 213 | +STATIC MP_DEFINE_CONST_FUN_OBJ_0(smartconfig_ssid_obj, smartconfig_ssid); |
| 214 | + |
| 215 | +/* get password */ |
| 216 | +STATIC mp_obj_t smartconfig_password(void) { |
| 217 | + return mp_obj_new_str((const char *)password, strlen((const char *)password)); |
| 218 | +} |
| 219 | +STATIC MP_DEFINE_CONST_FUN_OBJ_0(smartconfig_password_obj, smartconfig_password); |
| 220 | + |
| 221 | +/* get bssid */ |
| 222 | +STATIC mp_obj_t smartconfig_bssid(void) { |
| 223 | + return mp_obj_new_bytes(bssid, sizeof(bssid)); |
| 224 | +} |
| 225 | +STATIC MP_DEFINE_CONST_FUN_OBJ_0(smartconfig_bssid_obj, smartconfig_bssid); |
| 226 | + |
| 227 | +/* get rvd_data */ |
| 228 | +STATIC mp_obj_t smartconfig_rvd_data(void) { |
| 229 | + return mp_obj_new_bytes(rvd_data, strlen((const char *)rvd_data)); |
| 230 | +} |
| 231 | +STATIC MP_DEFINE_CONST_FUN_OBJ_0(smartconfig_rvd_data_obj, smartconfig_rvd_data); |
| 232 | + |
| 233 | +STATIC const mp_rom_map_elem_t smartconfig_module_globals_table[] = { |
| 234 | + {MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_smartconfig)}, |
| 235 | + {MP_ROM_QSTR(MP_QSTR_type), MP_ROM_PTR(&smartconfig_type_obj)}, |
| 236 | + {MP_ROM_QSTR(MP_QSTR_start), MP_ROM_PTR(&smartconfig_start_obj)}, |
| 237 | + {MP_ROM_QSTR(MP_QSTR_stop), MP_ROM_PTR(&smartconfig_stop_obj)}, |
| 238 | + {MP_ROM_QSTR(MP_QSTR_done), MP_ROM_PTR(&smartconfig_done_obj)}, |
| 239 | + {MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&smartconfig_info_obj)}, |
| 240 | + {MP_ROM_QSTR(MP_QSTR_ssid), MP_ROM_PTR(&smartconfig_ssid_obj)}, |
| 241 | + {MP_ROM_QSTR(MP_QSTR_password), MP_ROM_PTR(&smartconfig_password_obj)}, |
| 242 | + {MP_ROM_QSTR(MP_QSTR_bssid), MP_ROM_PTR(&smartconfig_bssid_obj)}, |
| 243 | + {MP_ROM_QSTR(MP_QSTR_rvd_data), MP_ROM_PTR(&smartconfig_rvd_data_obj)}, |
| 244 | + {MP_ROM_QSTR(MP_QSTR_TYPE_ESPTOUCH), MP_ROM_INT(SC_TYPE_ESPTOUCH)}, |
| 245 | + {MP_ROM_QSTR(MP_QSTR_TYPE_AIRKISS), MP_ROM_INT(SC_TYPE_AIRKISS)}, |
| 246 | + {MP_ROM_QSTR(MP_QSTR_TYPE_ESPTOUCH_AIRKISS), MP_ROM_INT(SC_TYPE_ESPTOUCH_AIRKISS)}, |
| 247 | + {MP_ROM_QSTR(MP_QSTR_TYPE_ESPTOUCH_V2), MP_ROM_INT(SC_TYPE_ESPTOUCH_V2)}, |
| 248 | +}; |
| 249 | +STATIC MP_DEFINE_CONST_DICT(smartconfig_module_globals, smartconfig_module_globals_table); |
| 250 | + |
| 251 | +const mp_obj_module_t smartconfig_user_cmodule = { |
| 252 | + .base = {&mp_type_module}, |
| 253 | + .globals = (mp_obj_dict_t *)&smartconfig_module_globals, |
| 254 | +}; |
| 255 | + |
| 256 | +MP_REGISTER_MODULE(MP_QSTR_smartconfig, smartconfig_user_cmodule); |
0 commit comments