From e2ada487f34a9fcb94dd240543edbe24cb998ab5 Mon Sep 17 00:00:00 2001 From: Robert Foss Date: Wed, 2 Sep 2015 08:41:27 -0400 Subject: [PATCH 01/11] Added ENDUSER_SETUP module. The module will start a SoftAP, DNS, HTTP server acting as a captive portal. The portal will have the SSID SetupGadget and will serve a website where credentials for the end users WLAN can be submitted. Once valid credentials have been submitted and used to connect to the local WLAN this module will stop. This module requires USE_DNS to enabled in dhcpserver.h --- app/include/user_modules.h | 1 + app/modules/enduser_setup.c | 834 ++++++++++++++++++++++++++++++++++++ app/modules/modules.h | 9 + 3 files changed, 844 insertions(+) create mode 100644 app/modules/enduser_setup.c diff --git a/app/include/user_modules.h b/app/include/user_modules.h index 688c7bcd..cfbb94f4 100644 --- a/app/include/user_modules.h +++ b/app/include/user_modules.h @@ -28,6 +28,7 @@ #define LUA_USE_MODULES_BIT #define LUA_USE_MODULES_MQTT #define LUA_USE_MODULES_COAP +//#define LUA_USE_MODULES_ENDUSER_SETUP // USE_DNS in dhcpserver.h needs to be enabled for this module to work. #define LUA_USE_MODULES_U8G // #define LUA_USE_MODULES_WS2801 #define LUA_USE_MODULES_WS2812 diff --git a/app/modules/enduser_setup.c b/app/modules/enduser_setup.c new file mode 100644 index 00000000..dfd05c4c --- /dev/null +++ b/app/modules/enduser_setup.c @@ -0,0 +1,834 @@ +#include "lualib.h" +#include "lauxlib.h" +#include "platform.h" +#include "auxmods.h" +#include "lrotable.h" +#include "c_stdlib.h" +#include "c_string.h" +#include "user_interface.h" +#include "espconn.h" +#include "flash_fs.h" + +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) + +#define PRINT_FUNC_ENABLE 0 +#if PRINT_FUNC_ENABLE +#define PRINT_FUNC c_printf +#else +#define PRINT_FUNC +#endif + +#define PRINT_DEBUG_ENABLE 0 +#if PRINT_DEBUG_ENABLE +#define PRINT_DEBUG c_printf +#else +#define PRINT_DEBUG +#endif + +/** + * DNS Response Packet: + * + * |DNS ID - 16 bits| + * |dns_header| + * |QNAME| + * |dns_body| + * |ip - 32 bits| + * + * DNS Header Part | FLAGS | | Q COUNT | | A CNT | |AUTH CNT| | ADD CNT| */ +static const char RAM_CONST_ATTR dns_header[] = { 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 }; +/* DNS Query Part | Q TYPE | | Q CLASS| */ +static const char RAM_CONST_ATTR dns_body[] = { 0x00, 0x01, 0x00, 0x01, +/* DNS Answer Part |LBL OFFS| | TYPE | | CLASS | | TTL | | RD LEN | */ + 0xC0, 0x0C, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04 }; + +static const char RAM_CONST_ATTR http_html_filename[] = "index.html"; +static const char RAM_CONST_ATTR http_header_200[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"; +static const char RAM_CONST_ATTR http_header_404[] = "HTTP/1.1 404 Not Found\r\n"; + +static const char RAM_CONST_ATTR http_html_backup[] = "Connect gadget to you WiFi

WiFi Login

Connect gadget to your WiFi

"; + +static struct espconn *espconn_dns_udp; +static struct espconn *espconn_http_tcp; +typedef struct http_payload_t { + char *data; + uint32_t len; +} http_payload_t; +static http_payload_t http_payload; +static os_timer_t check_station_timer; + +static int ICACHE_FLASH_ATTR enduser_setup_start(lua_State* L); +static int ICACHE_FLASH_ATTR enduser_setup_stop(lua_State* L); +static void ICACHE_FLASH_ATTR enduser_setup_station_start(void); +static void ICACHE_FLASH_ATTR enduser_setup_ap_start(void); +static void ICACHE_FLASH_ATTR enduser_setup_ap_stop(void); +static void ICACHE_RAM_ATTR enduser_setup_check_station(void); + + +static void ICACHE_RAM_ATTR enduser_setup_check_station_start(void) +{ + PRINT_FUNC("enduser_setup_check_station_start\n"); + + os_timer_setfn(&check_station_timer, enduser_setup_check_station, NULL); + os_timer_arm(&check_station_timer, 1*1000, TRUE); +} + + +static void ICACHE_RAM_ATTR enduser_setup_check_station_stop(void) +{ + PRINT_FUNC("enduser_setup_check_station_stop\n"); + + os_timer_disarm(&check_station_timer); +} + + +/** + * Check Station + * + * Check that we've successfully entered station mode. + */ +static void ICACHE_RAM_ATTR enduser_setup_check_station(void) +{ + struct ip_info ip; + c_memset(&ip, 0, sizeof(struct ip_info)); + + wifi_get_ip_info(STATION_IF, &ip); + + int i; + char has_ip = 0; + for (i = 0; i < sizeof(struct ip_info); ++i) + { + has_ip |= ((char *) &ip)[i]; + } + + if (has_ip == 0) + { + return; + } + + struct station_config cnf; + wifi_station_get_config(&cnf); + + uint8_t *ip_byte = (uint8_t *) &(ip.ip); + c_printf("Connected to \"%s\" as %u.%u.%u.%u\n", cnf.ssid, IP2STR(&ip)); + enduser_setup_stop(NULL); +} + + +/** + * Search String + * + * Search string for first occurance of any char in srch_str. + * + * @return -1 iff no occurance of char was found. + */ +static int ICACHE_RAM_ATTR enduser_setup_srch_str(const char *str, const char *srch_str) +{ + int srch_str_len = c_strlen(srch_str); + int first_hit = INT_MAX; + + int i; + for (i = 0; i < srch_str_len; ++i) + { + char *char_ptr = strchr(str, srch_str[i]); + if (char_ptr == NULL) + { + continue; + } + int char_idx = char_ptr - str; + first_hit = MIN(first_hit, char_idx); + } + if (first_hit == INT_MAX) + { + return -1; + } + return first_hit; +} + + +static void ICACHE_FLASH_ATTR enduser_setup_http_free(void) +{ + http_payload.len = 0; + c_free(http_payload.data); + http_payload.data = NULL; + + if (espconn_http_tcp != NULL) + { + if (espconn_http_tcp->proto.tcp != NULL) + { + c_free(espconn_http_tcp->proto.tcp); + } + c_free(espconn_http_tcp); + espconn_http_tcp = NULL; + } +} + + +/** + * Load HTTP Payload + * + * @return - 0 iff payload loaded successfully + * 1 iff backup html was loaded + * 2 iff out of memory + */ +static int ICACHE_FLASH_ATTR enduser_setup_http_load_payload(void) +{ + PRINT_FUNC("enduser_setup_http_load_payload\n"); + + int f = fs_open(http_html_filename, fs_mode2flag("r")); + int err = fs_seek(f, 0, FS_SEEK_END); + int file_len = (int) fs_tell(f); + int err2 = fs_seek(f, 0, FS_SEEK_SET); + + if (f == 0 || err == -1 || err2 == -1) + { + c_printf("enduser_setup_http_load_payload unable to load file \"%s\", loading backup HTML.\n", http_html_filename); + + int payload_len = sizeof(http_header_200) + sizeof(http_html_backup); + http_payload.len = payload_len; + http_payload.data = (char *) c_malloc(payload_len); + if (http_payload.data == NULL) + { + return 2; + } + + int offset = 0; + c_memcpy(&(http_payload.data[offset]), &(http_header_200), sizeof(http_header_200)); + offset += sizeof(http_header_200); + c_memcpy(&(http_payload.data[offset]), &(http_html_backup), sizeof(http_html_backup)); + + return 1; + } + + int payload_len = sizeof(http_header_200) + file_len; + http_payload.len = payload_len; + http_payload.data = (char *) c_malloc(payload_len); + if (http_payload.data == NULL) + { + return 2; + } + + int offset = 0; + c_memcpy(&(http_payload.data[offset]), &(http_header_200), sizeof(http_header_200)); + offset += sizeof(http_header_200); + fs_read(f, &(http_payload.data[offset]), file_len); + + return 0; +} + + +/** + * De-escape URL data + * + * Parse escaped and form encoded data of request. + */ +static void ICACHE_RAM_ATTR enduser_setup_http_urldecode(char *dst, const char *src, int src_len) +{ + char a, b; + int i; + for (i = 0; i < src_len && *src; ++i) + { + if ((*src == '%') && ((a = src[1]) && (b = src[2])) && (isxdigit(a) && isxdigit(b))) + { + if (a >= 'a') + { + a -= 'a'-'A'; + } + if (a >= 'A') + { + a -= ('A' - 10); + } + else + { + a -= '0'; + } + if (b >= 'a') + { + b -= 'a'-'A'; + } + if (b >= 'A') + { + b -= ('A' - 10); + } + else + { + b -= '0'; + } + *dst++ = 16 * a + b; + src += 3; + i += 2; + } else { + char c = *src++; + if (c == '+') + { + c = ' '; + } + *dst++ = c; + } + } + *dst++ = '\0'; +} + + +/** + * Handle HTTP Credentials + * + * @return - return 0 iff credentials are found and handled successfully + * return 1 iff credentials aren't found + * return 2 iff an error occured + */ +static int ICACHE_RAM_ATTR enduser_setup_http_handle_credentials(char *data, unsigned short data_len) +{ + PRINT_FUNC("enduser_setup_http_handle_credentials\n"); + + char *name_str = (char *) ((uint32_t)strstr(&(data[5]), "?wifi_ssid=") + (uint32_t)strstr(&(data[5]), "&wifi_ssid=")); + char *pwd_str = (char *) ((uint32_t)strstr(&(data[5]), "?wifi_password=") + (uint32_t)strstr(&(data[5]), "&wifi_password=")); + if (name_str == NULL || pwd_str == NULL) + { + return 1; + } + + int name_field_len = sizeof("?wifi_ssid=") - 1; + int pwd_field_len = sizeof("?wifi_password=") - 1; + char *name_str_start = name_str + name_field_len; + char *pwd_str_start = pwd_str + pwd_field_len; + + int name_str_len = enduser_setup_srch_str(name_str_start, "& "); + int pwd_str_len = enduser_setup_srch_str(pwd_str_start, "& "); + if (name_str_len == -1 || pwd_str_len == -1 || name_str_len > 31 || pwd_str_len > 63) + { + return 1; + } + + struct station_config cnf; + c_memset(&cnf, 0, sizeof(struct station_config)); + enduser_setup_http_urldecode(cnf.ssid, name_str_start, name_str_len); + enduser_setup_http_urldecode(cnf.password, pwd_str_start, pwd_str_len); + + int err = wifi_set_opmode(STATION_MODE | wifi_get_opmode()); + if (err == FALSE) + { + c_printf("enduser_setup_station_start failed. wifi_set_opmode failed.\n"); + wifi_set_opmode(~STATION_MODE & wifi_get_opmode()); + return 2; + } + err = wifi_station_set_config(&cnf); + if (err == FALSE) + { + c_printf("enduser_setup_station_start failed. wifi_station_set_config failed.\n"); + wifi_set_opmode(~STATION_MODE & wifi_get_opmode()); + return 2; + } + err = wifi_station_disconnect(); + if (err == FALSE) + { + c_printf("enduser_setup_station_start failed. wifi_station_disconnect failed.\n"); + } + err = wifi_station_connect(); + if (err == FALSE) + { + c_printf("enduser_setup_station_start failed. wifi_station_connect failed.\n"); + } + + c_printf("\n"); + c_printf("WiFi Credentials Stored\n"); + c_printf("-----------------------\n"); + c_printf("name: \"%s\"\n", cnf.ssid); + c_printf("pass: \"%s\"\n", cnf.password); + c_printf("bssid_set: %u\n", cnf.bssid_set); + c_printf("bssid: \"%s\"\n", cnf.bssid); + c_printf("-----------------------\n\n"); + + return 0; +} + + +/** + * Serve HTML + * + * @return - return 0 iff html was served successfully + */ +static int ICACHE_RAM_ATTR enduser_setup_http_serve_header(struct espconn *http_client, char *header, uint32_t header_len) +{ + PRINT_FUNC("enduser_setup_http_serve_404\n"); + + int8_t err = espconn_sent(http_client, header, header_len); + if (err == ESPCONN_MEM) + { + c_printf("enduser_setup_http_serve_header failed. espconn_send out of memory\n"); + return 1; + } + else if (err == ESPCONN_ARG) + { + c_printf("enduser_setup_http_serve_header failed. espconn_send can't find network transmission\n"); + return 1; + } + else if (err != 0) + { + c_printf("enduser_setup_http_serve_header failed. espconn_send failed\n"); + return 1; + } + + return 0; +} + + +/** + * Serve HTML + * + * @return - return 0 iff html was served successfully + */ +static int ICACHE_RAM_ATTR enduser_setup_http_serve_html(struct espconn *http_client) +{ + PRINT_FUNC("enduser_setup_http_serve_html\n"); + + if (http_payload.data == NULL) + { + enduser_setup_http_load_payload(); + } + + int8_t err = espconn_sent(http_client, http_payload.data, http_payload.len); + if (err == ESPCONN_MEM) + { + c_printf("enduser_setup_http_serve_html failed. espconn_send out of memory\n"); + return 1; + } + else if (err == ESPCONN_ARG) + { + c_printf("enduser_setup_http_serve_html failed. espconn_send can't find network transmission\n"); + return 1; + } + else if (err != 0) + { + c_printf("enduser_setup_http_serve_html failed. espconn_send failed\n"); + return 1; + } + + return 0; +} + + +/** + * Disconnect HTTP client + * + * End TCP connection and free up resources. + */ +static void ICACHE_RAM_ATTR enduser_setup_http_disconnect(struct espconn *espconn) +{ + PRINT_FUNC("enduser_setup_http_disconnect\n"); +//TODO: Construct and maintain os task queue(?) to be able to issue system_os_task with espconn_disconnect. +} + + +static void ICACHE_RAM_ATTR enduser_setup_http_recvcb(void *arg, char *data, unsigned short data_len) +{ + PRINT_FUNC("enduser_setup_http_recvcb\n"); + struct espconn *http_client = (struct espconn *) arg; + + if (c_strncmp(data, "GET ", 4) != 0) + { + enduser_setup_http_serve_header(http_client, (char *) http_header_404, sizeof(http_header_404)); + enduser_setup_http_disconnect(http_client); + return; + } + + int retval = enduser_setup_http_handle_credentials(data, data_len); + if (retval == 0) + { + enduser_setup_http_serve_header(http_client, (char *) http_header_200, sizeof(http_header_200)); + enduser_setup_http_disconnect(http_client); + return; + } + else if (retval == 2) + { + c_printf("enduser_setup_http_recvcb failed. Failed to handle wifi credentials.\n"); + return; + } + + if (retval != 1) + { + c_printf("enduser_setup_http_recvcb failed. Unknown error code #%u.\n", retval); + return; + } + + /* Reject requests that probably aren't relevant to free up resources. */ + if (c_strncmp(data, "GET / ", 6) != 0) + { + PRINT_DEBUG("enduser_setup_http_recvcb received too specific request.\n"); + enduser_setup_http_serve_header(http_client, (char *) http_header_404, sizeof(http_header_404)); + enduser_setup_http_disconnect(http_client); + return; + } + + retval = enduser_setup_http_serve_html(http_client); + if (retval != 0) + { + c_printf("enduser_setup_http_recvcb failed. Unable to send HTML.\n"); + enduser_setup_http_disconnect(http_client); + } +} + + +static void ICACHE_RAM_ATTR enduser_setup_http_connectcb(void *arg) +{ + PRINT_FUNC("enduser_setup_http_connectcb\n"); + + struct espconn *callback_espconn = (struct espconn *) arg; + + int8_t err = 0; + err |= espconn_regist_recvcb(callback_espconn, enduser_setup_http_recvcb); + + if (err != 0) + { + c_printf("enduser_setup_http_connectcb failed. Callback registration failed.\n"); + } +} + + +static void ICACHE_FLASH_ATTR enduser_setup_http_start(void) +{ + PRINT_FUNC("enduser_setup_http_start\n"); + + if (espconn_http_tcp != NULL) + { + c_printf("enduser_setup_http_start failed. Appears to already be started (espconn_http_tcp != NULL).\n"); + return; + } + espconn_http_tcp = (struct espconn *) c_malloc(sizeof(struct espconn)); + if (espconn_http_tcp == NULL) + { + c_printf("enduser_setup_http_start failed. Memory allocation failed (espconn_http_tcp == NULL).\n"); + return; + } + + esp_tcp *esp_tcp_data = (esp_tcp *) c_malloc(sizeof(esp_tcp)); + if (esp_tcp_data == NULL) + { + c_printf("enduser_setup_http_start failed. Memory allocation failed (esp_udp == NULL).\n"); + enduser_setup_http_free(); + return; + } + + c_memset(espconn_http_tcp, 0, sizeof(struct espconn)); + c_memset(esp_tcp_data, 0, sizeof(esp_tcp)); + espconn_http_tcp->proto.tcp = esp_tcp_data; + espconn_http_tcp->type = ESPCONN_TCP; + espconn_http_tcp->state = ESPCONN_NONE; + esp_tcp_data->local_port = 80; + + int8_t err; + err = espconn_regist_connectcb(espconn_http_tcp, enduser_setup_http_connectcb); + if (err != 0) + { + c_printf("enduser_setup_http_start failed. Couldn't add receive callback, ERRROR #%u.\n", err); + enduser_setup_http_free(); + return; + } + + err = espconn_accept(espconn_http_tcp); + if (err == ESPCONN_ISCONN) + { + c_printf("enduser_setup_http_start failed. Couldn't create connection, already listening for that connection.\n"); + enduser_setup_http_free(); + return; + } + else if (err == ESPCONN_MEM) + { + c_printf("enduser_setup_http_start failed. Couldn't create connection, out of memory.\n"); + enduser_setup_http_free(); + return; + } + else if (err == ESPCONN_ARG) + { + c_printf("enduser_setup_http_start failed. Can't find connection from espconn argument\n"); + enduser_setup_http_free(); + return; + } + else if (err != 0) + { + c_printf("enduser_setup_http_start failed. ERRROR #%u\n", err); + enduser_setup_http_free(); + return; + } + + err = espconn_regist_time(espconn_http_tcp, 2, 0); + if (err == ESPCONN_ARG) + { + c_printf("enduser_setup_http_start failed. Unable to set TCP timeout.\n"); + enduser_setup_http_free(); + return; + } + + err = enduser_setup_http_load_payload(); + if (err == 1) + { + PRINT_DEBUG("enduser_setup_http_start info. Loaded backup HTML.\n"); + } + else if (err == 2) + { + c_printf("enduser_setup_http_start failed. Unable to allocate memory for HTTP payload.\n"); + enduser_setup_http_free(); + return; + } +} + + +static void ICACHE_FLASH_ATTR enduser_setup_http_stop(void) +{ + PRINT_FUNC("enduser_setup_http_stop\n"); + + if (espconn_http_tcp == NULL) + { + c_printf("enduser_setup_http_stop failed. enduser_setup not enabled (espconn_dns_udp == NULL).\n"); + return; + } + + int8_t err = espconn_delete(espconn_http_tcp); + if (err == ESPCONN_ARG) + { + c_printf("enduser_setup_http_stop failed. espconn_delete returned ESPCONN_ARG. Can't find network transmission described.\n"); + } + else if (err != 0) + { + c_printf("enduser_setup_http_stop failed. espconn_delete returned ERROR #%u.\n", err); + } + + enduser_setup_http_free(); +} + +static void ICACHE_FLASH_ATTR enduser_setup_ap_stop(void) +{ + PRINT_FUNC("enduser_setup_station_stop\n"); + + wifi_set_opmode(~SOFTAP_MODE & wifi_get_opmode()); +} + + +static void ICACHE_FLASH_ATTR enduser_setup_ap_start(void) +{ + PRINT_FUNC("enduser_setup_ap_start\n"); + + struct softap_config cnf; + char ssid[] = "SetupGadget"; + c_memcpy(&(cnf.ssid), ssid, c_strlen(ssid)); + cnf.ssid_len = c_strlen(ssid); + cnf.channel = 1; + cnf.authmode = AUTH_OPEN; + cnf.ssid_hidden = 0; + cnf.max_connection = 5; + cnf.beacon_interval = 100; + wifi_softap_set_config(&cnf); + wifi_set_opmode(SOFTAP_MODE | wifi_get_opmode()); +} + + +static void ICACHE_RAM_ATTR enduser_setup_dns_recv_callback(void *arg, char *recv_data, unsigned short recv_len) +{ + PRINT_FUNC("enduser_setup_dns_recv_callback received query for %s\n", &(recv_data[12])); + + struct espconn *callback_espconn = arg; + struct ip_info ip_info; + + uint8_t if_mode = wifi_get_opmode(); + if ((if_mode & SOFTAP_MODE) == 0) + { + c_printf("enduser_setup_dns_recv_callback failed. Interface mode %d not supported.\n", if_mode); + return; + } + uint8_t if_index = (if_mode == STATION_MODE? STATION_IF : SOFTAP_IF); + if (wifi_get_ip_info(if_index , &ip_info) == false) + { + c_printf("enduser_setup_dns_recv_callback failed. Unable to get interface IP.\n"); + return; + } + + uint32_t qname_len = c_strlen(&(recv_data[12])) + 1; // \0=1byte + uint32_t dns_reply_static_len = (uint32_t) sizeof(dns_header) + (uint32_t) sizeof(dns_body) + 2 + 4; // dns_id=2bytes, ip=4bytes + uint32_t dns_reply_len = dns_reply_static_len + qname_len; + + char *dns_reply = (char *) c_malloc(dns_reply_len); + if (dns_reply == NULL) + { + c_printf("enduser_setup_dns_recv_callback failed. Failed to allocate memory.\n"); + return; + } + + uint32_t insert_byte = 0; + c_memcpy(&(dns_reply[insert_byte]), recv_data, 2); + insert_byte += 2; + c_memcpy(&(dns_reply[insert_byte]), dns_header, sizeof(dns_header)); + insert_byte += (uint32_t) sizeof(dns_header); + c_memcpy(&(dns_reply[insert_byte]), &(recv_data[12]), qname_len); + insert_byte += qname_len; + c_memcpy(&(dns_reply[insert_byte]), dns_body, sizeof(dns_body)); + insert_byte += (uint32_t) sizeof(dns_body); + c_memcpy(&(dns_reply[insert_byte]), &(ip_info.ip), 4); + + int8_t err; + err = espconn_sent(callback_espconn, dns_reply, dns_reply_len); + c_free(dns_reply); + if (err == ESPCONN_MEM) + { + c_printf("enduser_setup_dns_recv_callback failed. Failed to allocate memory for send.\n"); + return; + } + else if (err == ESPCONN_ARG) + { + c_printf("enduser_setup_dns_recv_callback failed. Can't execute transmission.\n"); + return; + } + else if (err != 0) + { + c_printf("enduser_setup_dns_recv_callback failed. espconn_send failed\n"); + return; + } +} + + +static void ICACHE_FLASH_ATTR enduser_setup_dns_free(void) +{ + PRINT_FUNC("enduser_setup_dns_free\n"); + + if (espconn_dns_udp != NULL) + { + if (espconn_dns_udp->proto.udp != NULL) + { + c_free(espconn_dns_udp->proto.udp); + } + c_free(espconn_dns_udp); + espconn_dns_udp = NULL; + } +} + + +static void ICACHE_FLASH_ATTR enduser_setup_dns_start(void) +{ + PRINT_FUNC("enduser_setup_dns_started\n"); + + if (espconn_dns_udp != NULL) + { + c_printf("enduser_setup_dns_start failed. Appears to already be started (espconn_dns_udp != NULL).\n"); + return; + } + espconn_dns_udp = (struct espconn *) c_malloc(sizeof(struct espconn)); + if (espconn_dns_udp == NULL) + { + c_printf("enduser_setup_dns_start failed. Memory allocation failed (espconn_dns_udp == NULL).\n"); + return; + } + + esp_udp *esp_udp_data = (esp_udp *) c_malloc(sizeof(esp_udp)); + if (esp_udp_data == NULL) + { + c_printf("enduser_setup_dns_start failed. Memory allocation failed (esp_udp == NULL).\n"); + enduser_setup_dns_free(); + return; + } + + c_memset(espconn_dns_udp, 0, sizeof(struct espconn)); + c_memset(esp_udp_data, 0, sizeof(esp_udp)); + espconn_dns_udp->proto.udp = esp_udp_data; + espconn_dns_udp->type = ESPCONN_UDP; + espconn_dns_udp->state = ESPCONN_NONE; + esp_udp_data->local_port = 53; + + int8_t err; + err = espconn_regist_recvcb(espconn_dns_udp, enduser_setup_dns_recv_callback); + if (err != 0) + { + c_printf("enduser_setup_dns_start failed. Couldn't add receive callback, ERRROR #%d.\n", err); + enduser_setup_dns_free(); + return; + } + + err = espconn_create(espconn_dns_udp); + if (err == ESPCONN_ISCONN) + { + c_printf("enduser_setup_dns_start failed. Couldn't create connection, already listening for that connection.\n"); + enduser_setup_dns_free(); + return; + } + else if (err == ESPCONN_MEM) + { + c_printf("enduser_setup_dns_start failed. Couldn't create connection, out of memory.\n"); + enduser_setup_dns_free(); + return; + } + else if (err != 0) + { + c_printf("enduser_setup_dns_start failed. Couldn't create connection, ERROR #%d.\n", err); + enduser_setup_dns_free(); + return; + } +} + + +static void ICACHE_FLASH_ATTR enduser_setup_dns_stop(void) +{ + PRINT_FUNC("enduser_setup_dns_stop\n"); + + if (espconn_dns_udp == NULL) + { + c_printf("enduser_setup_dns_stop failed. Hijacker not enabled (espconn_dns_udp == NULL).\n"); + return; + } + + int8_t err = espconn_delete(espconn_dns_udp); + if (err == ESPCONN_ARG) + { + c_printf("enduser_setup_http_stop failed. espconn_delete returned ESPCONN_ARG. Can't find network transmission described.\n"); + } + else if (err != 0) + { + c_printf("enduser_setup_http_stop failed. espconn_delete returned ERROR #%u.\n", err); + } + + enduser_setup_dns_free(); +} + + +static int ICACHE_FLASH_ATTR enduser_setup_start(lua_State* L) +{ + c_printf("\n"); + c_printf("-------------------\n"); + c_printf("enduser_setup_start\n"); + c_printf("-------------------\n\n"); + + enduser_setup_check_station_start(); + enduser_setup_ap_start(); + enduser_setup_dns_start(); + enduser_setup_http_start(); + + return 0; +} + + +static int ICACHE_FLASH_ATTR enduser_setup_stop(lua_State* L) +{ + c_printf("\n"); + c_printf("------------------\n"); + c_printf("enduser_setup_stop\n"); + c_printf("------------------\n\n"); + + enduser_setup_check_station_stop(); + enduser_setup_ap_stop(); + enduser_setup_dns_stop(); + enduser_setup_http_stop(); + + return 0; +} + + +#define MIN_OPT_LEVEL 2 +#include "lrodefs.h" +const LUA_REG_TYPE enduser_setup_map[] = +{ + { LSTRKEY( "start" ), LFUNCVAL( enduser_setup_start )}, + { LSTRKEY( "stop" ), LFUNCVAL( enduser_setup_stop )}, + { LNILKEY, LNILVAL} +}; + +LUALIB_API int luaopen_enduser_setup(lua_State *L) { + LREGISTER(L, "enduser_setup", enduser_setup_map); + return 1; +} + diff --git a/app/modules/modules.h b/app/modules/modules.h index 1bb26fb5..e3163d89 100644 --- a/app/modules/modules.h +++ b/app/modules/modules.h @@ -149,6 +149,14 @@ #define ROM_MODULES_WS2812 #endif +#if defined(LUA_USE_MODULES_ENDUSER_SETUP) +#define MODULES_ENDUSER_SETUP "enduser_setup" +#define ROM_MODULES_ENDUSER_SETUP \ + _ROM(MODULES_ENDUSER_SETUP, luaopen_enduser_setup, enduser_setup_map) +#else +#define ROM_MODULES_ENDUSER_SETUP +#endif + #if defined(LUA_USE_MODULES_CJSON) #define MODULES_CJSON "cjson" #define ROM_MODULES_CJSON \ @@ -230,6 +238,7 @@ ROM_MODULES_UART \ ROM_MODULES_OW \ ROM_MODULES_BIT \ + ROM_MODULES_ENDUSER_SETUP \ ROM_MODULES_WS2801 \ ROM_MODULES_WS2812 \ ROM_MODULES_CJSON \ From 0f883b1842e9d24ccb2345ec4fb19d000f76275c Mon Sep 17 00:00:00 2001 From: Robert Foss Date: Sat, 12 Sep 2015 12:07:01 -0400 Subject: [PATCH 02/11] Added ROM_CONST_ATTR attribute for forcing constants to live in flash. --- include/c_types.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/c_types.h b/include/c_types.h index 36ef6d12..ec0ce554 100644 --- a/include/c_types.h +++ b/include/c_types.h @@ -86,6 +86,7 @@ typedef enum { #define TEXT_SECTION_ATTR __attribute__((section(".text"))) #define RAM_CONST_ATTR __attribute__((section(".rodata"))) +#define ROM_CONST_ATTR __attribute__((section("irom0.rodata"))) #ifndef __cplusplus typedef unsigned char bool; From 3a05c3e402e142fa745d79c2e68ae4b8f117b565 Mon Sep 17 00:00:00 2001 From: Robert Foss Date: Sat, 12 Sep 2015 12:07:53 -0400 Subject: [PATCH 03/11] Moved CONST data to occupy flash, and remove storage instructions for functions. --- app/modules/enduser_setup.c | 70 ++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/app/modules/enduser_setup.c b/app/modules/enduser_setup.c index dfd05c4c..a844136d 100644 --- a/app/modules/enduser_setup.c +++ b/app/modules/enduser_setup.c @@ -35,17 +35,17 @@ * |ip - 32 bits| * * DNS Header Part | FLAGS | | Q COUNT | | A CNT | |AUTH CNT| | ADD CNT| */ -static const char RAM_CONST_ATTR dns_header[] = { 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 }; +static const char ROM_CONST_ATTR dns_header[] = { 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 }; /* DNS Query Part | Q TYPE | | Q CLASS| */ -static const char RAM_CONST_ATTR dns_body[] = { 0x00, 0x01, 0x00, 0x01, +static const char ROM_CONST_ATTR dns_body[] = { 0x00, 0x01, 0x00, 0x01, /* DNS Answer Part |LBL OFFS| | TYPE | | CLASS | | TTL | | RD LEN | */ 0xC0, 0x0C, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04 }; -static const char RAM_CONST_ATTR http_html_filename[] = "index.html"; -static const char RAM_CONST_ATTR http_header_200[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"; -static const char RAM_CONST_ATTR http_header_404[] = "HTTP/1.1 404 Not Found\r\n"; +static const char ROM_CONST_ATTR http_html_filename[] = "index.html"; +static const char ROM_CONST_ATTR http_header_200[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"; +static const char ROM_CONST_ATTR http_header_404[] = "HTTP/1.1 404 Not Found\r\n"; -static const char RAM_CONST_ATTR http_html_backup[] = "Connect gadget to you WiFi

WiFi Login

Connect gadget to your WiFi

"; +static const char ROM_CONST_ATTR http_html_backup[] = "Connect gadget to you WiFi

WiFi Login

Connect gadget to your WiFi

"; static struct espconn *espconn_dns_udp; static struct espconn *espconn_http_tcp; @@ -56,15 +56,15 @@ typedef struct http_payload_t { static http_payload_t http_payload; static os_timer_t check_station_timer; -static int ICACHE_FLASH_ATTR enduser_setup_start(lua_State* L); -static int ICACHE_FLASH_ATTR enduser_setup_stop(lua_State* L); -static void ICACHE_FLASH_ATTR enduser_setup_station_start(void); -static void ICACHE_FLASH_ATTR enduser_setup_ap_start(void); -static void ICACHE_FLASH_ATTR enduser_setup_ap_stop(void); -static void ICACHE_RAM_ATTR enduser_setup_check_station(void); +static int enduser_setup_start(lua_State* L); +static int enduser_setup_stop(lua_State* L); +static void enduser_setup_station_start(void); +static void enduser_setup_ap_start(void); +static void enduser_setup_ap_stop(void); +static void enduser_setup_check_station(void); -static void ICACHE_RAM_ATTR enduser_setup_check_station_start(void) +static void enduser_setup_check_station_start(void) { PRINT_FUNC("enduser_setup_check_station_start\n"); @@ -73,7 +73,7 @@ static void ICACHE_RAM_ATTR enduser_setup_check_station_start(void) } -static void ICACHE_RAM_ATTR enduser_setup_check_station_stop(void) +static void enduser_setup_check_station_stop(void) { PRINT_FUNC("enduser_setup_check_station_stop\n"); @@ -86,7 +86,7 @@ static void ICACHE_RAM_ATTR enduser_setup_check_station_stop(void) * * Check that we've successfully entered station mode. */ -static void ICACHE_RAM_ATTR enduser_setup_check_station(void) +static void enduser_setup_check_station(void) { struct ip_info ip; c_memset(&ip, 0, sizeof(struct ip_info)); @@ -121,7 +121,7 @@ static void ICACHE_RAM_ATTR enduser_setup_check_station(void) * * @return -1 iff no occurance of char was found. */ -static int ICACHE_RAM_ATTR enduser_setup_srch_str(const char *str, const char *srch_str) +static int enduser_setup_srch_str(const char *str, const char *srch_str) { int srch_str_len = c_strlen(srch_str); int first_hit = INT_MAX; @@ -145,7 +145,7 @@ static int ICACHE_RAM_ATTR enduser_setup_srch_str(const char *str, const char *s } -static void ICACHE_FLASH_ATTR enduser_setup_http_free(void) +static void enduser_setup_http_free(void) { http_payload.len = 0; c_free(http_payload.data); @@ -170,7 +170,7 @@ static void ICACHE_FLASH_ATTR enduser_setup_http_free(void) * 1 iff backup html was loaded * 2 iff out of memory */ -static int ICACHE_FLASH_ATTR enduser_setup_http_load_payload(void) +static int enduser_setup_http_load_payload(void) { PRINT_FUNC("enduser_setup_http_load_payload\n"); @@ -221,7 +221,7 @@ static int ICACHE_FLASH_ATTR enduser_setup_http_load_payload(void) * * Parse escaped and form encoded data of request. */ -static void ICACHE_RAM_ATTR enduser_setup_http_urldecode(char *dst, const char *src, int src_len) +static void enduser_setup_http_urldecode(char *dst, const char *src, int src_len) { char a, b; int i; @@ -276,7 +276,7 @@ static void ICACHE_RAM_ATTR enduser_setup_http_urldecode(char *dst, const char * * return 1 iff credentials aren't found * return 2 iff an error occured */ -static int ICACHE_RAM_ATTR enduser_setup_http_handle_credentials(char *data, unsigned short data_len) +static int enduser_setup_http_handle_credentials(char *data, unsigned short data_len) { PRINT_FUNC("enduser_setup_http_handle_credentials\n"); @@ -347,7 +347,7 @@ static int ICACHE_RAM_ATTR enduser_setup_http_handle_credentials(char *data, uns * * @return - return 0 iff html was served successfully */ -static int ICACHE_RAM_ATTR enduser_setup_http_serve_header(struct espconn *http_client, char *header, uint32_t header_len) +static int enduser_setup_http_serve_header(struct espconn *http_client, char *header, uint32_t header_len) { PRINT_FUNC("enduser_setup_http_serve_404\n"); @@ -377,7 +377,7 @@ static int ICACHE_RAM_ATTR enduser_setup_http_serve_header(struct espconn *http_ * * @return - return 0 iff html was served successfully */ -static int ICACHE_RAM_ATTR enduser_setup_http_serve_html(struct espconn *http_client) +static int enduser_setup_http_serve_html(struct espconn *http_client) { PRINT_FUNC("enduser_setup_http_serve_html\n"); @@ -412,14 +412,14 @@ static int ICACHE_RAM_ATTR enduser_setup_http_serve_html(struct espconn *http_cl * * End TCP connection and free up resources. */ -static void ICACHE_RAM_ATTR enduser_setup_http_disconnect(struct espconn *espconn) +static void enduser_setup_http_disconnect(struct espconn *espconn) { PRINT_FUNC("enduser_setup_http_disconnect\n"); //TODO: Construct and maintain os task queue(?) to be able to issue system_os_task with espconn_disconnect. } -static void ICACHE_RAM_ATTR enduser_setup_http_recvcb(void *arg, char *data, unsigned short data_len) +static void enduser_setup_http_recvcb(void *arg, char *data, unsigned short data_len) { PRINT_FUNC("enduser_setup_http_recvcb\n"); struct espconn *http_client = (struct espconn *) arg; @@ -468,7 +468,7 @@ static void ICACHE_RAM_ATTR enduser_setup_http_recvcb(void *arg, char *data, uns } -static void ICACHE_RAM_ATTR enduser_setup_http_connectcb(void *arg) +static void enduser_setup_http_connectcb(void *arg) { PRINT_FUNC("enduser_setup_http_connectcb\n"); @@ -484,7 +484,7 @@ static void ICACHE_RAM_ATTR enduser_setup_http_connectcb(void *arg) } -static void ICACHE_FLASH_ATTR enduser_setup_http_start(void) +static void enduser_setup_http_start(void) { PRINT_FUNC("enduser_setup_http_start\n"); @@ -572,7 +572,7 @@ static void ICACHE_FLASH_ATTR enduser_setup_http_start(void) } -static void ICACHE_FLASH_ATTR enduser_setup_http_stop(void) +static void enduser_setup_http_stop(void) { PRINT_FUNC("enduser_setup_http_stop\n"); @@ -595,7 +595,7 @@ static void ICACHE_FLASH_ATTR enduser_setup_http_stop(void) enduser_setup_http_free(); } -static void ICACHE_FLASH_ATTR enduser_setup_ap_stop(void) +static void enduser_setup_ap_stop(void) { PRINT_FUNC("enduser_setup_station_stop\n"); @@ -603,7 +603,7 @@ static void ICACHE_FLASH_ATTR enduser_setup_ap_stop(void) } -static void ICACHE_FLASH_ATTR enduser_setup_ap_start(void) +static void enduser_setup_ap_start(void) { PRINT_FUNC("enduser_setup_ap_start\n"); @@ -621,7 +621,7 @@ static void ICACHE_FLASH_ATTR enduser_setup_ap_start(void) } -static void ICACHE_RAM_ATTR enduser_setup_dns_recv_callback(void *arg, char *recv_data, unsigned short recv_len) +static void enduser_setup_dns_recv_callback(void *arg, char *recv_data, unsigned short recv_len) { PRINT_FUNC("enduser_setup_dns_recv_callback received query for %s\n", &(recv_data[12])); @@ -684,7 +684,7 @@ static void ICACHE_RAM_ATTR enduser_setup_dns_recv_callback(void *arg, char *rec } -static void ICACHE_FLASH_ATTR enduser_setup_dns_free(void) +static void enduser_setup_dns_free(void) { PRINT_FUNC("enduser_setup_dns_free\n"); @@ -700,7 +700,7 @@ static void ICACHE_FLASH_ATTR enduser_setup_dns_free(void) } -static void ICACHE_FLASH_ATTR enduser_setup_dns_start(void) +static void enduser_setup_dns_start(void) { PRINT_FUNC("enduser_setup_dns_started\n"); @@ -762,7 +762,7 @@ static void ICACHE_FLASH_ATTR enduser_setup_dns_start(void) } -static void ICACHE_FLASH_ATTR enduser_setup_dns_stop(void) +static void enduser_setup_dns_stop(void) { PRINT_FUNC("enduser_setup_dns_stop\n"); @@ -786,7 +786,7 @@ static void ICACHE_FLASH_ATTR enduser_setup_dns_stop(void) } -static int ICACHE_FLASH_ATTR enduser_setup_start(lua_State* L) +static int enduser_setup_start(lua_State* L) { c_printf("\n"); c_printf("-------------------\n"); @@ -802,7 +802,7 @@ static int ICACHE_FLASH_ATTR enduser_setup_start(lua_State* L) } -static int ICACHE_FLASH_ATTR enduser_setup_stop(lua_State* L) +static int enduser_setup_stop(lua_State* L) { c_printf("\n"); c_printf("------------------\n"); From 3d5c54cef7e8e55002867879d200ff58ad0971d9 Mon Sep 17 00:00:00 2001 From: Robert Foss Date: Mon, 14 Sep 2015 18:43:09 -0400 Subject: [PATCH 04/11] Moved all debug prints into the NODE_DEBUG macro. --- app/modules/enduser_setup.c | 122 ++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 69 deletions(-) diff --git a/app/modules/enduser_setup.c b/app/modules/enduser_setup.c index a844136d..0ec9df19 100644 --- a/app/modules/enduser_setup.c +++ b/app/modules/enduser_setup.c @@ -18,12 +18,6 @@ #define PRINT_FUNC #endif -#define PRINT_DEBUG_ENABLE 0 -#if PRINT_DEBUG_ENABLE -#define PRINT_DEBUG c_printf -#else -#define PRINT_DEBUG -#endif /** * DNS Response Packet: @@ -109,7 +103,7 @@ static void enduser_setup_check_station(void) wifi_station_get_config(&cnf); uint8_t *ip_byte = (uint8_t *) &(ip.ip); - c_printf("Connected to \"%s\" as %u.%u.%u.%u\n", cnf.ssid, IP2STR(&ip)); + NODE_DEBUG("Connected to \"%s\" as %u.%u.%u.%u\n", cnf.ssid, IP2STR(&ip)); enduser_setup_stop(NULL); } @@ -181,7 +175,7 @@ static int enduser_setup_http_load_payload(void) if (f == 0 || err == -1 || err2 == -1) { - c_printf("enduser_setup_http_load_payload unable to load file \"%s\", loading backup HTML.\n", http_html_filename); + NODE_DEBUG("enduser_setup_http_load_payload unable to load file \"%s\", loading backup HTML.\n", http_html_filename); int payload_len = sizeof(http_header_200) + sizeof(http_html_backup); http_payload.len = payload_len; @@ -307,36 +301,36 @@ static int enduser_setup_http_handle_credentials(char *data, unsigned short data int err = wifi_set_opmode(STATION_MODE | wifi_get_opmode()); if (err == FALSE) { - c_printf("enduser_setup_station_start failed. wifi_set_opmode failed.\n"); + NODE_DEBUG("enduser_setup_station_start failed. wifi_set_opmode failed.\n"); wifi_set_opmode(~STATION_MODE & wifi_get_opmode()); return 2; } err = wifi_station_set_config(&cnf); if (err == FALSE) { - c_printf("enduser_setup_station_start failed. wifi_station_set_config failed.\n"); + NODE_DEBUG("enduser_setup_station_start failed. wifi_station_set_config failed.\n"); wifi_set_opmode(~STATION_MODE & wifi_get_opmode()); return 2; } err = wifi_station_disconnect(); if (err == FALSE) { - c_printf("enduser_setup_station_start failed. wifi_station_disconnect failed.\n"); + NODE_DEBUG("enduser_setup_station_start failed. wifi_station_disconnect failed.\n"); } err = wifi_station_connect(); if (err == FALSE) { - c_printf("enduser_setup_station_start failed. wifi_station_connect failed.\n"); + NODE_DEBUG("enduser_setup_station_start failed. wifi_station_connect failed.\n"); } - c_printf("\n"); - c_printf("WiFi Credentials Stored\n"); - c_printf("-----------------------\n"); - c_printf("name: \"%s\"\n", cnf.ssid); - c_printf("pass: \"%s\"\n", cnf.password); - c_printf("bssid_set: %u\n", cnf.bssid_set); - c_printf("bssid: \"%s\"\n", cnf.bssid); - c_printf("-----------------------\n\n"); + NODE_DEBUG("\n"); + NODE_DEBUG("WiFi Credentials Stored\n"); + NODE_DEBUG("-----------------------\n"); + NODE_DEBUG("name: \"%s\"\n", cnf.ssid); + NODE_DEBUG("pass: \"%s\"\n", cnf.password); + NODE_DEBUG("bssid_set: %u\n", cnf.bssid_set); + NODE_DEBUG("bssid: \"%s\"\n", cnf.bssid); + NODE_DEBUG("-----------------------\n\n"); return 0; } @@ -354,17 +348,17 @@ static int enduser_setup_http_serve_header(struct espconn *http_client, char *he int8_t err = espconn_sent(http_client, header, header_len); if (err == ESPCONN_MEM) { - c_printf("enduser_setup_http_serve_header failed. espconn_send out of memory\n"); + NODE_DEBUG("enduser_setup_http_serve_header failed. espconn_send out of memory\n"); return 1; } else if (err == ESPCONN_ARG) { - c_printf("enduser_setup_http_serve_header failed. espconn_send can't find network transmission\n"); + NODE_DEBUG("enduser_setup_http_serve_header failed. espconn_send can't find network transmission\n"); return 1; } else if (err != 0) { - c_printf("enduser_setup_http_serve_header failed. espconn_send failed\n"); + NODE_DEBUG("enduser_setup_http_serve_header failed. espconn_send failed\n"); return 1; } @@ -389,17 +383,17 @@ static int enduser_setup_http_serve_html(struct espconn *http_client) int8_t err = espconn_sent(http_client, http_payload.data, http_payload.len); if (err == ESPCONN_MEM) { - c_printf("enduser_setup_http_serve_html failed. espconn_send out of memory\n"); + NODE_DEBUG("enduser_setup_http_serve_html failed. espconn_send out of memory\n"); return 1; } else if (err == ESPCONN_ARG) { - c_printf("enduser_setup_http_serve_html failed. espconn_send can't find network transmission\n"); + NODE_DEBUG("enduser_setup_http_serve_html failed. espconn_send can't find network transmission\n"); return 1; } else if (err != 0) { - c_printf("enduser_setup_http_serve_html failed. espconn_send failed\n"); + NODE_DEBUG("enduser_setup_http_serve_html failed. espconn_send failed\n"); return 1; } @@ -440,13 +434,13 @@ static void enduser_setup_http_recvcb(void *arg, char *data, unsigned short data } else if (retval == 2) { - c_printf("enduser_setup_http_recvcb failed. Failed to handle wifi credentials.\n"); + NODE_DEBUG("enduser_setup_http_recvcb failed. Failed to handle wifi credentials.\n"); return; } if (retval != 1) { - c_printf("enduser_setup_http_recvcb failed. Unknown error code #%u.\n", retval); + NODE_DEBUG("enduser_setup_http_recvcb failed. Unknown error code #%u.\n", retval); return; } @@ -462,7 +456,7 @@ static void enduser_setup_http_recvcb(void *arg, char *data, unsigned short data retval = enduser_setup_http_serve_html(http_client); if (retval != 0) { - c_printf("enduser_setup_http_recvcb failed. Unable to send HTML.\n"); + NODE_DEBUG("enduser_setup_http_recvcb failed. Unable to send HTML.\n"); enduser_setup_http_disconnect(http_client); } } @@ -479,7 +473,7 @@ static void enduser_setup_http_connectcb(void *arg) if (err != 0) { - c_printf("enduser_setup_http_connectcb failed. Callback registration failed.\n"); + NODE_DEBUG("enduser_setup_http_connectcb failed. Callback registration failed.\n"); } } @@ -490,20 +484,20 @@ static void enduser_setup_http_start(void) if (espconn_http_tcp != NULL) { - c_printf("enduser_setup_http_start failed. Appears to already be started (espconn_http_tcp != NULL).\n"); + NODE_DEBUG("enduser_setup_http_start failed. Appears to already be started (espconn_http_tcp != NULL).\n"); return; } espconn_http_tcp = (struct espconn *) c_malloc(sizeof(struct espconn)); if (espconn_http_tcp == NULL) { - c_printf("enduser_setup_http_start failed. Memory allocation failed (espconn_http_tcp == NULL).\n"); + NODE_DEBUG("enduser_setup_http_start failed. Memory allocation failed (espconn_http_tcp == NULL).\n"); return; } esp_tcp *esp_tcp_data = (esp_tcp *) c_malloc(sizeof(esp_tcp)); if (esp_tcp_data == NULL) { - c_printf("enduser_setup_http_start failed. Memory allocation failed (esp_udp == NULL).\n"); + NODE_DEBUG("enduser_setup_http_start failed. Memory allocation failed (esp_udp == NULL).\n"); enduser_setup_http_free(); return; } @@ -519,7 +513,7 @@ static void enduser_setup_http_start(void) err = espconn_regist_connectcb(espconn_http_tcp, enduser_setup_http_connectcb); if (err != 0) { - c_printf("enduser_setup_http_start failed. Couldn't add receive callback, ERRROR #%u.\n", err); + NODE_DEBUG("enduser_setup_http_start failed. Couldn't add receive callback, ERRROR #%u.\n", err); enduser_setup_http_free(); return; } @@ -527,25 +521,25 @@ static void enduser_setup_http_start(void) err = espconn_accept(espconn_http_tcp); if (err == ESPCONN_ISCONN) { - c_printf("enduser_setup_http_start failed. Couldn't create connection, already listening for that connection.\n"); + NODE_DEBUG("enduser_setup_http_start failed. Couldn't create connection, already listening for that connection.\n"); enduser_setup_http_free(); return; } else if (err == ESPCONN_MEM) { - c_printf("enduser_setup_http_start failed. Couldn't create connection, out of memory.\n"); + NODE_DEBUG("enduser_setup_http_start failed. Couldn't create connection, out of memory.\n"); enduser_setup_http_free(); return; } else if (err == ESPCONN_ARG) { - c_printf("enduser_setup_http_start failed. Can't find connection from espconn argument\n"); + NODE_DEBUG("enduser_setup_http_start failed. Can't find connection from espconn argument\n"); enduser_setup_http_free(); return; } else if (err != 0) { - c_printf("enduser_setup_http_start failed. ERRROR #%u\n", err); + NODE_DEBUG("enduser_setup_http_start failed. ERRROR #%u\n", err); enduser_setup_http_free(); return; } @@ -553,7 +547,7 @@ static void enduser_setup_http_start(void) err = espconn_regist_time(espconn_http_tcp, 2, 0); if (err == ESPCONN_ARG) { - c_printf("enduser_setup_http_start failed. Unable to set TCP timeout.\n"); + NODE_DEBUG("enduser_setup_http_start failed. Unable to set TCP timeout.\n"); enduser_setup_http_free(); return; } @@ -565,7 +559,7 @@ static void enduser_setup_http_start(void) } else if (err == 2) { - c_printf("enduser_setup_http_start failed. Unable to allocate memory for HTTP payload.\n"); + NODE_DEBUG("enduser_setup_http_start failed. Unable to allocate memory for HTTP payload.\n"); enduser_setup_http_free(); return; } @@ -578,18 +572,18 @@ static void enduser_setup_http_stop(void) if (espconn_http_tcp == NULL) { - c_printf("enduser_setup_http_stop failed. enduser_setup not enabled (espconn_dns_udp == NULL).\n"); + NODE_DEBUG("enduser_setup_http_stop failed. enduser_setup not enabled (espconn_dns_udp == NULL).\n"); return; } int8_t err = espconn_delete(espconn_http_tcp); if (err == ESPCONN_ARG) { - c_printf("enduser_setup_http_stop failed. espconn_delete returned ESPCONN_ARG. Can't find network transmission described.\n"); + NODE_DEBUG("enduser_setup_http_stop failed. espconn_delete returned ESPCONN_ARG. Can't find network transmission described.\n"); } else if (err != 0) { - c_printf("enduser_setup_http_stop failed. espconn_delete returned ERROR #%u.\n", err); + NODE_DEBUG("enduser_setup_http_stop failed. espconn_delete returned ERROR #%u.\n", err); } enduser_setup_http_free(); @@ -631,13 +625,13 @@ static void enduser_setup_dns_recv_callback(void *arg, char *recv_data, unsigned uint8_t if_mode = wifi_get_opmode(); if ((if_mode & SOFTAP_MODE) == 0) { - c_printf("enduser_setup_dns_recv_callback failed. Interface mode %d not supported.\n", if_mode); + NODE_DEBUG("enduser_setup_dns_recv_callback failed. Interface mode %d not supported.\n", if_mode); return; } uint8_t if_index = (if_mode == STATION_MODE? STATION_IF : SOFTAP_IF); if (wifi_get_ip_info(if_index , &ip_info) == false) { - c_printf("enduser_setup_dns_recv_callback failed. Unable to get interface IP.\n"); + NODE_DEBUG("enduser_setup_dns_recv_callback failed. Unable to get interface IP.\n"); return; } @@ -648,7 +642,7 @@ static void enduser_setup_dns_recv_callback(void *arg, char *recv_data, unsigned char *dns_reply = (char *) c_malloc(dns_reply_len); if (dns_reply == NULL) { - c_printf("enduser_setup_dns_recv_callback failed. Failed to allocate memory.\n"); + NODE_DEBUG("enduser_setup_dns_recv_callback failed. Failed to allocate memory.\n"); return; } @@ -668,17 +662,17 @@ static void enduser_setup_dns_recv_callback(void *arg, char *recv_data, unsigned c_free(dns_reply); if (err == ESPCONN_MEM) { - c_printf("enduser_setup_dns_recv_callback failed. Failed to allocate memory for send.\n"); + NODE_DEBUG("enduser_setup_dns_recv_callback failed. Failed to allocate memory for send.\n"); return; } else if (err == ESPCONN_ARG) { - c_printf("enduser_setup_dns_recv_callback failed. Can't execute transmission.\n"); + NODE_DEBUG("enduser_setup_dns_recv_callback failed. Can't execute transmission.\n"); return; } else if (err != 0) { - c_printf("enduser_setup_dns_recv_callback failed. espconn_send failed\n"); + NODE_DEBUG("enduser_setup_dns_recv_callback failed. espconn_send failed\n"); return; } } @@ -706,20 +700,20 @@ static void enduser_setup_dns_start(void) if (espconn_dns_udp != NULL) { - c_printf("enduser_setup_dns_start failed. Appears to already be started (espconn_dns_udp != NULL).\n"); + NODE_DEBUG("enduser_setup_dns_start failed. Appears to already be started (espconn_dns_udp != NULL).\n"); return; } espconn_dns_udp = (struct espconn *) c_malloc(sizeof(struct espconn)); if (espconn_dns_udp == NULL) { - c_printf("enduser_setup_dns_start failed. Memory allocation failed (espconn_dns_udp == NULL).\n"); + NODE_DEBUG("enduser_setup_dns_start failed. Memory allocation failed (espconn_dns_udp == NULL).\n"); return; } esp_udp *esp_udp_data = (esp_udp *) c_malloc(sizeof(esp_udp)); if (esp_udp_data == NULL) { - c_printf("enduser_setup_dns_start failed. Memory allocation failed (esp_udp == NULL).\n"); + NODE_DEBUG("enduser_setup_dns_start failed. Memory allocation failed (esp_udp == NULL).\n"); enduser_setup_dns_free(); return; } @@ -735,7 +729,7 @@ static void enduser_setup_dns_start(void) err = espconn_regist_recvcb(espconn_dns_udp, enduser_setup_dns_recv_callback); if (err != 0) { - c_printf("enduser_setup_dns_start failed. Couldn't add receive callback, ERRROR #%d.\n", err); + NODE_DEBUG("enduser_setup_dns_start failed. Couldn't add receive callback, ERRROR #%d.\n", err); enduser_setup_dns_free(); return; } @@ -743,19 +737,19 @@ static void enduser_setup_dns_start(void) err = espconn_create(espconn_dns_udp); if (err == ESPCONN_ISCONN) { - c_printf("enduser_setup_dns_start failed. Couldn't create connection, already listening for that connection.\n"); + NODE_DEBUG("enduser_setup_dns_start failed. Couldn't create connection, already listening for that connection.\n"); enduser_setup_dns_free(); return; } else if (err == ESPCONN_MEM) { - c_printf("enduser_setup_dns_start failed. Couldn't create connection, out of memory.\n"); + NODE_DEBUG("enduser_setup_dns_start failed. Couldn't create connection, out of memory.\n"); enduser_setup_dns_free(); return; } else if (err != 0) { - c_printf("enduser_setup_dns_start failed. Couldn't create connection, ERROR #%d.\n", err); + NODE_DEBUG("enduser_setup_dns_start failed. Couldn't create connection, ERROR #%d.\n", err); enduser_setup_dns_free(); return; } @@ -768,18 +762,18 @@ static void enduser_setup_dns_stop(void) if (espconn_dns_udp == NULL) { - c_printf("enduser_setup_dns_stop failed. Hijacker not enabled (espconn_dns_udp == NULL).\n"); + NODE_DEBUG("enduser_setup_dns_stop failed. Hijacker not enabled (espconn_dns_udp == NULL).\n"); return; } int8_t err = espconn_delete(espconn_dns_udp); if (err == ESPCONN_ARG) { - c_printf("enduser_setup_http_stop failed. espconn_delete returned ESPCONN_ARG. Can't find network transmission described.\n"); + NODE_DEBUG("enduser_setup_http_stop failed. espconn_delete returned ESPCONN_ARG. Can't find network transmission described.\n"); } else if (err != 0) { - c_printf("enduser_setup_http_stop failed. espconn_delete returned ERROR #%u.\n", err); + NODE_DEBUG("enduser_setup_http_stop failed. espconn_delete returned ERROR #%u.\n", err); } enduser_setup_dns_free(); @@ -788,11 +782,6 @@ static void enduser_setup_dns_stop(void) static int enduser_setup_start(lua_State* L) { - c_printf("\n"); - c_printf("-------------------\n"); - c_printf("enduser_setup_start\n"); - c_printf("-------------------\n\n"); - enduser_setup_check_station_start(); enduser_setup_ap_start(); enduser_setup_dns_start(); @@ -804,11 +793,6 @@ static int enduser_setup_start(lua_State* L) static int enduser_setup_stop(lua_State* L) { - c_printf("\n"); - c_printf("------------------\n"); - c_printf("enduser_setup_stop\n"); - c_printf("------------------\n\n"); - enduser_setup_check_station_stop(); enduser_setup_ap_stop(); enduser_setup_dns_stop(); From 8982d370f2c2c6a474501ee364d7dd3c76ee295b Mon Sep 17 00:00:00 2001 From: Robert Foss Date: Wed, 16 Sep 2015 08:56:44 -0400 Subject: [PATCH 05/11] Removed #define for forcing storage on flash --- app/modules/enduser_setup.c | 59 ++++++++++++++++++------------------- include/c_types.h | 1 - 2 files changed, 29 insertions(+), 31 deletions(-) diff --git a/app/modules/enduser_setup.c b/app/modules/enduser_setup.c index 0ec9df19..3e6b18c1 100644 --- a/app/modules/enduser_setup.c +++ b/app/modules/enduser_setup.c @@ -28,18 +28,17 @@ * |dns_body| * |ip - 32 bits| * - * DNS Header Part | FLAGS | | Q COUNT | | A CNT | |AUTH CNT| | ADD CNT| */ -static const char ROM_CONST_ATTR dns_header[] = { 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 }; -/* DNS Query Part | Q TYPE | | Q CLASS| */ -static const char ROM_CONST_ATTR dns_body[] = { 0x00, 0x01, 0x00, 0x01, -/* DNS Answer Part |LBL OFFS| | TYPE | | CLASS | | TTL | | RD LEN | */ - 0xC0, 0x0C, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04 }; + * DNS Header Part | FLAGS | | Q COUNT | | A CNT | |AUTH CNT| | ADD CNT| */ +static const char dns_header[] = { 0x80, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00 }; +/* DNS Query Part | Q TYPE | | Q CLASS| */ +static const char dns_body[] = { 0x00, 0x01, 0x00, 0x01, +/* DNS Answer Part |LBL OFFS| | TYPE | | CLASS | | TTL | | RD LEN | */ + 0xC0, 0x0C, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x78, 0x00, 0x04 }; -static const char ROM_CONST_ATTR http_html_filename[] = "index.html"; -static const char ROM_CONST_ATTR http_header_200[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"; -static const char ROM_CONST_ATTR http_header_404[] = "HTTP/1.1 404 Not Found\r\n"; - -static const char ROM_CONST_ATTR http_html_backup[] = "Connect gadget to you WiFi

WiFi Login

Connect gadget to your WiFi

"; +static const char http_html_filename[] = "index.html"; +static const char http_header_200[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"; +static const char http_header_404[] = "HTTP/1.1 404 Not Found\r\n"; +static const char http_html_backup[] = "Connect gadget to you WiFi

WiFi Login

Connect gadget to your WiFi

"; static struct espconn *espconn_dns_udp; static struct espconn *espconn_http_tcp; @@ -93,12 +92,12 @@ static void enduser_setup_check_station(void) { has_ip |= ((char *) &ip)[i]; } - + if (has_ip == 0) { return; } - + struct station_config cnf; wifi_station_get_config(&cnf); @@ -368,18 +367,18 @@ static int enduser_setup_http_serve_header(struct espconn *http_client, char *he /** * Serve HTML - * + * * @return - return 0 iff html was served successfully */ static int enduser_setup_http_serve_html(struct espconn *http_client) { PRINT_FUNC("enduser_setup_http_serve_html\n"); - + if (http_payload.data == NULL) { enduser_setup_http_load_payload(); } - + int8_t err = espconn_sent(http_client, http_payload.data, http_payload.len); if (err == ESPCONN_MEM) { @@ -394,9 +393,9 @@ static int enduser_setup_http_serve_html(struct espconn *http_client) else if (err != 0) { NODE_DEBUG("enduser_setup_http_serve_html failed. espconn_send failed\n"); - return 1; + return 1; } - + return 0; } @@ -424,7 +423,7 @@ static void enduser_setup_http_recvcb(void *arg, char *data, unsigned short data enduser_setup_http_disconnect(http_client); return; } - + int retval = enduser_setup_http_handle_credentials(data, data_len); if (retval == 0) { @@ -437,13 +436,13 @@ static void enduser_setup_http_recvcb(void *arg, char *data, unsigned short data NODE_DEBUG("enduser_setup_http_recvcb failed. Failed to handle wifi credentials.\n"); return; } - + if (retval != 1) { NODE_DEBUG("enduser_setup_http_recvcb failed. Unknown error code #%u.\n", retval); return; } - + /* Reject requests that probably aren't relevant to free up resources. */ if (c_strncmp(data, "GET / ", 6) != 0) { @@ -452,7 +451,7 @@ static void enduser_setup_http_recvcb(void *arg, char *data, unsigned short data enduser_setup_http_disconnect(http_client); return; } - + retval = enduser_setup_http_serve_html(http_client); if (retval != 0) { @@ -470,7 +469,7 @@ static void enduser_setup_http_connectcb(void *arg) int8_t err = 0; err |= espconn_regist_recvcb(callback_espconn, enduser_setup_http_recvcb); - + if (err != 0) { NODE_DEBUG("enduser_setup_http_connectcb failed. Callback registration failed.\n"); @@ -535,21 +534,21 @@ static void enduser_setup_http_start(void) { NODE_DEBUG("enduser_setup_http_start failed. Can't find connection from espconn argument\n"); enduser_setup_http_free(); - return; + return; } else if (err != 0) { NODE_DEBUG("enduser_setup_http_start failed. ERRROR #%u\n", err); enduser_setup_http_free(); - return; + return; } - + err = espconn_regist_time(espconn_http_tcp, 2, 0); if (err == ESPCONN_ARG) { NODE_DEBUG("enduser_setup_http_start failed. Unable to set TCP timeout.\n"); enduser_setup_http_free(); - return; + return; } err = enduser_setup_http_load_payload(); @@ -561,7 +560,7 @@ static void enduser_setup_http_start(void) { NODE_DEBUG("enduser_setup_http_start failed. Unable to allocate memory for HTTP payload.\n"); enduser_setup_http_free(); - return; + return; } } @@ -751,7 +750,7 @@ static void enduser_setup_dns_start(void) { NODE_DEBUG("enduser_setup_dns_start failed. Couldn't create connection, ERROR #%d.\n", err); enduser_setup_dns_free(); - return; + return; } } @@ -786,7 +785,7 @@ static int enduser_setup_start(lua_State* L) enduser_setup_ap_start(); enduser_setup_dns_start(); enduser_setup_http_start(); - + return 0; } diff --git a/include/c_types.h b/include/c_types.h index ec0ce554..36ef6d12 100644 --- a/include/c_types.h +++ b/include/c_types.h @@ -86,7 +86,6 @@ typedef enum { #define TEXT_SECTION_ATTR __attribute__((section(".text"))) #define RAM_CONST_ATTR __attribute__((section(".rodata"))) -#define ROM_CONST_ATTR __attribute__((section("irom0.rodata"))) #ifndef __cplusplus typedef unsigned char bool; From cd85e50e739e7bc7437b90541bb4c1716ea55380 Mon Sep 17 00:00:00 2001 From: Robert Foss Date: Sat, 19 Sep 2015 15:06:56 -0400 Subject: [PATCH 06/11] Added support for connected, error and debug callbacks. --- app/include/user_modules.h | 2 +- app/modules/enduser_setup.c | 589 +++++++++++++++++++++--------------- 2 files changed, 345 insertions(+), 246 deletions(-) diff --git a/app/include/user_modules.h b/app/include/user_modules.h index cfbb94f4..60d4e93b 100644 --- a/app/include/user_modules.h +++ b/app/include/user_modules.h @@ -28,7 +28,7 @@ #define LUA_USE_MODULES_BIT #define LUA_USE_MODULES_MQTT #define LUA_USE_MODULES_COAP -//#define LUA_USE_MODULES_ENDUSER_SETUP // USE_DNS in dhcpserver.h needs to be enabled for this module to work. +#define LUA_USE_MODULES_ENDUSER_SETUP // USE_DNS in dhcpserver.h needs to be enabled for this module to work. #define LUA_USE_MODULES_U8G // #define LUA_USE_MODULES_WS2801 #define LUA_USE_MODULES_WS2812 diff --git a/app/modules/enduser_setup.c b/app/modules/enduser_setup.c index 3e6b18c1..1d0823a8 100644 --- a/app/modules/enduser_setup.c +++ b/app/modules/enduser_setup.c @@ -1,3 +1,37 @@ +/* + * Copyright 2015 Robert Foss. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * - Neither the name of the copyright holders nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @author Robert Foss + */ + + #include "lualib.h" #include "lauxlib.h" #include "platform.h" @@ -11,12 +45,14 @@ #define MIN(x, y) (((x) < (y)) ? (x) : (y)) -#define PRINT_FUNC_ENABLE 0 -#if PRINT_FUNC_ENABLE -#define PRINT_FUNC c_printf -#else -#define PRINT_FUNC -#endif +#define ENDUSER_SETUP_ERR_FATAL (1 << 0) +#define ENDUSER_SETUP_ERR_NONFATAL (1 << 1) +#define ENDUSER_SETUP_ERR_NO_RETURN (1 << 2) + +#define ENDUSER_SETUP_ERR_OUT_OF_MEMORY 1 +#define ENDUSER_SETUP_ERR_CONNECTION_NOT_FOUND 2 +#define ENDUSER_SETUP_ERR_UNKOWN_ERROR 3 +#define ENDUSER_SETUP_ERR_SOCKET_ALREADY_OPEN 4 /** @@ -40,37 +76,101 @@ static const char http_header_200[] = "HTTP/1.1 200 OK\r\nContent-Type: text/htm static const char http_header_404[] = "HTTP/1.1 404 Not Found\r\n"; static const char http_html_backup[] = "Connect gadget to you WiFi

WiFi Login

Connect gadget to your WiFi

"; -static struct espconn *espconn_dns_udp; -static struct espconn *espconn_http_tcp; -typedef struct http_payload_t { - char *data; - uint32_t len; -} http_payload_t; -static http_payload_t http_payload; -static os_timer_t check_station_timer; + +typedef struct +{ + lua_State *lua_L; + struct espconn *espconn_dns_udp; + struct espconn *espconn_http_tcp; + char *http_payload_data; + uint32_t http_payload_len; + os_timer_t check_station_timer; + int lua_connected_cb_ref; + int lua_err_cb_ref; + int lua_dbg_cb_ref; +} enduser_setup_state_t; + +static enduser_setup_state_t *state; static int enduser_setup_start(lua_State* L); static int enduser_setup_stop(lua_State* L); static void enduser_setup_station_start(void); +static void enduser_setup_station_start(void); static void enduser_setup_ap_start(void); static void enduser_setup_ap_stop(void); static void enduser_setup_check_station(void); +static void enduser_setup_debug(lua_State *L, const char *str); + + +#define ENDUSER_SETUP_DEBUG_ENABLE 0 +#if ENDUSER_SETUP_DEBUG_ENABLE +#define ENDUSER_SETUP_DEBUG(l, str) enduser_setup_debug(l, str) +#else +#define ENDUSER_SETUP_DEBUG(l, str) +#endif + + +static void enduser_setup_debug(lua_State *L, const char *str) +{ + if(state != NULL && L != NULL && state->lua_dbg_cb_ref != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, state->lua_dbg_cb_ref); + lua_pushstring(L, str); + lua_call(L, 1, 0); + } +} + + +#define ENDUSER_SETUP_ERROR(str, err, err_severity) if (err_severity & ENDUSER_SETUP_ERR_FATAL) enduser_setup_stop(state->lua_L);\ + enduser_setup_error(state->lua_L, str, err);\ + if (!(err_severity & ENDUSER_SETUP_ERR_NO_RETURN)) return err + +#define ENDUSER_SETUP_ERROR_VOID(str, err, err_severity) if (err_severity & ENDUSER_SETUP_ERR_FATAL) enduser_setup_stop(state->lua_L);\ + enduser_setup_error(state->lua_L, str, err);\ + if (!(err_severity & ENDUSER_SETUP_ERR_NO_RETURN)) return + + +static void enduser_setup_error(lua_State *L, const char *str, int err) +{ + ENDUSER_SETUP_DEBUG(L, "enduser_setup_error"); + + if (state != NULL && L != NULL && state->lua_err_cb_ref != LUA_NOREF) + { + lua_rawgeti (L, LUA_REGISTRYINDEX, state->lua_err_cb_ref); + lua_pushnumber(L, err); + lua_pushstring(L, str); + lua_call (L, 2, 0); + } +} + + +static void enduser_setup_connected_callback(lua_State *L) +{ + ENDUSER_SETUP_DEBUG(L, "enduser_setup_connected_callback"); + + if(state != NULL && L != NULL && state->lua_connected_cb_ref != LUA_NOREF) + { + lua_rawgeti(L, LUA_REGISTRYINDEX, state->lua_connected_cb_ref); + lua_call(L, 0, 0); + } +} static void enduser_setup_check_station_start(void) { - PRINT_FUNC("enduser_setup_check_station_start\n"); - os_timer_setfn(&check_station_timer, enduser_setup_check_station, NULL); - os_timer_arm(&check_station_timer, 1*1000, TRUE); + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_check_station_start"); + + os_timer_setfn(&(state->check_station_timer), enduser_setup_check_station, NULL); + os_timer_arm(&(state->check_station_timer), 1*1000, TRUE); } static void enduser_setup_check_station_stop(void) { - PRINT_FUNC("enduser_setup_check_station_stop\n"); + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_check_station_stop"); - os_timer_disarm(&check_station_timer); + os_timer_disarm(&(state->check_station_timer)); } @@ -101,8 +201,7 @@ static void enduser_setup_check_station(void) struct station_config cnf; wifi_station_get_config(&cnf); - uint8_t *ip_byte = (uint8_t *) &(ip.ip); - NODE_DEBUG("Connected to \"%s\" as %u.%u.%u.%u\n", cnf.ssid, IP2STR(&ip)); + enduser_setup_connected_callback(state->lua_L); enduser_setup_stop(NULL); } @@ -138,24 +237,6 @@ static int enduser_setup_srch_str(const char *str, const char *srch_str) } -static void enduser_setup_http_free(void) -{ - http_payload.len = 0; - c_free(http_payload.data); - http_payload.data = NULL; - - if (espconn_http_tcp != NULL) - { - if (espconn_http_tcp->proto.tcp != NULL) - { - c_free(espconn_http_tcp->proto.tcp); - } - c_free(espconn_http_tcp); - espconn_http_tcp = NULL; - } -} - - /** * Load HTTP Payload * @@ -165,46 +246,46 @@ static void enduser_setup_http_free(void) */ static int enduser_setup_http_load_payload(void) { - PRINT_FUNC("enduser_setup_http_load_payload\n"); + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_http_load_payload"); int f = fs_open(http_html_filename, fs_mode2flag("r")); int err = fs_seek(f, 0, FS_SEEK_END); int file_len = (int) fs_tell(f); int err2 = fs_seek(f, 0, FS_SEEK_SET); - + if (f == 0 || err == -1 || err2 == -1) { - NODE_DEBUG("enduser_setup_http_load_payload unable to load file \"%s\", loading backup HTML.\n", http_html_filename); + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_http_load_payload unable to load file index.html, loading backup HTML."); int payload_len = sizeof(http_header_200) + sizeof(http_html_backup); - http_payload.len = payload_len; - http_payload.data = (char *) c_malloc(payload_len); - if (http_payload.data == NULL) + state->http_payload_len = payload_len; + state->http_payload_data = (char *) c_malloc(payload_len); + if (state->http_payload_data == NULL) { return 2; } - + int offset = 0; - c_memcpy(&(http_payload.data[offset]), &(http_header_200), sizeof(http_header_200)); + c_memcpy(&(state->http_payload_data[offset]), &(http_header_200), sizeof(http_header_200)); offset += sizeof(http_header_200); - c_memcpy(&(http_payload.data[offset]), &(http_html_backup), sizeof(http_html_backup)); + c_memcpy(&(state->http_payload_data[offset]), &(http_html_backup), sizeof(http_html_backup)); return 1; } - + int payload_len = sizeof(http_header_200) + file_len; - http_payload.len = payload_len; - http_payload.data = (char *) c_malloc(payload_len); - if (http_payload.data == NULL) + state->http_payload_len = payload_len; + state->http_payload_data = (char *) c_malloc(payload_len); + if (state->http_payload_data == NULL) { return 2; } - + int offset = 0; - c_memcpy(&(http_payload.data[offset]), &(http_header_200), sizeof(http_header_200)); + c_memcpy(&(state->http_payload_data[offset]), &(http_header_200), sizeof(http_header_200)); offset += sizeof(http_header_200); - fs_read(f, &(http_payload.data[offset]), file_len); - + fs_read(f, &(state->http_payload_data[offset]), file_len); + return 0; } @@ -271,7 +352,7 @@ static void enduser_setup_http_urldecode(char *dst, const char *src, int src_len */ static int enduser_setup_http_handle_credentials(char *data, unsigned short data_len) { - PRINT_FUNC("enduser_setup_http_handle_credentials\n"); + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_http_handle_credentials"); char *name_str = (char *) ((uint32_t)strstr(&(data[5]), "?wifi_ssid=") + (uint32_t)strstr(&(data[5]), "&wifi_ssid=")); char *pwd_str = (char *) ((uint32_t)strstr(&(data[5]), "?wifi_password=") + (uint32_t)strstr(&(data[5]), "&wifi_password=")); @@ -291,7 +372,7 @@ static int enduser_setup_http_handle_credentials(char *data, unsigned short data { return 1; } - + struct station_config cnf; c_memset(&cnf, 0, sizeof(struct station_config)); enduser_setup_http_urldecode(cnf.ssid, name_str_start, name_str_len); @@ -300,36 +381,33 @@ static int enduser_setup_http_handle_credentials(char *data, unsigned short data int err = wifi_set_opmode(STATION_MODE | wifi_get_opmode()); if (err == FALSE) { - NODE_DEBUG("enduser_setup_station_start failed. wifi_set_opmode failed.\n"); wifi_set_opmode(~STATION_MODE & wifi_get_opmode()); - return 2; + ENDUSER_SETUP_ERROR("enduser_setup_station_start failed. wifi_set_opmode failed.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_FATAL); } err = wifi_station_set_config(&cnf); if (err == FALSE) { - NODE_DEBUG("enduser_setup_station_start failed. wifi_station_set_config failed.\n"); wifi_set_opmode(~STATION_MODE & wifi_get_opmode()); - return 2; + ENDUSER_SETUP_ERROR("enduser_setup_station_start failed. wifi_station_set_config failed.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_FATAL); } err = wifi_station_disconnect(); if (err == FALSE) { - NODE_DEBUG("enduser_setup_station_start failed. wifi_station_disconnect failed.\n"); + ENDUSER_SETUP_ERROR_VOID("enduser_setup_station_start failed. wifi_station_disconnect failed.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_NONFATAL); } err = wifi_station_connect(); if (err == FALSE) { - NODE_DEBUG("enduser_setup_station_start failed. wifi_station_connect failed.\n"); + ENDUSER_SETUP_ERROR("enduser_setup_station_start failed. wifi_station_connect failed.\n", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_FATAL); } - NODE_DEBUG("\n"); - NODE_DEBUG("WiFi Credentials Stored\n"); - NODE_DEBUG("-----------------------\n"); - NODE_DEBUG("name: \"%s\"\n", cnf.ssid); - NODE_DEBUG("pass: \"%s\"\n", cnf.password); - NODE_DEBUG("bssid_set: %u\n", cnf.bssid_set); - NODE_DEBUG("bssid: \"%s\"\n", cnf.bssid); - NODE_DEBUG("-----------------------\n\n"); + ENDUSER_SETUP_DEBUG(state->lua_L, "WiFi Credentials Stored"); + ENDUSER_SETUP_DEBUG(state->lua_L, "-----------------------"); + ENDUSER_SETUP_DEBUG(state->lua_L, "name: "); + ENDUSER_SETUP_DEBUG(state->lua_L, cnf.ssid); + ENDUSER_SETUP_DEBUG(state->lua_L, "pass: "); + ENDUSER_SETUP_DEBUG(state->lua_L, cnf.password); + ENDUSER_SETUP_DEBUG(state->lua_L, "-----------------------"); return 0; } @@ -337,30 +415,27 @@ static int enduser_setup_http_handle_credentials(char *data, unsigned short data /** * Serve HTML - * + * * @return - return 0 iff html was served successfully */ static int enduser_setup_http_serve_header(struct espconn *http_client, char *header, uint32_t header_len) { - PRINT_FUNC("enduser_setup_http_serve_404\n"); - + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_http_serve_404"); + int8_t err = espconn_sent(http_client, header, header_len); if (err == ESPCONN_MEM) { - NODE_DEBUG("enduser_setup_http_serve_header failed. espconn_send out of memory\n"); - return 1; + ENDUSER_SETUP_ERROR("enduser_setup_http_serve_header failed. espconn_send out of memory", ENDUSER_SETUP_ERR_OUT_OF_MEMORY, ENDUSER_SETUP_ERR_NONFATAL); } else if (err == ESPCONN_ARG) { - NODE_DEBUG("enduser_setup_http_serve_header failed. espconn_send can't find network transmission\n"); - return 1; + ENDUSER_SETUP_ERROR("enduser_setup_http_serve_header failed. espconn_send can't find network transmission", ENDUSER_SETUP_ERR_CONNECTION_NOT_FOUND, ENDUSER_SETUP_ERR_NONFATAL); } else if (err != 0) { - NODE_DEBUG("enduser_setup_http_serve_header failed. espconn_send failed\n"); - return 1; + ENDUSER_SETUP_ERROR("enduser_setup_http_serve_header failed. espconn_send failed", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_NONFATAL); } - + return 0; } @@ -372,28 +447,25 @@ static int enduser_setup_http_serve_header(struct espconn *http_client, char *he */ static int enduser_setup_http_serve_html(struct espconn *http_client) { - PRINT_FUNC("enduser_setup_http_serve_html\n"); + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_http_serve_html"); - if (http_payload.data == NULL) + if (state->http_payload_data == NULL) { enduser_setup_http_load_payload(); } - int8_t err = espconn_sent(http_client, http_payload.data, http_payload.len); + int8_t err = espconn_sent(http_client, state->http_payload_data, state->http_payload_len); if (err == ESPCONN_MEM) { - NODE_DEBUG("enduser_setup_http_serve_html failed. espconn_send out of memory\n"); - return 1; + ENDUSER_SETUP_ERROR("enduser_setup_http_serve_html failed. espconn_send out of memory", ENDUSER_SETUP_ERR_OUT_OF_MEMORY, ENDUSER_SETUP_ERR_NONFATAL); } else if (err == ESPCONN_ARG) { - NODE_DEBUG("enduser_setup_http_serve_html failed. espconn_send can't find network transmission\n"); - return 1; + ENDUSER_SETUP_ERROR("enduser_setup_http_serve_html failed. espconn_send can't find network transmission", ENDUSER_SETUP_ERR_CONNECTION_NOT_FOUND, ENDUSER_SETUP_ERR_NONFATAL); } else if (err != 0) { - NODE_DEBUG("enduser_setup_http_serve_html failed. espconn_send failed\n"); - return 1; + ENDUSER_SETUP_ERROR("enduser_setup_http_serve_html failed. espconn_send failed", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_NONFATAL); } return 0; @@ -407,14 +479,14 @@ static int enduser_setup_http_serve_html(struct espconn *http_client) */ static void enduser_setup_http_disconnect(struct espconn *espconn) { - PRINT_FUNC("enduser_setup_http_disconnect\n"); + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_http_disconnect"); //TODO: Construct and maintain os task queue(?) to be able to issue system_os_task with espconn_disconnect. } static void enduser_setup_http_recvcb(void *arg, char *data, unsigned short data_len) { - PRINT_FUNC("enduser_setup_http_recvcb\n"); + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_http_recvcb"); struct espconn *http_client = (struct espconn *) arg; if (c_strncmp(data, "GET ", 4) != 0) @@ -433,20 +505,18 @@ static void enduser_setup_http_recvcb(void *arg, char *data, unsigned short data } else if (retval == 2) { - NODE_DEBUG("enduser_setup_http_recvcb failed. Failed to handle wifi credentials.\n"); - return; + ENDUSER_SETUP_ERROR_VOID("enduser_setup_http_recvcb failed. Failed to handle wifi credentials.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_NONFATAL); } if (retval != 1) { - NODE_DEBUG("enduser_setup_http_recvcb failed. Unknown error code #%u.\n", retval); - return; + ENDUSER_SETUP_ERROR_VOID("enduser_setup_http_recvcb failed. Unknown error code.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_NONFATAL); } /* Reject requests that probably aren't relevant to free up resources. */ if (c_strncmp(data, "GET / ", 6) != 0) { - PRINT_DEBUG("enduser_setup_http_recvcb received too specific request.\n"); + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_http_recvcb received too specific request."); enduser_setup_http_serve_header(http_client, (char *) http_header_404, sizeof(http_header_404)); enduser_setup_http_disconnect(http_client); return; @@ -455,16 +525,15 @@ static void enduser_setup_http_recvcb(void *arg, char *data, unsigned short data retval = enduser_setup_http_serve_html(http_client); if (retval != 0) { - NODE_DEBUG("enduser_setup_http_recvcb failed. Unable to send HTML.\n"); enduser_setup_http_disconnect(http_client); + ENDUSER_SETUP_ERROR_VOID("enduser_setup_http_recvcb failed. Unable to send HTML.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_NONFATAL); } } static void enduser_setup_http_connectcb(void *arg) { - PRINT_FUNC("enduser_setup_http_connectcb\n"); - + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_http_connectcb"); struct espconn *callback_espconn = (struct espconn *) arg; int8_t err = 0; @@ -472,125 +541,90 @@ static void enduser_setup_http_connectcb(void *arg) if (err != 0) { - NODE_DEBUG("enduser_setup_http_connectcb failed. Callback registration failed.\n"); + ENDUSER_SETUP_ERROR_VOID("enduser_setup_http_connectcb failed. Callback registration failed.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_NONFATAL); } } -static void enduser_setup_http_start(void) +static int enduser_setup_http_start(void) { - PRINT_FUNC("enduser_setup_http_start\n"); - - if (espconn_http_tcp != NULL) + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_http_start"); + state->espconn_http_tcp = (struct espconn *) c_malloc(sizeof(struct espconn)); + if (state->espconn_http_tcp == NULL) { - NODE_DEBUG("enduser_setup_http_start failed. Appears to already be started (espconn_http_tcp != NULL).\n"); - return; + ENDUSER_SETUP_ERROR("enduser_setup_http_start failed. Memory allocation failed (espconn_http_tcp == NULL).", ENDUSER_SETUP_ERR_OUT_OF_MEMORY, ENDUSER_SETUP_ERR_FATAL); } - espconn_http_tcp = (struct espconn *) c_malloc(sizeof(struct espconn)); - if (espconn_http_tcp == NULL) - { - NODE_DEBUG("enduser_setup_http_start failed. Memory allocation failed (espconn_http_tcp == NULL).\n"); - return; - } - esp_tcp *esp_tcp_data = (esp_tcp *) c_malloc(sizeof(esp_tcp)); if (esp_tcp_data == NULL) { - NODE_DEBUG("enduser_setup_http_start failed. Memory allocation failed (esp_udp == NULL).\n"); - enduser_setup_http_free(); - return; + ENDUSER_SETUP_ERROR("enduser_setup_http_start failed. Memory allocation failed (esp_udp == NULL).", ENDUSER_SETUP_ERR_OUT_OF_MEMORY, ENDUSER_SETUP_ERR_FATAL); } - c_memset(espconn_http_tcp, 0, sizeof(struct espconn)); + c_memset(state->espconn_http_tcp, 0, sizeof(struct espconn)); c_memset(esp_tcp_data, 0, sizeof(esp_tcp)); - espconn_http_tcp->proto.tcp = esp_tcp_data; - espconn_http_tcp->type = ESPCONN_TCP; - espconn_http_tcp->state = ESPCONN_NONE; + state->espconn_http_tcp->proto.tcp = esp_tcp_data; + state->espconn_http_tcp->type = ESPCONN_TCP; + state->espconn_http_tcp->state = ESPCONN_NONE; esp_tcp_data->local_port = 80; int8_t err; - err = espconn_regist_connectcb(espconn_http_tcp, enduser_setup_http_connectcb); + err = espconn_regist_connectcb(state->espconn_http_tcp, enduser_setup_http_connectcb); if (err != 0) { - NODE_DEBUG("enduser_setup_http_start failed. Couldn't add receive callback, ERRROR #%u.\n", err); - enduser_setup_http_free(); - return; + ENDUSER_SETUP_ERROR("enduser_setup_http_start failed. Couldn't add receive callback.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_FATAL); } - err = espconn_accept(espconn_http_tcp); + err = espconn_accept(state->espconn_http_tcp); if (err == ESPCONN_ISCONN) { - NODE_DEBUG("enduser_setup_http_start failed. Couldn't create connection, already listening for that connection.\n"); - enduser_setup_http_free(); - return; + ENDUSER_SETUP_ERROR("enduser_setup_http_start failed. Couldn't create connection, already listening for that connection.", ENDUSER_SETUP_ERR_SOCKET_ALREADY_OPEN, ENDUSER_SETUP_ERR_FATAL); } else if (err == ESPCONN_MEM) { - NODE_DEBUG("enduser_setup_http_start failed. Couldn't create connection, out of memory.\n"); - enduser_setup_http_free(); - return; + ENDUSER_SETUP_ERROR("enduser_setup_http_start failed. Couldn't create connection, out of memory.", ENDUSER_SETUP_ERR_OUT_OF_MEMORY, ENDUSER_SETUP_ERR_FATAL); } else if (err == ESPCONN_ARG) { - NODE_DEBUG("enduser_setup_http_start failed. Can't find connection from espconn argument\n"); - enduser_setup_http_free(); - return; + ENDUSER_SETUP_ERROR("enduser_setup_http_start failed. Can't find connection from espconn argument", ENDUSER_SETUP_ERR_CONNECTION_NOT_FOUND, ENDUSER_SETUP_ERR_FATAL); } else if (err != 0) { - NODE_DEBUG("enduser_setup_http_start failed. ERRROR #%u\n", err); - enduser_setup_http_free(); - return; + ENDUSER_SETUP_ERROR("enduser_setup_http_start failed. Unknown error", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_FATAL); } - err = espconn_regist_time(espconn_http_tcp, 2, 0); + err = espconn_regist_time(state->espconn_http_tcp, 2, 0); if (err == ESPCONN_ARG) { - NODE_DEBUG("enduser_setup_http_start failed. Unable to set TCP timeout.\n"); - enduser_setup_http_free(); - return; + ENDUSER_SETUP_ERROR("enduser_setup_http_start failed. Unable to set TCP timeout.", ENDUSER_SETUP_ERR_CONNECTION_NOT_FOUND, ENDUSER_SETUP_ERR_NONFATAL | ENDUSER_SETUP_ERR_NO_RETURN); } err = enduser_setup_http_load_payload(); if (err == 1) { - PRINT_DEBUG("enduser_setup_http_start info. Loaded backup HTML.\n"); + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_http_start info. Loaded backup HTML."); } else if (err == 2) { - NODE_DEBUG("enduser_setup_http_start failed. Unable to allocate memory for HTTP payload.\n"); - enduser_setup_http_free(); - return; + ENDUSER_SETUP_ERROR("enduser_setup_http_start failed. Unable to allocate memory for HTTP payload.", ENDUSER_SETUP_ERR_OUT_OF_MEMORY, ENDUSER_SETUP_ERR_FATAL); } + + return 0; } static void enduser_setup_http_stop(void) { - PRINT_FUNC("enduser_setup_http_stop\n"); + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_http_stop"); - if (espconn_http_tcp == NULL) + if (state != NULL && state->espconn_http_tcp != NULL) { - NODE_DEBUG("enduser_setup_http_stop failed. enduser_setup not enabled (espconn_dns_udp == NULL).\n"); - return; + espconn_delete(state->espconn_http_tcp); } - - int8_t err = espconn_delete(espconn_http_tcp); - if (err == ESPCONN_ARG) - { - NODE_DEBUG("enduser_setup_http_stop failed. espconn_delete returned ESPCONN_ARG. Can't find network transmission described.\n"); - } - else if (err != 0) - { - NODE_DEBUG("enduser_setup_http_stop failed. espconn_delete returned ERROR #%u.\n", err); - } - - enduser_setup_http_free(); } static void enduser_setup_ap_stop(void) { - PRINT_FUNC("enduser_setup_station_stop\n"); + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_station_stop"); wifi_set_opmode(~SOFTAP_MODE & wifi_get_opmode()); } @@ -598,7 +632,7 @@ static void enduser_setup_ap_stop(void) static void enduser_setup_ap_start(void) { - PRINT_FUNC("enduser_setup_ap_start\n"); + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_ap_start"); struct softap_config cnf; char ssid[] = "SetupGadget"; @@ -616,33 +650,32 @@ static void enduser_setup_ap_start(void) static void enduser_setup_dns_recv_callback(void *arg, char *recv_data, unsigned short recv_len) { - PRINT_FUNC("enduser_setup_dns_recv_callback received query for %s\n", &(recv_data[12])); + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_dns_recv_callback."); struct espconn *callback_espconn = arg; struct ip_info ip_info; - uint8_t if_mode = wifi_get_opmode(); - if ((if_mode & SOFTAP_MODE) == 0) - { - NODE_DEBUG("enduser_setup_dns_recv_callback failed. Interface mode %d not supported.\n", if_mode); - return; - } - uint8_t if_index = (if_mode == STATION_MODE? STATION_IF : SOFTAP_IF); - if (wifi_get_ip_info(if_index , &ip_info) == false) - { - NODE_DEBUG("enduser_setup_dns_recv_callback failed. Unable to get interface IP.\n"); - return; - } - uint32_t qname_len = c_strlen(&(recv_data[12])) + 1; // \0=1byte uint32_t dns_reply_static_len = (uint32_t) sizeof(dns_header) + (uint32_t) sizeof(dns_body) + 2 + 4; // dns_id=2bytes, ip=4bytes uint32_t dns_reply_len = dns_reply_static_len + qname_len; - + + uint8_t if_mode = wifi_get_opmode(); + if ((if_mode & SOFTAP_MODE) == 0) + { + ENDUSER_SETUP_ERROR_VOID("enduser_setup_dns_recv_callback failed. Interface mode not supported.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_FATAL); + } + + uint8_t if_index = (if_mode == STATION_MODE? STATION_IF : SOFTAP_IF); + if (wifi_get_ip_info(if_index , &ip_info) == false) + { + ENDUSER_SETUP_ERROR_VOID("enduser_setup_dns_recv_callback failed. Unable to get interface IP.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_FATAL); + } + + char *dns_reply = (char *) c_malloc(dns_reply_len); if (dns_reply == NULL) { - NODE_DEBUG("enduser_setup_dns_recv_callback failed. Failed to allocate memory.\n"); - return; + ENDUSER_SETUP_ERROR_VOID("enduser_setup_dns_recv_callback failed. Failed to allocate memory.", ENDUSER_SETUP_ERR_OUT_OF_MEMORY, ENDUSER_SETUP_ERR_NONFATAL); } uint32_t insert_byte = 0; @@ -655,136 +688,201 @@ static void enduser_setup_dns_recv_callback(void *arg, char *recv_data, unsigned c_memcpy(&(dns_reply[insert_byte]), dns_body, sizeof(dns_body)); insert_byte += (uint32_t) sizeof(dns_body); c_memcpy(&(dns_reply[insert_byte]), &(ip_info.ip), 4); - + int8_t err; err = espconn_sent(callback_espconn, dns_reply, dns_reply_len); c_free(dns_reply); if (err == ESPCONN_MEM) { - NODE_DEBUG("enduser_setup_dns_recv_callback failed. Failed to allocate memory for send.\n"); - return; + ENDUSER_SETUP_ERROR_VOID("enduser_setup_dns_recv_callback failed. Failed to allocate memory for send.", ENDUSER_SETUP_ERR_OUT_OF_MEMORY, ENDUSER_SETUP_ERR_FATAL); } else if (err == ESPCONN_ARG) { - NODE_DEBUG("enduser_setup_dns_recv_callback failed. Can't execute transmission.\n"); - return; + ENDUSER_SETUP_ERROR_VOID("enduser_setup_dns_recv_callback failed. Can't execute transmission.", ENDUSER_SETUP_ERR_CONNECTION_NOT_FOUND, ENDUSER_SETUP_ERR_FATAL); } else if (err != 0) { - NODE_DEBUG("enduser_setup_dns_recv_callback failed. espconn_send failed\n"); - return; + ENDUSER_SETUP_ERROR_VOID("enduser_setup_dns_recv_callback failed. espconn_send failed", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_FATAL); } } -static void enduser_setup_dns_free(void) +static void enduser_setup_free(void) { - PRINT_FUNC("enduser_setup_dns_free\n"); + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_free"); - if (espconn_dns_udp != NULL) + if (state == NULL) { - if (espconn_dns_udp->proto.udp != NULL) + return; + } + + if (state->espconn_dns_udp != NULL) + { + if (state->espconn_dns_udp->proto.udp != NULL) { - c_free(espconn_dns_udp->proto.udp); + c_free(state->espconn_dns_udp->proto.udp); } - c_free(espconn_dns_udp); - espconn_dns_udp = NULL; + c_free(state->espconn_dns_udp); } + + if (state->espconn_http_tcp != NULL) + { + if (state->espconn_http_tcp->proto.tcp != NULL) + { + c_free(state->espconn_http_tcp->proto.tcp); + } + c_free(state->espconn_http_tcp); + } + c_free(state->http_payload_data); + c_free(state); + state = NULL; } -static void enduser_setup_dns_start(void) +static int enduser_setup_dns_start(void) { - PRINT_FUNC("enduser_setup_dns_started\n"); + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_dns_start"); - if (espconn_dns_udp != NULL) + if (state->espconn_dns_udp != NULL) { - NODE_DEBUG("enduser_setup_dns_start failed. Appears to already be started (espconn_dns_udp != NULL).\n"); - return; + ENDUSER_SETUP_ERROR("enduser_setup_dns_start failed. Appears to already be started (espconn_dns_udp != NULL).", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_FATAL); } - espconn_dns_udp = (struct espconn *) c_malloc(sizeof(struct espconn)); - if (espconn_dns_udp == NULL) + state->espconn_dns_udp = (struct espconn *) c_malloc(sizeof(struct espconn)); + if (state->espconn_dns_udp == NULL) { - NODE_DEBUG("enduser_setup_dns_start failed. Memory allocation failed (espconn_dns_udp == NULL).\n"); - return; + ENDUSER_SETUP_ERROR("enduser_setup_dns_start failed. Memory allocation failed (espconn_dns_udp == NULL).", ENDUSER_SETUP_ERR_OUT_OF_MEMORY, ENDUSER_SETUP_ERR_FATAL); } esp_udp *esp_udp_data = (esp_udp *) c_malloc(sizeof(esp_udp)); if (esp_udp_data == NULL) { - NODE_DEBUG("enduser_setup_dns_start failed. Memory allocation failed (esp_udp == NULL).\n"); - enduser_setup_dns_free(); - return; + ENDUSER_SETUP_ERROR("enduser_setup_dns_start failed. Memory allocation failed (esp_udp == NULL).", ENDUSER_SETUP_ERR_OUT_OF_MEMORY, ENDUSER_SETUP_ERR_FATAL); } - c_memset(espconn_dns_udp, 0, sizeof(struct espconn)); + c_memset(state->espconn_dns_udp, 0, sizeof(struct espconn)); c_memset(esp_udp_data, 0, sizeof(esp_udp)); - espconn_dns_udp->proto.udp = esp_udp_data; - espconn_dns_udp->type = ESPCONN_UDP; - espconn_dns_udp->state = ESPCONN_NONE; + state->espconn_dns_udp->proto.udp = esp_udp_data; + state->espconn_dns_udp->type = ESPCONN_UDP; + state->espconn_dns_udp->state = ESPCONN_NONE; esp_udp_data->local_port = 53; int8_t err; - err = espconn_regist_recvcb(espconn_dns_udp, enduser_setup_dns_recv_callback); + err = espconn_regist_recvcb(state->espconn_dns_udp, enduser_setup_dns_recv_callback); if (err != 0) { - NODE_DEBUG("enduser_setup_dns_start failed. Couldn't add receive callback, ERRROR #%d.\n", err); - enduser_setup_dns_free(); - return; + ENDUSER_SETUP_ERROR("enduser_setup_dns_start failed. Couldn't add receive callback, unknown error.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_FATAL); } - err = espconn_create(espconn_dns_udp); + err = espconn_create(state->espconn_dns_udp); if (err == ESPCONN_ISCONN) { - NODE_DEBUG("enduser_setup_dns_start failed. Couldn't create connection, already listening for that connection.\n"); - enduser_setup_dns_free(); - return; + ENDUSER_SETUP_ERROR("enduser_setup_dns_start failed. Couldn't create connection, already listening for that connection.", ENDUSER_SETUP_ERR_SOCKET_ALREADY_OPEN, ENDUSER_SETUP_ERR_FATAL); } else if (err == ESPCONN_MEM) { - NODE_DEBUG("enduser_setup_dns_start failed. Couldn't create connection, out of memory.\n"); - enduser_setup_dns_free(); - return; + ENDUSER_SETUP_ERROR("enduser_setup_dns_start failed. Couldn't create connection, out of memory.", ENDUSER_SETUP_ERR_OUT_OF_MEMORY, ENDUSER_SETUP_ERR_FATAL); } else if (err != 0) { - NODE_DEBUG("enduser_setup_dns_start failed. Couldn't create connection, ERROR #%d.\n", err); - enduser_setup_dns_free(); - return; + ENDUSER_SETUP_ERROR("enduser_setup_dns_start failed. Couldn't create connection, unknown error.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_FATAL); } + + return 0; } static void enduser_setup_dns_stop(void) { - PRINT_FUNC("enduser_setup_dns_stop\n"); + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_dns_stop"); - if (espconn_dns_udp == NULL) + if (state->espconn_dns_udp != NULL) { - NODE_DEBUG("enduser_setup_dns_stop failed. Hijacker not enabled (espconn_dns_udp == NULL).\n"); - return; + espconn_delete(state->espconn_dns_udp); } - - int8_t err = espconn_delete(espconn_dns_udp); - if (err == ESPCONN_ARG) - { - NODE_DEBUG("enduser_setup_http_stop failed. espconn_delete returned ESPCONN_ARG. Can't find network transmission described.\n"); - } - else if (err != 0) - { - NODE_DEBUG("enduser_setup_http_stop failed. espconn_delete returned ERROR #%u.\n", err); - } - - enduser_setup_dns_free(); } -static int enduser_setup_start(lua_State* L) +static int enduser_setup_init(lua_State *L) { + ENDUSER_SETUP_DEBUG(L, "enduser_setup_init"); + + if (state != NULL) + { + enduser_setup_error(L, "enduser_setup_init failed. Appears to already be started.", ENDUSER_SETUP_ERR_UNKOWN_ERROR); + return ENDUSER_SETUP_ERR_UNKOWN_ERROR; + } + + state = (enduser_setup_state_t *) os_malloc(sizeof(enduser_setup_state_t)); + if (state == NULL) + { + enduser_setup_error(L, "enduser_setup_init failed. Unable to allocate memory.", ENDUSER_SETUP_ERR_OUT_OF_MEMORY); + return ENDUSER_SETUP_ERR_OUT_OF_MEMORY; + } + c_memset(state, 0, sizeof(enduser_setup_state_t)); + + state->lua_L = L; + state->lua_connected_cb_ref = LUA_NOREF; + state->lua_err_cb_ref = LUA_NOREF; + state->lua_dbg_cb_ref = LUA_NOREF; + + if (!lua_isnoneornil(L, 1)) + { + lua_pushvalue(L, 1); + state->lua_connected_cb_ref = luaL_ref(L, LUA_REGISTRYINDEX); + } + else + { + state->lua_connected_cb_ref = LUA_NOREF; + } + + if (!lua_isnoneornil(L, 2)) + { + lua_pushvalue (L, 2); + state->lua_err_cb_ref = luaL_ref(L, LUA_REGISTRYINDEX); + } + else + { + state->lua_err_cb_ref = LUA_NOREF; + } + + if (!lua_isnoneornil(L, 3)) + { + lua_pushvalue (L, 3); + state->lua_dbg_cb_ref = luaL_ref(L, LUA_REGISTRYINDEX); + } + else + { + state->lua_dbg_cb_ref = LUA_NOREF; + } + + return 0; +} + + +static int enduser_setup_start(lua_State *L) +{ + ENDUSER_SETUP_DEBUG(L, "enduser_setup_start"); + + if(enduser_setup_init(L)) + { + enduser_setup_stop(L); + return 0; + } + enduser_setup_check_station_start(); enduser_setup_ap_start(); - enduser_setup_dns_start(); - enduser_setup_http_start(); + + if(enduser_setup_dns_start()) + { + enduser_setup_stop(L); + return 0; + } + + if(enduser_setup_http_start()) + { + enduser_setup_stop(L); + return 0; + } return 0; } @@ -796,6 +894,7 @@ static int enduser_setup_stop(lua_State* L) enduser_setup_ap_stop(); enduser_setup_dns_stop(); enduser_setup_http_stop(); + enduser_setup_free(); return 0; } From a15097659beb5a9e312d19d8054284c13f4876de Mon Sep 17 00:00:00 2001 From: Robert Foss Date: Sat, 19 Sep 2015 15:22:01 -0400 Subject: [PATCH 07/11] Disabled enduser_setup module --- app/include/user_modules.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/include/user_modules.h b/app/include/user_modules.h index 60d4e93b..cfbb94f4 100644 --- a/app/include/user_modules.h +++ b/app/include/user_modules.h @@ -28,7 +28,7 @@ #define LUA_USE_MODULES_BIT #define LUA_USE_MODULES_MQTT #define LUA_USE_MODULES_COAP -#define LUA_USE_MODULES_ENDUSER_SETUP // USE_DNS in dhcpserver.h needs to be enabled for this module to work. +//#define LUA_USE_MODULES_ENDUSER_SETUP // USE_DNS in dhcpserver.h needs to be enabled for this module to work. #define LUA_USE_MODULES_U8G // #define LUA_USE_MODULES_WS2801 #define LUA_USE_MODULES_WS2812 From 721fadfd148f41015d3c6cc0c15187109159b6e5 Mon Sep 17 00:00:00 2001 From: Robert Foss Date: Sun, 27 Sep 2015 14:02:25 -0400 Subject: [PATCH 08/11] Changed SSID to be suffixed by MAC. --- app/modules/enduser_setup.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/app/modules/enduser_setup.c b/app/modules/enduser_setup.c index 1d0823a8..d5019890 100644 --- a/app/modules/enduser_setup.c +++ b/app/modules/enduser_setup.c @@ -43,6 +43,8 @@ #include "espconn.h" #include "flash_fs.h" +#define ENDUSER_SETUP_AP_SSID "SetupGadget" + #define MIN(x, y) (((x) < (y)) ? (x) : (y)) #define ENDUSER_SETUP_ERR_FATAL (1 << 0) @@ -635,9 +637,23 @@ static void enduser_setup_ap_start(void) ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_ap_start"); struct softap_config cnf; - char ssid[] = "SetupGadget"; - c_memcpy(&(cnf.ssid), ssid, c_strlen(ssid)); - cnf.ssid_len = c_strlen(ssid); + c_memset(&(cnf), 0, sizeof(struct softap_config)); + + char ssid[] = ENDUSER_SETUP_AP_SSID; + int ssid_name_len = c_strlen(ENDUSER_SETUP_AP_SSID); + c_memcpy(&(cnf.ssid), ssid, ssid_name_len); + + uint8_t mac[6]; + wifi_get_macaddr(SOFTAP_IF, mac); + cnf.ssid[ssid_name_len] = '_'; + cnf.ssid[ssid_name_len + 1] = (char) (65 + (0x0F & mac[3])); + cnf.ssid[ssid_name_len + 2] = (char) (65 + ((0xF0 & mac[3]) >> 4)); + cnf.ssid[ssid_name_len + 3] = (char) (65 + (0x0F & mac[4])); + cnf.ssid[ssid_name_len + 4] = (char) (65 + ((0xF0 & mac[4]) >> 4)); + cnf.ssid[ssid_name_len + 5] = (char) (65 + (0x0F & mac[5])); + cnf.ssid[ssid_name_len + 6] = (char) (65 + ((0xF0 & mac[5]) >> 4)); + + cnf.ssid_len = c_strlen(ssid) + 7; cnf.channel = 1; cnf.authmode = AUTH_OPEN; cnf.ssid_hidden = 0; From ee82b2ad12cf8900e66aeeeac8b0d3888a7aa965 Mon Sep 17 00:00:00 2001 From: Robert Foss Date: Wed, 30 Sep 2015 13:24:18 -0400 Subject: [PATCH 09/11] Moved SSID define to user_config.h --- app/include/user_config.h | 2 ++ app/modules/enduser_setup.c | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/include/user_config.h b/app/include/user_config.h index f5d33fb9..d7769351 100644 --- a/app/include/user_config.h +++ b/app/include/user_config.h @@ -68,6 +68,8 @@ #define LED_LOW_COUNT_DEFAULT 0 #endif +#define ENDUSER_SETUP_AP_SSID "SetupGadget" + #define STRBUF_DEFAULT_INCREMENT 32 #endif /* __USER_CONFIG_H__ */ diff --git a/app/modules/enduser_setup.c b/app/modules/enduser_setup.c index d5019890..50eec9a4 100644 --- a/app/modules/enduser_setup.c +++ b/app/modules/enduser_setup.c @@ -43,7 +43,6 @@ #include "espconn.h" #include "flash_fs.h" -#define ENDUSER_SETUP_AP_SSID "SetupGadget" #define MIN(x, y) (((x) < (y)) ? (x) : (y)) From 90f770412dd6d955f12ec70116ddb53587a43a7d Mon Sep 17 00:00:00 2001 From: Robert Foss Date: Wed, 30 Sep 2015 14:11:43 -0400 Subject: [PATCH 10/11] Switched from HTTP GET to HTTP POST. --- app/modules/enduser_setup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/modules/enduser_setup.c b/app/modules/enduser_setup.c index 50eec9a4..cee378de 100644 --- a/app/modules/enduser_setup.c +++ b/app/modules/enduser_setup.c @@ -75,7 +75,7 @@ static const char dns_body[] = { 0x00, 0x01, 0x00, 0x01, static const char http_html_filename[] = "index.html"; static const char http_header_200[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n"; static const char http_header_404[] = "HTTP/1.1 404 Not Found\r\n"; -static const char http_html_backup[] = "Connect gadget to you WiFi

WiFi Login

Connect gadget to your WiFi

"; +static const char http_html_backup[] = "Connect gadget to you WiFi

WiFi Login

Connect gadget to your WiFi

"; typedef struct From 8683ea4f1b6746305adc6c9eb275f16839478fd8 Mon Sep 17 00:00:00 2001 From: Robert Foss Date: Thu, 1 Oct 2015 14:22:45 -0400 Subject: [PATCH 11/11] Fixed previous POST patch. Also cleaned up HTTP request handling. --- app/modules/enduser_setup.c | 81 ++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/app/modules/enduser_setup.c b/app/modules/enduser_setup.c index cee378de..8a2b49db 100644 --- a/app/modules/enduser_setup.c +++ b/app/modules/enduser_setup.c @@ -355,15 +355,15 @@ static int enduser_setup_http_handle_credentials(char *data, unsigned short data { ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_http_handle_credentials"); - char *name_str = (char *) ((uint32_t)strstr(&(data[5]), "?wifi_ssid=") + (uint32_t)strstr(&(data[5]), "&wifi_ssid=")); - char *pwd_str = (char *) ((uint32_t)strstr(&(data[5]), "?wifi_password=") + (uint32_t)strstr(&(data[5]), "&wifi_password=")); + char *name_str = (char *) ((uint32_t)strstr(&(data[6]), "wifi_ssid=")); + char *pwd_str = (char *) ((uint32_t)strstr(&(data[6]), "wifi_password=")); if (name_str == NULL || pwd_str == NULL) { return 1; } - int name_field_len = sizeof("?wifi_ssid=") - 1; - int pwd_field_len = sizeof("?wifi_password=") - 1; + int name_field_len = sizeof("wifi_ssid=") - 1; + int pwd_field_len = sizeof("wifi_password=") - 1; char *name_str_start = name_str + name_field_len; char *pwd_str_start = pwd_str + pwd_field_len; @@ -489,46 +489,51 @@ static void enduser_setup_http_recvcb(void *arg, char *data, unsigned short data { ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_http_recvcb"); struct espconn *http_client = (struct espconn *) arg; + int retval; - if (c_strncmp(data, "GET ", 4) != 0) + if (c_strncmp(data, "POST ", 5) == 0) + { + retval = enduser_setup_http_handle_credentials(data, data_len); + if (retval == 0) + { + enduser_setup_http_serve_header(http_client, (char *) http_header_200, sizeof(http_header_200)); + enduser_setup_http_disconnect(http_client); + return; + } + else if (retval == 2) + { + ENDUSER_SETUP_ERROR_VOID("enduser_setup_http_recvcb failed. Failed to handle wifi credentials.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_NONFATAL); + } + + if (retval != 1) + { + ENDUSER_SETUP_ERROR_VOID("enduser_setup_http_recvcb failed. Unknown error code.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_NONFATAL); + } + } + else if (c_strncmp(data, "GET ", 4) == 0) + { + /* Reject requests that probably aren't relevant to free up resources. */ + if (c_strncmp(data, "GET / ", 6) != 0) + { + ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_http_recvcb received too specific request."); + enduser_setup_http_serve_header(http_client, (char *) http_header_404, sizeof(http_header_404)); + enduser_setup_http_disconnect(http_client); + return; + } + + retval = enduser_setup_http_serve_html(http_client); + if (retval != 0) + { + enduser_setup_http_disconnect(http_client); + ENDUSER_SETUP_ERROR_VOID("enduser_setup_http_recvcb failed. Unable to send HTML.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_NONFATAL); + } + } + else { enduser_setup_http_serve_header(http_client, (char *) http_header_404, sizeof(http_header_404)); enduser_setup_http_disconnect(http_client); return; } - - int retval = enduser_setup_http_handle_credentials(data, data_len); - if (retval == 0) - { - enduser_setup_http_serve_header(http_client, (char *) http_header_200, sizeof(http_header_200)); - enduser_setup_http_disconnect(http_client); - return; - } - else if (retval == 2) - { - ENDUSER_SETUP_ERROR_VOID("enduser_setup_http_recvcb failed. Failed to handle wifi credentials.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_NONFATAL); - } - - if (retval != 1) - { - ENDUSER_SETUP_ERROR_VOID("enduser_setup_http_recvcb failed. Unknown error code.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_NONFATAL); - } - - /* Reject requests that probably aren't relevant to free up resources. */ - if (c_strncmp(data, "GET / ", 6) != 0) - { - ENDUSER_SETUP_DEBUG(state->lua_L, "enduser_setup_http_recvcb received too specific request."); - enduser_setup_http_serve_header(http_client, (char *) http_header_404, sizeof(http_header_404)); - enduser_setup_http_disconnect(http_client); - return; - } - - retval = enduser_setup_http_serve_html(http_client); - if (retval != 0) - { - enduser_setup_http_disconnect(http_client); - ENDUSER_SETUP_ERROR_VOID("enduser_setup_http_recvcb failed. Unable to send HTML.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_NONFATAL); - } }