Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ESP8266.h Source File

ESP8266.h

00001 /* ESP8266Interface Example
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_H
00018 #define ESP8266_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 <stdint.h>
00022 
00023 #include "drivers/UARTSerial.h"
00024 #include "features/netsocket/nsapi_types.h"
00025 #include "features/netsocket/WiFiAccessPoint.h"
00026 #include "PinNames.h"
00027 #include "platform/ATCmdParser.h"
00028 #include "platform/Callback.h"
00029 #include "platform/mbed_error.h"
00030 #include "rtos/Mutex.h"
00031 #include "rtos/ThisThread.h"
00032 
00033 // Various timeouts for different ESP8266 operations
00034 #ifndef ESP8266_CONNECT_TIMEOUT
00035 #define ESP8266_CONNECT_TIMEOUT 15000
00036 #endif
00037 #ifndef ESP8266_SEND_TIMEOUT
00038 #define ESP8266_SEND_TIMEOUT    2000
00039 #endif
00040 #ifndef ESP8266_RECV_TIMEOUT
00041 #define ESP8266_RECV_TIMEOUT    2000
00042 #endif
00043 #ifndef ESP8266_MISC_TIMEOUT
00044 #define ESP8266_MISC_TIMEOUT    2000
00045 #endif
00046 
00047 #define ESP8266_SCAN_TIME_MIN 0     // [ms]
00048 #define ESP8266_SCAN_TIME_MAX 1500  // [ms]
00049 #define ESP8266_SCAN_TIME_MIN_DEFAULT 120 // [ms]
00050 #define ESP8266_SCAN_TIME_MAX_DEFAULT 360 // [ms]
00051 
00052 // Firmware version
00053 #define ESP8266_SDK_VERSION 2000000
00054 #define ESP8266_SDK_VERSION_MAJOR ESP8266_SDK_VERSION/1000000
00055 
00056 #define ESP8266_AT_VERSION 1000000
00057 #define ESP8266_AT_VERSION_MAJOR ESP8266_AT_VERSION/1000000
00058 #define ESP8266_AT_VERSION_TCP_PASSIVE_MODE 1070000
00059 #define ESP8266_AT_VERSION_WIFI_SCAN_CHANGE 1060000
00060 
00061 #define FW_AT_LEAST_VERSION(MAJOR,MINOR,PATCH,NUSED/*Not used*/,REF) \
00062     (((MAJOR)*1000000+(MINOR)*10000+(PATCH)*100) >= REF ? true : false)
00063 
00064 /** ESP8266Interface class.
00065     This is an interface to a ESP8266 radio.
00066  */
00067 class ESP8266 {
00068 public:
00069     ESP8266(PinName tx, PinName rx, bool debug = false, PinName rts = NC, PinName cts = NC);
00070 
00071     /**
00072     * ESP8266 firmware SDK version
00073     *
00074     * @param major Major version number
00075     * @param minor Minor version number
00076     * @param patch Patch version number
00077     */
00078     struct fw_sdk_version {
00079         int major;
00080         int minor;
00081         int patch;
00082         fw_sdk_version(int major, int minor, int patch) : major(major), minor(minor), patch(patch) {}
00083     };
00084 
00085     /**
00086     * ESP8266 firmware AT version
00087     *
00088     * @param major Major version number
00089     * @param minor Minor version number
00090     * @param patch Patch version number
00091     */
00092     struct fw_at_version {
00093         int major;
00094         int minor;
00095         int patch;
00096         fw_at_version(int major, int minor, int patch) : major(major), minor(minor), patch(patch) {}
00097     };
00098 
00099     /**
00100     * Check AT command interface of ESP8266
00101     *
00102     * @return true if ready to respond on AT commands
00103     */
00104     bool at_available(void);
00105 
00106     /**
00107      * Disable echo - required for OOB processing to work
00108      *
00109      * @return true if echo was successfully disabled
00110      */
00111     bool echo_off(void);
00112 
00113     /**
00114     * Check sdk version from which firmware is created
00115     *
00116     * @return fw_sdk_version which tells major, minor and patch version
00117     */
00118     struct fw_sdk_version sdk_version(void);
00119 
00120     /**
00121     * Check AT instruction set version from which firmware is created
00122     *
00123     * @return fw_at_version which tells major, minor and patch version
00124     */
00125     struct fw_at_version at_version(void);
00126 
00127     /**
00128     * Startup the ESP8266
00129     *
00130     * @param mode mode of WIFI 1-client, 2-host, 3-both
00131     * @return true only if ESP8266 was setup correctly
00132     */
00133     bool startup(int mode);
00134 
00135     /**
00136     * Reset ESP8266
00137     *
00138     * @return true only if ESP8266 resets successfully
00139     */
00140     bool reset(void);
00141 
00142     /**
00143     * Enable/Disable DHCP
00144     *
00145     * @param enabled DHCP enabled when true
00146     * @param mode mode of DHCP 0-softAP, 1-station, 2-both
00147     * @return true only if ESP8266 enables/disables DHCP successfully
00148     */
00149     bool dhcp(bool enabled, int mode);
00150 
00151     /**
00152     * Connect ESP8266 to AP
00153     *
00154     * @param ap the name of the AP
00155     * @param passPhrase the password of AP
00156     * @return NSAPI_ERROR_OK in success, negative error code in failure
00157     */
00158     nsapi_error_t connect(const char *ap, const char *passPhrase);
00159 
00160     /**
00161     * Disconnect ESP8266 from AP
00162     *
00163     * @return true only if ESP8266 is disconnected successfully
00164     */
00165     bool disconnect(void);
00166 
00167     /**
00168     * Get the IP address of ESP8266
00169     *
00170     * @return null-teriminated IP address or null if no IP address is assigned
00171     */
00172     const char *ip_addr(void);
00173 
00174     /**
00175     * Get the MAC address of ESP8266
00176     *
00177     * @return null-terminated MAC address or null if no MAC address is assigned
00178     */
00179     const char *mac_addr(void);
00180 
00181     /** Get the local gateway
00182     *
00183     *  @return         Null-terminated representation of the local gateway
00184     *                  or null if no network mask has been recieved
00185     */
00186     const char *gateway();
00187 
00188     /** Get the local network mask
00189      *
00190      *  @return         Null-terminated representation of the local network mask
00191      *                  or null if no network mask has been recieved
00192      */
00193     const char *netmask();
00194 
00195     /* Return RSSI for active connection
00196      *
00197      * @return      Measured RSSI
00198      */
00199     int8_t rssi();
00200 
00201     /** Scan mode
00202      */
00203     enum scan_mode {
00204         SCANMODE_ACTIVE  = 0, /*!< active mode */
00205         SCANMODE_PASSIVE  = 1 /*!< passive mode */
00206     };
00207 
00208     /** Scan for available networks
00209      *
00210      * @param  ap    Pointer to allocated array to store discovered AP
00211      * @param  limit Size of allocated @a res array, or 0 to only count available AP
00212      * @param  t_max Maximum scan time per channel
00213      * @param  t_min Minimum scan time per channel in active mode, can be omitted in passive mode
00214      * @return       Number of entries in @a res, or if @a count was 0 number of available networks, negative on error
00215      *               see @a nsapi_error
00216      */
00217     int scan(WiFiAccessPoint *res, unsigned limit, scan_mode mode, unsigned t_max, unsigned t_min);
00218 
00219     /**Perform a dns query
00220     *
00221     * @param name Hostname to resolve
00222     * @param ip   Buffer to store IP address
00223     * @return 0 true on success, false on failure
00224     */
00225     bool dns_lookup(const char *name, char *ip);
00226 
00227     /**
00228     * Open a socketed connection
00229     *
00230     * @param type the type of socket to open "UDP" or "TCP"
00231     * @param id id to give the new socket, valid 0-4
00232     * @param port port to open connection with
00233     * @param addr the IP address of the destination
00234     * @param port the port on the destination
00235     * @param local_port UDP socket's local port, zero means any
00236     * @return NSAPI_ERROR_OK in success, negative error code in failure
00237     */
00238     nsapi_error_t open_udp(int id, const char *addr, int port, int local_port = 0);
00239 
00240     /**
00241     * Open a socketed connection
00242     *
00243     * @param type the type of socket to open "UDP" or "TCP"
00244     * @param id id to give the new socket, valid 0-4
00245     * @param port port to open connection with
00246     * @param addr the IP address of the destination
00247     * @param port the port on the destination
00248     * @param tcp_keepalive TCP connection's keep alive time, zero means disabled
00249     * @return NSAPI_ERROR_OK in success, negative error code in failure
00250     */
00251     nsapi_error_t open_tcp(int id, const char *addr, int port, int keepalive = 0);
00252 
00253     /**
00254     * Sends data to an open socket
00255     *
00256     * @param id id of socket to send to
00257     * @param data data to be sent
00258     * @param amount amount of data to be sent - max 1024
00259     * @return NSAPI_ERROR_OK in success, negative error code in failure
00260     */
00261     nsapi_error_t send(int id, const void *data, uint32_t amount);
00262 
00263     /**
00264     * Receives datagram from an open UDP socket
00265     *
00266     * @param id id to receive from
00267     * @param data placeholder for returned information
00268     * @param amount number of bytes to be received
00269     * @return the number of bytes received
00270     */
00271     int32_t recv_udp(int id, void *data, uint32_t amount, uint32_t timeout = ESP8266_RECV_TIMEOUT);
00272 
00273     /**
00274     * Receives stream data from an open TCP socket
00275     *
00276     * @param id id to receive from
00277     * @param data placeholder for returned information
00278     * @param amount number of bytes to be received
00279     * @return the number of bytes received
00280     */
00281     int32_t recv_tcp(int id, void *data, uint32_t amount, uint32_t timeout = ESP8266_RECV_TIMEOUT);
00282 
00283     /**
00284     * Closes a socket
00285     *
00286     * @param id id of socket to close, valid only 0-4
00287     * @return true only if socket is closed successfully
00288     */
00289     bool close(int id);
00290 
00291     /**
00292     * Allows timeout to be changed between commands
00293     *
00294     * @param timeout_ms timeout of the connection
00295     */
00296     void set_timeout(uint32_t timeout_ms = ESP8266_MISC_TIMEOUT);
00297 
00298     /**
00299     * Checks if data is available
00300     */
00301     bool readable();
00302 
00303     /**
00304     * Checks if data can be written
00305     */
00306     bool writeable();
00307 
00308     /**
00309     * Attach a function to call whenever sigio happens in the serial
00310     *
00311     * @param func A pointer to a void function, or 0 to set as none
00312     */
00313     void sigio(mbed::Callback<void()> func);
00314 
00315     /**
00316     * Attach a function to call whenever sigio happens in the serial
00317     *
00318     * @param obj pointer to the object to call the member function on
00319     * @param method pointer to the member function to call
00320     */
00321     template <typename T, typename M>
00322     void sigio(T *obj, M method)
00323     {
00324         sigio(mbed::Callback<void()>(obj, method));
00325     }
00326 
00327     /**
00328     * Attach a function to call whenever network state has changed.
00329     *
00330     * @param func A pointer to a void function, or 0 to set as none
00331     */
00332     void attach(mbed::Callback<void()> status_cb);
00333 
00334     template <typename T, typename M>
00335     void attach(T *obj, M method)
00336     {
00337         attach(mbed::Callback<void()>(obj, method));
00338     }
00339 
00340     /**
00341      * Read default Wifi mode from flash
00342      *
00343      * return Station, SoftAP or SoftAP+Station - 0 on failure
00344      */
00345     int8_t default_wifi_mode();
00346 
00347     /**
00348      * Default Wifi mode written to flash only if changes
00349      */
00350     bool set_default_wifi_mode(const int8_t mode);
00351 
00352     /**
00353      * @param track_ap      if TRUE, sets the county code to be the same as the AP's that ESP is connected to,
00354      *                      if FALSE the code will not change
00355      * @param country_code  ISO 3166-1 Alpha-2 coded country code
00356      * @param channel_start the channel number to start at
00357      * @param channels      number of channels
00358      */
00359     bool set_country_code_policy (bool track_ap, const char *country_code, int channel_start, int channels);
00360 
00361     /** Get the connection status
00362      *
00363      *  @return         The connection status according to ConnectionStatusType
00364      */
00365     nsapi_connection_status_t connection_status() const;
00366 
00367     /**
00368      * Start board's and ESP8266's UART flow control
00369      *
00370      * @return true if started
00371      */
00372     bool start_uart_hw_flow_ctrl();
00373 
00374     /**
00375      * Stop board's and ESP8266's UART flow control
00376      *
00377      * @return true if started
00378      */
00379     bool stop_uart_hw_flow_ctrl();
00380 
00381     /*
00382      * From AT firmware v1.7.0.0 onwards enables TCP passive mode
00383      */
00384     bool cond_enable_tcp_passive_mode();
00385 
00386     /**
00387      * For executing OOB processing on background
00388      *
00389      * @param timeout AT parser receive timeout
00390      * @param if TRUE, process all OOBs instead of only one
00391      */
00392     void bg_process_oob(uint32_t timeout, bool all);
00393 
00394     /**
00395      * Flush the serial port input buffers.
00396      *
00397      * If you do HW reset for ESP module, you should
00398      * flush the input buffers from existing responses
00399      * from the device.
00400      */
00401     void flush();
00402 
00403     static const int8_t WIFIMODE_STATION = 1;
00404     static const int8_t WIFIMODE_SOFTAP = 2;
00405     static const int8_t WIFIMODE_STATION_SOFTAP = 3;
00406     static const int8_t SOCKET_COUNT = 5;
00407 
00408     /**
00409      * Enables or disables uart input and deep sleep
00410      *
00411      * @param lock if TRUE, uart input is enabled and  deep sleep is locked
00412      * if FALSE, uart input is disabled and  deep sleep is unlocked
00413      */
00414     int uart_enable_input(bool lock);
00415 
00416 private:
00417     // FW version
00418     struct fw_sdk_version _sdk_v;
00419     struct fw_at_version _at_v;
00420 
00421     // FW version specific settings and functionalities
00422     bool _tcp_passive;
00423     int32_t _recv_tcp_passive(int id, void *data, uint32_t amount, uint32_t timeout);
00424     mbed::Callback<void()> _callback;
00425 
00426     // UART settings
00427     mbed::UARTSerial _serial;
00428     PinName _serial_rts;
00429     PinName _serial_cts;
00430     rtos::Mutex _smutex; // Protect serial port access
00431 
00432     // AT Command Parser
00433     mbed::ATCmdParser _parser;
00434 
00435     // Wifi scan result handling
00436     bool _recv_ap(nsapi_wifi_ap_t *ap);
00437 
00438     // Socket data buffer
00439     struct packet {
00440         struct packet *next;
00441         int id;
00442         uint32_t len; // Remaining length
00443         uint32_t alloc_len; // Original length
00444         // data follows
00445     } *_packets, * *_packets_end;
00446     void _clear_socket_packets(int id);
00447     int _sock_active_id;
00448 
00449     // Memory statistics
00450     size_t _heap_usage; // (Socket data buffer usage)
00451 
00452     // OOB processing
00453     void _process_oob(uint32_t timeout, bool all);
00454 
00455     // OOB message handlers
00456     void _oob_packet_hdlr();
00457     void _oob_connect_err();
00458     void _oob_conn_already();
00459     void _oob_err();
00460     void _oob_socket0_closed();
00461     void _oob_socket1_closed();
00462     void _oob_socket2_closed();
00463     void _oob_socket3_closed();
00464     void _oob_socket4_closed();
00465     void _oob_connection_status();
00466     void _oob_socket_close_err();
00467     void _oob_watchdog_reset();
00468     void _oob_busy();
00469     void _oob_tcp_data_hdlr();
00470     void _oob_ready();
00471     void _oob_scan_results();
00472     void _oob_ok_received();
00473 
00474     // OOB state variables
00475     int _connect_error;
00476     bool _disconnect;
00477     bool _fail;
00478     bool _sock_already;
00479     bool _closed;
00480     bool _error;
00481     bool _busy;
00482     bool _reset_done;
00483     bool _ok_received;
00484 
00485     // Modem's address info
00486     char _ip_buffer[16];
00487     char _gateway_buffer[16];
00488     char _netmask_buffer[16];
00489     char _mac_buffer[18];
00490 
00491     // Modem's socket info
00492     struct _sock_info {
00493         bool open;
00494         nsapi_protocol_t proto;
00495         char *tcp_data;
00496         int32_t tcp_data_avbl; // Data waiting on modem
00497         int32_t tcp_data_rcvd;
00498     };
00499     struct _sock_info _sock_i[SOCKET_COUNT];
00500 
00501     // Scan results
00502     struct _scan_results {
00503         WiFiAccessPoint *res;
00504         unsigned limit;
00505         unsigned cnt;
00506     };
00507     struct _scan_results _scan_r;
00508 
00509     // Connection state reporting
00510     nsapi_connection_status_t _conn_status;
00511     mbed::Callback<void()> _conn_stat_cb; // ESP8266Interface registered
00512 };
00513 #endif
00514 #endif