leo hendrickson / Mbed OS example-Ethernet-mbed-Cloud-connect
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers WizFi310.h Source File

WizFi310.h

Go to the documentation of this file.
00001 /*
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 /**
00018   ******************************************************************************
00019   * @file    WizFi310.h
00020   * @author  Gateway Team
00021   * @brief   Header file of the WizFi310 WiFi Device
00022   ******************************************************************************
00023   * @attention
00024   *
00025   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
00026   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
00027   * TIME. AS A RESULT, WIZnet SHALL NOT BE HELD LIABLE FOR ANY
00028   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
00029   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
00030   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
00031   *
00032   * <h2><center>&copy; COPYRIGHT 2017 WIZnet Co.,Ltd.</center></h2>
00033   ******************************************************************************
00034   */
00035 
00036 #ifndef WIZFI310_H_
00037 #define WIZFI310_H_
00038 
00039 #include "mbed.h"
00040 #include "mbed_trace.h"
00041 #include "mbed_events.h"
00042 #include "netsocket/WiFiAccessPoint.h"
00043 #include "RawSerial.h"
00044 #include "Mutex.h"
00045 #include "Semaphore.h"
00046 #include "DigitalOut.h"
00047 #include "Packet.h"
00048 
00049 #define WIZFI310_SOCKET_COUNT       (8)
00050 
00051 /** WizFi310Interface class.
00052  *  This is an interface to a WizFi310Interface radio.
00053  */
00054 class WizFi310 {
00055 public:
00056     enum socket_event_t {
00057         EventConnected,
00058         EventDataReceived,
00059         EventDataSent,
00060         EventDisconnected
00061     };
00062     union socket_event_data_t {
00063         struct socket_event_connected_t {
00064             int32_t error_code;
00065         } connected;
00066         struct socket_event_data_received_t {
00067             Packet *packet;
00068         } data_received;
00069         struct socket_event_data_sent_t {
00070             int32_t amount_or_error;
00071         } data_sent;
00072         struct socket_event_disconnected_t {
00073 
00074         } disconnected;
00075     };
00076 
00077     /**
00078      * Creates a new WizFir310 driver.
00079      * @param tx    Tx pin name.
00080      * @param rx    Rx pin name.
00081      * @param rts   Rts pin name.
00082      * @param cts   Cts pin name.
00083      * @param rst   Rst pin name.
00084      */
00085     WizFi310(PinName tx, PinName rx, PinName rtx = NC, PinName cts = NC, PinName rst = NC);
00086     ~WizFi310();
00087 
00088     /**
00089      * Check firmware version of WizFi310
00090      *
00091      * @return character array firmware version or 0 if firmware query command gives outdated response
00092      * @warning This is only valid once the device is ready.
00093      */
00094     const char *get_firmware_version(void);
00095 
00096     /**
00097      * Enable/Disable DHCP
00098      *
00099      * @param enabled DHCP enabled when true
00100      * @return true only if WizFi310 enables/disables DHCP successfully
00101      */
00102     bool dhcp(bool enabled);
00103 
00104     /**
00105      * Attach a callback that will be invoked when the status changes.
00106      */
00107     void attach(Callback<void(nsapi_connection_status_t)> status_change_cb);
00108 
00109     /**
00110      * Connect WizFi310 to AP
00111      * @note This is blocking.
00112      *
00113      * @param ap the name of the AP
00114      * @param passPhrase the password of AP
00115      * @param security type of AP
00116      * @return see nsapi_error_t
00117      */
00118     nsapi_error_t connect(const char *ap, const char *passPhrase, const char *sec);
00119 
00120     /**
00121      * Returns the current connection status.
00122      *
00123      * @return Current connection status.
00124      */
00125     nsapi_connection_status_t status() const
00126     {
00127         return m_connection_status;
00128     }
00129 
00130     /**
00131      * Disconnect WizFi310 from AP
00132      *
00133      * @return see nsapi_error_t.
00134      */
00135     nsapi_error_t disconnect();
00136 
00137     /**
00138      *
00139      * @param ap_cb Called for each access point found. Last ap is NULL.
00140      * @return IN_PROGRESS or WOULD_BLOCK.
00141      */
00142     nsapi_error_t scan (Callback<void(nsapi_wifi_ap_t *)> ap_cb);
00143 
00144 
00145     const char *get_ip_address();
00146     int8_t get_rssi();
00147 
00148     /**
00149     * Open a socketed connection.
00150     * @note This is non-blocking.
00151     *
00152     * @param type the type of socket to open "UDP" or "TCP"
00153     * @param port port to open connection with
00154     * @param addr the IP address of the destination
00155     * @param callback     Function to call on state change
00156     * @param data         Argument to pass to callback
00157     * @note The callback is always called from the global event queue thread.
00158     * @return
00159     */
00160     int open(const char *type, const char *addr, int port, Callback<void(void *, socket_event_t, socket_event_data_t &)> callback, void *data);
00161 
00162     /**
00163     * Sends data to an open socket
00164     * @note This is non-blocking.
00165     *
00166     * @param id id of socket to send to
00167     * @param data data to be sent
00168     * @param amount amount of data to be sent
00169     * @return
00170     */
00171     int send(int id, const void *data, uint32_t amount);
00172 
00173     /**
00174     * Closes a socket
00175     * @note This is non-blocking.
00176     *
00177     * @param id id of socket to close, valid only 0-4
00178     * @return true only if socket is closed successfully
00179     */
00180     void close(int id);
00181 
00182     static const char *event2str(socket_event_t event)
00183     {
00184         switch (event) {
00185             case EventConnected:
00186                 return "Connected";
00187             case EventDataReceived:
00188                 return "Data received";
00189             case EventDataSent:
00190                 return "Data sent";
00191             case EventDisconnected:
00192                 return "Disconnected";
00193             default:
00194                 return "Invalid event";
00195         }
00196     }
00197 
00198 private:
00199     enum recv_state_t {
00200         Unknown,
00201         Ready,
00202         LinkUpGW,
00203         LinkUpIP,
00204         Status,
00205         Scan,
00206         Recv,
00207         RecvEnd,
00208         ResetRequired
00209     };
00210     static const char *recv_state2str(recv_state_t state)
00211     {
00212         switch (state) {
00213             case Unknown:
00214                 return "Unknown";
00215             case Ready:
00216                 return "Ready";
00217             case LinkUpGW:
00218                 return "Link-Up GW";
00219             case LinkUpIP:
00220                 return "Link-Up IP";
00221             case Status:
00222                 return "Status";
00223             case Scan:
00224                 return "Scan";
00225             case Recv:
00226                 return "Recv";
00227             case RecvEnd:
00228                 return "Recv end";
00229             case ResetRequired:
00230                 return "Reset required";
00231             default:
00232                 return "Invalid state";
00233         }
00234     }
00235     enum action_t {
00236         ActionNone,
00237         ActionBlocked,
00238         ActionDoReset,
00239         ActionDoConnect,
00240         ActionDoDisconnect,
00241         ActionDoStatus,
00242         ActionDoScan,
00243         ActionDoSOpen,
00244         ActionDoSSend,
00245         ActionDoSClose
00246     };
00247     static const char *action2str(action_t act)
00248     {
00249         switch (act) {
00250             case ActionNone:
00251                 return "None";
00252             case ActionBlocked:
00253                 return "Blocked";
00254             case ActionDoReset:
00255                 return "Reset";
00256             case ActionDoConnect:
00257                 return "Connect";
00258             case ActionDoDisconnect:
00259                 return "Disconnect";
00260             case ActionDoScan:
00261                 return "Scan";
00262             case ActionDoSOpen:
00263                 return "SOpen";
00264             case ActionDoSSend:
00265                 return "SSend";
00266             case ActionDoSClose:
00267                 return "SClose";
00268             default:
00269                 return "Invalid action";
00270         }
00271     }
00272     enum cmd_resp_t {
00273         CmdRspOk,
00274         CmdRspError,
00275         CmdRspErrorInvalidInput,
00276         CmdRspErrorInvalidScid,
00277         CmdRspErrorWifiStatus,
00278         CmdRspErrorModeStatus
00279     };
00280     struct socket_t {
00281         rtos::Mutex mutex;
00282         rtos::Semaphore evt;
00283 
00284         Packet *start;
00285         Packet **end;
00286 
00287         enum socket_status_t {
00288             StatusDisconnected,
00289             StatusConnecting,
00290             StatusConnected
00291         } volatile status;
00292         static const char *status2str(socket_status_t state)
00293         {
00294             switch (state) {
00295                 case StatusDisconnected:
00296                     return "Disconnected";
00297                 case StatusConnecting:
00298                     return "Connecting";
00299                 case StatusConnected:
00300                     return "Connected";
00301                 default:
00302                     return "Invalid state";
00303             }
00304         }
00305 
00306         Callback<void(void *, socket_event_t, socket_event_data_t &)> cbk;
00307         void *data;
00308 
00309         socket_t():
00310             mutex("socket_t"),
00311             evt(0, 1),
00312             start(NULL), end(&start),
00313             status(StatusDisconnected),
00314             cbk(NULL), data(NULL) {}
00315 
00316         void reset();
00317         void notify(socket_event_t evt, socket_event_data_t &data);
00318     };
00319     union cmd_ctx_u {
00320         struct connect_s {
00321             const char *ap;
00322             const char *pw;
00323             const char *sec;
00324             uint32_t attempt;
00325         } connect;
00326         struct sopen_s {
00327             socket_t *s;
00328         } sopen;
00329         struct ssend_s {
00330             socket_t *s;
00331             const void *data;
00332             uint32_t amount;
00333             bool did_send;
00334         } ssend;
00335         struct sclose_s {
00336             int id;
00337             bool done;
00338         } sclose;
00339     };
00340 
00341     // serial & lowlevel
00342     const PinName m_rst, m_rts, m_cts;
00343     DigitalOut m_nrst_pin;
00344     RawSerial m_serial;
00345     const bool m_has_hwfc;
00346     int m_rx_event_id;
00347     /// used for debug purposes
00348     volatile bool m_attached;
00349 
00350     volatile uint32_t m_isr_buf_len;
00351     uint8_t m_isr_buf[MBED_CONF_WIZFI310_RX_BUFFER_SIZE];
00352 
00353     uint32_t m_line_buf_len;
00354     uint8_t m_line_buf[MBED_CONF_WIZFI310_LINE_BUFFER_SIZE];
00355 
00356     // this buffer is not meant to keep data between call to serial_event.
00357     // it is meant to avoid potentially big stack allocation.
00358     uint8_t m_work_buf[MBED_CONF_WIZFI310_RX_BUFFER_SIZE];
00359 
00360     // state machine
00361     volatile uint32_t m_active_action;
00362     recv_state_t m_recv_state, m_prev_state;
00363     cmd_ctx_u m_cmd_ctx;
00364 
00365     Callback<void(const char[8])> m_greetings_cbk;
00366     Callback<void(cmd_resp_t)> m_on_cmd_end;
00367     Callback<void(nsapi_wifi_ap_t *ap)> m_scan_ap_cbk;
00368     Callback<void(nsapi_connection_status_t)> m_on_status_change;
00369 
00370     // sockets
00371     // One chain per socket.
00372     socket_t m_sockets[8];
00373 
00374     uint32_t m_data_to_receive;
00375     Packet *m_pending_packet;
00376     socket_t *m_pending_socket;
00377     volatile uint32_t m_heap_used;
00378 
00379     // misc
00380     Thread m_thread;
00381     events::EventQueue m_event_queue;
00382     nsapi_connection_status_t m_connection_status;
00383 
00384     // config
00385     bool m_dhcp;
00386 
00387     // information buffers
00388     char m_firmware_rev[8];
00389     char m_ip_buffer[16];
00390     char m_gateway_buffer[16];
00391     char m_netmask_buffer[16];
00392     char m_mac_buffer[18];
00393     int32_t m_rssi;
00394 
00395     void fatal_error(const char *msg);
00396     void serial_isr();
00397     void serial_event();
00398     bool recv_state_update(char *buf, uint32_t len);
00399 
00400     /**
00401      * Traces the command.
00402      *
00403      * @param fmt   format for the command.
00404      * @param ...   variadic arguments used with vprintf.
00405      */
00406     void trace_cmd(const char *fmt, ...);
00407 
00408     void heart_beat();
00409     void end_action();
00410 
00411     void do_reset();
00412     void do_echo_off(const char fw_rev[8]);
00413     void do_setup_serial(cmd_resp_t rsp);
00414     void do_set_access_point();
00415     void do_set_password(cmd_resp_t rsp);
00416     void do_set_dhcp(cmd_resp_t rsp);
00417     void do_join(cmd_resp_t rsp);
00418     void do_scan();
00419     void do_sclose(int id);
00420 
00421     void serial_setup_done(cmd_resp_t rsp);
00422     void join_done(cmd_resp_t rsp);
00423     void leave_done(cmd_resp_t rsp);
00424     void sopen_done(cmd_resp_t rsp);
00425     void ssend_done(cmd_resp_t rsp);
00426     void sclose_done(cmd_resp_t rsp);
00427     void device_ready(const char fw_rev[8]);
00428 
00429     void set_connection_status(nsapi_connection_status_t status);
00430 
00431     static nsapi_security_t str2sec(const char *str_sec);
00432 
00433     static bool parse_greeting(const char *buf, uint32_t len, char fw_ver[8]);
00434     static bool parse_error(const char *buf, uint32_t len, volatile cmd_resp_t &err);
00435     static bool parse_linkup_ip(const char *buf, uint32_t len, char ip[16]);
00436     static bool parse_linkup_gw(const char *buf, uint32_t len, char ip[16]);
00437     static bool parse_status(char *buf, uint32_t len, char ip_buf[16], char gw_buf[16], char mac_buf[18], int32_t &rssi);
00438     static bool parse_connect(const char *buf, uint32_t len, int &id);
00439     static bool parse_recv(const char *buf, uint32_t len, int &id, char ip_buf[16], uint16_t &port, uint32_t &plen);
00440     static bool parse_send_rdy(const char *buf, uint32_t len, int &id, uint32_t &plen);
00441     static bool parse_disconnect(const char *buf, uint32_t len, int &id);
00442     static bool parse_mac(const char *buf, uint32_t len, char mac_buf[18]);
00443     static bool parse_ip(const char *buf, uint32_t len, char ip_buf[16]);
00444     static bool parse_ap(char *buf, uint32_t len, nsapi_wifi_ap_t *ap);
00445     static const char *print_buf(const char *buf, uint32_t len);
00446 };
00447 #endif