Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: GPS_6Axis_DataLogger_SD_UDP
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];
