Add a bunch of APNs
Fork of C027_Support by
Diff: MDM.h
- 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];