/* Copyright (c) 2017-2019 Tony Pottier Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @file network_manager.h @author Tony Pottier @brief Defines all functions necessary for esp32 to connect to a wifi/scan wifis Contains the freeRTOS task and all necessary support @see https://idyl.io @see https://github.com/tonyp7/esp32-wifi-manager */ #ifndef WIFI_MANAGER_H_INCLUDED #define WIFI_MANAGER_H_INCLUDED #ifdef __cplusplus extern "C" { #endif #include "esp_system.h" #include "esp_wifi.h" #include "esp_wifi_types.h" #include "squeezelite-ota.h" #include "cJSON.h" #include "esp_eth.h" #include "freertos/event_groups.h" #include "state_machine.h" #include "state_machine.h" /** * @brief Defines the maximum size of a SSID name. 32 is IEEE standard. * @warning limit is also hard coded in wifi_config_t. Never extend this value. */ #define MAX_SSID_SIZE 32 /** * @brief Defines the maximum size of a WPA2 passkey. 64 is IEEE standard. * @warning limit is also hard coded in wifi_config_t. Never extend this value. */ #define MAX_PASSWORD_SIZE 64 #define MAX_COMMAND_LINE_SIZE 201 /** * @brief Defines the maximum number of access points that can be scanned. * * To save memory and avoid nasty out of memory errors, * we can limit the number of APs detected in a wifi scan. */ #define MAX_AP_NUM 15 /** * @brief Defines when a connection is lost/attempt to connect is made, how many retries should be made before giving up. * Setting it to 2 for instance means there will be 3 attempts in total (original request + 2 retries) */ #define WIFI_MANAGER_MAX_RETRY CONFIG_WIFI_MANAGER_MAX_RETRY /** @brief Defines the task priority of the wifi_manager. * * Tasks spawn by the manager will have a priority of WIFI_MANAGER_TASK_PRIORITY-1. * For this particular reason, minimum task priority is 1. It it highly not recommended to set * it to 1 though as the sub-tasks will now have a priority of 0 which is the priority * of freeRTOS' idle task. */ #define WIFI_MANAGER_TASK_PRIORITY CONFIG_WIFI_MANAGER_TASK_PRIORITY /** @brief Defines the auth mode as an access point * Value must be of type wifi_auth_mode_t * @see esp_wifi_types.h * @warning if set to WIFI_AUTH_OPEN, passowrd me be empty. See DEFAULT_AP_PASSWORD. */ #define AP_AUTHMODE WIFI_AUTH_WPA2_PSK /** @brief Defines visibility of the access point. 0: visible AP. 1: hidden */ #define DEFAULT_AP_SSID_HIDDEN 0 /** @brief Defines access point's name. Default value: esp32. Run 'make menuconfig' to setup your own value or replace here by a string */ #define DEFAULT_AP_SSID CONFIG_DEFAULT_AP_SSID /** @brief Defines access point's password. * @warning In the case of an open access point, the password must be a null string "" or "\0" if you want to be verbose but waste one byte. * In addition, the AP_AUTHMODE must be WIFI_AUTH_OPEN */ #define DEFAULT_AP_PASSWORD CONFIG_DEFAULT_AP_PASSWORD /** @brief Defines access point's bandwidth. * Value: WIFI_BW_HT20 for 20 MHz or WIFI_BW_HT40 for 40 MHz * 20 MHz minimize channel interference but is not suitable for * applications with high data speeds */ #define DEFAULT_AP_BANDWIDTH WIFI_BW_HT20 /** @brief Defines access point's channel. * Channel selection is only effective when not connected to another AP. * Good practice for minimal channel interference to use * For 20 MHz: 1, 6 or 11 in USA and 1, 5, 9 or 13 in most parts of the world * For 40 MHz: 3 in USA and 3 or 11 in most parts of the world */ #define DEFAULT_AP_CHANNEL CONFIG_DEFAULT_AP_CHANNEL /** @brief Defines the access point's default IP address. Default: "10.10.0.1 */ #define DEFAULT_AP_IP CONFIG_DEFAULT_AP_IP /** @brief Defines the access point's gateway. This should be the same as your IP. Default: "10.10.0.1" */ #define DEFAULT_AP_GATEWAY CONFIG_DEFAULT_AP_GATEWAY /** @brief Defines the access point's netmask. Default: "255.255.255.0" */ #define DEFAULT_AP_NETMASK CONFIG_DEFAULT_AP_NETMASK /** @brief Defines access point's maximum number of clients. Default: 4 */ #define DEFAULT_AP_MAX_CONNECTIONS CONFIG_DEFAULT_AP_MAX_CONNECTIONS /** @brief Defines access point's beacon interval. 100ms is the recommended default. */ #define DEFAULT_AP_BEACON_INTERVAL CONFIG_DEFAULT_AP_BEACON_INTERVAL /** @brief Defines if esp32 shall run both AP + STA when connected to another AP. * Value: 0 will have the own AP always on (APSTA mode) * Value: 1 will turn off own AP when connected to another AP (STA only mode when connected) * Turning off own AP when connected to another AP minimize channel interference and increase throughput */ #define DEFAULT_STA_ONLY 1 /** @brief Defines if wifi power save shall be enabled. * Value: WIFI_PS_NONE for full power (wifi modem always on) * Value: WIFI_PS_MODEM for power save (wifi modem sleep periodically) * Note: Power save is only effective when in STA only mode */ #define DEFAULT_STA_POWER_SAVE WIFI_PS_MIN_MODEM /** * @brief Defines the maximum length in bytes of a JSON representation of an access point. * * maximum ap string length with full 32 char ssid: 75 + \\n + \0 = 77\n * example: {"ssid":"abcdefghijklmnopqrstuvwxyz012345","chan":12,"rssi":-100,"auth":4},\n * BUT: we need to escape JSON. Imagine a ssid full of \" ? so it's 32 more bytes hence 77 + 32 = 99.\n * this is an edge case but I don't think we should crash in a catastrophic manner just because * someone decided to have a funny wifi name. */ #define JSON_ONE_APP_SIZE 99 /** * @brief Defines the complete list of all messages that the wifi_manager can process. * * Some of these message are events ("EVENT"), and some of them are action ("ORDER") * Each of these messages can trigger a callback function and each callback function is stored * in a function pointer array for convenience. Because of this behavior, it is extremely important * to maintain a strict sequence and the top level special element 'MESSAGE_CODE_COUNT' * * @see wifi_manager_set_callback */ typedef enum message_code_t { NONE = 0, ORDER_START_HTTP_SERVER = 1, ORDER_STOP_HTTP_SERVER = 2, ORDER_START_DNS_SERVICE = 3, ORDER_STOP_DNS_SERVICE = 4, ORDER_START_WIFI_SCAN = 5, ORDER_LOAD_AND_RESTORE_STA = 6, ORDER_CONNECT_STA = 7, ORDER_DISCONNECT_STA = 8, ORDER_START_AP = 9, ORDER_START_HTTP = 10, ORDER_START_DNS_HIJACK = 11, EVENT_STA_DISCONNECTED = 12, EVENT_SCAN_DONE = 13, EVENT_GOT_IP = 14, ORDER_RESTART_OTA = 15, ORDER_RESTART_RECOVERY = 16, ORDER_RESTART_OTA_URL = 17, ORDER_RESTART = 18, ORDER_UPDATE_STATUS = 19, EVENT_ETH_GOT_IP = 20, EVENT_ETH_TIMEOUT = 21, EVENT_ETH_LINK_UP = 22, EVENT_ETH_LINK_DOWN = 23, MESSAGE_CODE_COUNT = 24 /* important for the callback array */ }message_code_t; /* @brief indicate that the ESP32 is currently connected. */ extern const int WIFI_MANAGER_WIFI_CONNECTED_BIT; extern const int WIFI_MANAGER_AP_STA_CONNECTED_BIT; /* @brief Set automatically once the SoftAP is started */ extern const int WIFI_MANAGER_AP_STARTED_BIT; /* @brief When set, means a client requested to connect to an access point.*/ extern const int WIFI_MANAGER_REQUEST_STA_CONNECT_BIT; /* @brief This bit is set automatically as soon as a connection was lost */ extern const int WIFI_MANAGER_STA_DISCONNECT_BIT ; /* @brief When set, means the wifi manager attempts to restore a previously saved connection at startup. */ extern const int WIFI_MANAGER_REQUEST_RESTORE_STA_BIT ; /* @brief When set, means a client requested to disconnect from currently connected AP. */ extern const int WIFI_MANAGER_REQUEST_WIFI_DISCONNECT_BIT ; /* @brief When set, means a scan is in progress */ extern const int WIFI_MANAGER_SCAN_BIT ; /* @brief When set, means user requested for a disconnect */ extern const int WIFI_MANAGER_REQUEST_DISCONNECT_BIT ; /* @brief When set, means user requested connecting to a new network and it failed */ extern const int WIFI_MANAGER_REQUEST_STA_CONNECT_FAILED_BIT ; void network_manager_reboot_ota(char * url); /** * @brief simplified reason codes for a lost connection. * * esp-idf maintains a big list of reason codes which in practice are useless for most typical application. */ typedef enum update_reason_code_t { UPDATE_CONNECTION_OK = 0, UPDATE_FAILED_ATTEMPT = 1, UPDATE_USER_DISCONNECT = 2, UPDATE_LOST_CONNECTION = 3, UPDATE_FAILED_ATTEMPT_AND_RESTORE = 4, UPDATE_ETHERNET_CONNECTED = 5 }update_reason_code_t; typedef enum connection_request_made_by_code_t{ CONNECTION_REQUEST_NONE = 0, CONNECTION_REQUEST_USER = 1, CONNECTION_REQUEST_AUTO_RECONNECT = 2, CONNECTION_REQUEST_RESTORE_CONNECTION = 3, CONNECTION_REQUEST_MAX_FAILED = 4, CONNECTION_REQUEST_MAX = 0x7fffffff /*force the creation of this enum as a 32 bit int */ }connection_request_made_by_code_t; /** * The wifi manager settings in use */ //struct wifi_settings_t{ // bool sta_only; // bool sta_static_ip; // wifi_ps_type_t sta_power_save; // tcpip_adapter_ip_info_t sta_static_ip_config; //}; //extern struct wifi_settings_t wifi_settings; // /** // * @brief Structure used to store one message in the queue. // */ // typedef struct{ // message_code_t code; // void *param; // } queue_message; /** * Frees up all memory allocated by the wifi_manager and kill the task. */ void network_manager_destroy(); /** * Filters the AP scan list to unique SSIDs */ void filter_unique( wifi_ap_record_t * aplist, uint16_t * ap_num); /** * Main task for the wifi_manager */ void network_manager( void * pvParameters ); char* wifi_manager_alloc_get_ap_list_json(); cJSON * wifi_manager_clear_ap_list_json(cJSON **old); /** * @brief A standard wifi event handler as recommended by Espressif */ esp_err_t wifi_manager_event_handler(void *ctx, system_event_t *event); /** * @brief Clears the connection status json. * @note This is not thread-safe and should be called only if wifi_manager_lock_json_buffer call is successful. */ cJSON * wifi_manager_clear_ip_info_json(cJSON **old); cJSON * wifi_manager_get_new_json(cJSON **old); /** * @brief Start the mDNS service */ void wifi_manager_initialise_mdns(); /** * @brief Register a callback to a custom function when specific event message_code happens. */ void wifi_manager_set_callback(message_code_t message_code, void (*func_ptr)(void*) ); bool network_manager_is_flag_set(EventBits_t bit); void network_manager_set_flag(EventBits_t bit); void network_manager_clear_flag(EventBits_t bit); #ifdef __cplusplus } #endif #endif /* WIFI_MANAGER_H_INCLUDED */