Official reference client implementation for Cumulocity SmartREST on u-blox C027.

Dependencies:   C027_Support C12832 LM75B MMA7660 MbedSmartRest mbed-rtos mbed

Fork of MbedSmartRestMain by Vincent Wochnik

Files at this revision

API Documentation at this revision

Comitter:
xinlei
Date:
Mon May 11 18:10:44 2015 +0000
Parent:
105:fd3571349e5d
Child:
107:fc5f25f0e0d5
Commit message:
SmartRestSSLSocket and various bug-fixes for rc3

Changed in this revision

CyaSSL.lib Show annotated file Show diff for this revision Revisions of this file
MbedAgent.cpp Show annotated file Show diff for this revision Revisions of this file
MbedAgent.h Show annotated file Show diff for this revision Revisions of this file
config/ConfigParser.cpp Show annotated file Show diff for this revision Revisions of this file
config/ConfigSync.cpp Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
operation/ControlParser.cpp Show annotated file Show diff for this revision Revisions of this file
operation/PollThread.cpp Show annotated file Show diff for this revision Revisions of this file
operation/PollThread.h Show annotated file Show diff for this revision Revisions of this file
operation/ReportThread.cpp Show annotated file Show diff for this revision Revisions of this file
operation/ReportThread.h Show annotated file Show diff for this revision Revisions of this file
util/SmartRestConf.cpp Show annotated file Show diff for this revision Revisions of this file
util/SmartRestConf.h Show annotated file Show diff for this revision Revisions of this file
util/SmartRestSSLSocket.cpp Show annotated file Show diff for this revision Revisions of this file
util/SmartRestSSLSocket.h Show annotated file Show diff for this revision Revisions of this file
util/SmartRestSocket.cpp Show annotated file Show diff for this revision Revisions of this file
util/SmartRestSocket.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CyaSSL.lib	Mon May 11 18:10:44 2015 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/wolfSSL/code/CyaSSL/#1d1b8be1715f
--- a/MbedAgent.cpp	Fri May 08 14:50:43 2015 +0000
+++ b/MbedAgent.cpp	Mon May 11 18:10:44 2015 +0000
@@ -74,8 +74,10 @@
 int MbedAgent::run()
 {
     // device bootstrapping process
-    if (!_bootstrap.setUpCredentials())
+    if (!_bootstrap.setUpCredentials()) {
+        LCDDisplay::inst().setLines("Bootstrap error");
         return -1;
+    }
     setAuth(_bootstrap.username(), _bootstrap.password());
     aInfo("Set auth: %s:%s (%s)\n", srUsername, srPassword, srAuthStr);
 
@@ -83,6 +85,7 @@
 
     LCDDisplay::inst().setLines("Connect to Cloud", srHost);
     if (!_integration.integrate()) {
+        LCDDisplay::inst().setLines("Integrate failure");
         return -2;
     }
     setX_ID(_client.getIdentifier());
@@ -102,8 +105,8 @@
     wdt.kick(60.0);    // set a 60.0 seconds watchdog
     while (true) {
         for (size_t i = 0; i < N; ++i) {
-//            if (reporters[i] == &conf) {
-            size_t l = reporters[i]->read(buf2, SMARRESTBODY_SIZE, status, DISPLAY_LEN);
+//            if (reporters[i] == &acc) {
+            size_t l = reporters[i]->read(buf2, sizeof(buf2), status, DISPLAY_LEN);
             bool b = l;
             if (b) { // Refresh LCD display needed
                 LCDDisplay::inst().setThirdLine(status);
@@ -112,10 +115,10 @@
             }
             lcdThirdLineBlank = !b;
             if (b) {
-                int l2 = snprintf(buf, SMARTREST_SIZE, fmtSmartRest, "/s", l, buf2);
+                int l2 = snprintf(buf, sizeof(buf), fmtSmartRest, "/s", l, buf2);
                 l2 = sock.sendOnly(buf, l2);
                 if (l2 < 0)
-                    aError(status);
+                    aWarning("%s\n", status);
             }
 //            }
         }
--- a/MbedAgent.h	Fri May 08 14:50:43 2015 +0000
+++ b/MbedAgent.h	Mon May 11 18:10:44 2015 +0000
@@ -44,7 +44,7 @@
     Acceleration acc;
     ConfigSync conf;
     char buf[SMARTREST_SIZE];
-    char buf2[SMARRESTBODY_SIZE];
+    char buf2[SMARTREST_BODY_SIZE];
     char status[DISPLAY_LEN];
     AbstractReporter *reporters[N];
     SmartRestSocket sock;
--- a/config/ConfigParser.cpp	Fri May 08 14:50:43 2015 +0000
+++ b/config/ConfigParser.cpp	Mon May 11 18:10:44 2015 +0000
@@ -40,16 +40,11 @@
 void ConfigParser::parseValue(Token& tok)
 {
         if (tok.type != Token::NONE) {
-                if (strncmp(key, "interval", MAX_KEY_LEN) == 0 &&
-                    tok.type != Token::INT) {
-                        parseError(tok);
-                } else {
-                        memset(value, 0, MAX_VALUE_LEN);
-                        size_t num = tok.len<MAX_VALUE_LEN ? tok.len : MAX_VALUE_LEN;
-                        strncpy(value, tok.p, num);
-                        dict.set(key, value);
-                        ptrPF = &ConfigParser::parseSemiColon;
-                }
+                memset(value, 0, MAX_VALUE_LEN);
+                size_t num = tok.len<MAX_VALUE_LEN ? tok.len : MAX_VALUE_LEN;
+                strncpy(value, tok.p, num);
+                dict.set(key, value);
+                ptrPF = &ConfigParser::parseSemiColon;
         } else {
                 parseError(tok);
         }
--- a/config/ConfigSync.cpp	Fri May 08 14:50:43 2015 +0000
+++ b/config/ConfigSync.cpp	Mon May 11 18:10:44 2015 +0000
@@ -10,12 +10,21 @@
 
 bool validateConfiguration(Dict& d)
 {
-        return d.get(INTERVAL_KEY);
+        const Dict::Item *p = d.get(INTERVAL_KEY);
+        if (p) {
+                int v = 0, n = 0;
+                sscanf(p->value, "%d%n", &v, &n);
+                if (v > 0 && n == strlen(p->value))
+                        return true;
+                else
+                        return false;
+        } else
+                return false;
 }
 
 size_t ConfigSync::read(char *buf, size_t maxLen, char *status, size_t num)
 {
-        static const char *fmt = "130,%ld,%s,%.*s\r\n";
+        static const char *fmt = "130,%ld,\"%s\",%.*s\r\n";
         int l = 0;
         if (changed) {
                 changed = false;
--- a/main.cpp	Fri May 08 14:50:43 2015 +0000
+++ b/main.cpp	Mon May 11 18:10:44 2015 +0000
@@ -4,6 +4,7 @@
 #include "rtos.h"
 #include "MDM.h"
 #include "GPS.h"
+#include "cyassl/ssl.h"
 
 #include "DeviceInfo.h"
 #include "Storage.h"
@@ -23,10 +24,11 @@
 //#define SIM_APN ""
 //#define SIM_USER ""
 //#define SIM_PASS ""
-//MDMRtos<MDMSerial> *pMdm;
-MDMSerial* pMdm;
 
-unsigned short getMNCLen(const char *imsi)
+MDMSerial* pMdm = NULL;
+//CYASSL_CTX *pCtx = NULL;
+
+static unsigned short getMNCLen(const char *imsi)
 {
     if (strncmp(imsi, "310", 3) != 0) // Non American ISMI
         return 2;
@@ -34,22 +36,53 @@
         return 3;
 }
 
-void enableDebug()
+static void enableDebug()
 {
         setLevel(A_DEBUG);
         if (pMdm)
             pMdm->setDebug(3);
 }
 
-void disableDebug()
+static void disableDebug()
 {
        setLevel(A_NONE);
        if (pMdm)
            pMdm->setDebug(-1);
 }
 
+static void shutdown()
+{
+//    CyaSSL_CTX_free(pCtx);
+//    CyaSSL_Cleanup();
+    pMdm->disconnect();
+    pMdm->powerOff();
+}
+
+//static int send(CYASSL *ssl, char *buf, int size, void* ctx)
+//{
+//        int sockfd = *(int*)ctx;
+//        int ret = pMdm->socketSend(sockfd, buf, size);
+//        printf("[send](%d, %p): %d/%d\n", sockfd, ssl, ret, size);
+//        if (ret >= 0)
+//                return ret;
+//        else
+//                return CYASSL_CBIO_ERR_GENERAL;
+//}
+//
+//static int recv(CYASSL *ssl, char *buf, int maxSize, void* ctx)
+//{
+//        int sockfd = *(int*)ctx;
+//        int ret = pMdm->socketRecv(sockfd, buf, maxSize);
+//        printf("[recv](%d, %p): %d/%d\n", sockfd, ssl, ret, maxSize);
+//        if (ret >= 0)
+//                return ret;
+//        else
+//                return CYASSL_CBIO_ERR_GENERAL;
+//}
+
 int main()
 {
+    LCDDisplay::inst().setLines("Mbed Agent V2.1rc3", srHost);
     set_time(1256729737);
     MDMRtos<MDMSerial> mdm;
     pMdm = &mdm;
@@ -58,13 +91,23 @@
     joystickUp.rise(&enableDebug);
     joystickDown.rise(&disableDebug);
 
+//    CyaSSL_Init();
+//    pCtx = CyaSSL_CTX_new(CyaTLSv1_2_client_method());
+//    CyaSSL_Debugging_ON();
+//    if (pCtx == NULL) {
+//        shutdown();
+//        return 1;
+//    }
+//    CyaSSL_CTX_set_verify(pCtx, SSL_VERIFY_NONE, 0);
+//    CyaSSL_CTX_set_cipher_list(pCtx, "DHE-RSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA");
+//    CyaSSL_SetIORecv(pCtx, recv);
+//    CyaSSL_SetIOSend(pCtx, send);
+
     MDMParser::DevStatus devStatus;
-    LCDDisplay::inst().setLines("Mbed Agent V2.1rc3", srHost);
     if (!mdm.init(SIM_PIN, &devStatus)) {
         LCDDisplay::inst().setLines("Modem Init Failure", "No SIM card found", "Or SIM has PIN");
-        mdm.disconnect();
-        mdm.powerOff();
-        return 1;
+        shutdown();
+        return 2;
     }
 
     DigitalIn fireButton(D4);
@@ -75,16 +118,14 @@
             LCDDisplay::inst().setLines("Reset Failure");
         }
         Thread::wait(2000);
-        mdm.disconnect();
-        mdm.powerOff();
+        shutdown();
         return 0;
     }
     aInfo("Main Thread: %p\r\n", Thread::gettid());    
     LCDDisplay::inst().setLines("Register Network...", "IMEI", devStatus.imei);
     if (!mdm.registerNet()) {
         LCDDisplay::inst().setLines("No Network Coverage");
-        mdm.disconnect();
-        mdm.powerOff();
+        shutdown();
         return 3;
     }
 
@@ -100,8 +141,7 @@
             snprintf(s, sizeof(s), "%.*s-%.*s", 3, p, getMNCLen(p), p+3);
         }
         LCDDisplay::inst().setLines("Wrong APN Settting", "MCC-MNC:", s);
-        mdm.disconnect();
-        mdm.powerOff();
+        shutdown();
         return 4;
     }
 
@@ -111,8 +151,7 @@
 
         LCDDisplay::inst().setLines("Agent Init");
         if (!agent.init()) {
-            mdm.disconnect();
-            mdm.powerOff();
+            shutdown();
             return 5;
         }
         LCDDisplay::inst().setLines("Agent Run");
@@ -129,14 +168,9 @@
                 break;
             }
         }
-
-        switch (ret) {
-            case -1: LCDDisplay::inst().setLines("Bootstrap error"); break;
-            case -2: LCDDisplay::inst().setLines("Integrate failure"); break;
-            default: agent.loop();
-        }
-        mdm.disconnect();
-        mdm.powerOff();
+        if (ret == 0)
+            agent.loop();
+        shutdown();
         return ret;
     }
 }
--- a/operation/ControlParser.cpp	Fri May 08 14:50:43 2015 +0000
+++ b/operation/ControlParser.cpp	Mon May 11 18:10:44 2015 +0000
@@ -103,7 +103,7 @@
                 size_t num = tok.len < 30 ? tok.len : 30;
                 if (tok.type == Token::STRING)
                         strncpyEscape(line, tok.p, num);
-                else
+                else if (tok.type != Token::NONE)
                         strncpy(line, tok.p, num);
                 LCDDisplay::inst().setFirstLine(line);
         } else if (opType == 222) {
--- a/operation/PollThread.cpp	Fri May 08 14:50:43 2015 +0000
+++ b/operation/PollThread.cpp	Mon May 11 18:10:44 2015 +0000
@@ -6,10 +6,10 @@
 
 bool PollThread::handshake()
 {
-        int l = snprintf(buf2, SMARRESTBODY_SIZE, "%s", "80\r\n");
-        l = snprintf(buf, SMARTREST_SIZE, fmtSmartRest, uri, l, buf2);
-        sock.set_blocking(false);
-        l = sock.sendAndReceive(buf, l, SMARTREST_SIZE);
+        int l = snprintf(buf2, sizeof(buf2), "%s", "80\r\n");
+        l = snprintf(buf, sizeof(buf), fmtSmartRest, uri, l, buf2);
+        sock.setBlocking(3000);
+        l = sock.sendAndReceive(buf, l, sizeof(buf));
         if (l < 0)
                 return false;
         size_t i = 0;
@@ -22,19 +22,19 @@
 
 bool PollThread::subscribe()
 {
-        int l = snprintf(buf2, SMARRESTBODY_SIZE, "81,%s,%s\r\n", bayeuxId, chn);
-        l = snprintf(buf, SMARTREST_SIZE, fmtSmartRest, uri, l, buf2);
-        sock.set_blocking(false);
+        int l = snprintf(buf2, sizeof(buf2), "81,%s,%s\r\n", bayeuxId, chn);
+        l = snprintf(buf, sizeof(buf), fmtSmartRest, uri, l, buf2);
+        sock.setBlocking(3000);
         l = sock.sendOnly(buf, l);
         return l>=0;
 }
 
 bool PollThread::connect()
 {
-        int l = snprintf(buf2, SMARRESTBODY_SIZE, "83,%s\r\n", bayeuxId);
-        l = snprintf(buf, SMARTREST_SIZE, fmtSmartRest, uri, l, buf2);
-        sock.set_blocking(true);
-        l = sock.sendAndReceive(buf, l, SMARTREST_SIZE);
+        int l = snprintf(buf2, sizeof(buf2), "83,%s\r\n", bayeuxId);
+        l = snprintf(buf, sizeof(buf), fmtSmartRest, uri, l, buf2);
+        sock.setBlocking(-1);
+        l = sock.sendAndReceive(buf, l, sizeof(buf));
         return l>=0;
 }
 
--- a/operation/PollThread.h	Fri May 08 14:50:43 2015 +0000
+++ b/operation/PollThread.h	Mon May 11 18:10:44 2015 +0000
@@ -13,7 +13,6 @@
                 sock(), parser(pool, configSync),
                 thread(PollThread::threadWrapper, this) {
                 strncpy(uri, "/devicecontrol/notifications", sizeof(uri));
-                sock.set_blocking(true);
         }
         virtual ~PollThread() {}
         bool handshake();
@@ -27,7 +26,7 @@
         char uri[30];
         char bayeuxId[50];
         char buf[SMARTREST_SIZE];
-        char buf2[SMARRESTBODY_SIZE];
+        char buf2[SMARTREST_BODY_SIZE];
         SmartRestSocket sock;
         ControlParser parser;
         Thread thread;
--- a/operation/ReportThread.cpp	Fri May 08 14:50:43 2015 +0000
+++ b/operation/ReportThread.cpp	Mon May 11 18:10:44 2015 +0000
@@ -1,11 +1,11 @@
 #include "ReportThread.h"
 #include "logging.h"
 
-const char *fmt2 = "111,%ld,%s\r\n";
+static const char *fmt2 = "111,%ld,%s\r\n";
 
 void ReportThread::threadFunc()
 {
-    sock.set_blocking(false);
+    sock.setBlocking(3000);
     while (true) {
         osEvent e = ipool.get();
         if (e.status == osEventMail) {
@@ -21,7 +21,7 @@
                     id = op->identifier;
                     OperationState state = op->state;
                     ipool.free(op);
-                    l += snprintf(buf2+l, SMARRESTBODY_SIZE-l, fmt2, id, strOperationState(state));
+                    l += snprintf(buf2+l, sizeof(buf2)-l, fmt2, id, strOperationState(state));
                 } else {
                     break;
                 }
--- a/operation/ReportThread.h	Fri May 08 14:50:43 2015 +0000
+++ b/operation/ReportThread.h	Mon May 11 18:10:44 2015 +0000
@@ -18,7 +18,7 @@
         char uri[4];
         OperationPool& ipool;
         char buf[SMARTREST_SIZE];
-        char buf2[SMARRESTBODY_SIZE];
+        char buf2[SMARTREST_BODY_SIZE];
         SmartRestSocket sock;
         Thread thread;
 };
--- a/util/SmartRestConf.cpp	Fri May 08 14:50:43 2015 +0000
+++ b/util/SmartRestConf.cpp	Mon May 11 18:10:44 2015 +0000
@@ -9,11 +9,10 @@
 const char *srX_ID = "com_cumulocity_MbedAgent_1.5.2";
 const char *srHost = "developer.cumulocity.com";
 //const char *srHost = "management.m2m-devicecloud.com";
-const int srPort = 80;
 long deviceID = 0;
 char fmtSmartRest[200] = {0};
 
-void setAuthStr(const char* p1, const char* p2)
+static void setAuthStr(const char* p1, const char* p2)
 {
         memset(srAuthStr, 0, sizeof(srAuthStr));
         size_t ul = strlen(p1);
@@ -38,17 +37,17 @@
         }
 }
 
-void setUsername(const char* username)
+static void setUsername(const char* username)
 {
         srUsername = username;
 }
 
-void setPassword(const char* password)
+static void setPassword(const char* password)
 {
         srPassword = password;
 }
 
-void setSmartRestFmt()
+static void setSmartRestFmt()
 {
         const char fmt[] = "POST %%s HTTP/1.0\r\nHost: %s\r\nAuthorization: Basic %s\r\nX-Id: %s\r\nContent-Length: %%d\r\n\r\n%%s";
         snprintf(fmtSmartRest, sizeof(fmtSmartRest), fmt, srHost, srAuthStr, srX_ID);
--- a/util/SmartRestConf.h	Fri May 08 14:50:43 2015 +0000
+++ b/util/SmartRestConf.h	Mon May 11 18:10:44 2015 +0000
@@ -1,16 +1,19 @@
 #ifndef SMARTRESTCONF_H
 #define SMARTRESTCONF_H
 #define SMARTREST_SIZE 600
-#define SMARRESTBODY_SIZE 300
+#define SMARTREST_BODY_SIZE 350
+#define SMARTREST_SSL_SIZE 6000
+#define SMARTREST_SSL_BODY_SIZE 5000
 
 extern const char *srUsername;
 extern const char *srPassword;
 extern char srAuthStr[];
 extern const char *srX_ID;
 extern const char *srHost;
-extern const int srPort;
 extern long deviceID;
 extern char fmtSmartRest[];
+const int srPort = 80;
+const int srSSLPort = 443;
 
 void setDeviceID(long id);
 void setAuth(const char* username, const char* password);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/SmartRestSSLSocket.cpp	Mon May 11 18:10:44 2015 +0000
@@ -0,0 +1,95 @@
+#include <string.h>
+#include "MDM.h"
+#include "SmartRestSSLSocket.h"
+#include "SmartRestConf.h"
+#include "logging.h"
+
+char SmartRestSSLSocket::cachedIP[16] = {0};
+
+int SmartRestSSLSocket::connect()
+{
+        sockfd = pMdm->socketSocket(MDMParser::IPPROTO_TCP);
+        if (sockfd < 0)
+                return -1;
+        bool n = false;
+        ipLock.lock();
+        for (size_t i = 0; i < 3; ++i) {
+                if (cachedIP[0] == 0) {
+                        MDMParser::IP ip = pMdm->gethostbyname(srHost);
+                        if (ip == NOIP) continue;
+                        const unsigned char *c = (const unsigned char*)&ip;
+                        snprintf(cachedIP, sizeof(cachedIP), "%u.%u.%u.%u",
+                                 c[3], c[2], c[1], c[0]);
+                }
+                n = pMdm->socketConnect(sockfd, cachedIP, srSSLPort);
+                if (n) {
+                        pMdm->socketSetBlocking(sockfd, timeout);
+                        CyaSSL_set_fd(ssl, sockfd);
+                        break;
+                } else {
+                        cachedIP[0] = 0;
+                }
+        }
+        ipLock.unlock();
+        return n ? 0 : -1;
+}
+
+int SmartRestSSLSocket::close()
+{
+        if (ssl)
+                CyaSSL_shutdown(ssl);
+        bool ret = true;
+        if (sockfd >= 0)
+                pMdm->socketFree(sockfd);
+//                ret = pMdm->socketClose(sockfd);
+        sockfd = -1;
+        return ret ? 0 : -1;
+}
+
+int SmartRestSSLSocket::sendOnly(char *buf, int size)
+{
+        int l = connect();
+        if (l < 0) {
+                aError("%s\n", "SO: connect");
+                return -3;
+        }
+        l = CyaSSL_write(ssl, buf, size);
+        close();
+        if (l < 0) {
+                char errorString[80];
+                int err = CyaSSL_get_error(ssl, 0);
+                CyaSSL_ERR_error_string(err, errorString);
+                aError("SO: %s\n", errorString);
+                return -2;
+        } else {
+                return l;
+        }
+}
+
+int SmartRestSSLSocket::sendAndReceive(char *buf, int size, int maxSize)
+{
+        int l = connect();
+        if (l < 0)
+                return -3;
+        l = CyaSSL_write(ssl, buf, size);
+        if (l < 0) {
+                char errorString[80];
+                int err = CyaSSL_get_error(ssl, 0);
+                CyaSSL_ERR_error_string(err, errorString);
+                aError("S: %s\n", errorString);
+                close();
+                return -2;
+        } else {
+                l = CyaSSL_read(ssl, buf, maxSize);
+                if (l >= 0)
+                        buf[l] = 0;
+                else {
+                        char errorString[80];
+                        int err = CyaSSL_get_error(ssl, 0);
+                        CyaSSL_ERR_error_string(err, errorString);
+                        printf("R: %s\n", errorString);
+                }
+                close();
+                return l;
+        }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/SmartRestSSLSocket.h	Mon May 11 18:10:44 2015 +0000
@@ -0,0 +1,40 @@
+#ifndef SMARTRESTSSLSOCKET_H
+#define SMARTRESTSSLSOCKET_H
+#include "mbed.h"
+#include "rtos.h"
+#include "MDM.h"
+#include "cyassl/ssl.h"
+
+extern MDMSerial *pMdm;
+extern CYASSL_CTX *pCtx;
+
+class SmartRestSSLSocket
+{
+public:
+        SmartRestSSLSocket(): timeout(3000), sockfd(-1), ssl(NULL) {
+//                sockfd = pMdm->socketSocket(MDMParser::IPPROTO_TCP);
+                ssl = CyaSSL_new(pCtx);
+        }
+        virtual ~SmartRestSSLSocket() {
+                close(); 
+//                pMdm->socketFree(sockfd);
+                CyaSSL_free(ssl);
+        }
+        int sendOnly(char *buf, int size);
+        int sendAndReceive(char *buf, int size, int maxSize);
+        void setBlocking(int _timeout = -1) {
+                // timeout in milliseconds
+                timeout = _timeout;
+        }
+protected:
+        int connect();
+        int close();
+private:
+        static char cachedIP[16];
+        int timeout;
+        int sockfd;
+        CYASSL *ssl;
+        Mutex ipLock;
+};
+
+#endif /* SMARTRESTSSLSOCKET_H */
\ No newline at end of file
--- a/util/SmartRestSocket.cpp	Fri May 08 14:50:43 2015 +0000
+++ b/util/SmartRestSocket.cpp	Mon May 11 18:10:44 2015 +0000
@@ -2,7 +2,6 @@
 #include "SmartRestSocket.h"
 #include "SmartRestConf.h"
 
-//memset((void*)SmartRestSocket::cachedIP, 0, sizeof(SmartRestSocket::cachedIP));
 char SmartRestSocket::cachedIP[16] = {0};
 
 int SmartRestSocket::connect()
@@ -20,6 +19,10 @@
                 }
                 n = TCPSocketConnection::connect(cachedIP, srPort);
                 if (n >= 0) {
+                        if (timeout == -1)
+                            Socket::set_blocking(true);
+                        else
+                            Socket::set_blocking(false, timeout);
                         break;
                 } else {
                         cachedIP[0] = '\0';
--- a/util/SmartRestSocket.h	Fri May 08 14:50:43 2015 +0000
+++ b/util/SmartRestSocket.h	Mon May 11 18:10:44 2015 +0000
@@ -6,16 +6,17 @@
 class SmartRestSocket : private TCPSocketConnection
 {
 public:
-        SmartRestSocket(): TCPSocketConnection() {}
+        SmartRestSocket(): TCPSocketConnection(), timeout(-1) {}
         virtual ~SmartRestSocket() {}
         int sendOnly(char *buf, int size);
         int sendAndReceive(char *buf, int size, int maxSize);
-        void set_blocking(bool blocking, unsigned int timeout = 3000) { // timeout in milliseconds
-                Socket::set_blocking(blocking, timeout);
+        void setBlocking(int _timeout = -1) { // timeout in milliseconds
+                timeout = _timeout;
         }
 private:
         int connect();
         static char cachedIP[16];
+        int timeout;
         Mutex ipLock;
 };