u-blox / C027_Support_HTTP

Fork of C027_Support by u-blox

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MDM.h Source File

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