Demo application for using the AT&T IoT Starter Kit Powered by AWS.
Dependencies: SDFileSystem
Fork of ATT_AWS_IoT_demo by
WncController.h
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 static const uint8_t MAX_LEN_IP_STR = 16; // Length includes room for the extra NULL 00055 00056 /** 00057 * \brief Contains info fields for the WNC Internet Attributes 00058 */ 00059 struct WncIpStats 00060 { 00061 string wncMAC; 00062 char ip[MAX_LEN_IP_STR]; 00063 char mask[MAX_LEN_IP_STR]; 00064 char gateway[MAX_LEN_IP_STR]; 00065 char dnsPrimary[MAX_LEN_IP_STR]; 00066 char dnsSecondary[MAX_LEN_IP_STR]; 00067 }; 00068 00069 class WncController 00070 { 00071 public: 00072 static const unsigned MAX_NUM_WNC_SOCKETS = 5; // Max number of simultaneous sockets that the WNC supports 00073 static const unsigned MAX_POWERUP_TIMEOUT = 60; // How long the powerUp method will try to turn on the WNC Shield 00074 // (this is the default if the user does not over-ride on power-up 00075 00076 // Tracks mode of the WNC Shield hardware 00077 enum WncState_e { 00078 WNC_OFF = 0, 00079 WNC_ON, // This is intended to mean all systems go, including cell link up but socket may not be open 00080 WNC_ON_NO_CELL_LINK, 00081 WNC_NO_RESPONSE 00082 }; 00083 00084 /** 00085 * \brief Constructor for UART controlled WNC 00086 * 00087 * \param [in] wnc_uart - Reference to a SerialBuffered object which will 00088 * be used as the bus to control the WNC. apnStr = a text string for 00089 * the cellular APN name. 00090 * 00091 * \return None. 00092 * 00093 * \details Adding another way to talk to the WNC, like I2C or USB, 00094 * a constructor should be added for each type just like the SerialBuffered 00095 * constructor below. Assumes UART is enabled, setup and ready to go. This 00096 * class will read and write to this UART. 00097 */ 00098 WncController(void); 00099 00100 // WncController( const char * const apnStr, MODSERIAL * wnc_uart, MODSERIAL * debug_uart = NULL); 00101 00102 /** 00103 * \brief Used internally but also make public for a user of the Class to interrogate state as well. 00104 * 00105 * \param [in] None. 00106 * 00107 * \return The state of the WNC Modem. 00108 * 00109 * \details None. 00110 */ 00111 WncState_e getWncStatus(void); 00112 00113 bool setApnName(const char * const apnStr); 00114 00115 /** 00116 * \brief Return signal quality dBm level 00117 * 00118 * \param [in] None. 00119 * 00120 * \return The dBm signal level at the time of the request. 00121 * 00122 * \details This polls (at the time of the call) the cell signal. 00123 */ 00124 int16_t getDbmRssi(void); 00125 int16_t get3gBer(void); 00126 00127 /** 00128 * \brief Power up and down (down not implemented yet) 00129 * 00130 * \param [in] NXP Pins that are critical for the initialization of the WNC Shield. 00131 * 00132 * \return true if request successful else false. 00133 * 00134 * \details Power-on works but not power-down. This will manipulate WNC Shield hardware 00135 * and bring it to life. It will also initialize the WNC enough to get it to be able to open sockets 00136 * (with AT commands) 00137 */ 00138 bool powerWncOn(const char * const apn, uint8_t powerUpTimeoutSecs = MAX_POWERUP_TIMEOUT); 00139 00140 /** 00141 * \brief Query the WNC modem for its Internet attributes 00142 * 00143 * \param [in] Pointer to a struct where to put the info. 00144 * 00145 * \return true if request successful else false. 00146 * 00147 * \details This method will do a few sanity checks and then gather the 00148 * fields of the struct. 00149 */ 00150 bool getWncNetworkingStats(WncIpStats * s); 00151 00152 /** 00153 * \brief Look-up a URL text string and convert into an IP Address string. 00154 * 00155 * \param [in] url - the URL to lookup. numSock - the socket reference. 00156 * 00157 * \return true - if the IP address has been resolved. false - if the URL could not be resolved. 00158 * 00159 * \details None. 00160 */ 00161 bool resolveUrl(uint16_t numSock, const char * url); 00162 00163 /** 00164 * \brief Set IP Address string 00165 * 00166 * \param [in] numSock - socket reference to set the string for. ipStr - text string of the IP 00167 * address you want to talk to. There is no sanity check - beware!!! 00168 * 00169 * \return true - if the IP address has been set. false - if the IP could not be set. 00170 * 00171 * \details None. 00172 */ 00173 bool setIpAddr(uint16_t numSock, const char * ipStr); 00174 00175 /** 00176 * \brief Opens a WNC socket. 00177 * 00178 * \param [in] sockNum - the number of the socket to open. ipAddr - a string containing 00179 * the IP address. port - the IP port number to open the socket connection. 00180 * 00181 * \return true - if the socket is/was opened. false otherwise. 00182 * 00183 * \details None. 00184 */ 00185 bool openSocket(uint16_t numSock, uint16_t port, bool tcp, uint16_t timeOutSec = 30); 00186 00187 bool openSocketUrl(uint16_t numSock, const char * url, uint16_t port, bool tcp, uint16_t timeOutSec = 30); 00188 00189 bool openSocketIpAddr(uint16_t numSock, const char * ipAddr, uint16_t port, bool tcp, uint16_t timeOutSec = 30); 00190 00191 00192 /** 00193 * \brief Write bytes of data to an open socket 00194 * 00195 * \param [in] sockNum - the number of the socket to write. s - a string containing 00196 * the byte data to send. 00197 * 00198 * \return true - if the write was successful. false otherwise. 00199 * 00200 * \details The results of the write do not have anything to do with the data 00201 * arriving at the endpoint. 00202 */ 00203 bool write(uint16_t numSock, const char * s, uint32_t n); 00204 00205 /** 00206 * \brief Poll and read back data from the WNC (if it has any) 00207 * If auto poll is enabled this read might fail (return with no data). 00208 * 00209 * \param [in] sockNum - the number of the socket to read. result - a string pointer containing 00210 * the byte data readback from the WNC. 00211 * 00212 * \return The number of bytes/chars that are read from the socket. 00213 * 00214 * \details DO NOT use the same string as is passed to the auto poll setup method! 00215 */ 00216 size_t read(uint16_t numSock, uint8_t * readBuf, uint32_t maxReadBufLen); 00217 00218 size_t read(uint16_t numSock, const uint8_t ** readBuf); 00219 00220 /** 00221 * \brief Set how many times the above read method will retry if data is not returned. 00222 * 00223 * \param [in] sockNum - the number of the socket to set. retries - how many times to 00224 * poll until data is found. 00225 * 00226 * \return None. 00227 * 00228 * \details None. 00229 */ 00230 void setReadRetries(uint16_t numSock, uint16_t retries); 00231 00232 /** 00233 * \brief Set how long between retries to wait. 00234 * 00235 * \param [in] sockNum - the number of the socket to set. waitMs - how long to wait 00236 * before doing the read poll (calling read(...)). 00237 * 00238 * \return None. 00239 * 00240 * \details None. 00241 */ 00242 void setReadRetryWait(uint16_t numSock, uint16_t waitMs); 00243 00244 /** 00245 * \brief Close the socket. 00246 * 00247 * \param [in] sockNum - the number of the socket to close. 00248 * 00249 * \return None. 00250 * 00251 * \details None. 00252 */ 00253 bool closeSocket(uint16_t numSock); 00254 00255 void setWncCmdTimeout(uint16_t toMs); 00256 00257 bool getIpAddr(uint16_t numSock, char myIpAddr[MAX_LEN_IP_STR]); 00258 00259 void enableDebug(bool on, bool moreDebugOn); 00260 00261 /////////////////////////////////////////// 00262 // SMS messaging 00263 /////////////////////////////////////////// 00264 00265 static const uint16_t MAX_WNC_SMS_MSG_SLOTS = 3; // How many SMS messages the WNC can store and receive at a time. 00266 static const uint16_t MAX_WNC_SMS_LENGTH = 160; // The maximum length of a 7-bit SMS message the WNC can send and receive. 00267 00268 struct WncSmsInfo 00269 { 00270 // Content 00271 char idx; 00272 string number; 00273 string date; 00274 string time; 00275 string msg; 00276 00277 // Attributes 00278 bool incoming; 00279 bool unsent; 00280 bool unread; 00281 bool pduMode; 00282 bool msgReceipt; 00283 }; 00284 00285 struct WncSmsList 00286 { 00287 uint8_t msgCount; 00288 WncSmsInfo e[MAX_WNC_SMS_MSG_SLOTS]; 00289 }; 00290 00291 bool sendSMSText(const char * const phoneNum, const char * const text); 00292 00293 bool readSMSLog(struct WncSmsList * log); 00294 00295 bool readUnreadSMSText(struct WncSmsList * w, bool deleteRead = true); 00296 00297 bool saveSMSText(const char * const phoneNum, const char * const text, char * msgIdx); 00298 00299 bool sendSMSTextFromMem(char msgIdx); 00300 00301 bool deleteSMSTextFromMem(char msgIdx); 00302 00303 bool getICCID(string * iccid); 00304 00305 bool convertICCIDtoMSISDN(const string & iccid, string * msisdn); 00306 00307 /////////////////////////////////////////// 00308 // Neighborhood Cell Info 00309 /////////////////////////////////////////// 00310 size_t getSignalQuality(const char ** log); 00311 00312 // Date Time 00313 struct WncDateTime 00314 { 00315 uint8_t year; 00316 uint8_t month; 00317 uint8_t day; 00318 uint8_t hour; 00319 uint8_t min; 00320 uint8_t sec; 00321 }; 00322 00323 bool getTimeDate(struct WncDateTime * tod); 00324 00325 // Ping 00326 bool pingUrl(const char * url); 00327 bool pingIp(const char * ip); 00328 00329 // User command: 00330 size_t sendCustomCmd(const char * cmd, char * resp, size_t sizeRespBuf, int ms_timeout); 00331 00332 protected: 00333 00334 // Debug output methods 00335 int dbgPutsNoTime(const char * s, bool crlf = true); 00336 int dbgPuts(const char * s, bool crlf = true); 00337 const char * _to_string(int64_t value); 00338 const char * _to_hex_string(uint8_t value); 00339 00340 // Sends commands to WNC via 00341 enum AtCmdErr_e { 00342 WNC_AT_CMD_OK, 00343 WNC_AT_CMD_ERR, 00344 WNC_AT_CMD_ERREXT, 00345 WNC_AT_CMD_ERRCME, 00346 WNC_AT_CMD_INVALID_RESPONSE, 00347 WNC_AT_CMD_TIMEOUT, 00348 WNC_AT_CMD_NO_CELL_LINK, 00349 WNC_AT_CMD_WNC_NOT_ON 00350 }; 00351 00352 // Users must define these functionalities: 00353 virtual int putc(char c) = 0; 00354 virtual int puts(const char * s) = 0; 00355 virtual char getc(void) = 0; 00356 virtual int charReady(void) = 0; 00357 virtual int dbgWriteChar(char b) = 0; 00358 virtual int dbgWriteChars(const char *b) = 0; 00359 virtual void waitMs(int t) = 0; 00360 virtual void waitUs(int t) = 0; 00361 virtual bool initWncModem(uint8_t powerUpTimeoutSecs) = 0; 00362 00363 // Isolate OS timers 00364 virtual int getLogTimerTicks(void) = 0; 00365 virtual void startTimerA(void) = 0; 00366 virtual void stopTimerA(void) = 0; 00367 virtual int getTimerTicksA_mS(void) = 0; 00368 virtual void startTimerB(void) = 0; 00369 virtual void stopTimerB(void) = 0; 00370 virtual int getTimerTicksB_mS(void) = 0; 00371 00372 bool waitForPowerOnModemToRespond(uint8_t powerUpTimeoutSecs); 00373 AtCmdErr_e sendWncCmd(const char * const s, string ** r, int ms_timeout); 00374 00375 private: 00376 00377 bool softwareInitMdm(void); 00378 bool checkCellLink(void); 00379 AtCmdErr_e mdmSendAtCmdRsp(const char * cmd, int timeout_ms, string * rsp, bool crLf = true); 00380 size_t mdmGetline(string * buff, int timeout_ms); 00381 bool at_at_wnc(void); 00382 bool at_init_wnc(bool hardReset = false); 00383 int16_t at_sockopen_wnc(const char * const ip, uint16_t port, uint16_t numSock, bool tcp, uint16_t timeOutSec); 00384 bool at_sockclose_wnc(uint16_t numSock); 00385 bool at_dnsresolve_wnc(const char * s, string * ipStr); 00386 AtCmdErr_e at_sockwrite_wnc(const char * s, uint16_t n, uint16_t numSock, bool isTcp); 00387 AtCmdErr_e at_sockread_wnc(uint8_t * pS, uint16_t * numRead, uint16_t n, uint16_t numSock, bool isTcp); 00388 AtCmdErr_e at_sockread_wnc(string * pS, uint16_t numSock, bool isTcp); 00389 bool at_reinitialize_mdm(void); 00390 AtCmdErr_e at_send_wnc_cmd(const char * s, string ** r, int ms_timeout); 00391 bool at_setapn_wnc(const char * const apnStr); 00392 bool at_sendSMStext_wnc(const char * const phoneNum, const char * const text); 00393 bool at_get_wnc_net_stats(WncIpStats * s); 00394 bool at_readSMSlog_wnc(string ** log); 00395 size_t at_readSMStext_wnc(const char ** log); 00396 size_t at_readSMStext_wnc(const char n, const char ** log); 00397 bool at_getrssiber_wnc(int16_t * dBm, int16_t * ber3g); 00398 void closeOpenSocket(uint16_t numSock); 00399 bool sockWrite(const char * const s, uint16_t n, uint16_t numSock, bool isTcp); 00400 bool at_sendSMStextMem_wnc(char n); 00401 bool at_deleteSMSTextFromMem_wnc(char n); 00402 bool at_saveSMStext_wnc(const char * const phoneNum, const char * const text, char * msgIdx); 00403 size_t at_getSignalQuality_wnc(const char ** log); 00404 bool at_gettimedate_wnc(struct WncDateTime * tod); 00405 bool at_ping_wnc(const char * ip); 00406 bool at_geticcid_wnc(string * iccid); 00407 00408 // Utility methods 00409 void sendCmd(const char * cmd, bool crLf); 00410 void sendCmd(const char * cmd, unsigned n, unsigned wait_uS, bool crLf); 00411 inline void rx_char_wait(void) { 00412 // waitUs(1000); 00413 } 00414 00415 // Important constants 00416 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 00417 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. 00418 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. 00419 static const uint16_t WNC_AUTO_POLL_MS = 250; // Sets default (may be overriden with method) poll interval (currently not used, future possible feature. 00420 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. 00421 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. 00422 static const uint16_t WNC_WAIT_FOR_AT_CMD_MS = 0; // Wait this much between multiple in a row AT commands to the WNC. 00423 static const uint16_t WNC_SOFT_INIT_RETRY_COUNT = 10; // How many times the WNC will be tried to revive if it stops responding. 00424 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. 00425 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. 00426 static const uint16_t WNC_APNSET_TIMEOUT_MS = 60000; // How long to wait for the WNC to respond to setting the APN string. 00427 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) 00428 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. 00429 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. 00430 static const char * const INVALID_IP_STR; // Just a string set to an IP address when DNS resolve fails. 00431 00432 struct WncSocketInfo_s { 00433 int16_t numWncSock; 00434 bool open; 00435 string myIpAddressStr; 00436 uint16_t myPort; 00437 uint8_t readRetries; 00438 uint16_t readRetryWaitMs; 00439 bool isTcp; 00440 uint16_t timeOutSec; 00441 }; 00442 00443 static WncSocketInfo_s m_sSock[MAX_NUM_WNC_SOCKETS]; 00444 static const WncSocketInfo_s defaultSockStruct; 00445 static WncState_e m_sState; 00446 static uint16_t m_sCmdTimeoutMs; 00447 static string m_sApnStr; 00448 static string m_sWncStr; 00449 static uint8_t m_sPowerUpTimeoutSecs; 00450 static bool m_sDebugEnabled; 00451 static bool m_sMoreDebugEnabled; 00452 static bool m_sCheckNetStatus; 00453 static bool m_sReadyForSMS; 00454 }; 00455 00456 }; // End namespace WncController_fk 00457 00458 #endif
Generated on Tue Jul 12 2022 22:13:21 by 1.7.2