Jim Flynn / Mbed OS aws-iot-device-sdk-mbed-c
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers WNC14A2AInterface.h Source File

WNC14A2AInterface.h

Go to the documentation of this file.
00001 /**
00002 * copyright (c) 2017-2018, James Flynn
00003 * SPDX-License-Identifier: Apache-2.0
00004 */
00005 
00006 /*
00007 * Licensed under the Apache License, Version 2.0 (the "License");
00008 * you may not use this file except in compliance with the License.
00009 * You may obtain a copy of the License at
00010 *
00011 *     http://www.apache.org/licenses/LICENSE-2.0
00012 *
00013 * Unless required by applicable law or agreed to in writing, software
00014 * distributed under the License is distributed on an "AS IS" BASIS,
00015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016 *
00017 * See the License for the specific language governing permissions and
00018 * limitations under the License.
00019 */
00020 
00021 /**
00022 *  @file WNC14A2AInterface.h
00023 *  @brief Implements a standard NetworkInterface class for use with WNC M14A2A 
00024 *  data module. 
00025 *
00026 *  @author James Flynn
00027 * 
00028 *  @date 1-Feb-2018
00029 *  
00030 */
00031  
00032 #ifndef WNC14A2A_INTERFACE_H
00033 #define WNC14A2A_INTERFACE_H
00034 
00035 #include <stdint.h>
00036 
00037 #include "mbed.h"
00038 #include "Callback.h"
00039 #include "WNCDebug.h"
00040 #include "WncControllerK64F/WncControllerK64F.h"
00041 
00042 #define WNC14A2A_SOCKET_COUNT WncController::MAX_NUM_WNC_SOCKETS 
00043 
00044 // If target board does not support Arduino pins, define pins as Not Connected
00045 #if defined(TARGET_FF_ARDUINO)
00046 #if !defined(MBED_CONF_WNC14A2A_LIBRARY_WNC_RX_BOOT_SEL)
00047 #define MBED_CONF_WNC14A2A_LIBRARY_WNC_RX_BOOT_SEL                     D1
00048 #endif
00049 #if !defined(MBED_CONF_WNC14A2A_LIBRARY_WNC_POWER_ON)
00050 #define MBED_CONF_WNC14A2A_LIBRARY_WNC_POWER_ON                        D2
00051 #endif
00052 #if !defined(MBED_CONF_WNC14A2A_LIBRARY_WNC_WAKEUP)
00053 #define MBED_CONF_WNC14A2A_LIBRARY_WNC_WAKEUP                          D6
00054 #endif
00055 #if !defined(MBED_CONF_WNC14A2A_LIBRARY_WNC_RESET)
00056 #define MBED_CONF_WNC14A2A_LIBRARY_WNC_RESET                           D8
00057 #endif
00058 #if !defined(MBED_CONF_WNC14A2A_LIBRARY_WNC_LVLTRANSLATOR)
00059 #define MBED_CONF_WNC14A2A_LIBRARY_WNC_LVLTRANSLATOR                   D9
00060 #endif
00061 #if !defined(MBED_CONF_WNC14A2A_LIBRARY_WNC_CTS)
00062 #define MBED_CONF_WNC14A2A_LIBRARY_WNC_CTS                             D10
00063 #endif
00064 #if !defined(MBED_CONF_WNC14A2A_LIBRARY_WNC_RXD)
00065 #define MBED_CONF_WNC14A2A_LIBRARY_WNC_RXD                             D11
00066 #endif
00067 #if !defined(MBED_CONF_WNC14A2A_LIBRARY_WNC_TXD)
00068 #define MBED_CONF_WNC14A2A_LIBRARY_WNC_TXD                             D12
00069 #endif
00070 #else // !defined(TARGET_FF_ARDUINO)
00071 #define MBED_CONF_WNC14A2A_LIBRARY_WNC_RX_BOOT_SEL                     NC
00072 #define MBED_CONF_WNC14A2A_LIBRARY_WNC_POWER_ON                        NC
00073 #define MBED_CONF_WNC14A2A_LIBRARY_WNC_WAKEUP                          NC
00074 #define MBED_CONF_WNC14A2A_LIBRARY_WNC_RESET                           NC
00075 #define MBED_CONF_WNC14A2A_LIBRARY_WNC_LVLTRANSLATOR                   NC
00076 #define MBED_CONF_WNC14A2A_LIBRARY_WNC_CTS                             NC
00077 #define MBED_CONF_WNC14A2A_LIBRARY_WNC_RXD                             NC
00078 #define MBED_CONF_WNC14A2A_LIBRARY_WNC_TXD                             NC
00079 #endif // !defined(TARGET_FF_ARDUINO)
00080 
00081 typedef struct smsmsg_t {
00082         string number;
00083         string date;
00084         string time;
00085         string msg;
00086     } IOTSMS;
00087 
00088 typedef struct socket_t {
00089         int socket;                         //index of this socket
00090         string url;
00091         SocketAddress addr;                 //address info for this socket
00092         bool opened;                        //is the socket opened
00093         bool connected;                     //is the socket connected
00094         int proto;                          //this is a TCP or UDP socket
00095         void (*_callback)(void*);           //callback used with attach
00096         void *_cb_data;                     //callback data to be returned
00097     } WNCSOCKET;
00098 
00099 typedef struct rx_event_t {
00100         int      m_rx_wnc_state;            //state of the socket receive 
00101         int      m_rx_socket;               //which socket is being rcvd on
00102         uint8_t *m_rx_dptr;                 //pointer to the users data buffer
00103         uint32_t m_rx_req_size;             //Requested number of bytes to receive
00104         uint32_t m_rx_total_cnt;            //Total number of bytes received
00105         int      m_rx_timer;                //Rx Timeout Timer
00106         int      m_rx_disTO;                //Flag to disable Timeout Timer
00107         void    (*m_rx_callback)(void*);    //callback used with attach
00108         void     *m_rx_cb_data;             //callback data to be returned
00109         uint32_t m_rx_return_cnt;           //number of bytes the Event Queue is returning
00110     } RXEVENT;
00111 
00112 typedef struct tx_event_t {
00113     // Transmit Interrupt simulation to enabled non-blocking operation
00114     int      m_tx_wnc_state;
00115     int      m_tx_socket;
00116     uint8_t *m_tx_dptr;
00117     unsigned m_tx_orig_size;
00118     uint32_t m_tx_req_size;
00119     uint32_t m_tx_total_sent;
00120     void    (*m_tx_callback)(void*);
00121     void     *m_tx_cb_data;
00122     } TXEVENT;
00123 
00124 #define WNC_DEBUG   0           //1=enable the WNC startup debug output
00125                                 //0=disable the WNC startup debug output
00126 #define STOP_ON_FE  1           //1=hang forever if a fatal error occurs
00127                                 //0=simply return failed response for all socket calls
00128 #define DISPLAY_FE  1           //1 to display the fatal error when it occurs
00129                                 //0 to NOT display the fatal error
00130 #define RESETON_FE  0           //1 to cause the MCU to reset on fatal error
00131                                 //0 to NOT reset the MCU
00132 
00133 #define APN_DEFAULT             "m2m.com.attz"
00134                         
00135 /** Error Handling macros & data
00136 *   @brief  The macros CHK_WNCFE is used to check if a fatal error has occured. If it has
00137 *           then execute the action specified: fail, void, null, resume
00138 *
00139 *    CHK_WNCFE( condition-to-check, fail|void|null|resume )
00140 *
00141 *     'fail'   if you want FATAL_WNC_ERROR to be called.  
00142 *     'void'   if you want to execute a void return
00143 *     'null'   if you want to execute a null return
00144 *     'resume' if you simply want to resume program execution
00145 *
00146 *  There are several settings that control how FATAL_WNC_ERROR behaves:
00147 *      1) RESETON_FE determines if the system will reset or hang.
00148 *      2) DISPLAY_FE determine if an error message is generated or not
00149 *
00150 *  The DISPLAY_FE setting determines if a failure message is displayed. 
00151 *  If set to 1, user sees this messageo:
00152 *
00153 *      WNC FAILED @ source-file-name:source-file-line-number
00154 *
00155 *  if not set, nothing is displayed.
00156 */
00157 
00158 #define FATAL_FLAG  WncController::WNC_NO_RESPONSE
00159 #define WNC_GOOD    WncController::WNC_ON
00160 
00161 #define RETfail return -1
00162 #define RETvoid return
00163 #define RETnull return NULL
00164 #define RETresume   
00165 
00166 #define DORET(x) RET##x
00167 
00168 #define TOSTR(x) #x
00169 #define INTSTR(x) TOSTR(x)
00170 #define FATAL_STR (char*)(__FILE__ ":" INTSTR(__LINE__))
00171 
00172 #if RESETON_FE == 1   //reset on fatal error
00173 #define MCURESET     ((*((volatile unsigned long *)0xE000ED0CU))=(unsigned long)((0x5fa<<16) | 0x04L))
00174 #define RSTMSG       "RESET MCU! "
00175 #else
00176 #define MCURESET
00177 #define RSTMSG       ""
00178 #endif
00179 
00180 #if DISPLAY_FE == 1  //display fatal error message
00181 #define PFE     {if(_debugUart)_debugUart->printf((char*)RSTMSG "\r\n>>WNC FAILED @ %s\r\n", FATAL_STR);}
00182 #else
00183 #define PFE
00184 #endif
00185 
00186 #if STOP_ON_FE == 1  //halt cpu on fatal error
00187 #define FATAL_WNC_ERROR(v)  {_fatal_err_loc=FATAL_STR;PFE;MCURESET;while(1);}
00188 #else
00189 #define FATAL_WNC_ERROR(v)  {_fatal_err_loc=FATAL_STR;PFE;DORET(v);}
00190 #endif
00191 
00192 #define CHK_WNCFE(x,y)    if( x ){FATAL_WNC_ERROR(y);}
00193 
00194 #define FIRMWARE_REV(x) (((WNC14A2AInterface*)x)->getWNCRev())
00195 #define DBGMSG_DRV  0x04
00196 #define DBGMSG_EQ   0x08
00197 #define DBGMSG_SMS  0x10
00198 #define DBGMSG_ARRY     0x20
00199 
00200 #define MAX_SMS_MSGS    3
00201 
00202 using namespace WncController_fk;
00203  
00204 /** WNC14A2AInterface class
00205  *  Implementation of the NetworkInterface for WNC14A2A 
00206  */
00207 class WNC14A2AInterface : public NetworkStack, public NetworkInterface
00208 {
00209 public:
00210 
00211     /** WNC14A2AInterface Constructor.
00212      * @param optionally include a pointer to WNCDEBUG object for 
00213      * debug information to be displayed.
00214      */
00215     WNC14A2AInterface(WNCDebug *_dbgUart = NULL);
00216     virtual ~WNC14A2AInterface();
00217 
00218     /** Set the cellular network credentials
00219      *
00220      *  @param apn      Optional, APN of network
00221      *  @param user     Optional, username --not used--
00222      *  @param pass     Optional, password --not used--
00223      *  @return         nsapi_error_t
00224      */
00225     virtual nsapi_error_t set_credentials(const char *apn = 0,
00226             const char *username = 0, const char *password = 0);
00227  
00228     /** Connect to the network
00229      *
00230      *  @param apn      Optional, APN of network
00231      *  @param user     Optional, username --not used--
00232      *  @param pass     Optional, password --not used--
00233      *  @return         nsapi_error_t
00234      */
00235     virtual nsapi_error_t connect(const char *apn,
00236             const char *username = 0, const char *password = 0);
00237  
00238     /** Connect to the network (no parameters)
00239      *
00240      *  @return         nsapi_error_t
00241      */
00242     virtual nsapi_error_t connect();
00243 
00244     /** disconnect from the network
00245      *
00246      *  provided for completness, but function does nothing becase
00247      *  WNC part can not disconnect from network once connected.
00248      *
00249      *  @return         nsapi_error_t
00250      */
00251     virtual nsapi_error_t disconnect();
00252  
00253     /** Get the IP address of WNC device. From NetworkStack Class
00254      *
00255      *  @return         IP address string or null 
00256      */
00257     virtual const char *get_ip_address();
00258  
00259     /** Get the network assigned IP address.
00260      *
00261      *  @return         IP address or null 
00262      */
00263     const char *get_my_ip_address();
00264 
00265     /** Get the MAC address of the WNC device.  
00266      *
00267      *  @return         MAC address of the interface
00268      */
00269     virtual const char *get_mac_address();
00270  
00271     /** Attach a callback function for when a SMS is recevied
00272      *
00273      *  @param          function pointer to call
00274      */
00275     void sms_attach(void (*callback)(IOTSMS *));
00276 
00277     /** Set the level of Debug output
00278      *
00279      *  @param          bit field 
00280      *         basic AT command info= 0x01
00281      *         more AT command info = 0x02
00282      *         mbed driver info     = 0x04
00283      *         dump buffers         = 0x08
00284      *         all debug            = 0x0f
00285      */
00286     void doDebug(int v);
00287 
00288     /** Return the WNC reported Firmware Revision
00289      *
00290      *  @param          none.
00291      */
00292     const char* getWNCRev(void);
00293 
00294     /** Query registered state of WNC
00295      *
00296      *  @return         true if registerd, false if not 
00297      */
00298     bool registered();
00299 
00300     /** Start the SMS monitoring service
00301      */
00302     void sms_start(void);
00303 
00304     /** start listening for incomming SMS messages
00305      *
00306      *  @param time in msec to check
00307      */
00308     void sms_listen(uint16_t=1000);         // Configure device to listen for text messages 
00309         
00310     /** retrieve a SMS message
00311      *
00312      *  @param          pointer to an array of IOTSMS messages
00313      */
00314     int getSMS(IOTSMS **msg);
00315 
00316     /** send a SMS message
00317      *
00318      *  @param          a string containing number to send message to
00319      *  @param          a string containing message to send
00320      *  @return         true on success, 0 on failure
00321      */
00322     int sendIOTSms(const string&, const string&);
00323 
00324     /** return this devices SMS number
00325      *
00326      *  @brief The IOTSMS number used, isn't phone number, it is device ICCID.  
00327      *
00328      *  @return          this devices IOTSMS number
00329      */
00330     char* getSMSnbr();
00331 
00332 
00333 protected:
00334 
00335     /** Get Host IP by name. 
00336      *
00337      *  @return         nsapi_error_t
00338      */
00339     virtual nsapi_error_t gethostbyname(const char* name, SocketAddress *address, nsapi_version_t version);
00340 
00341 
00342     /** return a pointer to the NetworkStack object
00343      *
00344      *  @return          The underlying NetworkStack object
00345      */
00346     virtual NetworkStack *get_stack();
00347 
00348     /** Open a socket. 
00349      *
00350      *  @param handle       Handle in which to store new socket
00351      *  @param proto        Type of socket to open, NSAPI_TCP or NSAPI_UDP
00352      *  @return             0 on success, negative on failure
00353      */
00354     virtual int socket_open(void **handle, nsapi_protocol_t proto);
00355  
00356     /** Close the socket. 
00357      *
00358      *  @param handle       Socket handle
00359      *  @return             0 on success, negative on failure
00360      */
00361     virtual int socket_close(void *handle);
00362  
00363     /** Bind a server socket to a specific port.
00364      *
00365      *  @brief              Bind the socket to a specific port
00366      *  @param handle       Socket handle
00367      *  @param address      address to listen for 
00368      *  @return             0;
00369      */
00370     virtual int socket_bind(void *handle, const SocketAddress &address);
00371  
00372     /** Start listening for incoming connections.
00373      *
00374      *  @brief              NOT SUPPORTED
00375      *  @param handle       Socket handle
00376      *  @param backlog      Number of pending connections that can be queued up at any
00377      *                      one time [Default: 1]
00378      *  @return             NSAPI_ERROR_UNSUPPORTED;
00379      *  @note This function causes the receive time-out to be ignored resulting in continuous
00380      *        monitoring of received data. This is non-standard behaviour but it is how the
00381      *        mbed-cloud servcies use it...
00382      */
00383     virtual int socket_listen(void *handle, int backlog);
00384  
00385     /** Accept a new connection.
00386      *
00387      *  @brief              NOT SUPPORTED
00388      *  @return             NSAPI_ERROR_UNSUPPORTED;
00389      */
00390     virtual int socket_accept(nsapi_socket_t server,
00391             nsapi_socket_t *handle, SocketAddress *address=0);
00392  
00393     /** Connects this socket to the server.
00394      *
00395      *  @param handle       Socket handle
00396      *  @param address      SocketAddress 
00397      *  @return             0 on success, negative on failure
00398      */
00399     virtual int socket_connect(void *handle, const SocketAddress &address);
00400  
00401     /** Send data to the remote host.
00402      *
00403      *  @param handle       Socket handle
00404      *  @param data         buffer to send
00405      *  @param size         length of buffer
00406      *  @return             Number of bytes written or negative on failure
00407      *
00408      *  @note This call is blocking. 
00409      */
00410     virtual int socket_send(void *handle, const void *data, unsigned size);
00411  
00412     /** Receive data from the remote host.
00413      *
00414      *  @param handle       Socket handle
00415      *  @param data         buffer to store the recived data
00416      *  @param size         bytes to receive
00417      *  @return             received bytes received, negative on failure
00418      *
00419      *  @note This call is not-blocking 
00420      */
00421     virtual int socket_recv(void *handle, void *data, unsigned size);
00422  
00423     /** Send a packet to a remote endpoint.
00424      *
00425      *  @param handle       Socket handle
00426      *  @param address      SocketAddress
00427      *  @param data         data to send
00428      *  @param size         number of bytes to send
00429      *  @return the         number of bytes sent or negative on failure
00430      *
00431      *  @note This call is blocking.
00432      */
00433     virtual int socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned size);
00434  
00435     /** Receive packet remote endpoint
00436      *
00437      *  @param handle       Socket handle
00438      *  @param address      SocketAddress 
00439      *  @param buffer       buffer to store data to
00440      *  @param size         number of bytes to receive
00441      *  @return the         number bytes received or negative on failure
00442      *
00443      *  @note This call is not-blocking.
00444      */
00445     virtual int socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size);
00446  
00447     /** Register a callback on state change of the socket
00448      *
00449      *  @param handle       Socket handle
00450      *  @param callback     Function to call on state change
00451      *  @param data         Argument to pass to callback
00452      *
00453      *  @note Callback may be called in an interrupt context.
00454      */
00455     virtual void socket_attach(void *handle, void (*callback)(void *), void *data);
00456     
00457     /** get the status of internal errors
00458      *
00459      *  @brief Called after any WNC14A2A operation to determine error specifics 
00460      *  @param none.
00461      */
00462     uint16_t wnc14a2a_chk_error(void) { return m_errors; }
00463 
00464 private:
00465 
00466     //! WncController Class for interacting with the 14A2a hardware
00467     friend class WncControllerK64F;  
00468 
00469     bool     m_wncpoweredup;                //track if WNC has been power-up
00470     unsigned m_debug;
00471 
00472     WncIpStats myNetStats;                  //maintaint the network statistics
00473     WncControllerK64F_fk::WncControllerK64F  *m_pwnc; //pointer to the WncController instance
00474 
00475     WNCDebug *_debugUart;                     // Serial object for parser to communicate with radio
00476     char *_fatal_err_loc;                   // holds string containing location of fatal error
00477     nsapi_error_t m_errors;
00478 
00479     bool m_smsmoning;                       // Track if the SMS monitoring thread is running
00480     EventQueue sms_queue;                   // Queue used to schedule for SMS checks
00481     void (*_sms_cb)(IOTSMS *);              // Callback when text message is received. User must define this as 
00482                                             // a static function because I'm not handling an object offset
00483     IOTSMS m_MsgText, m_MsgText_array[MAX_SMS_MSGS];       // Used to pass SMS message to the user
00484     struct WncController::WncSmsList m_smsmsgs;            //use the WncSmsList structure to hold messages
00485 
00486     EventQueue wnc_queue;                   // Queue used to schedule for receiving data
00487     void handle_sms_event();                // SMS tx/rx handler
00488     void wnc_eq_event();                    // Simulated ISR
00489     int  rx_event(RXEVENT *);               // receive data handler
00490     int  tx_event(TXEVENT *);               // tx data handler
00491 
00492     char _mac_address[NSAPI_MAC_SIZE];      // local Mac
00493     void _dbOut(const char *format, ...);
00494     void _dbDump_arry( const uint8_t* data, unsigned int size );
00495 
00496     WNCSOCKET _sockets[WNC14A2A_SOCKET_COUNT];  //WNC supports 8 open sockets but driver only supports 1 currently
00497     TXEVENT   _socTxS[WNC14A2A_SOCKET_COUNT];
00498     RXEVENT   _socRxS[WNC14A2A_SOCKET_COUNT];
00499     Thread    _smsThread, _eqThread;            //Event Queue thread for SMS and Rx/Tx data
00500     Mutex     _pwnc_mutex;                      
00501     int       _active_socket;
00502 
00503     UARTSerial mdmUart;
00504     WncIO wnc_io;
00505 };
00506 
00507 #endif
00508