Iftikhar Aziz / C027_Support

Fork of C027_Support by Umar Naeem

Files at this revision

API Documentation at this revision

Comitter:
mazgch
Date:
Thu Apr 17 20:41:30 2014 +0000
Parent:
43:a89a7a505991
Child:
45:ebc2fd8dcf21
Commit message:
adding mbed style (tcp)socket api

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/Socket.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
--- a/MDM.cpp	Fri Apr 11 20:10:28 2014 +0000
+++ b/MDM.cpp	Thu Apr 17 20:41:30 2014 +0000
@@ -36,8 +36,11 @@
  #define WHY(t) COL("37m",t)
 #endif
 
+MDMParser* MDMParser::inst;
+
 MDMParser::MDMParser(void)
 {
+    inst = this;
     memset(&_dev, 0, sizeof(_dev));
     memset(&_net, 0, sizeof(_net));
     _ip        = NOIP;
@@ -635,6 +638,7 @@
     // successfull
     _sockets[socket].state = SOCK_CREATED;
     _sockets[socket].pending = 0;
+    _sockets[socket].timeout_ms = 0; // non blocking
     return socket;
 }
 
@@ -653,6 +657,19 @@
     return true;
 }
 
+bool MDMParser::socketIsConnected(int socket)
+{
+    return (ISSOCKET(socket) && (_sockets[socket].state == SOCK_CONNECTED));
+}
+
+bool MDMParser::socketSetBlocking(int socket, unsigned int timeout_ms)
+{
+    if (!ISSOCKET(socket))
+        return false;
+    _sockets[socket].timeout_ms = timeout_ms;
+    return true;
+}
+
 bool  MDMParser::socketClose(int socket)
 {
     if (!ISSOCKET(socket) || (_sockets[socket].state != SOCK_CONNECTED))
@@ -660,6 +677,7 @@
     sendFormated("AT+USOCL=%d\r\n", socket);
     if (OK != waitFinalResp())
         return false;
+    _sockets[socket].state = SOCK_CREATED;
     return true;
 }
 
@@ -729,27 +747,33 @@
     if (!ISSOCKET(socket))
         return SOCKET_ERROR;
     memset(buf, '\0', len);
+    Timer timer;
+    timer.start();
     while (len) {
         int blk = MAX_SIZE - 64; // still need space for headers and unsolicited  commands 
-        if (_sockets[socket].state != SOCK_CONNECTED)
-            return cnt ? cnt : SOCKET_ERROR;
         if (_sockets[socket].pending < blk)
             blk = _sockets[socket].pending;
         if (len < blk) blk = len;
         if (blk) {
-             sendFormated("AT+USORD=%d,%d\r\n",socket, blk);
+            sendFormated("AT+USORD=%d,%d\r\n",socket, blk);
             if (OK != waitFinalResp(_cbUSORD, buf)) {
-                return cnt ? cnt : SOCKET_ERROR;
+                return SOCKET_ERROR;
             }
             len -= blk;
             cnt += blk;
             buf += blk;
             _sockets[socket].pending -= blk;
-        } else {
+        } else if ((_sockets[socket].state == SOCK_CONNECTED) && (
+                   (_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 {
+            len = 0; // no more data and socket closed or timed-out
         }
     }
+    timer.stop();
+    timer.reset();
     return cnt;
 }
 
@@ -774,10 +798,10 @@
     if (!ISSOCKET(socket))
         return SOCKET_ERROR;
     memset(buf, '\0', len);
+    Timer timer;
+    timer.start();
     while (len) {
         int blk = MAX_SIZE - 64; // still need space for headers and unsolicited commands 
-        if (_sockets[socket].state != SOCK_CONNECTED)
-            return cnt ? cnt : SOCKET_ERROR;
         if (_sockets[socket].pending < blk)
             blk = _sockets[socket].pending;
         if (len < blk) blk = len;
@@ -786,7 +810,7 @@
             USORFparam param;
             param.buf = buf;
             if (OK != waitFinalResp(_cbUSORF, &param)) {
-                return cnt ? cnt : SOCKET_ERROR;
+                return SOCKET_ERROR;
             }
             *ip = param.ip;
             //*port = param.port;
@@ -794,11 +818,17 @@
             cnt += blk;
             buf += blk;
             _sockets[socket].pending -= blk;
-        } else {
+        } else if ((_sockets[socket].state == SOCK_CONNECTED) && (
+                   (_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 {
+            len = 0; // no more data and socket closed or timed-out
         }
     }
+    timer.stop();
+    timer.reset();
     return cnt;
 }
 
--- a/MDM.h	Fri Apr 11 20:10:28 2014 +0000
+++ b/MDM.h	Thu Apr 17 20:41:30 2014 +0000
@@ -22,6 +22,8 @@
 public:
     //! Constructor 
     MDMParser();
+    //! get static instance
+    static MDMParser* getInstance() { return inst; };
     
     // ----------------------------------------------------------------
     // Types 
@@ -142,6 +144,19 @@
     */
     bool socketConnect(int socket, const char* host, int port);
         
+    /** make a socket connection
+        \param socket the socket handle
+        \return true if connected, false otherwise
+    */
+    bool socketIsConnected(int socket);
+     
+    /** Get the number of bytes pending for reading for this socket
+        \param socket the socket handle
+        \param timeout_ms -1 blocking, else non blocking timeout in ms
+        \return 0 if successful or SOCKET_ERROR on failure 
+    */
+    bool socketSetBlocking(int socket, unsigned int timeout_ms);
+    
     /** Write socket data 
         \param socket the socket handle
         \param buf the buffer to write
@@ -398,8 +413,9 @@
     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;
+    typedef struct { SockState state; int pending; unsigned int timeout_ms; } SockCtrl;
     SockCtrl _sockets[16];
+    static MDMParser* inst;
 };
 
 // -----------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket/Socket.h	Thu Apr 17 20:41:30 2014 +0000
@@ -0,0 +1,41 @@
+#ifndef SOCKET_H_
+#define SOCKET_H_
+
+#include "MDM.h"
+
+/** Socket file descriptor and select wrapper
+  */
+class Socket {
+public:
+    Socket() {
+        _socket = -1;
+        _mdm = MDMParser::getInstance();
+        if (_mdm == NULL) {
+            error("Socket constructor error: no modem instance available!\r\n");
+        }       
+    }
+    
+    void set_blocking(bool blocking, unsigned int timeout=1) { 
+        _mdm->socketSetBlocking(_socket, blocking ? (unsigned int) -1 /* blocking */ : timeout); 
+    }
+    
+    int close() {
+        bool ret = false;
+        if (_socket >= 0)
+        {
+            ret = _mdm->socketClose(_socket);
+            _mdm->socketFree(_socket);
+            _socket = -1;
+        }
+        return ret ? 0 : -1;
+    }
+    
+    ~Socket() { close(); }
+    
+protected:
+    int _socket;
+    MDMParser* _mdm;
+};
+
+
+#endif /* SOCKET_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Socket/TCPSocketConnection.h	Thu Apr 17 20:41:30 2014 +0000
@@ -0,0 +1,71 @@
+#ifndef TCPSOCKET_H
+#define TCPSOCKET_H
+
+#include "Socket.h"
+
+/** TCP socket connection
+ */
+class TCPSocketConnection: public Socket
+{
+    friend class TCPSocketServer;
+
+public:
+    /** TCP socket connection
+    */
+    TCPSocketConnection() {}
+
+    /** Connects this TCP socket to the server
+    \param host The host to connect to. It can either be an IP Address or a hostname that will be resolved with DNS.
+    \param port The host's port to connect to.
+    \return 0 on success, -1 on failure.
+    */
+    int connect(const char* host, const int port)
+    {
+        if (_socket < 0) {
+            _socket = _mdm->socketSocket(MDMParser::IPPROTO_TCP);
+            if (_socket < 0) {
+                return -1;
+            }
+        }
+    
+        if (!_mdm->socketConnect(_socket, host, port)) {
+            return false;
+        }
+        return true;
+    }
+    /** Check if the socket is connected
+    \return true if connected, false otherwise.
+    */
+    bool is_connected(void)                 { return _mdm->socketIsConnected(_socket); }
+
+    /** Send data to the remote host.
+    \param data The buffer to send to the host.
+    \param length The length of the buffer to send.
+    \return the number of written bytes on success (>=0) or -1 on failure
+     */
+    int send(char* data, int length)        { return _mdm->socketSend(_socket, data, length); }
+
+    /** Send all the data to the remote host.
+    \param data The buffer to send to the host.
+    \param length The length of the buffer to send.
+    \return the number of written bytes on success (>=0) or -1 on failure
+    */
+    int send_all(char* data, int length)    { return send(data,length); }
+
+    /** Receive data from the remote host.
+    \param data The buffer in which to store the data received from the host.
+    \param length The maximum length of the buffer.
+    \return the number of received bytes on success (>=0) or -1 on failure
+     */
+    int receive(char* data, int length)     { return _mdm->socketRecv(_socket, data, length); }
+
+    /** Receive all the data from the remote host.
+    \param data The buffer in which to store the data received from the host.
+    \param length The maximum length of the buffer.
+    \return the number of received bytes on success (>=0) or -1 on failure
+    */
+    int receive_all(char* data, int length) { return receive(data,length); }
+    
+};
+
+#endif