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.

Dependents:   HTTPClient_Cellular_HelloWorld Cellular_HelloMQTT MbedSmartRestMain Car_Bon_car_module ... more

This library is intended to be used with u-blox products such as the C027 or a shield with u-blox cellular and GPS modules like the cellular and positioning shield from Embedded Artist.

For 2G/GSM and 3G/UMTS you need to:

  • have a SIM card and know its PIN number
  • need to know you network operators APN setting These setting should be passed to the connect or init and join functions. You can also extend the APN database in MDMAPN.h.

For CDMA products you need to make sure that you have provisioned and activated the modem with either Sprint or Verizon.

Files at this revision

API Documentation at this revision

Comitter:
mazgch
Date:
Tue May 13 12:31:33 2014 +0000
Parent:
60:1f65abb842be
Child:
64:ba4ea655a451
Commit message:
some progress on UDP

Changed in this revision

MDM.cpp Show annotated file Show diff for this revision Revisions of this file
MDM.h Show annotated file Show diff for this revision Revisions of this file
Socket/Endpoint.h Show annotated file Show diff for this revision Revisions of this file
Socket/TCPSocketConnection.h Show annotated file Show diff for this revision Revisions of this file
Socket/UDPSocket.h Show annotated file Show diff for this revision Revisions of this file
--- a/MDM.cpp	Tue May 13 07:13:27 2014 +0000
+++ b/MDM.cpp	Tue May 13 12:31:33 2014 +0000
@@ -3,8 +3,8 @@
 #include <string.h>
 #include "MDM.h"
 
-#define TRACE           (1/*1=off,0=trace*/)?:printf
-//#define DEBUG         // enable this for AT command debugging
+#define TRACE           (0/*1=off,0=trace*/)?:printf
+#define DEBUG         // enable this for AT command debugging
 #define PROFILE         "0"   // this is the psd profile used
 #define MAX_SIZE        256  // max expected messages
 // some helper 
@@ -121,12 +121,7 @@
                 // Socket Specific Command ---------------------------------
                 // +UUSORD: <socket>,<length>
                 } else if ((sscanf(cmd, "UUSORD: %d,%d", &a, &b) == 2) && 
-                    ISSOCKET(a) && (_sockets[a].state == SOCK_CONNECTED)) {
-                    TRACE("Socket %d: %d bytes pending\r\n", a, b);
-                    _sockets[a].pending = b;
-                // +UUSORF: <socket>,<length>
-                } else if ((sscanf(cmd, "UUSORF: %d,%d", &a, &b) == 2) && 
-                    ISSOCKET(a) && (_sockets[a].state == SOCK_CONNECTED)) {
+                    ISSOCKET(a) /*&& (_sockets[a].state == SOCK_CONNECTED)*/) {
                     TRACE("Socket %d: %d bytes pending\r\n", a, b);
                     _sockets[a].pending = b;
                 // +UUSOCL: <socket>
@@ -686,18 +681,18 @@
     return WAIT;
 }
 
-int MDMParser::socketSocket(IpProtocol ipproto)
+int MDMParser::socketSocket(IpProtocol ipproto, int port)
 {
     TRACE("socketSocket(%d)\r\n", ipproto);
-    const char* cmd;
     if(ipproto == IPPROTO_TCP) {
-        cmd = "AT+USOCR=6\r\n";
-    } else if(ipproto == IPPROTO_UDP) {
-        cmd = "AT+USOCR=17\r\n";
+        sendFormated("AT+USOCR=6\r\n");
+    } else if ((ipproto == IPPROTO_UDP) && (port == -1)){
+        sendFormated("AT+USOCR=17\r\n");
+    } else if (ipproto == IPPROTO_UDP){
+        sendFormated("AT+USOCR=17,%d\r\n", port);
     } else { // other types not supported
         return SOCKET_ERROR;
     }
-    sendFormated(cmd);
     int socket = -1;
     if (RESP_OK != waitFinalResp(_cbUSOCR, &socket))
         return SOCKET_ERROR;
@@ -785,12 +780,12 @@
 {
     TRACE("socketSendTo(%d," IPSTR "%d,,%d)\r\n", socket, IPNUM(ip),port,len);
     if(len > 0) {
-        sendFormated("AT+USOWR=%d,\"" IPSTR "\",%d,%d\r\n",socket,IPNUM(ip),port,len);
+        sendFormated("AT+USOST=%d,\"" IPSTR "\",%d,%d\r\n",socket,IPNUM(ip),port,len);
         if (RESP_PROMPT != waitFinalResp())
             return SOCKET_ERROR;
         wait_ms(50);
         send(buf, len);
-        if (RESP_OK != waitFinalResp()) 
+        if (RESP_OK != waitFinalResp())
             return SOCKET_ERROR;
     }
     return len;
@@ -873,10 +868,10 @@
     return WAIT;
 }
 
-int MDMParser::socketRecvFrom(int socket, char* buf, int len, IP* ip)
+int MDMParser::socketRecvFrom(int socket, IP* ip, int* port, char* buf, int len)
 {
     int cnt = 0;
-    TRACE("socketRecvFrom(%d,,%d" IPSTR ")\r\n", socket, len, IPNUM(*ip));
+    TRACE("socketRecvFrom(%d,,%d)\r\n", socket, len);
     if (!ISSOCKET(socket))
         return SOCKET_ERROR;
     memset(buf, '\0', len);
@@ -895,14 +890,13 @@
                 return SOCKET_ERROR;
             }
             *ip = param.ip;
-            //*port = param.port;
+            *port = param.port;
             len -= blk;
             cnt += blk;
             buf += blk;
             _sockets[socket].pending -= blk;
-        } else if ((_sockets[socket].state == SOCK_CONNECTED) && (
-                   (_sockets[socket].timeout_ms == (unsigned int)-1 /* blocking */) || 
-                   (timer.read_ms() < _sockets[socket].timeout_ms))){
+        } else if ((_sockets[socket].timeout_ms == (unsigned int)-1 /* blocking */) || 
+                   (timer.read_ms() < _sockets[socket].timeout_ms)) {
             // allow to receive unsolicited commands 
             waitFinalResp(NULL, NULL, 10);
         } else {
--- a/MDM.h	Tue May 13 07:13:27 2014 +0000
+++ b/MDM.h	Tue May 13 12:31:33 2014 +0000
@@ -146,11 +146,12 @@
     //! Socket error return codes
     #define SOCKET_ERROR -1
     
-    /** Create a socket for a ip protocol
+    /** Create a socket for a ip protocol (and optionaly bind)
         \param ipproto the protocol (UDP or TCP) 
+        \param port in case of UDP, this optional port where it is bind
         \return the socket handle if successful or SOCKET_ERROR on failure 
     */
-    int socketSocket(IpProtocol ipproto);
+    int socketSocket(IpProtocol ipproto, int port = -1);
     
     /** make a socket connection
         \param socket the socket handle
@@ -207,12 +208,13 @@
     
     /** Read from this socket
         \param socket the socket handle
+        \param ip the ip of host where the data originates from
+        \param port the port where the data originates from
         \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);
+    int socketRecvFrom(int socket, IP* ip, int* port, char* buf, int len);
     
     /** Close a connectied socket (that was connected with #socketConnect)
         \param socket the socket handle
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket/Endpoint.h	Tue May 13 12:31:33 2014 +0000
@@ -0,0 +1,65 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef ENDPOINT_H
+#define ENDPOINT_H
+
+#include "MDM.h"
+
+class UDPSocket;
+
+class Endpoint {
+    friend class UDPSocket;
+public:
+    Endpoint(void)  { 
+        _ip[0] = '\0'; 
+        _port = 0; 
+        _mdm = NULL; 
+    }
+    
+    void reset_address(void) { 
+        _ip[0] = '\0'; 
+        _port = 0; 
+    }
+    
+    int  set_address(const char* host, const int port) {
+        _ip[0] = '\0';
+        _port = 0;
+        if (_mdm == NULL)
+            _mdm = MDMParser::getInstance();
+        if (_mdm == NULL)
+            return -1;
+        // resove the host name (eventually does a dns lookup)
+        MDMParser::IP ip = _mdm->gethostbyname(host);
+        if (ip == NOIP)
+            return -1;
+        sprintf(_ip, IPSTR, IPNUM(ip));
+        _port = port;
+        return 0;
+    }
+    
+    char* get_address(void)     {   return _ip; }
+    
+    int get_port(void)          {   return _port; }
+    
+protected:
+    MDMParser* _mdm;
+    char _ip[17];
+    int _port;
+};
+
+#endif
--- a/Socket/TCPSocketConnection.h	Tue May 13 07:13:27 2014 +0000
+++ b/Socket/TCPSocketConnection.h	Tue May 13 12:31:33 2014 +0000
@@ -21,7 +21,8 @@
     */
     int connect(const char* host, const int port)
     {
-        _mdm = MDMParser::getInstance();
+        if (_mdm == NULL)
+            _mdm = MDMParser::getInstance();
         if (_mdm == NULL)
             return -1;
             
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket/UDPSocket.h	Tue May 13 12:31:33 2014 +0000
@@ -0,0 +1,79 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef UDPSOCKET_H
+#define UDPSOCKET_H
+
+#include "Socket/Socket.h"
+#include "Socket/Endpoint.h"
+
+/**
+UDP Socket
+*/
+class UDPSocket : public Socket {
+
+public:
+    int init(void) 
+    {
+        if (_mdm == NULL)
+            _mdm = MDMParser::getInstance();
+        if (_mdm == NULL)
+            return -1;
+        return 0;
+    }
+    
+    int bind(int port) {
+        if (_socket < 0) {
+            _socket = _mdm->socketSocket(MDMParser::IPPROTO_UDP, port);
+            if (_socket < 0) {
+                return -1;
+            }
+        }
+        _mdm->socketSetBlocking(_socket, _timeout); 
+        return 0;
+    }
+    
+    int join_multicast_group(const char* address)   { return -1; }
+    
+    int set_broadcasting(bool broadcast=true)       { return -1; }
+    
+    int sendTo(Endpoint &remote, char *packet, int length)
+    {
+        char* str = remote.get_address();
+        int port = remote.get_port();
+        MDMParser::IP ip = _mdm->gethostbyname(str);
+        if (ip == NOIP)
+            return -1;
+        return _mdm->socketSendTo(_socket, ip, port, packet, length); 
+    }
+    
+    int receiveFrom(Endpoint &remote, char *buffer, int length)
+    { 
+        MDMParser::IP ip;
+        int port;
+        int ret = _mdm->socketRecvFrom(_socket, &ip, &port, buffer, length); 
+        if (ret >= 0) {
+            char str[17];
+            sprintf(str, IPSTR, IPNUM(ip));
+            remote.set_address(str, port);
+        }
+        return ret;
+    }
+};
+
+#endif