Jim Flynn / wnc14a2a-driver
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 5
00043 
00044 typedef struct smsmsg_t {
00045         string number;
00046         string date;
00047         string time;
00048         string msg;
00049     } IOTSMS;
00050 
00051 typedef struct socket_t {
00052         int socket;                         //index of this socket
00053         string url;
00054         SocketAddress addr;                 //hold info for this socket
00055         bool opened;                        //has the socket been opened
00056         bool _wnc_opened;                   //has the socket been opened
00057         int proto;                          //this is a TCP or UDP socket
00058         void (*_callback)(void*);           //callback used with attach
00059         void *_cb_data;                     //callback data to be returned
00060     } WNCSOCKET;
00061 
00062 #define WNC_DEBUG   0           //1=enable the WNC startup debug output
00063                                 //0=disable the WNC startup debug output
00064 #define STOP_ON_FE  1           //1=hang forever if a fatal error occurs
00065                                 //0=simply return failed response for all socket calls
00066 #define DISPLAY_FE  1           //1 to display the fatal error when it occurs
00067                                 //0 to NOT display the fatal error
00068 #define RESETON_FE  0           //1 to cause the MCU to reset on fatal error
00069                                 //0 to NOT reset the MCU
00070 
00071 #define APN_DEFAULT             "m2m.com.attz"
00072                         
00073 /** Error Handling macros & data
00074 *   @brief  The macros CHK_WNCFE is used to check if a fatal error has occured. If it has
00075 *           then execute the action specified: fail, void, null, resume
00076 *
00077 *    CHK_WNCFE( condition-to-check, fail|void|null|resume )
00078 *
00079 *     'fail'   if you want to FATAL_WNC_ERROR will be called.  
00080 *     'void'   if you want to execute a void return
00081 *     'null'   if you want to execute a null return
00082 *     'resume' if you simply want to resume program execution
00083 *
00084 *  There are several settings that control how FATAL_WNC_ERROR behaves:
00085 *      1) RESETON_FE determines if the system will reset or hang.
00086 *      2) DISPLAY_FE determine if an error message is generated or not
00087 *
00088 *  The DISPLAY_FE setting determines if a failure message is displayed. 
00089 *  If set to 1, user sees this messageo:
00090 *
00091 *      WNC FAILED @ source-file-name:source-file-line-number
00092 *
00093 *  if not set, nothing is displayed.
00094 */
00095 
00096 #define FATAL_FLAG  WncController::WNC_NO_RESPONSE
00097 #define WNC_GOOD    WncController::WNC_ON
00098 
00099 #define RETfail return -1
00100 #define RETvoid return
00101 #define RETnull return NULL
00102 #define RETresume   
00103 
00104 #define DORET(x) RET##x
00105 
00106 #define TOSTR(x) #x
00107 #define INTSTR(x) TOSTR(x)
00108 #define FATAL_STR (char*)(__FILE__ ":" INTSTR(__LINE__))
00109 
00110 #if RESETON_FE == 1   //reset on fatal error
00111 #define MCURESET     ((*((volatile unsigned long *)0xE000ED0CU))=(unsigned long)((0x5fa<<16) | 0x04L))
00112 #define RSTMSG       "RESET MCU! "
00113 #else
00114 #define MCURESET
00115 #define RSTMSG       ""
00116 #endif
00117 
00118 #if DISPLAY_FE == 1  //display fatal error message
00119 #define PFE     {if(_debugUart)_debugUart->printf((char*)RSTMSG "\r\n>>WNC FAILED @ %s\r\n", FATAL_STR);}
00120 #else
00121 #define PFE
00122 #endif
00123 
00124 #if STOP_ON_FE == 1  //halt cpu on fatal error
00125 #define FATAL_WNC_ERROR(v)  {_fatal_err_loc=FATAL_STR;PFE;MCURESET;while(1);}
00126 #else
00127 #define FATAL_WNC_ERROR(v)  {_fatal_err_loc=FATAL_STR;PFE;DORET(v);}
00128 #endif
00129 
00130 #define CHK_WNCFE(x,y)    if( x ){FATAL_WNC_ERROR(y);}
00131 
00132 #define MAX_SMS_MSGS    3
00133 
00134 using namespace WncController_fk;
00135  
00136 /** WNC14A2AInterface class
00137  *  Implementation of the NetworkInterface for WNC14A2A 
00138  */
00139 class WNC14A2AInterface : public NetworkStack, public CellularInterface
00140 {
00141 public:
00142     /** WNC14A2AInterface Constructor.
00143      * @param optionally include a pointer to WNCDEBUG object for 
00144      * debug information to be displayed.
00145      */
00146     WNC14A2AInterface(WNCDebug *_dbgUart = NULL);
00147     virtual ~WNC14A2AInterface();
00148 
00149     /** Set the cellular network credentials
00150      *
00151      *  @param apn      Optional, APN of network
00152      *  @param user     Optional, username --not used--
00153      *  @param pass     Optional, password --not used--
00154      *  @return         nsapi_error_t
00155      */
00156     virtual nsapi_error_t set_credentials(const char *apn = 0,
00157             const char *username = 0, const char *password = 0);
00158  
00159     /** Connect to the network
00160      *
00161      *  @param apn      Optional, APN of network
00162      *  @param user     Optional, username --not used--
00163      *  @param pass     Optional, password --not used--
00164      *  @return         nsapi_error_t
00165      */
00166     virtual nsapi_error_t connect(const char *apn,
00167             const char *username = 0, const char *password = 0);
00168  
00169     /** Connect to the network (no parameters)
00170      *
00171      *  @return         nsapi_error_t
00172      */
00173     virtual nsapi_error_t connect();
00174 
00175     /** disconnect from the network
00176      *
00177      *  provided for completness, but function does nothing becase
00178      *  WNC part can not disconnect from network once connected.
00179      *
00180      *  @return         nsapi_error_t
00181      */
00182     virtual nsapi_error_t disconnect();
00183  
00184     /** Get the IP address of WNC device. From NetworkStack Class
00185      *
00186      *  @return         IP address string or null 
00187      */
00188     virtual const char *get_ip_address();
00189  
00190     /** Get the network assigned IP address.
00191      *
00192      *  @return         IP address or null 
00193      */
00194     const char *get_my_ip_address();
00195 
00196     /** Get the MAC address of the WNC device.  
00197      *
00198      *  @return         MAC address of the interface
00199      */
00200     virtual const char *get_mac_address();
00201  
00202     /** Attach a callback function for when a SMS is recevied
00203      *
00204      *  @param          function pointer to call
00205      */
00206     void sms_attach(void (*callback)(IOTSMS *));
00207 
00208     /** Set the level of Debug output
00209      *
00210      *  @param          bit field 
00211      *         basic AT command info= 0x01
00212      *         more AT command info = 0x02
00213      *         mbed driver info     = 0x04
00214      *         dump buffers         = 0x08
00215      *         all debug            = 0x0f
00216      */
00217     void doDebug(int v);
00218 
00219     /** Query registered state of WNC
00220      *
00221      *  @return         true if registerd, false if not 
00222      */
00223     bool registered();
00224 
00225     /** Start the SMS monitoring service
00226      */
00227     void sms_start(void);
00228 
00229     /** start listening for incomming SMS messages
00230      *
00231      *  @param time in msec to check
00232      */
00233     void sms_listen(uint16_t=1000);         // Configure device to listen for text messages 
00234         
00235     /** retrieve a SMS message
00236      *
00237      *  @param          pointer to an array of IOTSMS messages
00238      */
00239     int getSMS(IOTSMS **msg);
00240 
00241     /** send a SMS message
00242      *
00243      *  @param          a string containing number to send message to
00244      *  @param          a string containing message to send
00245      *  @return         true on success, 0 on failure
00246      */
00247     int sendIOTSms(const string&, const string&);
00248 
00249     /** return this devices SMS number
00250      *
00251      *  @brief The IOTSMS number used, isn't phone number, it is device ICCID.  
00252      *
00253      *  @return          this devices IOTSMS number
00254      */
00255     char* getSMSnbr();
00256 
00257 
00258 protected:
00259 
00260     /** Get Host IP by name. 
00261      *
00262      *  @return         nsapi_error_t
00263      */
00264     virtual nsapi_error_t gethostbyname(const char* name, SocketAddress *address, nsapi_version_t version);
00265 
00266 
00267     /** return a pointer to the NetworkStack object
00268      *
00269      *  @return          The underlying NetworkStack object
00270      */
00271     virtual NetworkStack *get_stack();
00272 
00273     /** Open a socket. 
00274      *
00275      *  @param handle       Handle in which to store new socket
00276      *  @param proto        Type of socket to open, NSAPI_TCP or NSAPI_UDP
00277      *  @return             0 on success, negative on failure
00278      */
00279     virtual int socket_open(void **handle, nsapi_protocol_t proto);
00280  
00281     /** Close the socket. 
00282      *
00283      *  @param handle       Socket handle
00284      *  @return             0 on success, negative on failure
00285      */
00286     virtual int socket_close(void *handle);
00287  
00288     /** Bind a server socket to a specific port.
00289      *
00290      *  @brief              NOT SUPPORTED
00291      *  @param handle       Socket handle
00292      *  @param address      address to listen for incoming connections on 
00293      *  @return             NSAPI_ERROR_UNSUPPORTED;
00294      */
00295     virtual int socket_bind(void *handle, const SocketAddress &address);
00296  
00297     /** Start listening for incoming connections.
00298      *
00299      *  @brief              NOT SUPPORTED
00300      *  @param handle       Socket handle
00301      *  @param backlog      Number of pending connections that can be queued up at any
00302      *                      one time [Default: 1]
00303      *  @return             NSAPI_ERROR_UNSUPPORTED;
00304      */
00305     virtual int socket_listen(void *handle, int backlog);
00306  
00307     /** Accept a new connection.
00308      *
00309      *  @brief              NOT SUPPORTED
00310      *  @return             NSAPI_ERROR_UNSUPPORTED;
00311      */
00312     virtual int socket_accept(nsapi_socket_t server,
00313             nsapi_socket_t *handle, SocketAddress *address=0);
00314  
00315     /** Connects this socket to the server.
00316      *
00317      *  @param handle       Socket handle
00318      *  @param address      SocketAddress 
00319      *  @return             0 on success, negative on failure
00320      */
00321     virtual int socket_connect(void *handle, const SocketAddress &address);
00322  
00323     /** Send data to the remote host.
00324      *
00325      *  @param handle       Socket handle
00326      *  @param data         buffer to send
00327      *  @param size         length of buffer
00328      *  @return             Number of bytes written or negative on failure
00329      *
00330      *  @note This call is blocking. 
00331      */
00332     virtual int socket_send(void *handle, const void *data, unsigned size);
00333  
00334     /** Receive data from the remote host.
00335      *
00336      *  @param handle       Socket handle
00337      *  @param data         buffer to store the recived data
00338      *  @param size         bytes to receive
00339      *  @return             received bytes received, negative on failure
00340      *
00341      *  @note This call is not-blocking 
00342      */
00343     virtual int socket_recv(void *handle, void *data, unsigned size);
00344  
00345     /** Send a packet to a remote endpoint.
00346      *
00347      *  @param handle       Socket handle
00348      *  @param address      SocketAddress
00349      *  @param data         data to send
00350      *  @param size         number of bytes to send
00351      *  @return the         number of bytes sent or negative on failure
00352      *
00353      *  @note This call is blocking.
00354      */
00355     virtual int socket_sendto(void *handle, const SocketAddress &address, const void *data, unsigned size);
00356  
00357     /** Receive packet remote endpoint
00358      *
00359      *  @param handle       Socket handle
00360      *  @param address      SocketAddress 
00361      *  @param buffer       buffer to store data to
00362      *  @param size         number of bytes to receive
00363      *  @return the         number bytes received or negative on failure
00364      *
00365      *  @note This call is not-blocking.
00366      */
00367     virtual int socket_recvfrom(void *handle, SocketAddress *address, void *buffer, unsigned size);
00368  
00369     /** Register a callback on state change of the socket
00370      *
00371      *  @param handle       Socket handle
00372      *  @param callback     Function to call on state change
00373      *  @param data         Argument to pass to callback
00374      *
00375      *  @note Callback may be called in an interrupt context.
00376      */
00377     virtual void socket_attach(void *handle, void (*callback)(void *), void *data);
00378     
00379     /** get the status of internal errors
00380      *
00381      *  @brief Called after any WNC14A2A operation to determine error specifics 
00382      *  @param none.
00383      */
00384     uint16_t wnc14a2a_chk_error(void) { return _errors; }
00385 
00386 
00387 private:
00388     //! WncController Class for managing the 14A2a hardware
00389     friend class WncControllerK64F;  
00390 
00391     bool     m_wncpoweredup;                //track if WNC has been power-up
00392     unsigned m_debug;
00393 
00394     WncIpStats myNetStats;                  //maintaint the network statistics
00395     WncControllerK64F_fk::WncControllerK64F  *_pwnc; //pointer to the WncController instance
00396 
00397     int m_active_socket;                    // a 'pseudo' global to track the active socket
00398     WNCDebug *_debugUart;                     // Serial object for parser to communicate with radio
00399     char *_fatal_err_loc;                   // holds string containing location of fatal error
00400     nsapi_error_t _errors;
00401 
00402     bool m_smsmoning;                       // Track if the SMS monitoring thread is running
00403     EventQueue sms_queue;                   // Queue used to schedule for SMS checks
00404     EventQueue isr_queue;                   // Queue used to schedule for receiving data
00405     void (*_sms_cb)(IOTSMS *);              // Callback when text message is received. User must define this as 
00406                                             // a static function because I'm not handling an object offset
00407     IOTSMS m_MsgText, m_MsgText_array[MAX_SMS_MSGS];       // Used to pass SMS message to the user
00408     struct WncController::WncSmsList m_smsmsgs;            //use the WncSmsList structure to hold messages
00409 
00410     void handle_sms_event();                // SMS tx/rx handler
00411     void wnc_isr_event();                   // Simulated ISR
00412     int  rx_event();                        // receive data handler
00413     int  tx_event();                        // tx data handler
00414 
00415     char _mac_address[NSAPI_MAC_SIZE];      // local Mac
00416     void _dbOut(const char *format, ...);
00417     void _dbDump_arry( const uint8_t* data, unsigned int size );
00418 
00419     // Receive Interrupt simulation to enabled non-blocking operation
00420     uint8_t *m_recv_dptr;
00421     int      m_recv_wnc_state;
00422     int      m_recv_events;
00423     int      m_recv_socket;
00424     int      m_recv_timer;
00425     unsigned m_recv_orig_size;
00426     uint32_t m_recv_req_size, m_recv_total_cnt;
00427     uint32_t m_recv_return_cnt;
00428     void    (*m_recv_callback)(void*);
00429     void     *m_recv_cb_data;
00430 
00431     // Transmit Interrupt simulation to enabled non-blocking operation
00432     uint8_t *m_tx_dptr;
00433     int      m_tx_wnc_state;
00434     int      m_tx_socket;
00435     unsigned m_tx_orig_size;
00436     uint32_t m_tx_req_size, m_tx_total_sent;
00437     void    (*m_tx_callback)(void*);
00438     void     *m_tx_cb_data;
00439 
00440 };
00441 
00442 #endif
00443