Brandon Fictorie / Mbed 2 deprecated BF_Websocket

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Websocket.cpp Source File

Websocket.cpp

00001 #include "Websocket.h"
00002 #include <string>
00003 
00004 #define DEBUG
00005 
00006 #ifdef TARGET_LPC1768
00007 Websocket::Websocket(char * url) {
00008     server_ip = NULL;
00009     netif = ETH;
00010     eth_writeable = false;
00011     eth_readable = false;
00012     eth_connected = false;
00013     response_server_eth = false;
00014     new_msg = false;
00015     fillFields(url);
00016 
00017     eth = new EthernetNetIf();
00018     sock = new TCPSocket();
00019 
00020     EthernetErr ethErr = eth->setup();
00021 #ifdef DEBUG
00022     if (ethErr) {
00023         printf("\r\nERROR %d in setup.\r\n", ethErr);
00024     }
00025 #endif
00026 
00027     //we must use dnsresolver to find the ip address
00028     if (server_ip == NULL) {
00029         DNSResolver dr;
00030         server_ip = new IpAddr();
00031         *server_ip = dr.resolveName(ip_domain.c_str());
00032 #ifdef DEBUG
00033         printf("\r\nserver with dns=%d.%d.%d.%d\r\n", (*server_ip)[0], (*server_ip)[1], (*server_ip)[2], (*server_ip)[3]);
00034 #endif
00035 
00036     }
00037 
00038     IpAddr ipt = eth->getIp();
00039 #ifdef DEBUG
00040     printf("\r\nmbed IP Address is %d.%d.%d.%d\r\n", ipt[0], ipt[1], ipt[2], ipt[3]);
00041 #endif
00042 
00043     sock->setOnEvent(this, &Websocket::onTCPSocketEvent);
00044 }
00045 #endif //target
00046 
00047 void Websocket::fillFields(char * url) {
00048     char *res = NULL;
00049     char *res1 = NULL;
00050 
00051     char buf[50];
00052     strcpy(buf, url);
00053 
00054     res = strtok(buf, ":");
00055     if (strcmp(res, "ws")) {
00056 #ifdef DEBUG
00057         printf("\r\nFormat error: please use: \"ws://ip-or-domain[:port]/path\"\r\n\r\n");
00058 #endif
00059     } else {
00060         //ip_domain and port
00061         res = strtok(NULL, "/");
00062 
00063         //path
00064         res1 = strtok(NULL, " ");
00065         if (res1 != NULL) {
00066             path = res1;
00067         }
00068 
00069         //ip_domain
00070         res = strtok(res, ":");
00071 
00072         //port
00073         res1 = strtok(NULL, " ");
00074         //port
00075         if (res1 != NULL) {
00076             port = res1;
00077         } else {
00078             port = "80";
00079         }
00080 
00081         if (res != NULL) {
00082             ip_domain = res;
00083 
00084             //if we use ethernet, we must decode ip address or use dnsresolver
00085 #ifdef TARGET_LPC1768
00086             if (netif == ETH) {
00087                 strcpy(buf, res);
00088 
00089                 //we try to decode the ip address
00090                 if (buf[0] >= '0' && buf[0] <= '9') {
00091                     res = strtok(buf, ".");
00092                     int i = 0;
00093                     int ip[4];
00094                     while (res != NULL) {
00095                         ip[i] = atoi(res);
00096                         res = strtok(NULL, ".");
00097                         i++;
00098                     }
00099                     server_ip = new IpAddr(ip[0], ip[1], ip[2], ip[3]);
00100 #ifdef DEBUG
00101                     printf("Connecting to Sever %i.%i.%i.%i...\r\n",(*server_ip)[0],(*server_ip)[1],(*server_ip)[2],(*server_ip)[3]);
00102 #endif
00103                 }
00104             }
00105 #endif //target
00106         }
00107     }
00108 }
00109 
00110 bool Websocket::connect() {
00111     char cmd[50];
00112 #ifdef TARGET_LPC1768
00113     if (netif == ETH) {
00114         Host server (*server_ip, atoi(port.c_str()));
00115         sprintf(cmd, "Just before sock->close();\r\n");
00116         sock->send(cmd, strlen(cmd));
00117         //sock->close();
00118         TCPSocketErr bindErr = sock->connect(server);
00119         if (bindErr) {
00120 #ifdef DEBUG
00121             printf("\r\nERROR binderr: %d\r\n", bindErr);
00122 #endif
00123             return false;
00124         }
00125 
00126         //Timer tmr;
00127         //tmr.start();
00128 
00129         //Timer stop;
00130         //stop.start();
00131 
00132 #ifdef DEBUG
00133         printf("\r\nip_domain: %s\r\npath: /%s\r\nport: %s\r\n\r\n",this->ip_domain.c_str(), this->path.c_str(), this->port.c_str());
00134 #endif
00135         return true;
00136     }
00137 #endif //target
00138     //the program shouldn't be here
00139     return false;
00140 }
00141 
00142 void Websocket::sendLength(uint32_t len) {
00143     if (len < 126) {
00144         sendChar(len | (1 << 7));
00145     } else if (len < 65535) {
00146         sendChar(126 | (1 << 7));
00147         sendChar(len & 0xff);
00148         sendChar((len >> 8) & 0xff);
00149     } else {
00150         sendChar(127 | (1 << 7));
00151         for (int i = 0; i < 8; i++) {
00152             sendChar((len >> i * 8) & 0xff);
00153         }
00154     }
00155 }
00156 
00157 void Websocket::sendChar(uint8_t c) {
00158 #ifdef TARGET_LPC1768
00159     if (netif == ETH) {
00160         Net::poll();
00161         sock->send((const char *)&c, 1);
00162     }
00163 #endif
00164 }
00165 
00166 void Websocket::send(char * str) {
00167 #ifdef TARGET_LPC1768
00168     if (netif == ETH) {
00169         Net::poll();
00170         sock->send(str, strlen(str));
00171     }
00172 #endif //target
00173 }
00174 
00175 bool Websocket::read(char * message) {
00176     int i = 0;
00177     uint32_t len_msg;
00178     char opcode = 0;
00179     char mask[4] = { 0, 0, 0, 0 };
00180     Timer tmr;
00181 
00182 #ifdef TARGET_LPC1768
00183     if (netif == ETH) {
00184 
00185         uint32_t index = 0;
00186         Net::poll();
00187 
00188         if (new_msg) {
00189             tmr.start();
00190             // read the opcode
00191             while (true) {
00192                 if (tmr.read() > 3) {
00193                     return false;
00194                 }
00195                 opcode = eth_rx[index++];
00196                 if (opcode == 0x81) {
00197                     break;
00198                 }
00199             }
00200 #ifdef DEBUG
00201             printf("opcode: 0x%X\r\n", opcode);
00202 #endif
00203 
00204             len_msg = eth_rx[index++] & 0x7f;
00205             if (len_msg == 126) {
00206                 len_msg = eth_rx[index++];
00207                 len_msg += eth_rx[index++] << 8;
00208             } else if (len_msg == 127) {
00209                 len_msg = 0;
00210                 for (int i = 0; i < 8; i++) {
00211                     len_msg += eth_rx[index++] << i*8;
00212                 }
00213             }
00214             if (len_msg == 0) {
00215                 return false;
00216             }
00217 #ifdef DEBUG
00218             printf("length: %d\r\n", len_msg);
00219 #endif
00220             if ((len_msg & 0x80)) {
00221                 for (int i = 0; i < 4; i++)
00222                     mask[i] = eth_rx[index++];
00223             }
00224 
00225             for (i = 0; i < len_msg; i++) {
00226                 message[i] = eth_rx[index++];// ^ mask[i % 4];
00227             }
00228 
00229             message[len_msg] = 0;
00230             new_msg = false;
00231             return true;
00232         }
00233         return false;
00234     }
00235 #endif //target
00236 //the program shouldn't be here
00237     return false;
00238 }
00239 
00240 bool Websocket::close() {
00241 
00242 #ifdef TARGET_LPC1768
00243     if (netif == ETH) {
00244 
00245         if (sock->close())
00246             return false;
00247         return true;
00248     }
00249 #endif //target
00250     //the program shouldn't be here
00251     return false;
00252 }
00253 
00254 bool Websocket::connected() {
00255 #ifdef TARGET_LPC1768
00256     if (netif == ETH) {
00257         return eth_connected;
00258     }
00259 #endif //target
00260     //the program shouldn't be here
00261     return false;
00262 }
00263 
00264 std::string Websocket::getPath() {
00265     return path;
00266 }
00267 
00268 #ifdef TARGET_LPC1768
00269 void Websocket::onTCPSocketEvent(TCPSocketEvent e) {
00270     if (e == TCPSOCKET_CONNECTED) {
00271         eth_connected = true;
00272 #ifdef DEBUG
00273         printf("TCP Socket Connected\r\n");
00274 #endif
00275     } else if (e == TCPSOCKET_WRITEABLE) {
00276     } else if (e == TCPSOCKET_READABLE) {
00277         int len = sock->recv(eth_rx, 512);
00278         eth_rx[len] = 0;
00279         new_msg = true;
00280         if (!response_server_eth) {
00281             string checking;
00282             size_t found = string::npos;
00283             checking = eth_rx;
00284             found = checking.find("DdLWT/1JcX+nQFHebYP+rqEx5xI=");
00285             if (found != string::npos)
00286                 response_server_eth = true;
00287         }
00288     } else {
00289 #ifdef DEBUG
00290         printf("TCP Socket Fail\r\n");
00291 #endif
00292         eth_connected = false;
00293     }
00294 }
00295 #endif //target