support library for C027 helper functions for Buffer Pipes, Buffered Serial Port (rtos capable) and GPS parsing. It includes modem APIs for USSD, SMS and Sockets.
Fork of C027_Support by
MDM.h
00001 #pragma once 00002 00003 #include "mbed.h" 00004 #include <stdarg.h> 00005 00006 #include "Pipe.h" 00007 #include "SerialPipe.h" 00008 00009 00010 00011 #ifdef TARGET_UBLOX_C027 00012 // you can change this is you like to use a shield even on the C027 00013 #define MDM_IF(onboard,shield) onboard 00014 #else 00015 #define MDM_IF(onboard,shield) shield 00016 #endif 00017 00018 //! include debug capabilty on more powerful targets with a dedicated debug port 00019 #if defined(TARGET_LPC1768) || defined(TARGET_LPC4088) || defined(TARGET_K64F) 00020 #define MDM_DEBUG 00021 #endif 00022 00023 /** basic modem parser class 00024 */ 00025 class MDMParser 00026 { 00027 public: 00028 //! Constructor 00029 MDMParser(void); 00030 //! get static instance 00031 static MDMParser* getInstance() { return inst; }; 00032 00033 // ---------------------------------------------------------------- 00034 // Types 00035 // ---------------------------------------------------------------- 00036 //! MT Device Types 00037 typedef enum { DEV_UNKNOWN, 00038 DEV_SARA_G35, DEV_LISA_U2, DEV_LISA_U2_03S, DEV_LISA_C2, 00039 DEV_SARA_U2, DEV_LEON_G2, DEV_TOBY_L2, DEV_MPCI_L2 } Dev; 00040 //! SIM Status 00041 typedef enum { SIM_UNKNOWN, SIM_MISSING, SIM_PIN, SIM_PUK, SIM_READY, WRONG_PIN } Sim; 00042 //! SIM Status 00043 typedef enum { LPM_DISABLED, LPM_ENABLED, LPM_ACTIVE } Lpm; 00044 //! COPS status 00045 typedef enum { COPS_UNKOWN, COPS_AUTOMATIC_REG, COPS_MANUAL_REG, COPS_DISABLED_REG} CopsMode; 00046 //! Device status 00047 typedef struct { 00048 Dev dev; //!< Device Type 00049 Lpm lpm; //!< Power Saving 00050 Sim sim; //!< SIM Card Status 00051 char ccid[20+1]; //!< Integrated Circuit Card ID 00052 char imsi[15+1]; //!< International Mobile Station Identity 00053 char imei[15+1]; //!< International Mobile Equipment Identity 00054 char meid[18+1]; //!< Mobile Equipment IDentifier 00055 char manu[16]; //!< Manufacturer (u-blox) 00056 char model[16]; //!< Model Name (LISA-U200, LISA-C200 or SARA-G350) 00057 char ver[16]; //!< Software Version 00058 } DevStatus; 00059 //! Registration Status 00060 typedef enum { REG_UNKNOWN, REG_DENIED, REG_NONE, REG_HOME, REG_ROAMING } Reg; 00061 //! Access Technology 00062 typedef enum { ACT_UNKNOWN, ACT_GSM, ACT_EDGE, ACT_UTRAN, ACT_CDMA, ACT_LTE } AcT; 00063 //! Network Status 00064 typedef struct { 00065 Reg csd; //!< CSD Registration Status (Circuit Switched Data) 00066 Reg psd; //!< PSD Registration status (Packet Switched Data) 00067 Reg eps; //!< EPS Registration status 00068 AcT act; //!< Access Technology 00069 int rssi; //!< Received Signal Strength Indication (in dBm, range -113..-51) 00070 int ber; //!< Bit Error Rate (BER), see 3GPP TS 45.008 [20] subclause 8.2.4 00071 char opr[16+1]; //!< Operator Name 00072 char num[32]; //!< Mobile Directory Number 00073 unsigned short lac; //!< location area code in hexadecimal format (2 bytes in hex) 00074 unsigned int ci; //!< Cell ID in hexadecimal format (2 to 4 bytes in hex) 00075 CopsMode regStatus; //!< Cops mode 00076 } NetStatus; 00077 typedef enum { CELL_LAST = 0, CELL_GNSS, CELL_LOCATE, CELL_HYBRID} CellSensType; 00078 typedef enum { CELL_DETAILED = 1, CELL_MULTIHYP = 2} CellRespType; 00079 #define CELL_MAX_HYP (16 + 1) 00080 int _locRcvPos; //!< Received positions 00081 int _locExpPos; //!< Expected positions 00082 //! Cell Locate Data 00083 typedef struct { 00084 bool validData; //!< Flag for indicating if data is valid 00085 struct tm time; //!< GPS Timestamp 00086 float longitude; //!< Estimated longitude, in degrees 00087 float latitude; //!< Estimated latitude, in degrees 00088 int altitutude; //!< Estimated altitude, in meters^2 00089 int uncertainty; //!< Maximum possible error, in meters 00090 int speed; //!< Speed over ground m/s^2 00091 int direction; //!< Course over ground in degrees 00092 int verticalAcc; //!< Vertical accuracy, in meters^2 00093 CellSensType sensor; //!< Sensor used for last calculation 00094 int svUsed; //!< number of satellite used 00095 }CellLocData; 00096 //! An IP v4 address 00097 typedef uint32_t IP; 00098 #define NOIP ((MDMParser::IP)0) //!< No IP address 00099 // ip number formating and conversion 00100 #define IPSTR "%d.%d.%d.%d" 00101 #define IPNUM(ip) ((ip)>>24)&0xff, \ 00102 ((ip)>>16)&0xff, \ 00103 ((ip)>> 8)&0xff, \ 00104 ((ip)>> 0)&0xff 00105 #define IPADR(a,b,c,d) ((((IP)(a))<<24) | \ 00106 (((IP)(b))<<16) | \ 00107 (((IP)(c))<< 8) | \ 00108 (((IP)(d))<< 0)) 00109 00110 00111 // ---------------------------------------------------------------- 00112 // Device 00113 // ---------------------------------------------------------------- 00114 00115 typedef enum { AUTH_NONE, AUTH_PAP, AUTH_CHAP, AUTH_DETECT } Auth; 00116 00117 /** Combined Init, checkNetStatus, join suitable for simple applications 00118 \param simpin a optional pin of the SIM card 00119 \param apn the of the network provider e.g. "internet" or "apn.provider.com" 00120 \param username is the user name text string for the authentication phase 00121 \param password is the password text string for the authentication phase 00122 \param auth is the authentication mode (CHAP,PAP,NONE or DETECT) 00123 \return true if successful, false otherwise 00124 */ 00125 bool connect(const char* simpin = NULL, 00126 const char* apn = NULL, const char* username = NULL, 00127 const char* password = NULL, Auth auth = AUTH_DETECT, 00128 PinName pn MDM_IF( = MDMPWRON, = D4)); 00129 00130 /** register (Attach) the MT to the GPRS service. 00131 \param simpin a optional pin of the SIM card 00132 \param status an optional struture to with device information 00133 \return true if successful, false otherwise 00134 */ 00135 virtual bool init(const char* simpin = NULL, DevStatus* status = NULL, 00136 PinName pn MDM_IF( = MDMPWRON, = D4)); 00137 00138 /** get the current device status 00139 \param strocture holding the device information. 00140 */ 00141 void getDevStatus(MDMParser::DevStatus* dev) { memcpy(dev, &_dev, sizeof(DevStatus)); } 00142 00143 /** register to the network 00144 \param status an optional structure to with network information 00145 \param timeout_ms -1 blocking, else non blocking timeout in ms 00146 \return true if successful and connected to network, false otherwise 00147 */ 00148 bool registerNet(NetStatus* status = NULL, int timeout_ms = 180000); 00149 00150 /** check if the network is available 00151 \param status an optional structure to with network information 00152 \return true if successful and connected to network, false otherwise 00153 */ 00154 bool checkNetStatus(NetStatus* status = NULL); 00155 00156 /** Power off the MT, This function has to be called prior to 00157 switching off the supply. 00158 \return true if successfully, false otherwise 00159 */ 00160 bool powerOff(void); 00161 00162 // ---------------------------------------------------------------- 00163 // Data Connection (GPRS) 00164 // ---------------------------------------------------------------- 00165 00166 /** register (Attach) the MT to the GPRS service. 00167 \param apn the of the network provider e.g. "internet" or "apn.provider.com" 00168 \param username is the user name text string for the authentication phase 00169 \param password is the password text string for the authentication phase 00170 \param auth is the authentication mode (CHAP,PAP,NONE or DETECT) 00171 \return the ip that is assigned 00172 */ 00173 MDMParser::IP join(const char* apn = NULL, const char* username = NULL, 00174 const char* password = NULL, Auth auth = AUTH_DETECT); 00175 00176 /** deregister (detach) the MT from the GPRS service. 00177 \return true if successful, false otherwise 00178 */ 00179 bool disconnect(void); 00180 00181 /** Translates a domain name to an IP address 00182 \param host the domain name to translate e.g. "u-blox.com" 00183 \return the IP if successful, 0 otherwise 00184 */ 00185 MDMParser::IP gethostbyname(const char* host); 00186 00187 /** get the current assigned IP address 00188 \return the ip that is assigned 00189 */ 00190 MDMParser::IP getIpAddress(void) { return _ip; } 00191 00192 // ---------------------------------------------------------------- 00193 // Sockets 00194 // ---------------------------------------------------------------- 00195 00196 //! Type of IP protocol 00197 typedef enum { IPPROTO_TCP, IPPROTO_UDP } IpProtocol; 00198 00199 //! Socket error return codes 00200 #define SOCKET_ERROR -1 00201 00202 /** Create a socket for a ip protocol (and optionaly bind) 00203 \param ipproto the protocol (UDP or TCP) 00204 \param port in case of UDP, this optional port where it is bind 00205 \return the socket handle if successful or SOCKET_ERROR on failure 00206 */ 00207 int socketSocket(IpProtocol ipproto, int port = -1); 00208 00209 /** make a socket connection 00210 \param socket the socket handle 00211 \param host the domain name to connect e.g. "u-blox.com" 00212 \param port the port to connect 00213 \return true if successfully, false otherwise 00214 */ 00215 bool socketConnect(int socket, const char* host, int port); 00216 00217 /** make a socket connection 00218 \param socket the socket handle 00219 \return true if connected, false otherwise 00220 */ 00221 bool socketIsConnected(int socket); 00222 00223 /** Get the number of bytes pending for reading for this socket 00224 \param socket the socket handle 00225 \param timeout_ms -1 blocking, else non blocking timeout in ms 00226 \return 0 if successful or SOCKET_ERROR on failure 00227 */ 00228 bool socketSetBlocking(int socket, int timeout_ms); 00229 00230 /** Write socket data 00231 \param socket the socket handle 00232 \param buf the buffer to write 00233 \param len the size of the buffer to write 00234 \return the size written or SOCKET_ERROR on failure 00235 */ 00236 int socketSend(int socket, const char * buf, int len); 00237 00238 /** Write socket data to a IP 00239 \param socket the socket handle 00240 \param ip the ip to send to 00241 \param port the port to send to 00242 \param buf the buffer to write 00243 \param len the size of the buffer to write 00244 \return the size written or SOCKET_ERROR on failure 00245 */ 00246 int socketSendTo(int socket, IP ip, int port, const char * buf, int len); 00247 00248 /** Get the number of bytes pending for reading for this socket 00249 \param socket the socket handle 00250 \return the number of bytes pending or SOCKET_ERROR on failure 00251 */ 00252 int socketReadable(int socket); 00253 00254 /** Read this socket 00255 \param socket the socket handle 00256 \param buf the buffer to read into 00257 \param len the size of the buffer to read into 00258 \return the number of bytes read or SOCKET_ERROR on failure 00259 */ 00260 int socketRecv(int socket, char* buf, int len); 00261 00262 /** Read from this socket 00263 \param socket the socket handle 00264 \param ip the ip of host where the data originates from 00265 \param port the port where the data originates from 00266 \param buf the buffer to read into 00267 \param len the size of the buffer to read into 00268 \return the number of bytes read or SOCKET_ERROR on failure 00269 */ 00270 int socketRecvFrom(int socket, IP* ip, int* port, char* buf, int len); 00271 00272 /** Close a connectied socket (that was connected with #socketConnect) 00273 \param socket the socket handle 00274 \return true if successfully, false otherwise 00275 */ 00276 bool socketClose(int socket); 00277 00278 /** Free the socket (that was allocated before by #socketSocket) 00279 \param socket the socket handle 00280 \return true if successfully, false otherwise 00281 */ 00282 bool socketFree(int socket); 00283 00284 // ---------------------------------------------------------------- 00285 // HTTP 00286 // ---------------------------------------------------------------- 00287 00288 //! Type of HTTP Operational Codes (reference to HTTP control +UHTTP) 00289 typedef enum { HTTP_IP_ADDRESS, HTTP_SERVER_NAME, HTTP_USER_NAME, HTTP_PASSWORD, \ 00290 HTTP_AUTH_TYPE, HTTP_SERVER_PORT, HTTP_SECURE } HttpOpCode; 00291 00292 //! Type of HTTP Commands (reference to HTTP command +UHTTPC) 00293 typedef enum { HTTP_HEAD, HTTP_GET, HTTP_DELETE, HTTP_PUT, \ 00294 HTTP_POST_FILE, HTTP_POST_DATA } HttpCmd; 00295 00296 //! HTTP Profile error return codes 00297 #define HTTP_PROF_ERROR -1 00298 00299 /** find HTTP profile 00300 \return true if successfully, false otherwise 00301 */ 00302 int httpFindProfile(); 00303 00304 /** get the number of bytes pending for reading for this HTTP profile 00305 \param profile the HTTP profile handle 00306 \param timeout_ms -1 blocking, else non blocking timeout in ms 00307 \return 0 if successful or SOCKET_ERROR on failure 00308 */ 00309 bool httpSetBlocking(int profile, int timeout_ms); 00310 00311 /** set the HTTP profile for commands management 00312 \param profile the HTTP profile handle 00313 \return true if successfully, false otherwise 00314 */ 00315 bool httpSetProfileForCmdMng(int profile); 00316 00317 /** free the HTTP profile 00318 \param profile the HTTP profile handle 00319 \return true if successfully, false otherwise 00320 */ 00321 bool httpFreeProfile(int profile); 00322 00323 /** reset HTTP profile 00324 \param httpProfile the HTTP profile to be reset 00325 \return true if successfully, false otherwise 00326 */ 00327 bool httpResetProfile(int httpProfile); 00328 00329 /** set HTTP parameters 00330 \param httpProfile the HTTP profile identifier 00331 \param httpOpCode the HTTP operation code 00332 \param httpInPar the HTTP input parameter 00333 \return true if successfully, false otherwise 00334 */ 00335 bool httpSetPar(int httpProfile, HttpOpCode httpOpCode, const char * httpInPar); 00336 00337 /** HTTP commands management 00338 \param httpProfile the HTTP profile identifier 00339 \param httpCmdCode the HTTP command code 00340 \param httpPath the path of HTTP server resource 00341 \param httpOut the filename where the HTTP server response will be stored 00342 \param httpIn the input data (filename or string) to be sent 00343 to the HTTP server with the command request 00344 \param httpContentType the HTTP Content-Type identifier 00345 \param httpCustomPar the parameter for an user defined HTTP Content-Type 00346 \param buf the buffer to read into 00347 \param len the size of the buffer to read into 00348 \return true if successfully, false otherwise 00349 */ 00350 bool httpCommand(int httpProfile, HttpCmd httpCmdCode, const char* httpPath, \ 00351 const char* httpOut, const char* httpIn, int httpContentType, \ 00352 const char* httpCustomPar, char* buf, int len); 00353 00354 /** get HTTP commands 00355 \param httpCmdCode the HTTP command code (reference also the enum format) 00356 \return HTTP command in string format 00357 */ 00358 const char* getHTTPcmd(int httpCmdCode); 00359 00360 // ---------------------------------------------------------------- 00361 // SMS Short Message Service 00362 // ---------------------------------------------------------------- 00363 00364 /** count the number of sms in the device and optionally return a 00365 list with indexes from the storage locations in the device. 00366 \param stat what type of messages you can use use 00367 "REC UNREAD", "REC READ", "STO UNSENT", "STO SENT", "ALL" 00368 \param ix list where to save the storage positions 00369 \param num number of elements in the list 00370 \return the number of messages, this can be bigger than num, -1 on failure 00371 */ 00372 int smsList(const char* stat = "ALL", int* ix = NULL, int num = 0); 00373 00374 /** Read a Message from a storage position 00375 \param ix the storage position to read 00376 \param num the originator address (~16 chars) 00377 \param buf a buffer where to save the sm 00378 \param len the length of the sm 00379 \return true if successful, false otherwise 00380 */ 00381 bool smsRead(int ix, char* num, char* buf, int len); 00382 00383 /** Send a message to a recipient 00384 \param ix the storage position to delete 00385 \return true if successful, false otherwise 00386 */ 00387 bool smsDelete(int ix); 00388 00389 /** Send a message to a recipient 00390 \param num the phone number of the recipient 00391 \param buf the content of the message to sent 00392 \return true if successful, false otherwise 00393 */ 00394 bool smsSend(const char* num, const char* buf); 00395 00396 // ---------------------------------------------------------------- 00397 // USSD Unstructured Supplementary Service Data 00398 // ---------------------------------------------------------------- 00399 00400 /** Read a Message from a storage position 00401 \param cmd the ussd command to send e.g "*#06#" 00402 \param buf a buffer where to save the reply 00403 \return true if successful, false otherwise 00404 */ 00405 bool ussdCommand(const char* cmd, char* buf); 00406 00407 // ---------------------------------------------------------------- 00408 // FILE 00409 // ---------------------------------------------------------------- 00410 00411 /** Delete a file in the local file system 00412 \param filename the name of the file 00413 \return true if successful, false otherwise 00414 */ 00415 bool delFile(const char* filename); 00416 00417 /** Write some data to a file in the local file system 00418 \param filename the name of the file 00419 \param buf the data to write 00420 \param len the size of the data to write 00421 \return the number of bytes written 00422 */ 00423 int writeFile(const char* filename, const char* buf, int len); 00424 00425 /** Read a file from the local file system 00426 \param filename the name of the file 00427 \param buf a buffer to hold the data 00428 \param len the size to read 00429 \return the number of bytes read 00430 */ 00431 int readFile(const char* filename, char* buf, int len); 00432 00433 /** Read a file from the local file system 00434 (the file size is greater than MAX_SIZE bytes) 00435 \param filename the name of the file 00436 \param buf a buffer to hold the data 00437 \param len the size to read 00438 \return the number of bytes read 00439 */ 00440 int readFileNew(const char* filename, char* buf, int len); 00441 00442 /** Retrieve information about the dimension of a file from the local FFS 00443 \param filename the name of the file 00444 \return the file dimension in number of bytes 00445 */ 00446 int infoFile(const char* filename); 00447 00448 // ---------------------------------------------------------------- 00449 // CellLocate 00450 // ---------------------------------------------------------------- 00451 00452 /** Configures CellLocate Tcp Aiding server 00453 \server_1 Host name of the primary MGA server 00454 \server_2 Host name of the secondary MGA server 00455 \token Authentication Token for MGA server access 00456 \days The number of days into the future the Offline data for the u-blox 7 00457 \period The number of weeks into the future the Offline data for u-blox M8 00458 \resolution Resolution of offline data for u-blox M8: 1 everyday, 0 every other day 00459 */ 00460 int cellLocSrvTcp(const char* token, const char* server_1 = "cell-live1.services.u-blox.com", \ 00461 const char* server_2 = "cell-live2.services.u-blox.com", int days = 14, int period = 4, int resolution = 1); 00462 00463 /** Configures CellLocate Udp Aiding server 00464 \server_1 Host name of the primary MGA server 00465 \port Server port 00466 \latency Expected network latency in seconds from 0 to 10000ms 00467 \mode Assist now management, mode of operation: 0 data downloaded at GNSS power up, 00468 1 automatically kept alive, manual download 00469 */ 00470 int cellLocSrvUdp(const char* server_1 = "cell-live1.services.u-blox.com", int port = 46434, int latency = 1000, int mode = 0); 00471 00472 /** Configures CellLocate URCs in the case of +ULOC operations 00473 \mode Urc configuration: 0 disabled, 1 enabled 00474 */ 00475 int cellLocUnsol(int mode); 00476 00477 /** Configures CellLocate location sensor 00478 \scanMode Network scan mode: 0 normal, 1 deep scan 00479 */ 00480 int cellLocConfig(int scanMode); 00481 00482 /** Request CellLocate 00483 This function is not blocking, the result has to be retrived using cellLocGet 00484 \sensor Sensor selection: 00485 \timeout Timeout period in seconds (1 - 999) 00486 \accuracy Target accuracy in meters (1 - 999999) 00487 \type 00488 \hypotesis Maximum desired number of responses from CellLocate® (up to 16) 00489 */ 00490 int cellLocRequest(CellSensType sensor, int timeout, int accuracy, CellRespType type = CELL_DETAILED,int hypotesis = 1); 00491 00492 /** Get a position record 00493 \data pointer to a CellLocData struct where the location will be copied in 00494 \index of the position to retrive 00495 \return 1 if data has been retrived and copied, 0 otherwise 00496 */ 00497 int cellLocGetData(CellLocData *data, int index =0); 00498 00499 /** Get number of position records received 00500 \return number of position received 00501 */ 00502 int cellLocGetRes(); 00503 /** Get expected number of position to be received 00504 \return number of expected position to be received 00505 */ 00506 int cellLocGetExpRes(); 00507 00508 // ---------------------------------------------------------------- 00509 // DEBUG/DUMP status to standard out (printf) 00510 // ---------------------------------------------------------------- 00511 00512 /*! Set the debug level 00513 \param level -1 = OFF, 0 = ERROR, 1 = INFO(default), 2 = TRACE, 3 = ATCMD,TEST 00514 \return true if successful, false not possible 00515 */ 00516 bool setDebug (int level); 00517 00518 //! helper type for DPRINT 00519 typedef int (*_DPRINT)(void* param, char const * format, ...); 00520 00521 //! helper to declate templates and void versions 00522 #define _DUMP_TEMPLATE(func, type, arg) \ 00523 template<class T> \ 00524 inline void func(type arg, \ 00525 int (*dprint)( T* param, char const * format, ...), \ 00526 T* param) { func(arg, (_DPRINT)dprint, (void*)param); } \ 00527 static void func(type arg, \ 00528 _DPRINT dprint = (_DPRINT)fprintf, \ 00529 void* param = (void*)stdout); 00530 00531 /** dump the device status to stdout using printf 00532 \param status the status to convert to textual form, 00533 unavailable fields are ommited (not printed) 00534 \param dprint a function pointer 00535 \param param the irst argument passed to dprint 00536 */ 00537 _DUMP_TEMPLATE(dumpDevStatus, MDMParser::DevStatus*, status) 00538 00539 /** dump the network status to stdout using printf 00540 \param status the status to convert to textual form, 00541 unavailable fields are ommited (not printed) 00542 \param dprint a function pointer 00543 \param param the irst argument passed to dprint 00544 */ 00545 _DUMP_TEMPLATE(dumpNetStatus, MDMParser::NetStatus*, status) 00546 00547 /** dump the ip address to stdout using printf 00548 \param ip the ip to convert to textual form, 00549 unavailable fields are ommited (not printed) 00550 \param dprint a function pointer 00551 \param param the irst argument passed to dprint 00552 */ 00553 _DUMP_TEMPLATE(dumpIp, MDMParser::IP, ip) 00554 00555 // ---------------------------------------------------------------- 00556 // Parseing 00557 // ---------------------------------------------------------------- 00558 00559 enum { 00560 // waitFinalResp Responses 00561 NOT_FOUND = 0, 00562 WAIT = -1, // TIMEOUT 00563 RESP_OK = -2, 00564 RESP_ERROR = -3, 00565 RESP_PROMPT = -4, 00566 RESP_ERROR_CME= -5, 00567 00568 // getLine Responses 00569 #define LENGTH(x) (x & 0x00FFFF) //!< extract/mask the length 00570 #define TYPE(x) (x & 0xFF0000) //!< extract/mask the type 00571 00572 TYPE_UNKNOWN = 0x000000, 00573 TYPE_OK = 0x110000, 00574 TYPE_ERROR = 0x120000, 00575 TYPE_ERROR_CME = 0x130000, 00576 TYPE_RING = 0x210000, 00577 TYPE_CONNECT = 0x220000, 00578 TYPE_NOCARRIER = 0x230000, 00579 TYPE_NODIALTONE = 0x240000, 00580 TYPE_BUSY = 0x250000, 00581 TYPE_NOANSWER = 0x260000, 00582 TYPE_PROMPT = 0x300000, 00583 TYPE_PLUS = 0x400000, 00584 TYPE_TEXT = 0x500000, 00585 00586 // special timout constant 00587 TIMEOUT_BLOCKING = -1 00588 }; 00589 00590 /** Get a line from the physical interface. This function need 00591 to be implemented in a inherited class. Usually just calls 00592 #_getLine on the rx buffer pipe. 00593 00594 \param buf the buffer to store it 00595 \param buf size of the buffer 00596 \return type and length if something was found, 00597 WAIT if not enough data is available 00598 NOT_FOUND if nothing was found 00599 */ 00600 virtual int getLine(char* buf, int len) = 0; 00601 00602 /* clear the pending input data 00603 */ 00604 virtual void purge(void) = 0; 00605 00606 /** Write data to the device 00607 \param buf the buffer to write 00608 \param buf size of the buffer to write 00609 \return bytes written 00610 */ 00611 virtual int send(const char* buf, int len); 00612 00613 /** Write formated date to the physical interface (printf style) 00614 \param fmt the format string 00615 \param .. variable arguments to be formated 00616 \return bytes written 00617 */ 00618 int sendFormated(const char* format, ...); 00619 00620 /** callback function for #waitFinalResp with void* as argument 00621 \param type the #getLine response 00622 \param buf the parsed line 00623 \param len the size of the parsed line 00624 \param param the optional argument passed to #waitFinalResp 00625 \return WAIT if processing should continue, 00626 any other value aborts #waitFinalResp and this retunr value retuned 00627 */ 00628 typedef int (*_CALLBACKPTR)(int type, const char* buf, int len, void* param); 00629 00630 /** Wait for a final respons 00631 \param cb the optional callback function 00632 \param param the optional callback function parameter 00633 \param timeout_ms the timeout to wait (See Estimated command 00634 response time of AT manual) 00635 */ 00636 int waitFinalResp(_CALLBACKPTR cb = NULL, 00637 void* param = NULL, 00638 int timeout_ms = 10000); 00639 00640 /** template version of #waitFinalResp when using callbacks, 00641 This template will allow the compiler to do type cheking but 00642 internally symply casts the arguments and call the (void*) 00643 version of #waitFinalResp. 00644 \sa waitFinalResp 00645 */ 00646 template<class T> 00647 inline int waitFinalResp(int (*cb)(int type, const char* buf, int len, T* param), 00648 T* param, 00649 int timeout_ms = 10000) 00650 { 00651 return waitFinalResp((_CALLBACKPTR)cb, (void*)param, timeout_ms); 00652 } 00653 00654 protected: 00655 /** Write bytes to the physical interface. This function should be 00656 implemented in a inherited class. 00657 \param buf the buffer to write 00658 \param buf size of the buffer to write 00659 \return bytes written 00660 */ 00661 virtual int _send(const void* buf, int len) = 0; 00662 00663 /** Helper: Parse a line from the receiving buffered pipe 00664 \param pipe the receiving buffer pipe 00665 \param buf the parsed line 00666 \param len the size of the parsed line 00667 \return type and length if something was found, 00668 WAIT if not enough data is available 00669 NOT_FOUND if nothing was found 00670 */ 00671 static int _getLine(Pipe<char> * pipe, char* buffer, int length); 00672 00673 /** Helper: Parse a match from the pipe 00674 \param pipe the buffered pipe 00675 \param number of bytes to parse at maximum, 00676 \param sta the starting string, NULL if none 00677 \param end the terminating string, NULL if none 00678 \return size of parsed match 00679 */ 00680 static int _parseMatch(Pipe<char> * pipe, int len, const char* sta, const char* end); 00681 00682 /** Helper: Parse a match from the pipe 00683 \param pipe the buffered pipe 00684 \param number of bytes to parse at maximum, 00685 \param fmt the formating string (%d any number, %c any char of last %d len) 00686 \return size of parsed match 00687 */ 00688 static int _parseFormated(Pipe<char> * pipe, int len, const char* fmt); 00689 00690 protected: 00691 // for rtos over riding by useing Rtos<MDMxx> 00692 /** override in a rtos system, you us the wait function of a Thread 00693 \param ms the number of milliseconds to wait 00694 */ 00695 virtual void wait_ms(int ms) { if (ms) ::wait_ms(ms); } 00696 //! override the lock in a rtos system 00697 virtual void lock(void) { } 00698 //! override the unlock in a rtos system 00699 virtual void unlock(void) { } 00700 protected: 00701 bool _activateProfile(const char* apn, const char* username, const char* password, Auth auth); 00702 bool _activateProfileReuseExternal(void); 00703 bool _activateProfileByCid(int cid, const char* apn, const char* username, const char* password, Auth auth); 00704 // parsing callbacks for different AT commands and their parameter arguments 00705 static int _cbString(int type, const char* buf, int len, char* str); 00706 static int _cbInt(int type, const char* buf, int len, int* val); 00707 // device 00708 static int _cbATI(int type, const char* buf, int len, Dev* dev); 00709 static int _cbCPIN(int type, const char* buf, int len, Sim* sim); 00710 static int _cbCCID(int type, const char* buf, int len, char* ccid); 00711 // network 00712 static int _cbCSQ(int type, const char* buf, int len, NetStatus* status); 00713 static int _cbCOPS(int type, const char* buf, int len, NetStatus* status); 00714 static int _cbCNUM(int type, const char* buf, int len, char* num); 00715 static int _cbUACTIND(int type, const char* buf, int len, int* i); 00716 static int _cbCGDCONT(int type, const char* buf, int len, int* cid); 00717 static int _cbUDOPN(int type, const char* buf, int len, char* mccmnc); 00718 // sockets 00719 static int _cbCMIP(int type, const char* buf, int len, IP* ip); 00720 static int _cbUPSND(int type, const char* buf, int len, int* act); 00721 static int _cbUPSND(int type, const char* buf, int len, IP* ip); 00722 static int _cbUDNSRN(int type, const char* buf, int len, IP* ip); 00723 static int _cbUSOCR(int type, const char* buf, int len, int* handle); 00724 static int _cbUSORD(int type, const char* buf, int len, char* out); 00725 typedef struct { char* buf; IP ip; int port; } USORFparam; 00726 static int _cbUSORF(int type, const char* buf, int len, USORFparam* param); 00727 typedef struct { char* buf; char* num; } CMGRparam; 00728 static int _cbCUSD(int type, const char* buf, int len, char* resp); 00729 // sms 00730 typedef struct { int* ix; int num; } CMGLparam; 00731 static int _cbCMGL(int type, const char* buf, int len, CMGLparam* param); 00732 static int _cbCMGR(int type, const char* buf, int len, CMGRparam* param); 00733 // file 00734 typedef struct { const char* filename; char* buf; int sz; int len; } URDFILEparam; 00735 static int _cbUDELFILE(int type, const char* buf, int len, void*); 00736 static int _cbURDFILE(int type, const char* buf, int len, URDFILEparam* param); 00737 static int _cbURDBLOCK(int type, const char* buf, int len, char* out); 00738 static int _cbULSTFILE(int type, const char* buf, int len, int* infoFile); 00739 // variables 00740 DevStatus _dev; //!< collected device information 00741 NetStatus _net; //!< collected network information 00742 IP _ip; //!< assigned ip address 00743 CellLocData _loc[CELL_MAX_HYP]; //!< CellLocate data 00744 // management struture for sockets 00745 typedef struct { int handle; int timeout_ms; volatile bool connected; volatile int pending; } SockCtrl; 00746 // LISA-C has 6 TCP and 6 UDP sockets 00747 // LISA-U and SARA-G have 7 sockets 00748 SockCtrl _sockets[12]; 00749 int _findSocket(int handle = SOCKET_ERROR/* = CREATE*/); 00750 // management structure for HTTP profiles 00751 // it's possible to have up to 4 different HTTP profiles (LISA-C200, LISA-U200 and SARA-G350) having: 00752 // param handle the current HTTP profile is in handling state or not (default value is HTTP_ERROR) 00753 // param timeout_ms the timeout for the current HTTP command 00754 // param pending the status for the current HTTP command (in processing state or not) 00755 // param cmd the code for the current HTTP command 00756 // param result the result for the current HTTP command once processed 00757 typedef struct { int handle; int timeout_ms; bool pending; int cmd; int result; } HttpProfCtrl; 00758 HttpProfCtrl _httpProfiles[4]; 00759 int _findProfile(int handle = HTTP_PROF_ERROR/* = CREATE*/); 00760 static MDMParser* inst; 00761 bool _init; 00762 #ifdef TARGET_UBLOX_C027 00763 bool _onboard; 00764 #endif 00765 00766 #ifdef MDM_DEBUG 00767 00768 Timer _debugTime; 00769 void _debugPrint(int level, const char* color, const char* format, ...); 00770 #endif 00771 }; 00772 00773 // ----------------------------------------------------------------------- 00774 00775 /** modem class which uses a serial port 00776 as physical interface. 00777 */ 00778 class MDMSerial : public SerialPipe, public MDMParser 00779 { 00780 public: 00781 /** Constructor 00782 00783 \param tx is the serial ports transmit pin (modem to CPU) 00784 \param rx is the serial ports receive pin (CPU to modem) 00785 \param baudrate the baudrate of the modem use 115200 00786 \param rts is the serial ports ready to send pin (CPU to modem) 00787 this pin is optional 00788 \param cts is the serial ports clear to send pin (modem to CPU) 00789 this pin is optional, but required for power saving to be enabled 00790 \param rxSize the size of the serial rx buffer 00791 \param txSize the size of the serial tx buffer 00792 */ 00793 MDMSerial(PinName tx MDM_IF( = MDMTXD, = D1 ), 00794 PinName rx MDM_IF( = MDMRXD, = D0 ), 00795 int baudrate MDM_IF( = MDMBAUD, = 115200 ), 00796 #if DEVICE_SERIAL_FC 00797 PinName rts MDM_IF( = MDMRTS, = NC /* D2 resistor R62 on shield not mounted */ ), 00798 PinName cts MDM_IF( = MDMCTS, = NC /* D3 resistor R63 on shield not mounted */ ), 00799 #endif 00800 int rxSize = 256 , 00801 int txSize = 128 ); 00802 //! Destructor 00803 virtual ~MDMSerial(void); 00804 00805 /** Get a line from the physical interface. 00806 \param buf the buffer to store it 00807 \param buf size of the buffer 00808 \return type and length if something was found, 00809 WAIT if not enough data is available 00810 NOT_FOUND if nothing was found 00811 */ 00812 virtual int getLine(char* buffer, int length); 00813 00814 /* clear the pending input data */ 00815 virtual void purge(void) 00816 { 00817 while (readable()) 00818 getc(); 00819 } 00820 protected: 00821 /** Write bytes to the physical interface. 00822 \param buf the buffer to write 00823 \param buf size of the buffer to write 00824 \return bytes written 00825 */ 00826 virtual int _send(const void* buf, int len); 00827 }; 00828 00829 // ----------------------------------------------------------------------- 00830 00831 //#define HAVE_MDMUSB 00832 #ifdef HAVE_MDMUSB 00833 class MDMUsb : /*public UsbSerial,*/ public MDMParser 00834 { 00835 public: 00836 //! Constructor 00837 MDMUsb(void); 00838 //! Destructor 00839 virtual ~MDMUsb(void); 00840 virtual int getLine(char* buffer, int length); 00841 virtual void purge(void) { } 00842 protected: 00843 virtual int _send(const void* buf, int len); 00844 }; 00845 #endif 00846 00847 // ----------------------------------------------------------------------- 00848 00849 #ifdef RTOS_H 00850 /** Use this template to override the lock and wait functions of the 00851 modem driver in a Rtos system. For example declare it the modem 00852 object as MDMRtos<MDMSerial> instead of MDMSerial. 00853 */ 00854 template <class T> 00855 class MDMRtos : public T 00856 { 00857 protected: 00858 //! we assume that the modem runs in a thread so we yield when waiting 00859 virtual void wait_ms(int ms) { 00860 if (ms) Thread::wait(ms); 00861 else Thread::yield(); 00862 } 00863 //! lock a mutex when accessing the modem 00864 virtual void lock(void) { _mtx.lock(); } 00865 //! unlock the modem when done accessing it 00866 virtual void unlock(void) { _mtx.unlock(); } 00867 // the mutex resource 00868 Mutex _mtx; 00869 }; 00870 #endif
Generated on Wed Jul 13 2022 04:28:18 by 1.7.2