Rob Meades / C027_Support_N

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  #define MDM_IF(onboard,shield) onboard
00011 #else
00012  #define MDM_IF(onboard,shield) shield
00013 #endif
00014 
00015 //! include debug capabilty on more powerful targets with a dedicated debug port 
00016 #if defined(TARGET_LPC1768) || defined(TARGET_LPC4088) || defined(TARGET_K64F)
00017  #define MDM_DEBUG 
00018 #endif 
00019 
00020 /** basic modem parser class 
00021 */
00022 class MDMParser
00023 {
00024 public:
00025     //! Constructor 
00026     MDMParser(void);
00027     //! get static instance
00028     static MDMParser* getInstance() { return inst; };
00029     
00030     // ----------------------------------------------------------------
00031     // Types 
00032     // ----------------------------------------------------------------
00033     //! MT Device Types 
00034     typedef enum { DEV_UNKNOWN, DEV_SARA_G350, DEV_LISA_U200, DEV_LISA_C200, 
00035                    DEV_SARA_U260, DEV_SARA_U270, DEV_LEON_G200, DEV_LISA_N100 } Dev; 
00036     //! SIM Status
00037     typedef enum { SIM_UNKNOWN, SIM_MISSING, SIM_PIN, SIM_READY } Sim;
00038     //! SIM Status
00039     typedef enum { LPM_DISABLED, LPM_ENABLED, LPM_ACTIVE } Lpm; 
00040     //! Device status
00041     typedef struct { 
00042         Dev dev;            //!< Device Type
00043         Lpm lpm;            //!< Power Saving 
00044         Sim sim;            //!< SIM Card Status
00045         char ccid[20+1];    //!< Integrated Circuit Card ID
00046         char imsi[15+1];    //!< International Mobile Station Identity
00047         char imei[15+1];    //!< International Mobile Equipment Identity
00048         char meid[18+1];    //!< Mobile Equipment IDentifier
00049         char manu[16];      //!< Manufacturer (u-blox)
00050         char model[32];     //!< Model Name (LISA-U200, LISA-C200 or SARA-G350)
00051         char ver[16];       //!< Software Version
00052     } DevStatus;
00053     //! Registration Status
00054     typedef enum { REG_UNKNOWN, REG_DENIED, REG_NONE, REG_HOME, REG_ROAMING } Reg; 
00055     //! Access Technology
00056     typedef enum { ACT_UNKNOWN, ACT_GSM, ACT_EDGE, ACT_UTRAN, ACT_CDMA } AcT; 
00057     //! Network Status
00058     typedef struct { 
00059         Reg csd;        //!< CSD Registration Status (Circuit Switched Data)
00060         Reg psd;        //!< PSD Registration status (Packet Switched Data)
00061         AcT act;        //!< Access Technology
00062         int rssi;       //!< Received Signal Strength Indication (in dBm, range -113..-53)
00063         int ber;        //!< Bit Error Rate (BER), see 3GPP TS 45.008 [20] subclause 8.2.4
00064         char opr[16+1]; //!< Operator Name
00065         char num[32];   //!< Mobile Directory Number
00066         unsigned short lac;  //!< location area code in hexadecimal format (2 bytes in hex)
00067         unsigned int ci;     //!< Cell ID in hexadecimal format (2 to 4 bytes in hex)
00068     } NetStatus;
00069     //! An IP v4 address
00070     typedef uint32_t IP;
00071     #define NOIP ((MDMParser::IP)0) //!< No IP address
00072     // ip number formating and conversion
00073     #define IPSTR           "%d.%d.%d.%d"
00074     #define IPNUM(ip)       ((ip)>>24)&0xff, \
00075                             ((ip)>>16)&0xff, \
00076                             ((ip)>> 8)&0xff, \
00077                             ((ip)>> 0)&0xff
00078     #define IPADR(a,b,c,d) ((((IP)(a))<<24) | \
00079                             (((IP)(b))<<16) | \
00080                             (((IP)(c))<< 8) | \
00081                             (((IP)(d))<< 0))
00082 
00083     // ----------------------------------------------------------------
00084     // Device 
00085     // ----------------------------------------------------------------
00086     
00087     typedef enum { AUTH_NONE, AUTH_PAP, AUTH_CHAP, AUTH_DETECT } Auth; 
00088     
00089     /** Combined Init, checkNetStatus, join suitable for simple applications
00090         \param simpin a optional pin of the SIM card
00091         \param apn  the of the network provider e.g. "internet" or "apn.provider.com"
00092         \param username is the user name text string for the authentication phase
00093         \param password is the password text string for the authentication phase
00094         \param auth is the authentication mode (CHAP,PAP,NONE or DETECT)
00095         \return true if successful, false otherwise
00096     */
00097     bool connect(const char* simpin = NULL, 
00098             const char* apn = NULL, const char* username = NULL, 
00099             const char* password = NULL, Auth auth = AUTH_DETECT,
00100             PinName pn MDM_IF( = MDMPWRON, = D4));    
00101 
00102     /** register (Attach) the MT to the GPRS service. 
00103         \param simpin a optional pin of the SIM card
00104         \param status an optional struture to with device information 
00105         \return true if successful, false otherwise
00106     */
00107     bool init(const char* simpin = NULL, DevStatus* status = NULL, 
00108                 PinName pn MDM_IF( = MDMPWRON, = D4));
00109     
00110     /** register to the network 
00111         \param status an optional structure to with network information 
00112         \param timeout_ms -1 blocking, else non blocking timeout in ms
00113         \return true if successful and connected to network, false otherwise
00114     */
00115     bool registerNet(NetStatus* status = NULL, int timeout_ms = 180000);
00116     
00117     /** check if the network is available 
00118         \param status an optional structure to with network information 
00119         \return true if successful and connected to network, false otherwise
00120     */
00121     bool checkNetStatus(NetStatus* status = NULL);
00122     
00123     /** Power off the MT, This function has to be called prior to 
00124         switching off the supply. 
00125         \return true if successfully, false otherwise
00126     */ 
00127     bool powerOff(void);
00128     
00129     // ----------------------------------------------------------------
00130     // Data Connection (GPRS)
00131     // ----------------------------------------------------------------
00132     
00133     /** register (Attach) the MT to the GPRS service. 
00134         \param apn  the of the network provider e.g. "internet" or "apn.provider.com"
00135         \param username is the user name text string for the authentication phase
00136         \param password is the password text string for the authentication phase
00137         \param auth is the authentication mode (CHAP,PAP,NONE or DETECT)
00138         \return the ip that is assigned 
00139     */
00140     MDMParser::IP join(const char* apn = NULL, const char* username = NULL, 
00141                        const char* password = NULL, Auth auth = AUTH_DETECT);
00142     
00143     /** deregister (detach) the MT from the GPRS service.
00144         \return true if successful, false otherwise
00145     */
00146     bool disconnect(void);
00147     
00148     /** Translates a domain name to an IP address
00149         \param host the domain name to translate e.g. "u-blox.com"
00150         \return the IP if successful, 0 otherwise
00151     */
00152     MDMParser::IP gethostbyname(const char* host);
00153     
00154     // ----------------------------------------------------------------
00155     // Sockets
00156     // ----------------------------------------------------------------
00157     
00158     //! Type of IP protocol 
00159     typedef enum { IPPROTO_TCP, IPPROTO_UDP } IpProtocol; 
00160     
00161     //! Socket error return codes
00162     #define SOCKET_ERROR -1
00163     
00164     /** Create a socket for a ip protocol (and optionaly bind)
00165         \param ipproto the protocol (UDP or TCP) 
00166         \param port in case of UDP, this optional port where it is bind
00167         \return the socket handle if successful or SOCKET_ERROR on failure 
00168     */
00169     int socketSocket(IpProtocol ipproto, int port = -1);
00170     
00171     /** make a socket connection
00172         \param socket the socket handle
00173         \param host the domain name to connect e.g. "u-blox.com"
00174         \param port the port to connect
00175         \return true if successfully, false otherwise
00176     */
00177     bool socketConnect(int socket, const char* host, int port);
00178         
00179     /** make a socket connection
00180         \param socket the socket handle
00181         \return true if connected, false otherwise
00182     */
00183     bool socketIsConnected(int socket);
00184      
00185     /** Get the number of bytes pending for reading for this socket
00186         \param socket the socket handle
00187         \param timeout_ms -1 blocking, else non blocking timeout in ms
00188         \return 0 if successful or SOCKET_ERROR on failure 
00189     */
00190     bool socketSetBlocking(int socket, int timeout_ms);
00191     
00192     /** Write socket data 
00193         \param socket the socket handle
00194         \param buf the buffer to write
00195         \param len the size of the buffer to write
00196         \return the size written or SOCKET_ERROR on failure 
00197     */
00198     int socketSend(int socket, const char * buf, int len);
00199     
00200     /** Write socket data to a IP
00201         \param socket the socket handle
00202         \param ip the ip to send to
00203         \param port the port to send to
00204         \param buf the buffer to write
00205         \param len the size of the buffer to write
00206         \return the size written or SOCKET_ERROR on failure 
00207     */
00208     int socketSendTo(int socket, IP ip, int port, const char * buf, int len);
00209     
00210     /** Get the number of bytes pending for reading for this socket
00211         \param socket the socket handle
00212         \return the number of bytes pending or SOCKET_ERROR on failure 
00213     */
00214     int socketReadable(int socket);
00215     
00216     /** Read this socket
00217         \param socket the socket handle
00218         \param buf the buffer to read into
00219         \param len the size of the buffer to read into
00220         \return the number of bytes read or SOCKET_ERROR on failure 
00221     */
00222     int socketRecv(int socket, char* buf, int len);
00223     
00224     /** Read from this socket
00225         \param socket the socket handle
00226         \param ip the ip of host where the data originates from
00227         \param port the port where the data originates from
00228         \param buf the buffer to read into
00229         \param len the size of the buffer to read into
00230         \return the number of bytes read or SOCKET_ERROR on failure 
00231     */
00232     int socketRecvFrom(int socket, IP* ip, int* port, char* buf, int len);
00233     
00234     /** Close a connectied socket (that was connected with #socketConnect)
00235         \param socket the socket handle
00236         \return true if successfully, false otherwise
00237     */    
00238     bool socketClose(int socket);
00239     
00240     /** Free the socket (that was allocated before by #socketSocket)
00241         \param socket the socket handle
00242         \return true if successfully, false otherwise
00243     */    
00244     bool socketFree(int socket);
00245         
00246     // ----------------------------------------------------------------
00247     // SMS Short Message Service
00248     // ----------------------------------------------------------------
00249     
00250     /** count the number of sms in the device and optionally return a 
00251         list with indexes from the storage locations in the device.
00252         \param stat what type of messages you can use use 
00253                     "REC UNREAD", "REC READ", "STO UNSENT", "STO SENT", "ALL"
00254         \param ix   list where to save the storage positions
00255         \param num  number of elements in the list 
00256         \return the number of messages, this can be bigger than num, -1 on failure
00257     */
00258     int smsList(const char* stat = "ALL", int* ix = NULL, int num = 0);
00259     
00260     /** Read a Message from a storage position
00261         \param ix the storage position to read
00262         \param num the originator address (~16 chars)
00263         \param buf a buffer where to save the sm
00264         \param len the length of the sm
00265         \return true if successful, false otherwise
00266     */
00267     bool smsRead(int ix, char* num, char* buf, int len);
00268     
00269     /** Send a message to a recipient 
00270         \param ix the storage position to delete
00271         \return true if successful, false otherwise
00272     */
00273     bool smsDelete(int ix);
00274     
00275     /** Send a message to a recipient 
00276         \param num the phone number of the recipient
00277         \param buf the content of the message to sent
00278         \return true if successful, false otherwise
00279     */
00280     bool smsSend(const char* num, const char* buf);
00281     
00282     // ----------------------------------------------------------------
00283     // USSD Unstructured Supplementary Service Data
00284     // ----------------------------------------------------------------
00285     
00286     /** Read a Message from a storage position
00287         \param cmd the ussd command to send e.g "*#06#"
00288         \param buf a buffer where to save the reply
00289         \return true if successful, false otherwise
00290     */
00291     bool ussdCommand(const char* cmd, char* buf);
00292     
00293     // ----------------------------------------------------------------
00294     // DATAGRAMS (via C027N Neul module)
00295     // ----------------------------------------------------------------
00296 
00297     /** Determine the version of the module.
00298        \return the version string
00299     */
00300    char * getVersion (void);
00301 
00302     /** Initialise the modem with a MACTEST string.
00303         Only required for Phase 1 modules.
00304        \param size  the number of bytes in buf
00305        \param buf  the bytes to be sent
00306        \return true if successful, false otherwise
00307     */
00308    bool sendMactest(int size, const char* buf);
00309 
00310     /** Send a datagram
00311         \param size  the number of bytes in buf
00312         \param buf  the bytes to be sent
00313         \return true if successful, false otherwise
00314     */
00315     bool datagramSend(int size, const char* buf);
00316 
00317     /** Receive a datagram.
00318         \param size  when called, the size of buf and, on exit,
00319                      the number of bytes received into buf.
00320         \param buf   the bytes received
00321         \param timeoutMs optional time to wait in milliseconds
00322         \return true if something was received, false otherwise
00323     */
00324     bool datagramRecv(int* size, char* buf, int timeoutMs = 10000);
00325 
00326      /** Get the RSSI of the Neul modem
00327         \param rssi  a number in the range 0 to 255
00328         \return true if successful, false otherwise
00329      */
00330     bool getRssi(int *rssi);
00331 
00332     /** Reboot a Neul module
00333        \return true if successful, false otherwise
00334     */
00335     bool neulReboot(void);
00336 
00337     // ----------------------------------------------------------------
00338     // FILE 
00339     // ----------------------------------------------------------------
00340     
00341     /** Delete a file in the local file system
00342         \param filename the name of the file 
00343         \return true if successful, false otherwise
00344     */
00345     bool delFile(const char* filename);
00346     
00347     /** Write some data to a file in the local file system
00348         \param filename the name of the file 
00349         \param buf the data to write 
00350         \param len the size of the data to write
00351         \return the number of bytes written
00352     */
00353     int writeFile(const char* filename, const char* buf, int len);
00354     
00355     /** REad a file from the local file system
00356         \param filename the name of the file 
00357         \param buf a buffer to hold the data 
00358         \param len the size to read
00359         \return the number of bytes read
00360     */
00361     int readFile(const char* filename, char* buf, int len);
00362     
00363     // ----------------------------------------------------------------
00364     // DEBUG/DUMP status to standard out (printf)
00365     // ----------------------------------------------------------------
00366     
00367     /*! Set the debug level 
00368         \param level -1 = OFF, 0 = ERROR, 1 = INFO(default), 2 = TRACE, 3 = ATCMD,TEST
00369         \return true if successful, false not possible
00370     */ 
00371     bool setDebug (int level);
00372 
00373     //! helper type for DPRINT
00374     typedef int (*_DPRINT)(void* param, char const * format, ...);
00375     
00376     //! helper to declate templates and void versions
00377 #define _DUMP_TEMPLATE(func, type, arg) \
00378     template<class T> \
00379     inline void func(type arg, \
00380                 int (*dprint)( T* param, char const * format, ...), \
00381                 T* param) { func(arg, (_DPRINT)dprint, (void*)param); } \
00382     static void func(type arg, \
00383                 _DPRINT dprint = (_DPRINT)fprintf, \
00384                 void* param = (void*)stdout);
00385 
00386     /** dump the device status to stdout using printf
00387         \param status the status to convert to textual form, 
00388                unavailable fields are ommited (not printed)
00389         \param dprint a function pointer
00390         \param param  the irst argument passed to dprint
00391     */
00392     _DUMP_TEMPLATE(dumpDevStatus, MDMParser::DevStatus*, status)
00393 
00394     /** dump the network status to stdout using printf
00395         \param status the status to convert to textual form, 
00396                unavailable fields are ommited (not printed)
00397         \param dprint a function pointer
00398         \param param  the irst argument passed to dprint
00399     */
00400     _DUMP_TEMPLATE(dumpNetStatus, MDMParser::NetStatus*, status)
00401     
00402     /** dump the ip address to stdout using printf
00403         \param ip the ip to convert to textual form, 
00404                unavailable fields are ommited (not printed)
00405         \param dprint a function pointer
00406         \param param  the irst argument passed to dprint
00407     */
00408     _DUMP_TEMPLATE(dumpIp, MDMParser::IP, ip)
00409    
00410     // ----------------------------------------------------------------
00411     // Parseing
00412     // ----------------------------------------------------------------
00413     
00414     enum { 
00415         // waitFinalResp Responses
00416         NOT_FOUND     =  0,
00417         WAIT          = -1, // TIMEOUT
00418         RESP_OK       = -2, 
00419         RESP_ERROR    = -3,
00420         RESP_PROMPT   = -4,
00421     
00422         // getLine Responses
00423         #define LENGTH(x)  (x & 0x00FFFF) //!< extract/mask the length
00424         #define TYPE(x)    (x & 0xFF0000) //!< extract/mask the type
00425         
00426         TYPE_UNKNOWN    = 0x000000,
00427         TYPE_OK         = 0x110000,
00428         TYPE_ERROR      = 0x120000,
00429         TYPE_RING       = 0x210000,
00430         TYPE_CONNECT    = 0x220000,
00431         TYPE_NOCARRIER  = 0x230000,
00432         TYPE_NODIALTONE = 0x240000,
00433         TYPE_BUSY       = 0x250000,
00434         TYPE_NOANSWER   = 0x260000,
00435         TYPE_PROMPT     = 0x300000,
00436         TYPE_PLUS       = 0x400000,
00437         TYPE_TEXT       = 0x500000,
00438         
00439         // special timout constant
00440         TIMEOUT_BLOCKING = -1
00441     };
00442     
00443     /** Get a line from the physical interface. This function need 
00444         to be implemented in a inherited class. Usually just calls 
00445         #_getLine on the rx buffer pipe. 
00446             
00447         \param buf the buffer to store it
00448         \param buf size of the buffer
00449         \return type and length if something was found, 
00450                 WAIT if not enough data is available
00451                 NOT_FOUND if nothing was found
00452     */ 
00453     virtual int getLine(char* buf, int len) = 0; 
00454     
00455     /* clear the pending input data
00456     */
00457     virtual void purge(void) = 0;
00458     
00459     /** Write data to the device 
00460         \param buf the buffer to write
00461         \param buf size of the buffer to write
00462         \return bytes written
00463     */
00464     virtual int send(const char* buf, int len);
00465     
00466     /** Write formated date to the physical interface (printf style)
00467         \param fmt the format string
00468         \param .. variable arguments to be formated
00469         \return bytes written
00470     */
00471     int sendFormated(const char* format, ...);
00472     
00473     /** callback function for #waitFinalResp with void* as argument
00474         \param type the #getLine response
00475         \param buf the parsed line
00476         \param len the size of the parsed line
00477         \param param the optional argument passed to #waitFinalResp
00478         \return WAIT if processing should continue, 
00479                 any other value aborts #waitFinalResp and this retunr value retuned
00480     */
00481     typedef int (*_CALLBACKPTR)(int type, const char* buf, int len, void* param);
00482     
00483     /** Wait for a final respons
00484         \param cb the optional callback function
00485         \param param the optional callback function parameter
00486         \param timeout_ms the timeout to wait (See Estimated command 
00487                response time of AT manual)
00488     */
00489     int waitFinalResp(_CALLBACKPTR cb = NULL, 
00490                       void* param = NULL, 
00491                       int timeout_ms = 10000);
00492 
00493     /** template version of #waitFinalResp when using callbacks, 
00494         This template will allow the compiler to do type cheking but 
00495         internally symply casts the arguments and call the (void*) 
00496         version of #waitFinalResp.
00497         \sa waitFinalResp
00498     */ 
00499     template<class T>
00500     inline int waitFinalResp(int (*cb)(int type, const char* buf, int len, T* param), 
00501                     T* param, 
00502                     int timeout_ms = 10000) 
00503     {
00504         return waitFinalResp((_CALLBACKPTR)cb, (void*)param, timeout_ms);
00505     }
00506     
00507 protected:
00508     /** Write bytes to the physical interface. This function should be 
00509         implemented in a inherited class.
00510         \param buf the buffer to write
00511         \param buf size of the buffer to write
00512         \return bytes written
00513     */
00514     virtual int _send(const void* buf, int len) = 0;
00515 
00516     /** Helper: Parse a line from the receiving buffered pipe
00517         \param pipe the receiving buffer pipe 
00518         \param buf the parsed line
00519         \param len the size of the parsed line
00520         \return type and length if something was found, 
00521                 WAIT if not enough data is available
00522                 NOT_FOUND if nothing was found
00523     */
00524     static int _getLine(Pipe<char> * pipe, char* buffer, int length);
00525     
00526     /** Helper: Parse a match from the pipe
00527         \param pipe the buffered pipe
00528         \param number of bytes to parse at maximum, 
00529         \param sta the starting string, NULL if none
00530         \param end the terminating string, NULL if none
00531         \return size of parsed match 
00532     */   
00533     static int _parseMatch(Pipe<char> * pipe, int len, const char* sta, const char* end);
00534     
00535     /** Helper: Parse a match from the pipe
00536         \param pipe the buffered pipe
00537         \param number of bytes to parse at maximum, 
00538         \param fmt the formating string (%d any number, %c any char of last %d len)
00539         \return size of parsed match
00540     */   
00541     static int _parseFormated(Pipe<char> * pipe, int len, const char* fmt);
00542 
00543 protected:
00544     // for rtos over riding by useing Rtos<MDMxx> 
00545     /** override in a rtos system, you us the wait function of a Thread
00546         \param ms the number of milliseconds to wait
00547     */
00548     virtual void wait_ms(int ms)   { if (ms) ::wait_ms(ms); }
00549     //! override the lock in a rtos system
00550     virtual void lock(void)        { } 
00551     //! override the unlock in a rtos system
00552     virtual void unlock(void)      { } 
00553 protected:
00554     // parsing callbacks for different AT commands and their parameter arguments
00555     static int _cbString(int type, const char* buf, int len, char* str);
00556     static int _cbInt(int type, const char* buf, int len, int* val);
00557     static int _cbGmiString(int type, const char* buf, int len, char* str);
00558     static int _cbGmmString(int type, const char* buf, int len, char* str);
00559     static int _cbGmrString(int type, const char* buf, int len, char* str);
00560     // device
00561     static int _cbATI(int type, const char* buf, int len, Dev* dev);
00562     static int _cbCPIN(int type, const char* buf, int len, Sim* sim);
00563     static int _cbCCID(int type, const char* buf, int len, char* ccid);
00564     // network 
00565     static int _cbCSQ(int type, const char* buf, int len, NetStatus* status);
00566     static int _cbCSQN(int type, const char* buf, int len, int* rssi);
00567     static int _cbCOPS(int type, const char* buf, int len, NetStatus* status);
00568     static int _cbCNUM(int type, const char* buf, int len, char* num);
00569     static int _cbUACTIND(int type, const char* buf, int len, int* i);
00570     static int _cbRAS(int type, const char* buf, int len, bool* connected);
00571     static int _cbUDOPN(int type, const char* buf, int len, char* mccmnc);
00572     // sockets
00573     static int _cbCMIP(int type, const char* buf, int len, IP* ip);
00574     static int _cbUPSND(int type, const char* buf, int len, int* act);
00575     static int _cbUPSND(int type, const char* buf, int len, IP* ip);
00576     static int _cbUDNSRN(int type, const char* buf, int len, IP* ip);
00577     static int _cbUSOCR(int type, const char* buf, int len, int* handle);
00578     static int _cbUSORD(int type, const char* buf, int len, char* out);
00579     typedef struct { char* buf; IP ip; int port; } USORFparam;
00580     static int _cbUSORF(int type, const char* buf, int len, USORFparam* param);
00581     typedef struct { char* buf; char* num; } CMGRparam;
00582     static int _cbCUSD(int type, const char* buf, int len, char* resp);
00583     // sms
00584     typedef struct { int* ix; int num; } CMGLparam;
00585     static int _cbCMGL(int type, const char* buf, int len, CMGLparam* param);
00586     static int _cbCMGR(int type, const char* buf, int len, CMGRparam* param);
00587     // Neul
00588     static int _cbMGS (int type, const char* buf, int len, bool* ok);
00589     static int _cbSMI (int type, const char* buf, int len, bool* sent);
00590     typedef struct { char* buf; int maxlen; int outlen; } MGRparam;
00591     bool doMGR (int* size, char* buf, MGRparam* param);
00592     static int _cbMGR (int type, const char* buf, int len, MGRparam* param);
00593     static int _cbRB (int type, const char* buf, int len, bool* ok);
00594     // file
00595     typedef struct { const char* filename; char* buf; int sz; int len; } URDFILEparam;
00596     static int _cbUDELFILE(int type, const char* buf, int len, void*);
00597     static int _cbURDFILE(int type, const char* buf, int len, URDFILEparam* param);
00598     // variables
00599     DevStatus   _dev; //!< collected device information
00600     NetStatus   _net; //!< collected network information 
00601     IP          _ip;  //!< assigned ip address
00602     // management struture for sockets
00603     typedef struct { int handle; int timeout_ms; volatile bool connected; volatile int pending; } SockCtrl;
00604     // LISA-C has 6 TCP and 6 UDP sockets 
00605     // LISA-U and SARA-G have 7 sockets
00606     SockCtrl _sockets[12];
00607     int _findSocket(int handle = SOCKET_ERROR/* = CREATE*/);
00608     // Utilities to convert a hex string into bytes and vice-versa
00609     static void hexStringToBytes (const char *inBuf, int lenInBuf, char * outBuf, int* lenOutBuf);
00610     static int bytesToHexString (const char * inBuf, int size, char *outBuf, int lenOutBuf);
00611     static MDMParser* inst;
00612     bool _init;
00613     bool _ubloxat;
00614     bool _useNMI;
00615     int _outstandingNMI;
00616 #ifdef TARGET_UBLOX_C027
00617     bool _onboard;
00618 #endif
00619 #ifdef MDM_DEBUG
00620     int _debugLevel;
00621     Timer _debugTime;
00622     void _debugPrint(int level, const char* color, const char* format, ...);
00623 #endif
00624 };
00625 
00626 // -----------------------------------------------------------------------
00627 
00628 /** modem class which uses a serial port 
00629     as physical interface. 
00630 */
00631 class MDMSerial :  public SerialPipe, public MDMParser
00632 {
00633 public: 
00634     /** Constructor
00635     
00636         \param tx is the serial ports transmit pin (modem to CPU)
00637         \param rx is the serial ports receive pin (CPU to modem)
00638         \param baudrate the baudrate of the modem use 115200
00639         \param rts is the serial ports ready to send pin (CPU to modem) 
00640                this pin is optional 
00641         \param cts is the serial ports clear to send pin (modem to CPU) 
00642                this pin is optional, but required for power saving to be enabled
00643         \param rxSize the size of the serial rx buffer
00644         \param txSize the size of the serial tx buffer
00645     */
00646     MDMSerial(PinName tx    MDM_IF( = MDMTXD,  = D1 ), 
00647               PinName rx    MDM_IF( = MDMRXD,  = D0 ), 
00648               int baudrate  MDM_IF( = MDMBAUD, = 115200 ),
00649  #if DEVICE_SERIAL_FC
00650               PinName rts   MDM_IF( = MDMRTS,  = NC /* D2 resistor R62 on shield not mounted */ ), 
00651               PinName cts   MDM_IF( = MDMCTS,  = NC /* D3 resistor R63 on shield not mounted */ ),
00652  #endif
00653               int rxSize    = 256 , 
00654               int txSize    = 128 );
00655     //! Destructor          
00656     virtual ~MDMSerial(void);
00657     
00658     /** Get a line from the physical interface. 
00659         \param buf the buffer to store it
00660         \param buf size of the buffer
00661         \return type and length if something was found, 
00662                 WAIT if not enough data is available
00663                 NOT_FOUND if nothing was found
00664     */ 
00665     virtual int getLine(char* buffer, int length);
00666     
00667     /* clear the pending input data */
00668     virtual void purge(void) 
00669     { 
00670         while (readable())
00671             getc();
00672     }
00673 protected:
00674     /** Write bytes to the physical interface.
00675         \param buf the buffer to write
00676         \param buf size of the buffer to write
00677         \return bytes written
00678     */
00679     virtual int _send(const void* buf, int len);
00680 };
00681 
00682 // -----------------------------------------------------------------------
00683 
00684 //#define HAVE_MDMUSB
00685 #ifdef HAVE_MDMUSB
00686 class MDMUsb :  /*public UsbSerial,*/ public MDMParser
00687 {
00688 public: 
00689     //! Constructor          
00690     MDMUsb(void);
00691     //! Destructor          
00692     virtual ~MDMUsb(void);
00693     virtual int getLine(char* buffer, int length);
00694     virtual void purge(void) { }
00695 protected:
00696     virtual int _send(const void* buf, int len);
00697 };
00698 #endif
00699 
00700 // -----------------------------------------------------------------------
00701 
00702 #ifdef RTOS_H
00703 /** Use this template to override the lock and wait functions of the 
00704     modem driver in a Rtos system. For example declare it the modem 
00705     object as MDMRtos<MDMSerial> instead of MDMSerial.
00706 */
00707 template <class T>
00708 class MDMRtos :  public T
00709 {
00710 protected:
00711     //! we assume that the modem runs in a thread so we yield when waiting
00712     virtual void wait_ms(int ms)   {
00713         if (ms) Thread::wait(ms);
00714         else    Thread::yield();
00715     }
00716     //! lock a mutex when accessing the modem
00717     virtual void lock(void)     { _mtx.lock(); }  
00718     //! unlock the modem when done accessing it
00719     virtual void unlock(void)   { _mtx.unlock(); }
00720     // the mutex resource
00721     Mutex _mtx;
00722 };
00723 #endif