C027_Support library plus AT Comand for dialing.

Fork of C027_Support_New by irsan julfikar

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