* add C027_Support fork

Fork of C027_Support by u-blox

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MDM.h Source File

MDM.h

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