C027_SupportTest_xively_locationで使用しているC027用ライブラリ

Fork of C027_Support by u-blox

下記のプログラムC027_SupportTest_xively_locationで使用しているC027用ライブラリです。

Import programC027_SupportTest_xively_location

インターフェース2014年10月号のu-blox C027で3G通信する記事で使用したプログラム。   CQ publishing Interface 2014.10 issue, C027 3G test program.

オリジナルのライブラリは下記を参照してください。

Import libraryC027_Support

support library for C027 helper functions for Buffer Pipes, Buffered Serial Port (rtos capable) and GPS parsing. It includes modem APIs for USSD, SMS and Sockets.

Revision:
31:a0bed6c1e05d
Parent:
29:53d346010624
Child:
32:8f12ac182bbb
--- a/MDM.h	Tue Apr 08 15:49:04 2014 +0000
+++ b/MDM.h	Wed Apr 09 11:48:04 2014 +0000
@@ -18,12 +18,222 @@
 class MDMParser
 {
 public:
-    // waitFinalResp Responses
+    //! Constructor 
+    MDMParser(void);
+    
+    // ----------------------------------------------------------------
+    // Types 
+    // ----------------------------------------------------------------
+    
+    //! MT models
+    typedef enum { MODEL_UNKNOWN, MODEL_SARA_G350, MODEL_LISA_U200, MODEL_LISA_C200 } Model; 
+    //! SIM Status
+    typedef enum { SIM_UNKNOWN, SIM_PIN, SIM_READY } Sim; 
+    //! Device status
+    typedef struct { Model model; Sim sim; char ccid[20]; char imsi[16]; char imei[16]; } DevStatus;
+    //! Network Registration Status
+    typedef enum { REG_UNKNOWN, REG_DENIED, REG_NONE, REG_HOME, REG_ROAMING } Reg; 
+    // Access Technology
+    typedef enum { ACT_UNKNOWN, ACT_GSM, ACT_EDGE, ACT_UTRAN, ACT_CDMA } AcT; 
+    // Network Status
+    typedef struct { Reg reg; AcT act; int rssi; char opr[17]; char num[20]; } NetStatus;
+    //! An IP address
+    typedef uint32_t IP; 
+    //! No IP address
+    #define NOIP ((MDMParser::IP)0)
+    // ip number formating and conversion
+    #define IPSTR           "%d.%d.%d.%d"
+    #define IPNUM(ip)       ((ip)>>24)&0xff, \
+                            ((ip)>>16)&0xff, \
+                            ((ip)>> 8)&0xff, \
+                            ((ip)>> 0)&0xff
+    #define IPADR(a,b,c,d) ((((IP)(a))<<24) | \
+                            (((IP)(b))<<16) | \
+                            (((IP)(c))<< 8) | \
+                            (((IP)(d))<< 0))
+
+    
+    // ----------------------------------------------------------------
+    // Data Connection (GPRS)
+    // ----------------------------------------------------------------
+    
+    /** register (Attach) the MT to the GPRS service. 
+        \param pin  a optional pin of the SIM card
+        \param status an optional struture to with device information 
+        \return true if successful, false otherwise
+    */
+    bool init(const char* pin = NULL, DevStatus* status = NULL);
+    
+    /** check if the network is available 
+        \param status an optional structure to with network information 
+        \return true if successful and connected to network, false otherwise
+    */
+    bool checkNetStatus(NetStatus* status = NULL);
+    
+    /** Power off the MT, This function has to be called prior to 
+        switching off the supply. 
+        \return true if successfully, false otherwise
+    */ 
+    bool powerOff(void);
+    
+    // ----------------------------------------------------------------
+    // Data Connection (GPRS)
+    // ----------------------------------------------------------------
+    
+    /** register (Attach) the MT to the GPRS service. 
+        \param apn  the of the network provider e.g. "internet" or "apn.provider.com"
+        \param user is the user name text string for the authentication phase
+        \param password is the password text string for the authentication phase
+        \return the ip that is assigned 
+    */
+    MDMParser::IP join(const char* apn = NULL, const char* user = NULL, const char* password = NULL);
+    
+    /** deregister (detach) the MT from the GPRS service.
+        \return true if successful, false otherwise
+    */
+    bool disconnect(void);
+    
+    /** Translates a domain name to an IP address
+        \param host the domain name to translate e.g. "u-blox.com"
+        \return the IP if successful, 0 otherwise
+    */
+    MDMParser::IP gethostbyname(const char* host);
+    
+    // ----------------------------------------------------------------
+    // Sockets
+    // ----------------------------------------------------------------
+    
+    //! Type of IP protocol 
+    typedef enum { IPPROTO_TCP, IPPROTO_UDP } IpProtocol; 
+    
+    //! Socket error return codes
+    #define SOCKET_ERROR -1
+    
+    /** Create a socket for a ip protocol
+        \param ipproto the protocol (UDP or TCP) 
+        \return the socket handle if successful or SOCKET_ERROR on failure 
+    */
+    int socketSocket(IpProtocol ipproto);
+    
+    /** make a socket connection
+        \param socket the socket handle
+        \param host the domain name to connect e.g. "u-blox.com"
+        \param port the port to connect
+        \return true if successfully, false otherwise
+    */
+    bool socketConnect(int socket, const char* host, int port);
+        
+    /** Write socket data 
+        \param socket the socket handle
+        \param buf the buffer to write
+        \param len the size of the buffer to write
+        \return the size written or SOCKET_ERROR on failure 
+    */
+    int socketSend(int socket, const char * buf, int len);
+    
+    /** Write socket data to a IP
+        \param socket the socket handle
+        \param ip the ip to send to
+        \param port the port to send to
+        \param buf the buffer to write
+        \param len the size of the buffer to write
+        \return the size written or SOCKET_ERROR on failure 
+    */
+    int socketSendTo(int socket, IP ip, int port, const char * buf, int len);
+    
+    /** Get the number of bytes pending for reading for this socket
+        \param socket the socket handle
+        \return the number of bytes pending or SOCKET_ERROR on failure 
+    */
+    int socketReadable(int socket);
+    
+    /** Read this socket
+        \param socket the socket handle
+        \param buf the buffer to read into
+        \param len the size of the buffer to read into
+        \return the number of bytes read or SOCKET_ERROR on failure 
+    */
+    int socketRecv(int socket, char* buf, int len);
+    
+    /** Read from this socket
+        \param socket the socket handle
+        \param buf the buffer to read into
+        \param len the size of the buffer to read into
+        \param ip the ip of host where the data originates from
+        \return the number of bytes read or SOCKET_ERROR on failure 
+    */
+    int socketRecvFrom(int socket, char* buf, int len, IP* ip);
+    
+    /** Close a connectied socket (that was connected with #socketConnect)
+        \param socket the socket handle
+        \return true if successfully, false otherwise
+    */    
+    bool socketClose(int socket);
+    
+    /** Free the socket (that was allocated before by #socketSocket)
+        \param socket the socket handle
+        \return true if successfully, false otherwise
+    */    
+    bool socketFree(int socket);
+        
+    // ----------------------------------------------------------------
+    // SMS Short Message Service
+    // ----------------------------------------------------------------
+    
+    /** count the number of sms in the device and optionally return a 
+        list with indexes from the storage locations in the device.
+        \param stat what type of messages you can use use 
+                    "REC UNREAD", "REC READ", "STO UNSENT", "STO SENT", "ALL"
+        \param ix   list where to save the storage positions
+        \param num  number of elements in the list 
+        \return the number of messages, this can be bigger than num, -1 on failure
+    */
+    int smsList(const char* stat = "ALL", int* ix = NULL, int num = 0);
+    
+    /** Read a Message from a storage position
+        \param ix the storage position to read
+        \param num the originator address (~16 chars)
+        \param buf a buffer where to save the sm
+        \param len the length of the sm
+        \return true if successful, false otherwise
+    */
+    bool smsRead(int ix, char* num, char* buf, int len);
+    
+    /** Send a message to a recipient 
+        \param ix the storage position to delete
+        \return true if successful, false otherwise
+    */
+    bool smsDelete(int ix);
+    
+    /** Send a message to a recipient 
+        \param num the phone number of the recipient
+        \param buf the content of the message to sent
+        \return true if successful, false otherwise
+    */
+    bool smsSend(const char* num, const char* buf);
+    
+    // ----------------------------------------------------------------
+    // USSD Unstructured Supplementary Service Data
+    // ----------------------------------------------------------------
+    
+    /** Read a Message from a storage position
+        \param cmd the ussd command to send e.g "*#06#"
+        \param buf a buffer where to save the reply
+        \return true if successful, false otherwise
+    */
+    bool ussdCommand(const char* cmd, char* buf);
+    
+     // ----------------------------------------------------------------
+    // Parseing
+    // ----------------------------------------------------------------
+    
+   // waitFinalResp Responses
     #define NOT_FOUND    0
     #define WAIT        -1 // TIMEOUT
     #define OK          -2 
     #define ERROR       -3
     #define PROMPT      -4
+    
     // getLine Responses
     #define LENGTH(x)  (x & 0x00FFFF)
     #define TYPE(x)    (x & 0xFF0000)
@@ -38,29 +248,58 @@
     #define TYPE_NOANSWER   0x260000
     #define TYPE_PROMPT     0x300000
     #define TYPE_PLUS       0x400000
-    // Socket Return Codes
-    #define SOCKET_ERROR -1
-    #define SOCKET_OK     0 
-    typedef uint32_t IP;
+    
+    /** Get a line from the physical interface. This function need 
+        to be implemented in a inherited class. Usually just calls 
+        #_getLine on the rx buffer pipe. 
+            
+        \param buf the buffer to store it
+        \param buf size of the buffer
+        \return type and length if something was found, 
+                WAIT if not enough data is available
+                NOT_FOUND if nothing was found
+    */ 
+    virtual int getLine(char* buf, int len) = 0; 
     
-    typedef enum { MODEL_UNKNOWN, MODEL_SARA_G350, MODEL_LISA_U200, MODEL_LISA_C200 } Model; 
-    typedef enum { SIM_UNKNOWN, SIM_PIN, SIM_READY } Sim; 
-    typedef struct { Model model; Sim sim; const char* imsi; const char* imei; const char* ccid; } DevStatus;
-    typedef enum { NET_UNKNOWN, NET_DENIED, NET_NONE, NET_HOME, NET_ROAMING } Net; 
-    typedef enum { ACT_UNKNOWN, ACT_GSM, ACT_EDGE, ACT_UTRAN, ACT_CDMA } AcT; 
-    typedef struct { const char* num; const char* opr; int rssi; Net net; AcT act; } NetStatus;
+    /** Write data to the device 
+        \param buf the buffer to write
+        \param buf size of the buffer to write
+        \return bytes written
+    */
+    virtual int send(const char* buf, int len);
     
-    MDMParser(void);
-    
-    // interaction with AT command interface
-    virtual int getLine(char* buf, int len) = 0; 
-    virtual int send(const char* buf, int len);
+    /** Write formated date to the physical interface (printf style)
+        \param fmt the format string
+        \param .. variable arguments to be formated
+        \return bytes written
+    */
     int sendFormated(const char* format, ...);
     
+    /** callback function for #waitFinalResp with void* as argument
+        \param type the #getLine response
+        \param buf the parsed line
+        \param len the size of the parsed line
+        \param param the optional argument passed to #waitFinalResp
+        \return WAIT if processing should continue, 
+                any other value aborts #waitFinalResp and this retunr value retuned
+    */
     typedef int (*_CALLBACKPTR)(int type, const char* buf, int len, void* param);
-    int waitFinalResp(_CALLBACKPTR = NULL, 
+    
+    /** Wait for a final respons
+        \param cb the optional callback function
+        \param param the optional callback function parameter
+        \param timeout_ms the timeout to wait 
+    */
+    int waitFinalResp(_CALLBACKPTR cb = NULL, 
                       void* param = NULL, 
                       int timeout_ms = 5000);
+
+    /** template version of #waitFinalResp when using callbacks, 
+        This template will allow the compiler to do type cheking but 
+        internally symply casts the arguments and call the (void*) 
+        version of #waitFinalResp.
+        \sa waitFinalResp
+    */ 
     template<class T>
     int waitFinalResp(int (*cb)(int type, const char* buf, int len, 
                       T* param), 
@@ -68,40 +307,59 @@
     {
         return waitFinalResp((_CALLBACKPTR)cb, (void*)param, timeout_ms);
     }
-    // network
-    bool init(const char* pin = NULL, DevStatus* status = NULL);
-    bool checkNetStatus(NetStatus* status = NULL);
-    bool powerOff(void);
-    // internet connection
-    bool join(const char* apn = NULL, const char* user = NULL, const char* password = NULL);
-    bool disconnect(void);
-    bool gethostbyname(const char* host, IP* ip);
-    // socket interface
-    typedef enum { IPPROTO_TCP, IPPROTO_UDP } IpProtocol;
-    int socketSocket(IpProtocol ipproto);
-    bool socketConnect(int socket, const char * host, int port);
-    int socketSend(int socket, const char * buf, int len);
-    int socketSendTo(int socket, IP ip, int port, const char * buf, int len);
-    int socketReadable(int socket);
-    int socketRecv(int socket, char* buf, int len);
-    int socketRecvFrom(int socket, char* buf, int len, IP* ip);
-    bool socketClose(int socket);
-    bool socketFree(int socket);
-    // sms
-    int smsCount(void);
-    bool smsSend(const char* num, const char* buf);
-    bool smsDelete(int ix);
-    bool smsRead(int ix, char* num, char* buf, int len);
-    // ussd
-    int ussdCommand(const char* cmd, char* buf, int len);
+    
 protected:
-    static int _getLine(Pipe<char>* pipe, char* buffer, int length);
-    static int _parseMatch(Pipe<char>* pipe, int len, const char* sta, const char* end);
-    static int _parseFormated(Pipe<char>* pipe, int len, const char* fmt);
+    /** Write bytes to the physical interface. This function should be 
+        implemented in a inherited class.
+        \param buf the buffer to write
+        \param buf size of the buffer to write
+        \return bytes written
+    */
     virtual int _send(const void* buf, int len) = 0;
+
+    /** Helper: Parse a line from the receiving buffered pipe
+        \param pipe the receiving buffer pipe 
+        \param buf the parsed line
+        \param len the size of the parsed line
+        \return type and length if something was found, 
+                WAIT if not enough data is available
+                NOT_FOUND if nothing was found
+    */
+    static int _getLine(Pipe<char>* pipe, char* buffer, int length);
+    
+    /** Helper: Parse a match from the pipe
+        \param pipe the buffered pipe
+        \param number of bytes to parse at maximum, 
+        \param sta the starting string, NULL if none
+        \param end the terminating string, NULL if none
+        \return size of parsed match 
+    */   
+    static int _parseMatch(Pipe<char>* pipe, int len, const char* sta, const char* end);
+    
+    /** Helper: Parse a match from the pipe
+        \param pipe the buffered pipe
+        \param number of bytes to parse at maximum, 
+        \param fmt the formating string (%d any number, %c any char of last %d len)
+        \return size of parsed match
+    */   
+    static int _parseFormated(Pipe<char>* pipe, int len, const char* fmt);
+
 private:
+    // parsing callbacks for different AT commands and their parameter arguments
+    static int _cbString(int type, const char* buf, int len, char* str);
+    static int _cbInt(int type, const char* buf, int len, int* val);
+    // device
     static int _cbATI(int type, const char* buf, int len, Model* model);
-    static int _cbCIMI(int type, const char* buf, int len, char* imsi);
+    static int _cbCPIN(int type, const char* buf, int len, Sim* sim);
+    static int _cbCCID(int type, const char* buf, int len, char* ccid);
+    // network 
+    static int _cbCSQ(int type, const char* buf, int len, int* rssi);
+    static int _cbCOPS(int type, const char* buf, int len, NetStatus* status);
+    static int _cbCNUM(int type, const char* buf, int len, char* num);
+    static int _cbCGATT(int type, const char* buf, int len, int* state);
+    // sockets
+    static int _cbUPSND(int type, const char* buf, int len, int* act);
+    static int _cbUPSND(int type, const char* buf, int len, IP* ip);
     static int _cbUDNSRN(int type, const char* buf, int len, IP* ip);
     static int _cbUSOCR(int type, const char* buf, int len, int* socket);
     static int _cbUSORD(int type, const char* buf, int len, char* out);
@@ -109,24 +367,15 @@
     static int _cbUSORF(int type, const char* buf, int len, USORFparam* param);
     typedef struct { char* buf; char* num; } CMGRparam;
     static int _cbCUSD(int type, const char* buf, int len, char* buf);
-    static int _cbCPMS(int type, const char* buf, int len, int* num);
+    // sms
+    typedef struct { int* ix; int num; } CMGLparam;
+    static int _cbCMGL(int type, const char* buf, int len, CMGLparam* param);
     static int _cbCMGR(int type, const char* buf, int len, CMGRparam* param);
-    static int _cbCGSN(int type, const char* buf, int len, char* imei);
-    static int _cbGSN(int type, const char* buf, int len, char* imei);
-    static int _cbCCID(int type, const char* buf, int len, char* ccid);
-    static IP strToIp(const char* str);
-    IP _ip;
-    Model _model;
-    Sim _sim;
-    Net _net;
-    AcT _act;
-    char _num[32];
-    char _opr[32];
-    int _rssi;
-    char _imsi[32];
-    char _imei[32];
-    char _ccid[32];
-private:
+    // 
+    DevStatus   _dev; //!< collected device information
+    NetStatus   _net; //!< collected network information 
+    IP          _ip;  //!< assigned ip address
+    // management struture for sockets
     typedef enum { SOCK_FREE, SOCK_CREATED, SOCK_CONNECTED } SockState;
     typedef struct { SockState state; int pending; } SockCtrl;
     SockCtrl _sockets[16];