Own fork of C027_Support

Dependents:   MbedSmartRestMain MbedSmartRestMain

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; 
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[16];     //!< 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     // ----------------------------------------------------------------
00085     // Device 
00086     // ----------------------------------------------------------------
00087     
00088     typedef enum { AUTH_NONE, AUTH_PAP, AUTH_CHAP, AUTH_DETECT } Auth; 
00089     
00090     /** Combined Init, checkNetStatus, join suitable for simple applications
00091         \param simpin a optional pin of the SIM card
00092         \param apn  the of the network provider e.g. "internet" or "apn.provider.com"
00093         \param username is the user name text string for the authentication phase
00094         \param password is the password text string for the authentication phase
00095         \param auth is the authentication mode (CHAP,PAP,NONE or DETECT)
00096         \return true if successful, false otherwise
00097     */
00098     bool connect(const char* simpin = NULL, 
00099             const char* apn = NULL, const char* username = NULL, 
00100             const char* password = NULL, Auth auth = AUTH_DETECT,
00101             PinName pn MDM_IF( = MDMPWRON, = D4));    
00102 
00103     /** register (Attach) the MT to the GPRS service. 
00104         \param simpin a optional pin of the SIM card
00105         \param status an optional struture to with device information 
00106         \return true if successful, false otherwise
00107     */
00108     bool init(const char* simpin = NULL, DevStatus* status = NULL, 
00109                 PinName pn MDM_IF( = MDMPWRON, = D4));
00110     
00111     /** register to the network 
00112         \param status an optional structure to with network information 
00113         \param timeout_ms -1 blocking, else non blocking timeout in ms
00114         \return true if successful and connected to network, false otherwise
00115     */
00116     bool registerNet(NetStatus* status = NULL, int timeout_ms = 180000);
00117     
00118     /** check if the network is available 
00119         \param status an optional structure to with network information 
00120         \return true if successful and connected to network, false otherwise
00121     */
00122     bool checkNetStatus(NetStatus* status = NULL);
00123     
00124     /** Power off the MT, This function has to be called prior to 
00125         switching off the supply. 
00126         \return true if successfully, false otherwise
00127     */ 
00128     bool powerOff(void);
00129     
00130     // ----------------------------------------------------------------
00131     // Data Connection (GPRS)
00132     // ----------------------------------------------------------------
00133     
00134     /** register (Attach) the MT to the GPRS service. 
00135         \param apn  the of the network provider e.g. "internet" or "apn.provider.com"
00136         \param username is the user name text string for the authentication phase
00137         \param password is the password text string for the authentication phase
00138         \param auth is the authentication mode (CHAP,PAP,NONE or DETECT)
00139         \return the ip that is assigned 
00140     */
00141     MDMParser::IP join(const char* apn = NULL, const char* username = NULL, 
00142                        const char* password = NULL, Auth auth = AUTH_DETECT);
00143     
00144     /** deregister (detach) the MT from the GPRS service.
00145         \return true if successful, false otherwise
00146     */
00147     bool disconnect(void);
00148     
00149     /** Translates a domain name to an IP address
00150         \param host the domain name to translate e.g. "u-blox.com"
00151         \return the IP if successful, 0 otherwise
00152     */
00153     MDMParser::IP gethostbyname(const char* host);
00154     
00155     // ----------------------------------------------------------------
00156     // Sockets
00157     // ----------------------------------------------------------------
00158     
00159     //! Type of IP protocol 
00160     typedef enum { IPPROTO_TCP, IPPROTO_UDP } IpProtocol; 
00161     
00162     //! Socket error return codes
00163     #define SOCKET_ERROR -1
00164     
00165     /** Create a socket for a ip protocol (and optionaly bind)
00166         \param ipproto the protocol (UDP or TCP) 
00167         \param port in case of UDP, this optional port where it is bind
00168         \return the socket handle if successful or SOCKET_ERROR on failure 
00169     */
00170     int socketSocket(IpProtocol ipproto, int port = -1);
00171     
00172     /** make a socket connection
00173         \param socket the socket handle
00174         \param host the domain name to connect e.g. "u-blox.com"
00175         \param port the port to connect
00176         \return true if successfully, false otherwise
00177     */
00178     bool socketConnect(int socket, const char* host, int port);
00179         
00180     /** make a socket connection
00181         \param socket the socket handle
00182         \return true if connected, false otherwise
00183     */
00184     bool socketIsConnected(int socket);
00185      
00186     /** Get the number of bytes pending for reading for this socket
00187         \param socket the socket handle
00188         \param timeout_ms -1 blocking, else non blocking timeout in ms
00189         \return 0 if successful or SOCKET_ERROR on failure 
00190     */
00191     bool socketSetBlocking(int socket, int timeout_ms);
00192     
00193     /** Write socket data 
00194         \param socket the socket handle
00195         \param buf the buffer to write
00196         \param len the size of the buffer to write
00197         \return the size written or SOCKET_ERROR on failure 
00198     */
00199     int socketSend(int socket, const char * buf, int len);
00200     
00201     /** Write socket data to a IP
00202         \param socket the socket handle
00203         \param ip the ip to send to
00204         \param port the port to send to
00205         \param buf the buffer to write
00206         \param len the size of the buffer to write
00207         \return the size written or SOCKET_ERROR on failure 
00208     */
00209     int socketSendTo(int socket, IP ip, int port, const char * buf, int len);
00210     
00211     /** Get the number of bytes pending for reading for this socket
00212         \param socket the socket handle
00213         \return the number of bytes pending or SOCKET_ERROR on failure 
00214     */
00215     int socketReadable(int socket);
00216     
00217     /** Read this socket
00218         \param socket the socket handle
00219         \param buf the buffer to read into
00220         \param len the size of the buffer to read into
00221         \return the number of bytes read or SOCKET_ERROR on failure 
00222     */
00223     int socketRecv(int socket, char* buf, int len);
00224     
00225     /** Read from this socket
00226         \param socket the socket handle
00227         \param ip the ip of host where the data originates from
00228         \param port the port where the data originates from
00229         \param buf the buffer to read into
00230         \param len the size of the buffer to read into
00231         \return the number of bytes read or SOCKET_ERROR on failure 
00232     */
00233     int socketRecvFrom(int socket, IP* ip, int* port, char* buf, int len);
00234     
00235     /** Close a connectied socket (that was connected with #socketConnect)
00236         \param socket the socket handle
00237         \return true if successfully, false otherwise
00238     */    
00239     bool socketClose(int socket);
00240     
00241     /** Free the socket (that was allocated before by #socketSocket)
00242         \param socket the socket handle
00243         \return true if successfully, false otherwise
00244     */    
00245     bool socketFree(int socket);
00246         
00247     // ----------------------------------------------------------------
00248     // SMS Short Message Service
00249     // ----------------------------------------------------------------
00250     
00251     /** count the number of sms in the device and optionally return a 
00252         list with indexes from the storage locations in the device.
00253         \param stat what type of messages you can use use 
00254                     "REC UNREAD", "REC READ", "STO UNSENT", "STO SENT", "ALL"
00255         \param ix   list where to save the storage positions
00256         \param num  number of elements in the list 
00257         \return the number of messages, this can be bigger than num, -1 on failure
00258     */
00259     int smsList(const char* stat = "ALL", int* ix = NULL, int num = 0);
00260     
00261     /** Read a Message from a storage position
00262         \param ix the storage position to read
00263         \param num the originator address (~16 chars)
00264         \param buf a buffer where to save the sm
00265         \param len the length of the sm
00266         \return true if successful, false otherwise
00267     */
00268     bool smsRead(int ix, char* num, char* buf, int len);
00269     
00270     /** Send a message to a recipient 
00271         \param ix the storage position to delete
00272         \return true if successful, false otherwise
00273     */
00274     bool smsDelete(int ix);
00275     
00276     /** Send a message to a recipient 
00277         \param num the phone number of the recipient
00278         \param buf the content of the message to sent
00279         \return true if successful, false otherwise
00280     */
00281     bool smsSend(const char* num, const char* buf);
00282     
00283     // ----------------------------------------------------------------
00284     // USSD Unstructured Supplementary Service Data
00285     // ----------------------------------------------------------------
00286     
00287     /** Read a Message from a storage position
00288         \param cmd the ussd command to send e.g "*#06#"
00289         \param buf a buffer where to save the reply
00290         \return true if successful, false otherwise
00291     */
00292     bool ussdCommand(const char* cmd, char* buf);
00293     
00294     // ----------------------------------------------------------------
00295     // FILE 
00296     // ----------------------------------------------------------------
00297     
00298     /** Delete a file in the local file system
00299         \param filename the name of the file 
00300         \return true if successful, false otherwise
00301     */
00302     bool delFile(const char* filename);
00303     
00304     /** Write some data to a file in the local file system
00305         \param filename the name of the file 
00306         \param buf the data to write 
00307         \param len the size of the data to write
00308         \return the number of bytes written
00309     */
00310     int writeFile(const char* filename, const char* buf, int len);
00311     
00312     /** REad a file from the local file system
00313         \param filename the name of the file 
00314         \param buf a buffer to hold the data 
00315         \param len the size to read
00316         \return the number of bytes read
00317     */
00318     int readFile(const char* filename, char* buf, int len);
00319     
00320     // ----------------------------------------------------------------
00321     // DEBUG/DUMP status to standard out (printf)
00322     // ----------------------------------------------------------------
00323     
00324     /*! Set the debug level 
00325         \param level -1 = OFF, 0 = ERROR, 1 = INFO(default), 2 = TRACE, 3 = ATCMD,TEST
00326         \return true if successful, false not possible
00327     */ 
00328     bool setDebug (int level);
00329 
00330     //! helper type for DPRINT
00331     typedef int (*_DPRINT)(void* param, char const * format, ...);
00332     
00333     //! helper to declate templates and void versions
00334 #define _DUMP_TEMPLATE(func, type, arg) \
00335     template<class T> \
00336     inline void func(type arg, \
00337                 int (*dprint)( T* param, char const * format, ...), \
00338                 T* param) { func(arg, (_DPRINT)dprint, (void*)param); } \
00339     static void func(type arg, \
00340                 _DPRINT dprint = (_DPRINT)fprintf, \
00341                 void* param = (void*)stdout);
00342 
00343     /** dump the device status to stdout using printf
00344         \param status the status to convert to textual form, 
00345                unavailable fields are ommited (not printed)
00346         \param dprint a function pointer
00347         \param param  the irst argument passed to dprint
00348     */
00349     _DUMP_TEMPLATE(dumpDevStatus, MDMParser::DevStatus*, status)
00350 
00351     /** dump the network status to stdout using printf
00352         \param status the status to convert to textual form, 
00353                unavailable fields are ommited (not printed)
00354         \param dprint a function pointer
00355         \param param  the irst argument passed to dprint
00356     */
00357     _DUMP_TEMPLATE(dumpNetStatus, MDMParser::NetStatus*, status)
00358     
00359     /** dump the ip address to stdout using printf
00360         \param ip the ip to convert to textual form, 
00361                unavailable fields are ommited (not printed)
00362         \param dprint a function pointer
00363         \param param  the irst argument passed to dprint
00364     */
00365     _DUMP_TEMPLATE(dumpIp, MDMParser::IP, ip)
00366    
00367     // ----------------------------------------------------------------
00368     // Parseing
00369     // ----------------------------------------------------------------
00370     
00371     enum { 
00372         // waitFinalResp Responses
00373         NOT_FOUND     =  0,
00374         WAIT          = -1, // TIMEOUT
00375         RESP_OK       = -2, 
00376         RESP_ERROR    = -3,
00377         RESP_PROMPT   = -4,
00378     
00379         // getLine Responses
00380         #define LENGTH(x)  (x & 0x00FFFF) //!< extract/mask the length
00381         #define TYPE(x)    (x & 0xFF0000) //!< extract/mask the type
00382         
00383         TYPE_UNKNOWN    = 0x000000,
00384         TYPE_OK         = 0x110000,
00385         TYPE_ERROR      = 0x120000,
00386         TYPE_RING       = 0x210000,
00387         TYPE_CONNECT    = 0x220000,
00388         TYPE_NOCARRIER  = 0x230000,
00389         TYPE_NODIALTONE = 0x240000,
00390         TYPE_BUSY       = 0x250000,
00391         TYPE_NOANSWER   = 0x260000,
00392         TYPE_PROMPT     = 0x300000,
00393         TYPE_PLUS       = 0x400000,
00394         TYPE_TEXT       = 0x500000,
00395         
00396         // special timout constant
00397         TIMEOUT_BLOCKING = -1
00398     };
00399     
00400     /** Get a line from the physical interface. This function need 
00401         to be implemented in a inherited class. Usually just calls 
00402         #_getLine on the rx buffer pipe. 
00403             
00404         \param buf the buffer to store it
00405         \param buf size of the buffer
00406         \return type and length if something was found, 
00407                 WAIT if not enough data is available
00408                 NOT_FOUND if nothing was found
00409     */ 
00410     virtual int getLine(char* buf, int len) = 0; 
00411     
00412     /* clear the pending input data
00413     */
00414     virtual void purge(void) = 0;
00415     
00416     /** Write data to the device 
00417         \param buf the buffer to write
00418         \param buf size of the buffer to write
00419         \return bytes written
00420     */
00421     virtual int send(const char* buf, int len);
00422     
00423     /** Write formated date to the physical interface (printf style)
00424         \param fmt the format string
00425         \param .. variable arguments to be formated
00426         \return bytes written
00427     */
00428     int sendFormated(const char* format, ...);
00429     
00430     /** callback function for #waitFinalResp with void* as argument
00431         \param type the #getLine response
00432         \param buf the parsed line
00433         \param len the size of the parsed line
00434         \param param the optional argument passed to #waitFinalResp
00435         \return WAIT if processing should continue, 
00436                 any other value aborts #waitFinalResp and this retunr value retuned
00437     */
00438     typedef int (*_CALLBACKPTR)(int type, const char* buf, int len, void* param);
00439     
00440     /** Wait for a final respons
00441         \param cb the optional callback function
00442         \param param the optional callback function parameter
00443         \param timeout_ms the timeout to wait (See Estimated command 
00444                response time of AT manual)
00445     */
00446     int waitFinalResp(_CALLBACKPTR cb = NULL, 
00447                       void* param = NULL, 
00448                       int timeout_ms = 10000);
00449 
00450     /** template version of #waitFinalResp when using callbacks, 
00451         This template will allow the compiler to do type cheking but 
00452         internally symply casts the arguments and call the (void*) 
00453         version of #waitFinalResp.
00454         \sa waitFinalResp
00455     */ 
00456     template<class T>
00457     inline int waitFinalResp(int (*cb)(int type, const char* buf, int len, T* param), 
00458                     T* param, 
00459                     int timeout_ms = 10000) 
00460     {
00461         return waitFinalResp((_CALLBACKPTR)cb, (void*)param, timeout_ms);
00462     }
00463     
00464 protected:
00465     /** Write bytes to the physical interface. This function should be 
00466         implemented in a inherited class.
00467         \param buf the buffer to write
00468         \param buf size of the buffer to write
00469         \return bytes written
00470     */
00471     virtual int _send(const void* buf, int len) = 0;
00472 
00473     /** Helper: Parse a line from the receiving buffered pipe
00474         \param pipe the receiving buffer pipe 
00475         \param buf the parsed line
00476         \param len the size of the parsed line
00477         \return type and length if something was found, 
00478                 WAIT if not enough data is available
00479                 NOT_FOUND if nothing was found
00480     */
00481     static int _getLine(Pipe<char> * pipe, char* buffer, int length);
00482     
00483     /** Helper: Parse a match from the pipe
00484         \param pipe the buffered pipe
00485         \param number of bytes to parse at maximum, 
00486         \param sta the starting string, NULL if none
00487         \param end the terminating string, NULL if none
00488         \return size of parsed match 
00489     */   
00490     static int _parseMatch(Pipe<char> * pipe, int len, const char* sta, const char* end);
00491     
00492     /** Helper: Parse a match from the pipe
00493         \param pipe the buffered pipe
00494         \param number of bytes to parse at maximum, 
00495         \param fmt the formating string (%d any number, %c any char of last %d len)
00496         \return size of parsed match
00497     */   
00498     static int _parseFormated(Pipe<char> * pipe, int len, const char* fmt);
00499 
00500 protected:
00501     // for rtos over riding by useing Rtos<MDMxx> 
00502     /** override in a rtos system, you us the wait function of a Thread
00503         \param ms the number of milliseconds to wait
00504     */
00505     virtual void wait_ms(int ms)   { if (ms) ::wait_ms(ms); }
00506     //! override the lock in a rtos system
00507     virtual void lock(void)        { } 
00508     //! override the unlock in a rtos system
00509     virtual void unlock(void)      { } 
00510 protected:
00511     // parsing callbacks for different AT commands and their parameter arguments
00512     static int _cbString(int type, const char* buf, int len, char* str);
00513     static int _cbInt(int type, const char* buf, int len, int* val);
00514     // device
00515     static int _cbATI(int type, const char* buf, int len, Dev* dev);
00516     static int _cbCPIN(int type, const char* buf, int len, Sim* sim);
00517     static int _cbCCID(int type, const char* buf, int len, char* ccid);
00518     // network 
00519     static int _cbCSQ(int type, const char* buf, int len, NetStatus* status);
00520     static int _cbCOPS(int type, const char* buf, int len, NetStatus* status);
00521     static int _cbCNUM(int type, const char* buf, int len, char* num);
00522     static int _cbUACTIND(int type, const char* buf, int len, int* i);
00523     static int _cbUDOPN(int type, const char* buf, int len, char* mccmnc);
00524     // sockets
00525     static int _cbCMIP(int type, const char* buf, int len, IP* ip);
00526     static int _cbUPSND(int type, const char* buf, int len, int* act);
00527     static int _cbUPSND(int type, const char* buf, int len, IP* ip);
00528     static int _cbUDNSRN(int type, const char* buf, int len, IP* ip);
00529     static int _cbUSOCR(int type, const char* buf, int len, int* handle);
00530     static int _cbUSORD(int type, const char* buf, int len, char* out);
00531     typedef struct { char* buf; IP ip; int port; } USORFparam;
00532     static int _cbUSORF(int type, const char* buf, int len, USORFparam* param);
00533     typedef struct { char* buf; char* num; } CMGRparam;
00534     static int _cbCUSD(int type, const char* buf, int len, char* buf);
00535     // sms
00536     typedef struct { int* ix; int num; } CMGLparam;
00537     static int _cbCMGL(int type, const char* buf, int len, CMGLparam* param);
00538     static int _cbCMGR(int type, const char* buf, int len, CMGRparam* param);
00539     // file
00540     typedef struct { const char* filename; char* buf; int sz; int len; } URDFILEparam;
00541     static int _cbUDELFILE(int type, const char* buf, int len, void*);
00542     static int _cbURDFILE(int type, const char* buf, int len, URDFILEparam* param);
00543     // variables
00544     DevStatus   _dev; //!< collected device information
00545     NetStatus   _net; //!< collected network information 
00546     IP          _ip;  //!< assigned ip address
00547     // management struture for sockets
00548     typedef struct { int handle; int timeout_ms; volatile bool connected; volatile int pending; } SockCtrl;
00549     // LISA-C has 6 TCP and 6 UDP sockets 
00550     // LISA-U and SARA-G have 7 sockets
00551     SockCtrl _sockets[12];
00552     int _findSocket(int handle = SOCKET_ERROR/* = CREATE*/);
00553     static MDMParser* inst;
00554     bool _init;
00555 #ifdef TARGET_UBLOX_C027
00556     bool _onboard;
00557 #endif
00558 #ifdef MDM_DEBUG
00559     int _debugLevel;
00560     Timer _debugTime;
00561     void _debugPrint(int level, const char* color, const char* format, ...);
00562 #endif
00563 };
00564 
00565 // -----------------------------------------------------------------------
00566 
00567 /** modem class which uses a serial port 
00568     as physical interface. 
00569 */
00570 class MDMSerial :  public SerialPipe, public MDMParser
00571 {
00572 public: 
00573     /** Constructor
00574     
00575         \param tx is the serial ports transmit pin (modem to CPU)
00576         \param rx is the serial ports receive pin (CPU to modem)
00577         \param baudrate the baudrate of the modem use 115200
00578         \param rts is the serial ports ready to send pin (CPU to modem) 
00579                this pin is optional 
00580         \param cts is the serial ports clear to send pin (modem to CPU) 
00581                this pin is optional, but required for power saving to be enabled
00582         \param rxSize the size of the serial rx buffer
00583         \param txSize the size of the serial tx buffer
00584     */
00585     MDMSerial(PinName tx    MDM_IF( = MDMTXD,  = D1 ), 
00586               PinName rx    MDM_IF( = MDMRXD,  = D0 ), 
00587               int baudrate  MDM_IF( = MDMBAUD, = 115200 ),
00588  #if DEVICE_SERIAL_FC
00589               PinName rts   MDM_IF( = MDMRTS,  = NC /* D2 resistor R62 on shield not mounted */ ), 
00590               PinName cts   MDM_IF( = MDMCTS,  = NC /* D3 resistor R63 on shield not mounted */ ),
00591  #endif
00592               int rxSize    = 256 , 
00593               int txSize    = 128 );
00594     //! Destructor          
00595     virtual ~MDMSerial(void);
00596     
00597     /** Get a line from the physical interface. 
00598         \param buf the buffer to store it
00599         \param buf size of the buffer
00600         \return type and length if something was found, 
00601                 WAIT if not enough data is available
00602                 NOT_FOUND if nothing was found
00603     */ 
00604     virtual int getLine(char* buffer, int length);
00605     
00606     /* clear the pending input data */
00607     virtual void purge(void) 
00608     { 
00609         while (readable())
00610             getc();
00611     }
00612 protected:
00613     /** Write bytes to the physical interface.
00614         \param buf the buffer to write
00615         \param buf size of the buffer to write
00616         \return bytes written
00617     */
00618     virtual int _send(const void* buf, int len);
00619 };
00620 
00621 // -----------------------------------------------------------------------
00622 
00623 //#define HAVE_MDMUSB
00624 #ifdef HAVE_MDMUSB
00625 class MDMUsb :  /*public UsbSerial,*/ public MDMParser
00626 {
00627 public: 
00628     //! Constructor          
00629     MDMUsb(void);
00630     //! Destructor          
00631     virtual ~MDMUsb(void);
00632     virtual int getLine(char* buffer, int length);
00633     virtual void purge(void) { }
00634 protected:
00635     virtual int _send(const void* buf, int len);
00636 };
00637 #endif
00638 
00639 // -----------------------------------------------------------------------
00640 
00641 #ifdef RTOS_H
00642 /** Use this template to override the lock and wait functions of the 
00643     modem driver in a Rtos system. For example declare it the modem 
00644     object as MDMRtos<MDMSerial> instead of MDMSerial.
00645 */
00646 template <class T>
00647 class MDMRtos :  public T
00648 {
00649 protected:
00650     //! we assume that the modem runs in a thread so we yield when waiting
00651     virtual void wait_ms(int ms)   {
00652         if (ms) Thread::wait(ms);
00653         else    Thread::yield();
00654     }
00655     //! lock a mutex when accessing the modem
00656     virtual void lock(void)     { _mtx.lock(); }  
00657     //! unlock the modem when done accessing it
00658     virtual void unlock(void)   { _mtx.unlock(); }
00659     // the mutex resource
00660     Mutex _mtx;
00661 };
00662 #endif