Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
ESP8266Interface.h
00001 /* ESP8266 implementation of NetworkInterfaceAPI 00002 * Copyright (c) 2015 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef ESP8266_INTERFACE_H 00018 #define ESP8266_INTERFACE_H 00019 00020 #if DEVICE_SERIAL && DEVICE_INTERRUPTIN && defined(MBED_CONF_EVENTS_PRESENT) && defined(MBED_CONF_NSAPI_PRESENT) && defined(MBED_CONF_RTOS_API_PRESENT) 00021 #include "drivers/DigitalOut.h" 00022 #include "drivers/Timer.h" 00023 #include "ESP8266/ESP8266.h" 00024 #include "events/EventQueue.h" 00025 #include "events/mbed_shared_queues.h" 00026 #include "features/netsocket/NetworkInterface.h" 00027 #include "features/netsocket/NetworkStack.h" 00028 #include "features/netsocket/nsapi_types.h" 00029 #include "features/netsocket/SocketAddress.h" 00030 #include "features/netsocket/WiFiAccessPoint.h" 00031 #include "features/netsocket/WiFiInterface.h" 00032 #include "platform/Callback.h" 00033 #if MBED_CONF_RTOS_PRESENT 00034 #include "rtos/ConditionVariable.h" 00035 #endif 00036 #include "rtos/Mutex.h" 00037 00038 #define ESP8266_SOCKET_COUNT 5 00039 00040 #define ESP8266_INTERFACE_CONNECT_INTERVAL_MS (5000) 00041 #define ESP8266_INTERFACE_CONNECT_TIMEOUT_MS (2 * ESP8266_CONNECT_TIMEOUT + ESP8266_INTERFACE_CONNECT_INTERVAL_MS) 00042 00043 #ifdef TARGET_FF_ARDUINO 00044 #ifndef MBED_CONF_ESP8266_TX 00045 #define MBED_CONF_ESP8266_TX D1 00046 #endif 00047 00048 #ifndef MBED_CONF_ESP8266_RX 00049 #define MBED_CONF_ESP8266_RX D0 00050 #endif 00051 #endif /* TARGET_FF_ARDUINO */ 00052 00053 #ifndef MBED_CONF_ESP8266_COUNTRY_CODE 00054 #define MBED_CONF_ESP8266_COUNTRY_CODE "CN" 00055 #endif 00056 00057 #ifndef MBED_CONF_ESP8266_CHANNEL_START 00058 #define MBED_CONF_ESP8266_CHANNEL_START 1 00059 #endif 00060 00061 #ifndef MBED_CONF_ESP8266_CHANNELS 00062 #define MBED_CONF_ESP8266_CHANNELS 13 00063 #endif 00064 00065 /** ESP8266Interface class 00066 * Implementation of the NetworkStack for the ESP8266 00067 */ 00068 class ESP8266Interface : public NetworkStack, public WiFiInterface { 00069 public: 00070 #if defined MBED_CONF_ESP8266_TX && defined MBED_CONF_ESP8266_RX 00071 /** 00072 * @brief ESP8266Interface default constructor 00073 * Will use values defined in mbed_lib.json 00074 */ 00075 ESP8266Interface(); 00076 #endif 00077 00078 /** ESP8266Interface lifetime 00079 * @param tx TX pin 00080 * @param rx RX pin 00081 * @param debug Enable debugging 00082 */ 00083 ESP8266Interface(PinName tx, PinName rx, bool debug = false, PinName rts = NC, PinName cts = NC, PinName rst = NC, PinName pwr = NC); 00084 00085 /** 00086 * @brief ESP8266Interface default destructor 00087 */ 00088 virtual ~ESP8266Interface(); 00089 00090 /** Start the interface 00091 * 00092 * Attempts to connect to a WiFi network. Requires ssid and passphrase to be set. 00093 * If passphrase is invalid, NSAPI_ERROR_AUTH_ERROR is returned. 00094 * 00095 * @return 0 on success, negative error code on failure 00096 */ 00097 virtual int connect(); 00098 00099 /** Start the interface 00100 * 00101 * Attempts to connect to a WiFi network. 00102 * 00103 * If interface is configured blocking it will timeout after up to 00104 * ESP8266_INTERFACE_CONNECT_TIMEOUT_MS + ESP8266_CONNECT_TIMEOUT ms. 00105 * 00106 * @param ssid Name of the network to connect to 00107 * @param pass Security passphrase to connect to the network 00108 * @param security Type of encryption for connection (Default: NSAPI_SECURITY_NONE) 00109 * @param channel This parameter is not supported, setting it to anything else than 0 will result in NSAPI_ERROR_UNSUPPORTED 00110 * @return 0 on success, or error code on failure 00111 */ 00112 virtual int connect(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE , 00113 uint8_t channel = 0); 00114 00115 /** Set the WiFi network credentials 00116 * 00117 * @param ssid Name of the network to connect to 00118 * @param pass Security passphrase to connect to the network 00119 * @param security Type of encryption for connection 00120 * (defaults to NSAPI_SECURITY_NONE) 00121 * @return 0 on success, or error code on failure 00122 */ 00123 virtual int set_credentials(const char *ssid, const char *pass, nsapi_security_t security = NSAPI_SECURITY_NONE ); 00124 00125 /** Set the WiFi network channel - NOT SUPPORTED 00126 * 00127 * This function is not supported and will return NSAPI_ERROR_UNSUPPORTED 00128 * 00129 * @param channel Channel on which the connection is to be made, or 0 for any (Default: 0) 00130 * @return Not supported, returns NSAPI_ERROR_UNSUPPORTED 00131 */ 00132 virtual int set_channel(uint8_t channel); 00133 00134 /** Stop the interface 00135 * @return 0 on success, negative on failure 00136 */ 00137 virtual int disconnect(); 00138 00139 /** Get the internally stored IP address 00140 * @return IP address of the interface or null if not yet connected 00141 */ 00142 virtual nsapi_error_t get_ip_address(SocketAddress *address); 00143 00144 MBED_DEPRECATED_SINCE("mbed-os-5.15", "String-based APIs are deprecated") 00145 virtual const char *get_ip_address(); 00146 00147 /** Get the internally stored MAC address 00148 * @return MAC address of the interface 00149 */ 00150 virtual const char *get_mac_address(); 00151 00152 /** Get the local gateway 00153 * 00154 * @return Null-terminated representation of the local gateway 00155 * or null if no network mask has been recieved 00156 */ 00157 virtual nsapi_error_t get_gateway(SocketAddress *address); 00158 00159 MBED_DEPRECATED_SINCE("mbed-os-5.15", "String-based APIs are deprecated") 00160 virtual const char *get_gateway(); 00161 00162 /** Get the local network mask 00163 * 00164 * @return Null-terminated representation of the local network mask 00165 * or null if no network mask has been recieved 00166 */ 00167 virtual nsapi_error_t get_netmask(SocketAddress *address); 00168 00169 MBED_DEPRECATED_SINCE("mbed-os-5.15", "String-based APIs are deprecated") 00170 virtual const char *get_netmask(); 00171 00172 /** Get the network interface name 00173 * 00174 * @return Null-terminated representation of the network interface name 00175 * or null if interface not exists 00176 */ 00177 virtual char *get_interface_name(char *interface_name); 00178 00179 /** Gets the current radio signal strength for active connection 00180 * 00181 * @return Connection strength in dBm (negative value) 00182 */ 00183 virtual int8_t get_rssi(); 00184 00185 /** Scan mode 00186 */ 00187 enum scan_mode { 00188 SCANMODE_ACTIVE , /*!< active mode */ 00189 SCANMODE_PASSIVE /*!< passive mode */ 00190 }; 00191 00192 /** Scan for available networks 00193 * 00194 * This function will block. 00195 * 00196 * @param ap Pointer to allocated array to store discovered AP 00197 * @param count Size of allocated @a res array, or 0 to only count available AP 00198 * @return Number of entries in @a, or if @a count was 0 number of available networks, negative on error 00199 * see @a nsapi_error 00200 */ 00201 virtual int scan(WiFiAccessPoint *res, unsigned count); 00202 00203 /** Scan for available networks 00204 * 00205 * This function will block. 00206 * 00207 * @param ap Pointer to allocated array to store discovered AP 00208 * @param count Size of allocated @a res array, or 0 to only count available AP 00209 * @param t_max Scan time for each channel - 0-1500ms. If 0 - uses default value 00210 * @param t_min Minimum for each channel in active mode - 0-1500ms. If 0 - uses default value. Omit in passive mode 00211 * @return Number of entries in @a, or if @a count was 0 number of available networks, negative on error 00212 * see @a nsapi_error 00213 */ 00214 virtual int scan(WiFiAccessPoint *res, unsigned count, scan_mode mode = SCANMODE_PASSIVE , 00215 unsigned t_max = 0, unsigned t_min = 0); 00216 00217 /** Translates a hostname to an IP address with specific version 00218 * 00219 * The hostname may be either a domain name or an IP address. If the 00220 * hostname is an IP address, no network transactions will be performed. 00221 * 00222 * If no stack-specific DNS resolution is provided, the hostname 00223 * will be resolve using a UDP socket on the stack. 00224 * 00225 * @param address Destination for the host SocketAddress 00226 * @param host Hostname to resolve 00227 * @param version IP version of address to resolve, NSAPI_UNSPEC indicates 00228 * version is chosen by the stack (defaults to NSAPI_UNSPEC) 00229 * @return 0 on success, negative error code on failure 00230 */ 00231 using NetworkInterface::gethostbyname; 00232 00233 /** Add a domain name server to list of servers to query 00234 * 00235 * @param addr Destination for the host address 00236 * @return 0 on success, negative error code on failure 00237 */ 00238 using NetworkInterface::add_dns_server; 00239 00240 /** @copydoc NetworkStack::setsockopt 00241 */ 00242 virtual nsapi_error_t setsockopt (nsapi_socket_t handle, int level, 00243 int optname, const void *optval, unsigned optlen); 00244 00245 /** @copydoc NetworkStack::getsockopt 00246 */ 00247 virtual nsapi_error_t getsockopt (nsapi_socket_t handle, int level, int optname, 00248 void *optval, unsigned *optlen); 00249 00250 /** Register callback for status reporting 00251 * 00252 * The specified status callback function will be called on status changes 00253 * on the network. The parameters on the callback are the event type and 00254 * event-type dependent reason parameter. 00255 * 00256 * In ESP8266 the callback will be called when processing OOB-messages via 00257 * AT-parser. Do NOT call any ESP8266Interface -functions or do extensive 00258 * processing in the callback. 00259 * 00260 * @param status_cb The callback for status changes 00261 */ 00262 virtual void attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb); 00263 00264 /** Get the connection status 00265 * 00266 * @return The connection status according to ConnectionStatusType 00267 */ 00268 virtual nsapi_connection_status_t get_connection_status() const; 00269 00270 protected: 00271 /** Open a socket 00272 * @param handle Handle in which to store new socket 00273 * @param proto Type of socket to open, NSAPI_TCP or NSAPI_UDP 00274 * @return 0 on success, negative on failure 00275 */ 00276 virtual int socket_open(void **handle, nsapi_protocol_t proto); 00277 00278 /** Close the socket 00279 * @param handle Socket handle 00280 * @return 0 on success, negative on failure 00281 * @note On failure, any memory associated with the socket must still 00282 * be cleaned up 00283 */ 00284 virtual int socket_close(void *handle); 00285 00286 /** Bind a server socket to a specific port 00287 * @param handle Socket handle 00288 * @param address Local address to listen for incoming connections on 00289 * @return 0 on success, negative on failure. 00290 */ 00291 virtual int socket_bind(void *handle, const SocketAddress &address); 00292 00293 /** Start listening for incoming connections 00294 * @param handle Socket handle 00295 * @param backlog Number of pending connections that can be queued up at any 00296 * one time [Default: 1] 00297 * @return 0 on success, negative on failure 00298 */ 00299 virtual int socket_listen(void *handle, int backlog); 00300 00301 /** Connects this TCP socket to the server 00302 * @param handle Socket handle 00303 * @param address SocketAddress to connect to 00304 * @return 0 on success, negative on failure 00305 */ 00306 virtual int socket_connect(void *handle, const SocketAddress &address); 00307 00308 /** Accept a new connection. 00309 * @param handle Handle in which to store new socket 00310 * @param server Socket handle to server to accept from 00311 * @return 0 on success, negative on failure 00312 * @note This call is not-blocking, if this call would block, must 00313 * immediately return NSAPI_ERROR_WOULD_WAIT 00314 */ 00315 virtual int socket_accept(void *handle, void **socket, SocketAddress *address); 00316 00317 /** Send data to the remote host 00318 * @param handle Socket handle 00319 * @param data The buffer to send to the host 00320 * @param size The length of the buffer to send 00321 * @return Number of written bytes on success, negative on failure 00322 * @note This call is not-blocking, if this call would block, must 00323 * immediately return NSAPI_ERROR_WOULD_WAIT 00324 */ 00325 virtual int socket_send(void *handle, const void *data, unsigned size); 00326 00327 /** Receive data from the remote host 00328 * @param handle Socket handle 00329 * @param data The buffer in which to store the data received from the host 00330 * @param size The maximum length of the buffer 00331 * @return Number of received bytes on success, negative on failure 00332 * @note This call is not-blocking, if this call would block, must 00333 * immediately return NSAPI_ERROR_WOULD_WAIT 00334 */ 00335 virtual int socket_recv(void *handle, void *data, unsigned size); 00336 00337 /** Send a packet to a remote endpoint 00338 * @param handle Socket handle 00339 * @param address The remote SocketAddress 00340 * @param data The packet to be sent 00341 * @param size The length of the packet to be sent 00342 * @return The number of written bytes on success, negative on failure 00343 * @note This call is not-blocking, if this call would block, must 00344 * immediately return NSAPI_ERROR_WOULD_WAIT 00345 */ 00346 virtual int socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned size); 00347 00348 /** Receive a packet from a remote endpoint 00349 * @param handle Socket handle 00350 * @param address Destination for the remote SocketAddress or null 00351 * @param buffer The buffer for storing the incoming packet data 00352 * If a packet is too long to fit in the supplied buffer, 00353 * excess bytes are discarded 00354 * @param size The length of the buffer 00355 * @return The number of received bytes on success, negative on failure 00356 * @note This call is not-blocking, if this call would block, must 00357 * immediately return NSAPI_ERROR_WOULD_WAIT 00358 */ 00359 virtual int socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size); 00360 00361 /** Register a callback on state change of the socket 00362 * @param handle Socket handle 00363 * @param callback Function to call on state change 00364 * @param data Argument to pass to callback 00365 * @note Callback may be called in an interrupt context. 00366 */ 00367 virtual void socket_attach(void *handle, void (*callback)(void *), void *data); 00368 00369 /** Provide access to the NetworkStack object 00370 * 00371 * @return The underlying NetworkStack object 00372 */ 00373 virtual NetworkStack *get_stack() 00374 { 00375 return this; 00376 } 00377 00378 /** Set blocking status of connect() which by default should be blocking. 00379 * 00380 * @param blocking Use true to make connect() blocking. 00381 * @return NSAPI_ERROR_OK on success, negative error code on failure. 00382 */ 00383 virtual nsapi_error_t set_blocking(bool blocking); 00384 00385 /** Set country code 00386 * 00387 * @param track_ap if TRUE, use country code used by the AP ESP is connected to, 00388 * otherwise uses country_code always 00389 * @param country_code ISO 3166-1 coded, 2 character alphanumeric country code assumed 00390 * @param len Length of the country code 00391 * @param channel_start The channel number to start at 00392 * @param channel Number of channels 00393 * @return NSAPI_ERROR_OK on success, negative error code on failure. 00394 */ 00395 nsapi_error_t set_country_code(bool track_ap, const char *country_code, int len, int channel_start, int channels); 00396 00397 private: 00398 // AT layer 00399 ESP8266 _esp; 00400 void refresh_conn_state_cb(); 00401 00402 /** Status of software connection 00403 */ 00404 typedef enum esp_connection_software_status { 00405 IFACE_STATUS_DISCONNECTED = 0, 00406 IFACE_STATUS_CONNECTING = 1, 00407 IFACE_STATUS_CONNECTED = 2, 00408 IFACE_STATUS_DISCONNECTING = 3 00409 } esp_connection_software_status_t; 00410 00411 // HW reset pin 00412 class ResetPin { 00413 public: 00414 ResetPin(PinName rst_pin); 00415 void rst_assert(); 00416 void rst_deassert(); 00417 bool is_connected(); 00418 private: 00419 mbed::DigitalOut _rst_pin; 00420 } _rst_pin; 00421 00422 // HW power pin 00423 class PowerPin { 00424 public: 00425 PowerPin(PinName pwr_pin); 00426 void power_on(); 00427 void power_off(); 00428 bool is_connected(); 00429 private: 00430 mbed::DigitalOut _pwr_pin; 00431 } _pwr_pin; 00432 00433 /** Assert the reset and power pins 00434 * ESP8266 has two pins serving similar purpose and this function asserts them both 00435 * if they are configured in mbed_app.json. 00436 */ 00437 void _power_off(); 00438 00439 // Credentials 00440 static const int ESP8266_SSID_MAX_LENGTH = 32; /* 32 is what 802.11 defines as longest possible name */ 00441 char ap_ssid[ESP8266_SSID_MAX_LENGTH + 1]; /* The longest possible name; +1 for the \0 */ 00442 static const int ESP8266_PASSPHRASE_MAX_LENGTH = 63; /* The longest allowed passphrase */ 00443 static const int ESP8266_PASSPHRASE_MIN_LENGTH = 8; /* The shortest allowed passphrase */ 00444 char ap_pass[ESP8266_PASSPHRASE_MAX_LENGTH + 1]; /* The longest possible passphrase; +1 for the \0 */ 00445 nsapi_security_t _ap_sec; 00446 00447 // Country code 00448 struct _channel_info { 00449 bool track_ap; // Set country code based on the AP ESP is connected to 00450 char country_code[4]; // ISO 3166-1 coded, 2-3 character alphanumeric country code - +1 for the '\0' - assumed. Documentation doesn't tell. 00451 int channel_start; 00452 int channels; 00453 }; 00454 struct _channel_info _ch_info; 00455 00456 bool _if_blocking; // NetworkInterface, blocking or not 00457 #if MBED_CONF_RTOS_PRESENT 00458 rtos::ConditionVariable _if_connected; 00459 #endif 00460 00461 // connect status reporting 00462 nsapi_error_t _conn_status_to_error(); 00463 mbed::Timer _conn_timer; 00464 00465 // Drivers's socket info 00466 struct _sock_info { 00467 bool open; 00468 uint16_t sport; 00469 }; 00470 struct _sock_info _sock_i[ESP8266_SOCKET_COUNT]; 00471 00472 // Driver's state 00473 int _initialized; 00474 nsapi_error_t _connect_retval; 00475 nsapi_error_t _disconnect_retval; 00476 bool _get_firmware_ok(); 00477 nsapi_error_t _init(void); 00478 nsapi_error_t _reset(); 00479 00480 //sigio 00481 struct { 00482 void (*callback)(void *); 00483 void *data; 00484 uint8_t deferred; 00485 } _cbs[ESP8266_SOCKET_COUNT]; 00486 void event(); 00487 void event_deferred(); 00488 00489 // Connection state reporting to application 00490 nsapi_connection_status_t _conn_stat; 00491 mbed::Callback<void(nsapi_event_t, intptr_t)> _conn_stat_cb; 00492 00493 // Background OOB processing 00494 // Use global EventQueue 00495 events::EventQueue *_global_event_queue; 00496 int _oob_event_id; 00497 int _connect_event_id; 00498 int _disconnect_event_id; 00499 void proc_oob_evnt(); 00500 void _connect_async(); 00501 void _disconnect_async(); 00502 rtos::Mutex _cmutex; // Protect asynchronous connection logic 00503 esp_connection_software_status_t _software_conn_stat ; 00504 00505 }; 00506 #endif 00507 #endif
Generated on Tue Jul 12 2022 13:54:18 by
