WebSocket client library

Revision:
16:d4518b50f653
Parent:
15:79bfbc0ad6bc
Child:
17:1e339933c97a
--- a/Websocket.cpp	Tue Sep 06 16:44:56 2011 +0000
+++ b/Websocket.cpp	Wed Sep 21 09:31:36 2011 +0000
@@ -3,55 +3,65 @@
 
 Websocket::Websocket(char * url, Wifly * wifi) {
     this->wifi = wifi;
-    wifi_use = true;
-    eth_use = false;
-    response_server_eth = false;
-    fillFields(wifi_use, url);
+    netif = WIF;
+    fillFields(url);
 }
 
 
 Websocket::Websocket(char * url) {
-    wifi_use = false;
     server_ip = NULL;
-    eth_use = true;
+    netif = ETH;
     eth_writeable = false;
     eth_readable = false;
     eth_connected = false;
     response_server_eth = false;
-    fillFields(wifi_use, url);
+    new_msg = false;
+    fillFields(url);
 
+    eth = new EthernetNetIf();
+    sock = new TCPSocket();
 
-    EthernetErr ethErr = eth.setup();
+    EthernetErr ethErr = eth->setup();
+#ifdef DEBUG
     if (ethErr) {
         printf("\r\nERROR %d in setup.\r\n", ethErr);
     }
+#endif
 
     //we must use dnsresolver to find the ip address
     if (server_ip == NULL) {
         DNSResolver dr;
-        server_ip = dr.resolveName(ip_domain);
+        server_ip = new IpAddr();
+        *server_ip = dr.resolveName(ip_domain);
+#ifdef DEBUG
         printf("\r\nserver with dns=%i.%i.%i.%i\r\n",server_ip[0],server_ip[1],server_ip[2],server_ip[3]);
+#endif
+
     }
 
-    IpAddr ipt = eth.getIp();
+    IpAddr ipt = eth->getIp();
+#ifdef DEBUG
     printf("\r\nmbed IP Address is %d.%d.%d.%d\r\n", ipt[0], ipt[1], ipt[2], ipt[3]);
+#endif
 
-    sock.setOnEvent(this, &Websocket::onTCPSocketEvent);
+    sock->setOnEvent(this, &Websocket::onTCPSocketEvent);
 }
 
 
-void Websocket::fillFields(bool wifi, char * url) {
+void Websocket::fillFields(char * url) {
     char *res = NULL;
     char *res1 = NULL;
 
-    char buf[30];
+    char buf[50];
     strcpy(buf, url);
 
     res = strtok(buf, ":");
     if (strcmp(res, "ws")) {
-        this->ip_domain = NULL;
-        this->path = NULL;
+        strcpy(this->ip_domain, "");
+        strcpy(this->path, "");
+#ifdef DEBUG
         printf("\r\nFormat error: please use: \"ws://ip-or-domain[:port]/path\"\r\n\r\n");
+#endif
     } else {
         //ip_domain and port
         res = strtok(NULL, "/");
@@ -59,7 +69,6 @@
         //path
         res1 = strtok(NULL, " ");
         if (res1 != NULL) {
-            path = (char *) malloc (sizeof(char) * strlen(res1));
             strcpy(this->path, res1);
         }
 
@@ -70,18 +79,16 @@
         res1 = strtok(NULL, " ");
         //port
         if (res1 != NULL) {
-            port = (char *) malloc (sizeof(char) * strlen(res1));
             strcpy(this->port, res1);
         } else {
-            port = (char *) malloc (sizeof(char) * 3);
             strcpy(this->port, "80");
         }
 
         if (res != NULL) {
-            ip_domain = (char *) malloc (sizeof(char) * strlen(res));
             strcpy(this->ip_domain, res);
+
             //if we use ethernet, we must decode ip address or use dnsresolver
-            if (!wifi) {
+            if (netif == ETH) {
                 strcpy(buf, res);
 
                 //we try to decode the ip address
@@ -94,8 +101,10 @@
                         res = strtok(NULL, ".");
                         i++;
                     }
-                    server_ip = IpAddr(ip[0], ip[1], ip[2], ip[3]);
-                    printf("server without dns=%i.%i.%i.%i\n",server_ip[0],server_ip[1],server_ip[2],server_ip[3]);
+                    server_ip = new IpAddr(ip[0], ip[1], ip[2], ip[3]);
+#ifdef DEBUG
+                    printf("server without dns=%i.%i.%i.%i\n",(*server_ip)[0],(*server_ip)[1],(*server_ip)[2],(*server_ip)[3]);
+#endif
                 }
             }
         }
@@ -105,11 +114,13 @@
 
 bool Websocket::connect() {
     char cmd[50];
-    if ( wifi_use ) {
+    if (netif == WIF) {
         wifi->Send("exit\r", "NO");
         //enter in cmd mode
         while (!wifi->Send("$$$", "CMD")) {
+#ifdef DEBUG
             printf("cannot enter in CMD mode\r\n");
+#endif
             wifi->exit();
         }
 
@@ -117,7 +128,9 @@
         //open the connection
         sprintf(cmd, "open %s %s\r\n", ip_domain, port);
         if (!wifi->Send(cmd, "OPEN*")) {
+#ifdef DEBUG
             printf("Websocket::connect cannot open\r\n");
+#endif
             return false;
         }
 
@@ -140,16 +153,18 @@
         wifi->Send("Sec-WebSocket-key2: 12998 5 Y3 1  .P00\r\n\r\n", "NO");
         if (!wifi->Send("^n:ds[4U", "8jKS'y:G*Co,Wxa-"))
             return false;
-
+#ifdef DEBUG
         printf("\r\nip_domain: %s\r\npath: /%s\r\nport: %s\r\n\r\n",this->ip_domain, this->path, this->port);
+#endif
         return true;
-    } else if ( eth_use ) {
-
-        Host server (server_ip, atoi(port));
-        sock.close();
-        TCPSocketErr bindErr = sock.connect(server);
+    } else if (netif == ETH) {
+        Host server (*server_ip, atoi(port));
+        sock->close();
+        TCPSocketErr bindErr = sock->connect(server);
         if (bindErr) {
+#ifdef DEBUG
             printf("\r\nERROR binderr: %d\r\n", bindErr);
+#endif
             return false;
         }
 
@@ -170,41 +185,41 @@
                     switch (i) {
                         case 0:
                             sprintf(cmd, "GET /%s HTTP/1.1\r\n", path);
-                            sock.send(cmd, strlen(cmd));
+                            sock->send(cmd, strlen(cmd));
                             i++;
                             break;
                         case 1:
                             sprintf(cmd, "Host: %s:%s\r\n", ip_domain, port);
-                            sock.send(cmd, strlen(cmd));
+                            sock->send(cmd, strlen(cmd));
                             i++;
                             break;
                         case 2:
                             sprintf(cmd, "Upgrade: WebSocket\r\n");
-                            sock.send(cmd, strlen(cmd));
+                            sock->send(cmd, strlen(cmd));
                             i++;
                             break;
                         case 3:
                             sprintf(cmd, "Origin: http:%s:%s\r\n", ip_domain, port);
-                            sock.send(cmd, strlen(cmd));
+                            sock->send(cmd, strlen(cmd));
                             i++;
                             break;
                         case 4:
                             sprintf(cmd, "Connection: Upgrade\r\n");
-                            sock.send(cmd, strlen(cmd));
+                            sock->send(cmd, strlen(cmd));
                             i++;
                             break;
                         case 5:
                             sprintf(cmd, "Sec-WebSocket-Key1: 4 @1  46546xW%0l 1 5\r\n");
-                            sock.send(cmd, strlen(cmd));
+                            sock->send(cmd, strlen(cmd));
                             i++;
                             break;
                         case 6:
                             sprintf(cmd, "Sec-WebSocket-key2: 12998 5 Y3 1  .P00\r\n\r\n");
-                            sock.send(cmd, strlen(cmd));
+                            sock->send(cmd, strlen(cmd));
                             i++;
                             break;
                         case 7:
-                            sock.send("^n:ds[4U", 8);
+                            sock->send("^n:ds[4U", 8);
                             i++;
                             break;
                         case 8:
@@ -218,77 +233,85 @@
                     }
                 }
                 if (i==9) {
+#ifdef DEBUG
                     printf("\r\nip_domain: %s\r\npath: /%s\r\nport: %s\r\n\r\n",this->ip_domain, this->path, this->port);
+#endif
                     return true;
                 }
             }
         }
-
     }
-    return true;
+    //the program shouldn't be here
+    return false;
 }
 
 void Websocket::Send(char * str) {
-    char cmd[100];
-    if (wifi_use) {
+    if (netif == WIF) {
         wifi->putc('\x00');
-        sprintf(cmd, "%s%c", str, '\xff');
-        wifi->Send(cmd, "NO");
-    } else if (eth_use) {
-        sprintf(cmd, "%c%s%c", 0x00, str, 0xff);
+        wifi->Send(str, "NO");
+        wifi->putc('\xff');
+    } else if (netif == ETH) {
+        char c = '\x00';
         Net::poll();
-        sock.send(cmd, strlen(cmd + 1) + 1);
+        sock->send(&c, 1);
+        sock->send(str, strlen(str));
+        c = '\xff';
+        sock->send(&c, 1);
     }
 }
 
 bool Websocket::read(char * message) {
     int i = 0;
 
-    if (wifi_use) {
-
-        wifi->read(message);
-        //printf("msg: %s  strlen: %d\r\n", message + 1, strlen(message + 1) - 1);
+    if (netif == WIF) {
+        if (!wifi->read(message))
+            return false;
 
         //we check if the first byte is 0x00
         if (message == NULL || message[0] != 0x00) {
             message = NULL;
             return false;
         }
-        
-        while(message[i + 1] != 0xff && i < strlen(message + 1))
+
+        while (message[i + 1] != 0xff && i < strlen(message + 1))
             i++;
-        
-        if(message[i+1] == 0xff)
-        {
+
+        if (message[i+1] == 0xff) {
             message[i+1] = 0;
             memcpy(message, message + 1, strlen(message + 1) + 1);
-        }
-        else
-        {
+            return true;
+        } else {
             message = NULL;
             return false;
         }
-
-    } else if (eth_use) {
+    } else if (netif == ETH) {
         Net::poll();
 
-        if (eth_rx[0] != 0x00) {
-            message = NULL;
-            return false;
+        if (new_msg) {
+            if (eth_rx[0] != 0x00) {
+                message = NULL;
+                return false;
+            }
+            while (eth_rx[i + 1] != 0xff) {
+                message[i] = eth_rx[i + 1];
+                i++;
+            }
+            message[i] = 0;
+            new_msg = false;
+            return true;
         }
-        while (eth_rx[i + 1] != 0xff) {
-            message[i] = eth_rx[i + 1];
-            i++;
-        }
-        message[i] = 0;
+        return false;
     }
-    return true;
+    //the program shouldn't be here
+    return false;
 }
 
 bool Websocket::close() {
-    if (wifi_use) {
+    if (netif == WIF) {
         if (!wifi->CmdMode()) {
+#ifdef DEBUG
             printf("Websocket::close: cannot enter in cmd mode\r\n");
+#endif
             return false;
         }
 
@@ -296,22 +319,27 @@
 
         if (!wifi->exit())
             return false;
-    } else if (eth_use) {
-        if (sock.close())
+    } else if (netif == ETH) {
+
+        if (sock->close())
             return false;
+        return true;
     }
-    return true;
+    //the program shouldn't be here
+    return false;
 }
 
 
 
 bool Websocket::connected() {
-    if (wifi_use) {
+    if (netif == WIF) {
         char str[10];
 
         wait(0.25);
         if (!wifi->CmdMode()) {
+#ifdef DEBUG
             printf("Websocket::connected: cannot enter in cmd mode\r\n");
+#endif
             return false;
         }
         wait(0.25);
@@ -320,32 +348,41 @@
 
         if (str[3] == '1') {
             if (!wifi->exit()) {
+#ifdef DEBUG
                 printf("Websocket::connected: cannot exit\r\n");
+#endif
                 return false;
             }
             return true;
         }
-        if (!wifi->exit())
+        if (!wifi->exit()) {
+#ifdef DEBUG
             printf("Websocket::connected: cannot exit\r\n");
+#endif
+        }
         return false;
-    } else if (eth_use)
+    } else if (netif == ETH) {
+
         return eth_connected;
-
-    return true;
+    }
+    //the program shouldn't be here
+    return false;
 }
 
 
 
 
-
 void Websocket::onTCPSocketEvent(TCPSocketEvent e) {
     if (e == TCPSOCKET_CONNECTED) {
         eth_connected = true;
+#ifdef DEBUG
         printf("TCP Socket Connected\r\n");
+#endif
     } else if (e == TCPSOCKET_WRITEABLE) {
     } else if (e == TCPSOCKET_READABLE) {
-        int len = sock.recv(eth_rx, 512);
+        int len = sock->recv(eth_rx, 512);
         eth_rx[len] = 0;
+        new_msg = true;
         if (!response_server_eth) {
             string checking;
             size_t found = string::npos;
@@ -355,7 +392,9 @@
                 response_server_eth = true;
         }
     } else {
+#ifdef DEBUG
         printf("TCP Socket Fail\r\n");
+#endif
         eth_connected = false;
     }
 }