Advantech / Mbed OS pelion-example-common
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SPWFSAxx.h Source File

SPWFSAxx.h

00001 /* SPWFSAxx Devices
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 SPWFSAXX_H
00018 #define SPWFSAXX_H
00019 
00020 #include "mbed.h"
00021 #include "ATCmdParser.h"
00022 #include "BlockExecuter.h"
00023 
00024 /* Common SPWFSAxx macros */
00025 #define SPWFXX_WINDS_LOW_ON         "0x00000000"
00026 #define SPWFXX_DEFAULT_BAUD_RATE    115200
00027 #define SPWFXX_MAX_TRIALS           3
00028 
00029 #if !defined(SPWFSAXX_RTS_PIN)
00030 #define SPWFSAXX_RTS_PIN    NC
00031 #endif // !defined(SPWFSAXX_RTS_PIN)
00032 #if !defined(SPWFSAXX_CTS_PIN)
00033 #define SPWFSAXX_CTS_PIN    NC
00034 #endif // !defined(SPWFSAXX_CTS_PIN)
00035 
00036 #define SPWFXX_ERR_OK               (+1)
00037 #define SPWFXX_ERR_OOM              (-1)
00038 #define SPWFXX_ERR_READ             (-2)
00039 #define SPWFXX_ERR_LEN              (-3)
00040 
00041 
00042 /* Max number of sockets & packets */
00043 #define SPWFSA_SOCKET_COUNT         (8)
00044 #define SPWFSA_MAX_PACKETS          (4)
00045 
00046 #define PENDING_DATA_SLOTS          (13)
00047 
00048 /* Pending data packets size buffer */
00049 class SpwfRealPendingPackets {
00050 public:
00051     SpwfRealPendingPackets() {
00052         reset();
00053     }
00054 
00055     void add(uint32_t new_cum_size) {
00056         MBED_ASSERT(new_cum_size >= cumulative_size);
00057 
00058         if(new_cum_size == cumulative_size) {
00059             /* nothing to do */
00060             return;
00061         }
00062 
00063         /* => `new_cum_size > cumulative_size` */
00064         real_pkt_sizes[last_pkt_ptr] = (uint16_t)(new_cum_size - cumulative_size);
00065         cumulative_size = new_cum_size;
00066 
00067         last_pkt_ptr = (last_pkt_ptr + 1) % PENDING_DATA_SLOTS;
00068 
00069         MBED_ASSERT(first_pkt_ptr != last_pkt_ptr);
00070     }
00071 
00072     uint32_t get(void) {
00073         if(empty()) return 0;
00074 
00075         return real_pkt_sizes[first_pkt_ptr];
00076     }
00077 
00078     uint32_t cumulative(void) {
00079         return cumulative_size;
00080     }
00081 
00082     uint32_t remove(uint32_t size) {
00083         MBED_ASSERT(!empty());
00084 
00085         uint32_t ret = real_pkt_sizes[first_pkt_ptr];
00086         first_pkt_ptr = (first_pkt_ptr + 1) % PENDING_DATA_SLOTS;
00087 
00088         MBED_ASSERT(ret == size);
00089         MBED_ASSERT(ret <= cumulative_size);
00090         cumulative_size -= ret;
00091 
00092         return ret;
00093     }
00094 
00095     void reset(void) {
00096         memset(this, 0, sizeof(*this));
00097     }
00098 
00099 private:
00100     bool empty(void) {
00101         if(first_pkt_ptr == last_pkt_ptr) {
00102             MBED_ASSERT(cumulative_size == 0);
00103             return true;
00104         }
00105         return false;
00106     }
00107 
00108     uint16_t real_pkt_sizes[PENDING_DATA_SLOTS];
00109     uint8_t  first_pkt_ptr;
00110     uint8_t  last_pkt_ptr;
00111     uint32_t cumulative_size;
00112 };
00113 
00114 class SpwfSAInterface;
00115 
00116 /** SPWFSAxx Interface class.
00117     This is an interface to a SPWFSAxx module.
00118  */
00119 class SPWFSAxx
00120 {
00121 private:
00122     /* abstract class*/
00123     SPWFSAxx(PinName tx, PinName rx, PinName rts, PinName cts,
00124              SpwfSAInterface &ifce, bool debug,
00125              PinName wakeup, PinName reset);
00126 
00127 public:
00128     /**
00129      * Init the SPWFSAxx
00130      *
00131      * @param mode mode in which to startup
00132      * @return true only if SPWFSAxx has started up correctly
00133      */
00134     bool startup(int mode);
00135 
00136     /**
00137      * Connect SPWFSAxx to AP
00138      *
00139      * @param ap the name of the AP
00140      * @param passPhrase the password of AP
00141      * @param securityMode the security mode of AP (WPA/WPA2, WEP, Open)
00142      * @return true only if SPWFSAxx is connected successfully
00143      */
00144     bool connect(const char *ap, const char *passPhrase, int securityMode);
00145 
00146     /**
00147      * Disconnect SPWFSAxx from AP
00148      *
00149      * @return true only if SPWFSAxx is disconnected successfully
00150      */
00151     bool disconnect(void);
00152 
00153     /**
00154      * Get the IP address of SPWFSAxx
00155      *
00156      * @return null-terminated IP address or null if no IP address is assigned
00157      */
00158     const char *getIPAddress(void);
00159 
00160     /**
00161      * Get the MAC address of SPWFSAxx
00162      *
00163      * @return null-terminated MAC address or null if no MAC address is assigned
00164      */
00165     const char *getMACAddress(void);
00166 
00167     /** Get the local gateway
00168      *
00169      *  @return         Null-terminated representation of the local gateway
00170      *                  or null if no network mask has been received
00171      */
00172     const char *getGateway(void);
00173 
00174     /** Get the local network mask
00175      *
00176      *  @return         Null-terminated representation of the local network mask
00177      *                  or null if no network mask has been received
00178      */
00179     const char *getNetmask(void);
00180 
00181     /** Gets the current radio signal strength for active connection
00182      *
00183      * @return          Connection strength in dBm (negative value)
00184      */
00185     int8_t getRssi();
00186 
00187     /**
00188      * Sends data to an open socket
00189      *
00190      * @param spwf_id module id of socket to send to
00191      * @param data data to be sent
00192      * @param amount amount of data to be sent - max 1024
00193      * @param internal_id driver id of socket to send to
00194      * @return number of written bytes on success, negative on failure
00195      */
00196     nsapi_size_or_error_t send(int spwf_id, const void *data, uint32_t amount, int internal_id);
00197 
00198     /**
00199      * Receives data from an open socket
00200      *
00201      * @param id id to receive from
00202      * @param data placeholder for returned information
00203      * @param amount number of bytes to be received
00204      * @param datagram receive a datagram packet
00205      * @return the number of bytes received
00206      */
00207     int32_t recv(int id, void *data, uint32_t amount, bool datagram);
00208 
00209     /**
00210      * Closes a socket
00211      *
00212      * @param id id of socket to close, valid only 0-4
00213      * @return true only if socket is closed successfully
00214      */
00215     bool close(int id);
00216 
00217     /**
00218      * Allows timeout to be changed between commands
00219      *
00220      * @param timeout_ms timeout of the connection
00221      */
00222     void setTimeout(uint32_t timeout_ms);
00223 
00224     /**
00225      * Attach a function to call whenever network state has changed
00226      *
00227      * @param func A pointer to a void function, or 0 to set as none
00228      */
00229     void attach(Callback<void()> func);
00230 
00231     /**
00232      * Attach a function to call whenever network state has changed
00233      *
00234      * @param obj pointer to the object to call the member function on
00235      * @param method pointer to the member function to call
00236      */
00237     template <typename T, typename M>
00238     void attach(T *obj, M method) {
00239         attach(Callback<void()>(obj, method));
00240     }
00241 
00242     static const char _cr_ = '\x0d'; // '\r' carriage return
00243     static const char _lf_ = '\x0a'; // '\n' line feed
00244 
00245 private:
00246     UARTSerial _serial;
00247     ATCmdParser _parser;
00248 
00249     DigitalOut _wakeup;
00250     DigitalOut _reset;
00251     PinName _rts;
00252     PinName _cts;
00253 
00254     int _timeout;
00255     bool _dbg_on;
00256 
00257     int _pending_sockets_bitmap;
00258     SpwfRealPendingPackets _pending_pkt_sizes[SPWFSA_SOCKET_COUNT];
00259 
00260     bool _network_lost_flag;
00261     SpwfSAInterface &_associated_interface;
00262 
00263     /**
00264      * Reset SPWFSAxx
00265      *
00266      * @return true only if SPWFSAxx resets successfully
00267      */
00268     bool hw_reset(void);
00269     bool reset(void);
00270 
00271     /**
00272      * Check if SPWFSAxx is connected
00273      *
00274      * @return true only if the chip has an IP address
00275      */
00276     bool isConnected(void);
00277 
00278     /**
00279      * Checks if data is available
00280      */
00281     bool readable(void) {
00282         return _serial.FileHandle::readable();
00283     }
00284 
00285     /**
00286      * Checks if data can be written
00287      */
00288     bool writeable(void) {
00289         return _serial.FileHandle::writable();
00290     }
00291 
00292     /**
00293      * Try to empty RX buffer
00294      * Can be used when commands fail receiving expected response to try to recover situation
00295      * @note Gives no guarantee that situation improves
00296      */
00297     void empty_rx_buffer(void) {
00298         while(readable()) _parser.getc();
00299     }
00300 
00301     /* block calling (external) callback */
00302     volatile unsigned int _call_event_callback_blocked;
00303     Callback<void()> _callback_func;
00304 
00305     struct packet {
00306         struct packet *next;
00307         int id;
00308         uint32_t len;
00309         // data follows
00310     } *_packets, **_packets_end;
00311 
00312     void _packet_handler_th(void);
00313     void _execute_bottom_halves(void);
00314     void _network_lost_handler_th(void);
00315     void _network_lost_handler_bh(void);
00316     void _hard_fault_handler(void);
00317     void _wifi_hwfault_handler(void);
00318     void _server_gone_handler(void);
00319 #if MBED_CONF_IDW0XX1_EXPANSION_BOARD == IDW04A1
00320     void _skip_oob(void);
00321 #endif
00322     bool _wait_wifi_hw_started(void);
00323     bool _wait_console_active(void);
00324     int _read_len(int);
00325     int _flush_in(char*, int);
00326     bool _winds_off(void);
00327     void _winds_on(void);
00328     void _read_in_pending(void);
00329     int _read_in_pkt(int spwf_id, bool close);
00330     int _read_in_packet(int spwf_id, uint32_t amount);
00331     void _recover_from_hard_faults(void);
00332     void _free_packets(int spwf_id);
00333     void _free_all_packets(void);
00334     void _process_winds();
00335 
00336     virtual int _read_in(char*, int, uint32_t) = 0;
00337 
00338     bool _recv_delim_lf(void) {
00339         return (_parser.getc() == _lf_);
00340     }
00341 
00342     bool _recv_delim_cr(void) {
00343         return (_parser.getc() == _cr_);
00344     }
00345 
00346     bool _recv_delim_cr_lf(void) {
00347         return _recv_delim_cr() && _recv_delim_lf();
00348     }
00349 
00350     bool _recv_ok(void) {
00351         return _parser.recv(SPWFXX_RECV_OK) && _recv_delim_lf();
00352     }
00353 
00354     void _add_pending_packet_sz(int spwf_id, uint32_t size);
00355     void _add_pending_pkt_size(int spwf_id, uint32_t size) {
00356         _pending_pkt_sizes[spwf_id].add(size);
00357     }
00358 
00359     uint32_t _get_cumulative_size(int spwf_id) {
00360         return _pending_pkt_sizes[spwf_id].cumulative();
00361     }
00362 
00363     uint32_t _remove_pending_pkt_size(int spwf_id, uint32_t size) {
00364         return _pending_pkt_sizes[spwf_id].remove(size);
00365     }
00366 
00367     uint32_t _get_pending_pkt_size(int spwf_id) {
00368         return _pending_pkt_sizes[spwf_id].get();
00369     }
00370 
00371    void _reset_pending_pkt_sizes(int spwf_id) {
00372         _pending_pkt_sizes[spwf_id].reset();
00373     }
00374 
00375    void _set_pending_data(int spwf_id) {
00376        _pending_sockets_bitmap |= (1 << spwf_id);
00377    }
00378 
00379    void _clear_pending_data(int spwf_id) {
00380         _pending_sockets_bitmap &= ~(1 << spwf_id);
00381     }
00382 
00383     bool _is_data_pending(int spwf_id) {
00384         return (_pending_sockets_bitmap & (1 << spwf_id)) ? true : false;
00385     }
00386 
00387     bool _is_data_pending(void) {
00388         if(_pending_sockets_bitmap != 0) return true;
00389         else return false;
00390     }
00391 
00392     void _packet_handler_bh(void) {
00393         /* read in other eventually pending packages */
00394         _read_in_pending();
00395     }
00396 
00397     /* Do not call the (external) callback in IRQ context while performing critical module operations */
00398     void _event_handler(void);
00399 
00400     void _error_handler(void);
00401 
00402     void _call_callback(void) {
00403         if((bool)_callback_func) {
00404             _callback_func();
00405         }
00406     }
00407 
00408     bool _is_event_callback_blocked(void) {
00409         return (_call_event_callback_blocked != 0);
00410     }
00411 
00412     void _block_event_callback(void) {
00413         _call_event_callback_blocked++;
00414     }
00415 
00416     void _unblock_event_callback(void) {
00417         MBED_ASSERT(_call_event_callback_blocked > 0);
00418         _call_event_callback_blocked--;
00419         if(_call_event_callback_blocked == 0) {
00420             _trigger_event_callback();
00421         }
00422     }
00423 
00424     /* trigger call of (external) callback in case there is still data */
00425     void _trigger_event_callback(void) {
00426         MBED_ASSERT(_call_event_callback_blocked == 0);
00427         /* if still data available */
00428         if(readable()) {
00429             _call_callback();
00430         }
00431     }
00432 
00433     char _ip_buffer[16];
00434     char _gateway_buffer[16];
00435     char _netmask_buffer[16];
00436     char _mac_buffer[18];
00437 
00438     char _msg_buffer[256];
00439 
00440 private:
00441     friend class SPWFSA01;
00442     friend class SPWFSA04;
00443     friend class SpwfSAInterface;
00444 };
00445 
00446 #endif // SPWFSAXX_H