AerCloud / C027_Support_AerCloud

Dependents:   AerCloud_C027_Sample

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