V.06 11/3

Dependencies:   FT6206 SDFileSystem SPI_TFT_ILI9341 TFT_fonts

Fork of ATT_AWS_IoT_demo by attiot

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers WncController.h Source File

WncController.h

Go to the documentation of this file.
00001 /*
00002     Copyright (c) 2016 Fred Kellerman
00003  
00004     Permission is hereby granted, free of charge, to any person obtaining a copy
00005     of this software and associated documentation files (the "Software"), to deal
00006     in the Software without restriction, including without limitation the rights
00007     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008     copies of the Software, and to permit persons to whom the Software is
00009     furnished to do so, subject to the following conditions:
00010  
00011     The above copyright notice and this permission notice shall be included in
00012     all copies or substantial portions of the Software.
00013  
00014     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020     THE SOFTWARE.
00021     
00022     @file          WncController.h
00023     @purpose       Controls WNC Cellular Modem
00024     @version       1.0
00025     @date          July 2016
00026     @author        Fred Kellerman
00027     
00028     Notes: This code originates from the following mbed repository:
00029     
00030     https://developer.mbed.org/teams/Avnet/code/WncControllerLibrary/
00031 */
00032 
00033 
00034 #ifndef __WNCCONTROLLER_H_
00035 #define __WNCCONTROLLER_H_
00036 
00037 #include <string>
00038 #include <stdint.h>
00039 
00040 namespace WncController_fk {
00041     
00042 using namespace std;
00043 
00044 /**
00045  *  \file WncController.h
00046  *  \brief This mbed C++ class is for controlling the WNC
00047  *  Cellular modem via the AT command interface.  This was
00048  *  developed with respect to version 1.3 of the WNC authored
00049  *  spec.  This class is only designed to have 1 instantiation
00050  *  it is also not multi-thread safe.
00051  */
00052 
00053 
00054 
00055 
00056 static const uint8_t  MAX_LEN_IP_STR = 16;         // Length includes room for the extra NULL
00057 
00058 /**
00059  *  \brief  Contains info fields for the WNC Internet Attributes
00060  */
00061 struct WncIpStats
00062 {
00063     string wncMAC;
00064     char ip[MAX_LEN_IP_STR];
00065     char mask[MAX_LEN_IP_STR];
00066     char gateway[MAX_LEN_IP_STR];
00067     char dnsPrimary[MAX_LEN_IP_STR];
00068     char dnsSecondary[MAX_LEN_IP_STR];
00069 };
00070 
00071 class WncController
00072 {
00073 public:
00074     static const unsigned MAX_NUM_WNC_SOCKETS = 5;  // Max number of simultaneous sockets that the WNC supports
00075     static const unsigned MAX_POWERUP_TIMEOUT = 60; // How long the powerUp method will try to turn on the WNC Shield
00076                                                     //  (this is the default if the user does not over-ride on power-up
00077 
00078     // Tracks mode of the WNC Shield hardware
00079     enum WncState_e {
00080         WNC_OFF = 0,
00081         WNC_ON, // This is intended to mean all systems go, including cell link up but socket may not be open
00082         WNC_ON_NO_CELL_LINK,
00083         WNC_NO_RESPONSE
00084     };
00085 
00086     /**
00087      *  \brief Constructor for UART controlled WNC
00088      *
00089      *  \param [in] wnc_uart - Reference to a SerialBuffered object which will
00090      *  be used as the bus to control the WNC.  apnStr = a text string for
00091      *  the cellular APN name.
00092      *
00093      *  \return None.
00094      *
00095      *  \details Adding another way to talk to the WNC, like I2C or USB,
00096      *  a constructor should be added for each type just like the SerialBuffered
00097      *  constructor below.  Assumes UART is enabled, setup and ready to go. This
00098      *  class will read and write to this UART.
00099      */
00100     WncController(void);
00101     
00102     // WncController( const char * const apnStr, MODSERIAL * wnc_uart, MODSERIAL * debug_uart = NULL);
00103     
00104     /**
00105      *  \brief Used internally but also make public for a user of the Class to interrogate state as well.
00106      *
00107      *  \param [in] None.
00108      *
00109      *  \return The state of the WNC Modem.
00110      *
00111      *  \details None.
00112      */
00113     WncState_e getWncStatus(void);
00114     
00115     bool setApnName(const char * const apnStr);
00116 
00117     /**
00118      *  \brief Return signal quality dBm level
00119      *
00120      *  \param [in] None.
00121      *
00122      *  \return The dBm signal level at the time of the request.
00123      *
00124      *  \details This polls (at the time of the call) the cell signal.
00125      */
00126     int16_t getDbmRssi(void);
00127     int16_t get3gBer(void);
00128 
00129     /**
00130      *  \brief  Power up and down (down not implemented yet)
00131      *
00132      *  \param [in] NXP Pins that are critical for the initialization of the WNC Shield.
00133      *
00134      *  \return true if request successful else false.
00135      *
00136      *  \details Power-on works but not power-down.  This will manipulate WNC Shield hardware
00137      *  and bring it to life.  It will also initialize the WNC enough to get it to be able to open sockets
00138      *  (with AT commands)
00139      */
00140     bool powerWncOn(const char * const apn, uint8_t powerUpTimeoutSecs = MAX_POWERUP_TIMEOUT);
00141 
00142     /**
00143      *  \brief  Query the WNC modem for its Internet attributes
00144      *
00145      *  \param [in] Pointer to a struct where to put the info.
00146      *
00147      *  \return true if request successful else false.
00148      *
00149      *  \details This method will do a few sanity checks and then gather the
00150      *  fields of the struct.
00151      */
00152     bool getWncNetworkingStats(WncIpStats * s);
00153 
00154     /**
00155      *  \brief Look-up a URL text string and convert into an IP Address string.
00156      *
00157      *  \param [in] url - the URL to lookup.  numSock - the socket reference.
00158      *
00159      *  \return true - if the IP address has been resolved. false - if the URL could not be resolved.
00160      *
00161      *  \details None.
00162      */
00163     bool resolveUrl(uint16_t numSock, const char * url);
00164 
00165     /**
00166      *  \brief Set IP Address string
00167      *
00168      *  \param [in] numSock - socket reference to set the string for. ipStr - text string of the IP
00169      *  address you want to talk to.  There is no sanity check - beware!!!
00170      *
00171      *  \return true - if the IP address has been set. false - if the IP could not be set.
00172      *
00173      *  \details None.
00174      */
00175     bool setIpAddr(uint16_t numSock, const char * ipStr);
00176 
00177     /**
00178      *  \brief Opens a WNC socket.
00179      *
00180      *  \param [in] sockNum - the number of the socket to open.  ipAddr - a string containing
00181      *  the IP address.  port - the IP port number to open the socket connection.
00182      *
00183      *  \return true - if the socket is/was opened.  false otherwise.
00184      *
00185      *  \details None.
00186      */
00187     bool openSocket(uint16_t numSock, uint16_t port, bool tcp, uint16_t timeOutSec = 30);
00188     
00189     bool openSocketUrl(uint16_t numSock, const char * url, uint16_t port, bool tcp, uint16_t timeOutSec = 30);
00190 
00191     bool openSocketIpAddr(uint16_t numSock, const char * ipAddr, uint16_t port, bool tcp, uint16_t timeOutSec = 30);
00192 
00193 
00194     /**
00195      *  \brief Write bytes of data to an open socket
00196      *
00197      *  \param [in] sockNum - the number of the socket to write.  s - a string containing
00198      *  the byte data to send.
00199      *
00200      *  \return true - if the write was successful.  false otherwise.
00201      *
00202      *  \details The results of the write do not have anything to do with the data
00203      *  arriving at the endpoint.
00204      */
00205      bool write(uint16_t numSock, const char * s, uint32_t n);
00206 
00207     /**
00208      *  \brief Poll and read back data from the WNC (if it has any)
00209      *  If auto poll is enabled this read might fail (return with no data).
00210      *
00211      *  \param [in] sockNum - the number of the socket to read.  result - a string pointer containing
00212      *  the byte data readback from the WNC.
00213      *
00214      *  \return The number of bytes/chars that are read from the socket.
00215      *
00216      *  \details DO NOT use the same string as is passed to the auto poll setup method!
00217      */
00218     size_t read(uint16_t numSock, uint8_t * readBuf, uint32_t maxReadBufLen);
00219     
00220     size_t read(uint16_t numSock, const uint8_t ** readBuf);
00221 
00222     /**
00223      *  \brief Set how many times the above read method will retry if data is not returned.
00224      *
00225      *  \param [in] sockNum - the number of the socket to set.  retries - how many times to
00226      *  poll until data is found.
00227      *
00228      *  \return None.
00229      *
00230      *  \details None.
00231      */
00232     void setReadRetries(uint16_t numSock, uint16_t retries);
00233 
00234     /**
00235      *  \brief Set how long between retries to wait.
00236      *
00237      *  \param [in] sockNum - the number of the socket to set.  waitMs - how long to wait
00238      *  before doing the read poll (calling read(...)).
00239      *
00240      *  \return None.
00241      *
00242      *  \details None.
00243      */
00244     void setReadRetryWait(uint16_t numSock, uint16_t waitMs);
00245 
00246     /**
00247      *  \brief Close the socket.
00248      *
00249      *  \param [in] sockNum - the number of the socket to close.
00250      *
00251      *  \return None.
00252      *
00253      *  \details None.
00254      */
00255     bool closeSocket(uint16_t numSock);
00256 
00257     void setWncCmdTimeout(uint16_t toMs);
00258         
00259     bool getIpAddr(uint16_t numSock, char myIpAddr[MAX_LEN_IP_STR]);
00260     
00261     void enableDebug(bool on, bool moreDebugOn);
00262     
00263     ///////////////////////////////////////////
00264     //  SMS messaging
00265     ///////////////////////////////////////////
00266 
00267     static const uint16_t MAX_WNC_SMS_MSG_SLOTS = 3;   // How many SMS messages the WNC can store and receive at a time.
00268     static const uint16_t MAX_WNC_SMS_LENGTH    = 160; // The maximum length of a 7-bit SMS message the WNC can send and receive.
00269     
00270     struct WncSmsInfo
00271     {
00272         // Content
00273         char   idx;
00274         string number;
00275         string date;
00276         string time;
00277         string msg;
00278         
00279         // Attributes
00280         bool incoming;
00281         bool unsent;
00282         bool unread;
00283         bool pduMode;
00284         bool msgReceipt;
00285     };
00286 
00287     struct WncSmsList
00288     {
00289         uint8_t msgCount;
00290         WncSmsInfo e[MAX_WNC_SMS_MSG_SLOTS];
00291     };
00292 
00293     bool sendSMSText(const char * const phoneNum, const char * const text);
00294 
00295     bool readSMSLog(struct WncSmsList * log);
00296 
00297     bool readUnreadSMSText(struct WncSmsList * w, bool deleteRead = true);
00298     
00299     bool saveSMSText(const char * const phoneNum, const char * const text, char * msgIdx);
00300     
00301     bool sendSMSTextFromMem(char msgIdx);
00302 
00303     bool deleteSMSTextFromMem(char msgIdx);
00304     
00305     bool getICCID(string * iccid);
00306 
00307     bool convertICCIDtoMSISDN(const string & iccid, string * msisdn);
00308     
00309     //certificate and key object related funtions
00310     bool getObject(string sObjectName, unsigned char *ucObject, int *iObjectLength);
00311     bool getSubjectName(string sObjectName, unsigned char *ucObject, int *iObjectLength);
00312     bool getUpdateStatus(unsigned char *cStatus);
00313     bool getAllObjects();
00314     
00315     
00316     ///////////////////////////////////////////
00317     // Neighborhood Cell Info
00318     ///////////////////////////////////////////
00319     size_t getSignalQuality(const char ** log);
00320     
00321     //  Date Time
00322     struct WncDateTime
00323     {
00324         uint8_t  year;
00325         uint8_t  month;
00326         uint8_t  day;
00327         uint8_t  hour;
00328         uint8_t  min;
00329         uint8_t  sec;
00330     };
00331 
00332     bool getTimeDate(struct WncDateTime * tod);
00333     
00334     // Ping
00335     bool pingUrl(const char * url);
00336     bool pingIp(const char * ip);
00337     
00338     // User command:
00339     size_t sendCustomCmd(const char * cmd, char * resp, size_t sizeRespBuf, int ms_timeout);
00340 
00341 protected:
00342 
00343     // Debug output methods
00344     int dbgPutsNoTime(const char * s, bool crlf = true);
00345     int dbgPuts(const char * s, bool crlf = true);
00346     const char * _to_string(int64_t value);
00347     const char * _to_hex_string(uint8_t value);    
00348 
00349     // Sends commands to WNC via
00350     enum AtCmdErr_e {
00351         WNC_AT_CMD_OK,
00352         WNC_AT_CMD_ERR,
00353         WNC_AT_CMD_ERREXT,
00354         WNC_AT_CMD_ERRCME,
00355         WNC_AT_CMD_INVALID_RESPONSE,
00356         WNC_AT_CMD_TIMEOUT,
00357         WNC_AT_CMD_NO_CELL_LINK,
00358         WNC_AT_CMD_WNC_NOT_ON
00359     };
00360 
00361     // Users must define these functionalities:
00362     virtual int putc(char c)              = 0;
00363     virtual int puts(const char * s)      = 0;
00364     virtual char getc(void)               = 0;
00365     virtual int charReady(void)           = 0;
00366     virtual int dbgWriteChar(char b)      = 0;
00367     virtual int dbgWriteChars(const char *b) = 0;
00368     virtual void waitMs(int t)            = 0;
00369     virtual void waitUs(int t)            = 0;
00370     virtual bool initWncModem(uint8_t powerUpTimeoutSecs) = 0;
00371     
00372     // Isolate OS timers
00373     virtual int  getLogTimerTicks(void)  = 0;
00374     virtual void startTimerA(void)       = 0;
00375     virtual void stopTimerA(void)        = 0;
00376     virtual int  getTimerTicksA_mS(void) = 0;
00377     virtual void startTimerB(void)       = 0;
00378     virtual void stopTimerB(void)        = 0;
00379     virtual int  getTimerTicksB_mS(void) = 0;
00380         
00381     bool waitForPowerOnModemToRespond(uint8_t powerUpTimeoutSecs);    
00382     AtCmdErr_e sendWncCmd(const char * const s, string ** r, int ms_timeout);
00383     
00384 private:
00385 
00386     bool softwareInitMdm(void);
00387     bool checkCellLink(void);
00388     AtCmdErr_e mdmSendAtCmdRsp(const char * cmd, int timeout_ms, string * rsp, bool crLf = true);
00389     size_t mdmGetline(string * buff, int timeout_ms);
00390     bool at_at_wnc(void);
00391     bool at_init_wnc(bool hardReset = false);
00392     int16_t at_sockopen_wnc(const char * const ip, uint16_t port, uint16_t numSock, bool tcp, uint16_t timeOutSec);
00393     bool at_sockclose_wnc(uint16_t numSock);
00394     bool at_dnsresolve_wnc(const char * s, string * ipStr);
00395     AtCmdErr_e at_sockwrite_wnc(const char * s, uint16_t n, uint16_t numSock, bool isTcp);
00396     AtCmdErr_e at_sockread_wnc(uint8_t * pS, uint16_t * numRead, uint16_t n, uint16_t numSock, bool isTcp);
00397     AtCmdErr_e at_sockread_wnc(string * pS, uint16_t numSock, bool isTcp);
00398     bool at_reinitialize_mdm(void);
00399     AtCmdErr_e at_send_wnc_cmd(const char * s, string ** r, int ms_timeout);
00400     bool at_setapn_wnc(const char * const apnStr);
00401     bool at_sendSMStext_wnc(const char * const phoneNum, const char * const text);
00402     bool at_get_wnc_net_stats(WncIpStats * s);
00403     bool at_readSMSlog_wnc(string ** log);
00404     size_t at_readSMStext_wnc(const char ** log);
00405     size_t at_readSMStext_wnc(const char n, const char ** log);
00406     bool at_getrssiber_wnc(int16_t * dBm, int16_t * ber3g);
00407     void closeOpenSocket(uint16_t numSock);
00408     bool sockWrite(const char * const s, uint16_t n, uint16_t numSock, bool isTcp);
00409     bool at_sendSMStextMem_wnc(char n);
00410     bool at_deleteSMSTextFromMem_wnc(char n);
00411     bool at_saveSMStext_wnc(const char * const phoneNum, const char * const text, char * msgIdx);
00412     size_t at_getSignalQuality_wnc(const char ** log);
00413     bool at_gettimedate_wnc(struct WncDateTime * tod);
00414     bool at_ping_wnc(const char * ip);
00415     bool at_geticcid_wnc(string * iccid);
00416     
00417     //certificate and key objects
00418     bool at_openChannel_wnc(string *sChannelID);
00419     bool at_closeChannel_wnc(string sChannelID);
00420     bool at_selectObject_wnc(string sChannelID, string sObject, int *iObjectLength);
00421     bool at_getObjectBlock_wnc(string sChannelID, string sObject, string sBlock, int *iObjectBlockLength, string *sData);
00422     bool at_getSubjectName_wnc(string sChannelID, int *iObjectBlockLength, string *sData);
00423     bool at_getUpdateStatus_wnc(string sChannelID, int *iLength, string *sData);
00424     
00425     // Utility methods
00426     void sendCmd(const char * cmd, bool crLf);
00427     void sendCmd(const char * cmd, unsigned n, unsigned wait_uS, bool crLf);    
00428     inline void rx_char_wait(void) {
00429         // waitUs(1000);
00430     }
00431     
00432     // Important constants
00433     static const uint16_t MAX_WNC_READ_BYTES        = 1500;                            // This bounds the largest amount of data that the WNC read from a socket will return
00434     static const uint16_t MAX_WNC_WRITE_BYTES       = MAX_WNC_READ_BYTES;              // This is the largest amount of data that the WNC can write per sockwrite.
00435     static const uint16_t MAX_LEN_WNC_CMD_RESPONSE  = (MAX_WNC_READ_BYTES * 2 + 100);  // Max number of text characters in a WNC AT response *2 because bytes are converted into 2 hex-digits +100 for other AT@ chars.
00436     static const uint16_t WNC_AUTO_POLL_MS          = 250;   // Sets default (may be overriden with method) poll interval (currently not used, future possible feature.
00437     static const uint16_t WNC_CMD_TIMEOUT_MS        = 40000; // Sets default (may be overriden) time that the software waits for an AT response from the WNC.
00438     static const uint16_t WNC_QUICK_CMD_TIMEOUT_MS  = 2000;  // Used for simple commands that should immediately respond such as "AT", cmds that are quicker than WNC_CMD_TIMEOUT_MS.
00439     static const uint16_t WNC_WAIT_FOR_AT_CMD_MS    = 0;     // Wait this much between multiple in a row AT commands to the WNC.
00440     static const uint16_t WNC_SOFT_INIT_RETRY_COUNT = 10;    // How many times the WNC will be tried to revive if it stops responding.
00441     static const uint16_t WNC_DNS_RESOLVE_WAIT_MS   = 60000; // How much time to wait for the WNC to respond to a DNS resolve/lookup.
00442     static const uint16_t WNC_TRUNC_DEBUG_LENGTH    = 80;    // Always make this an even number, how many chars for the debug output before shortening the debug ouput, this is used when moreDebug = false. 
00443     static const uint16_t WNC_APNSET_TIMEOUT_MS     = 60000; // How long to wait for the WNC to respond to setting the APN string.
00444     static const uint16_t WNC_PING_CMD_TIMEOUT_MS   = 60000; // Amount of time to wait for the WNC to respond to AT@PINGREQ (with cmd default params for timeout, does not change WNC cmd's timeout) 
00445     static const int      WNC_REINIT_MAX_TIME_MS    = 60000; // How long to wait for the WNC to reset after it was already up and running after power-up.
00446     static const uint16_t WNC_SOCK_CLOSE_RETRY_CNT  = 3;     // How many times to try to close the socket if the WNC gives an error.
00447     static const char * const INVALID_IP_STR;                // Just a string set to an IP address when DNS resolve fails.
00448         
00449     struct WncSocketInfo_s {
00450         int16_t numWncSock;
00451         bool open;
00452         string myIpAddressStr;
00453         uint16_t myPort;
00454         uint8_t readRetries;
00455         uint16_t readRetryWaitMs;
00456         bool isTcp;
00457         uint16_t timeOutSec;
00458     };
00459 
00460     static WncSocketInfo_s m_sSock[MAX_NUM_WNC_SOCKETS];
00461     static const WncSocketInfo_s defaultSockStruct;
00462     static WncState_e m_sState;
00463     static uint16_t m_sCmdTimeoutMs;
00464     static string m_sApnStr;
00465     static string m_sWncStr;
00466     static uint8_t m_sPowerUpTimeoutSecs;
00467     static bool m_sDebugEnabled;
00468     static bool m_sMoreDebugEnabled;
00469     static bool m_sCheckNetStatus;
00470     static bool m_sReadyForSMS;
00471     
00472     static string m_sChannelID;
00473     static char sOutput[100];
00474     static char sCommand[256];
00475     //static unsigned char ucObject[2500];
00476 };
00477 
00478 };  // End namespace WncController_fk
00479 
00480 #endif