Brandon Fictorie / Mbed 2 deprecated BF_Websocket

Dependencies:   mbed

Committer:
bfictorie
Date:
Sun Mar 25 17:26:30 2012 +0000
Revision:
0:8cdad1c73e8e

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bfictorie 0:8cdad1c73e8e 1 #include "Websocket.h"
bfictorie 0:8cdad1c73e8e 2 #include <string>
bfictorie 0:8cdad1c73e8e 3
bfictorie 0:8cdad1c73e8e 4 #define DEBUG
bfictorie 0:8cdad1c73e8e 5
bfictorie 0:8cdad1c73e8e 6 #ifdef TARGET_LPC1768
bfictorie 0:8cdad1c73e8e 7 Websocket::Websocket(char * url) {
bfictorie 0:8cdad1c73e8e 8 server_ip = NULL;
bfictorie 0:8cdad1c73e8e 9 netif = ETH;
bfictorie 0:8cdad1c73e8e 10 eth_writeable = false;
bfictorie 0:8cdad1c73e8e 11 eth_readable = false;
bfictorie 0:8cdad1c73e8e 12 eth_connected = false;
bfictorie 0:8cdad1c73e8e 13 response_server_eth = false;
bfictorie 0:8cdad1c73e8e 14 new_msg = false;
bfictorie 0:8cdad1c73e8e 15 fillFields(url);
bfictorie 0:8cdad1c73e8e 16
bfictorie 0:8cdad1c73e8e 17 eth = new EthernetNetIf();
bfictorie 0:8cdad1c73e8e 18 sock = new TCPSocket();
bfictorie 0:8cdad1c73e8e 19
bfictorie 0:8cdad1c73e8e 20 EthernetErr ethErr = eth->setup();
bfictorie 0:8cdad1c73e8e 21 #ifdef DEBUG
bfictorie 0:8cdad1c73e8e 22 if (ethErr) {
bfictorie 0:8cdad1c73e8e 23 printf("\r\nERROR %d in setup.\r\n", ethErr);
bfictorie 0:8cdad1c73e8e 24 }
bfictorie 0:8cdad1c73e8e 25 #endif
bfictorie 0:8cdad1c73e8e 26
bfictorie 0:8cdad1c73e8e 27 //we must use dnsresolver to find the ip address
bfictorie 0:8cdad1c73e8e 28 if (server_ip == NULL) {
bfictorie 0:8cdad1c73e8e 29 DNSResolver dr;
bfictorie 0:8cdad1c73e8e 30 server_ip = new IpAddr();
bfictorie 0:8cdad1c73e8e 31 *server_ip = dr.resolveName(ip_domain.c_str());
bfictorie 0:8cdad1c73e8e 32 #ifdef DEBUG
bfictorie 0:8cdad1c73e8e 33 printf("\r\nserver with dns=%d.%d.%d.%d\r\n", (*server_ip)[0], (*server_ip)[1], (*server_ip)[2], (*server_ip)[3]);
bfictorie 0:8cdad1c73e8e 34 #endif
bfictorie 0:8cdad1c73e8e 35
bfictorie 0:8cdad1c73e8e 36 }
bfictorie 0:8cdad1c73e8e 37
bfictorie 0:8cdad1c73e8e 38 IpAddr ipt = eth->getIp();
bfictorie 0:8cdad1c73e8e 39 #ifdef DEBUG
bfictorie 0:8cdad1c73e8e 40 printf("\r\nmbed IP Address is %d.%d.%d.%d\r\n", ipt[0], ipt[1], ipt[2], ipt[3]);
bfictorie 0:8cdad1c73e8e 41 #endif
bfictorie 0:8cdad1c73e8e 42
bfictorie 0:8cdad1c73e8e 43 sock->setOnEvent(this, &Websocket::onTCPSocketEvent);
bfictorie 0:8cdad1c73e8e 44 }
bfictorie 0:8cdad1c73e8e 45 #endif //target
bfictorie 0:8cdad1c73e8e 46
bfictorie 0:8cdad1c73e8e 47 void Websocket::fillFields(char * url) {
bfictorie 0:8cdad1c73e8e 48 char *res = NULL;
bfictorie 0:8cdad1c73e8e 49 char *res1 = NULL;
bfictorie 0:8cdad1c73e8e 50
bfictorie 0:8cdad1c73e8e 51 char buf[50];
bfictorie 0:8cdad1c73e8e 52 strcpy(buf, url);
bfictorie 0:8cdad1c73e8e 53
bfictorie 0:8cdad1c73e8e 54 res = strtok(buf, ":");
bfictorie 0:8cdad1c73e8e 55 if (strcmp(res, "ws")) {
bfictorie 0:8cdad1c73e8e 56 #ifdef DEBUG
bfictorie 0:8cdad1c73e8e 57 printf("\r\nFormat error: please use: \"ws://ip-or-domain[:port]/path\"\r\n\r\n");
bfictorie 0:8cdad1c73e8e 58 #endif
bfictorie 0:8cdad1c73e8e 59 } else {
bfictorie 0:8cdad1c73e8e 60 //ip_domain and port
bfictorie 0:8cdad1c73e8e 61 res = strtok(NULL, "/");
bfictorie 0:8cdad1c73e8e 62
bfictorie 0:8cdad1c73e8e 63 //path
bfictorie 0:8cdad1c73e8e 64 res1 = strtok(NULL, " ");
bfictorie 0:8cdad1c73e8e 65 if (res1 != NULL) {
bfictorie 0:8cdad1c73e8e 66 path = res1;
bfictorie 0:8cdad1c73e8e 67 }
bfictorie 0:8cdad1c73e8e 68
bfictorie 0:8cdad1c73e8e 69 //ip_domain
bfictorie 0:8cdad1c73e8e 70 res = strtok(res, ":");
bfictorie 0:8cdad1c73e8e 71
bfictorie 0:8cdad1c73e8e 72 //port
bfictorie 0:8cdad1c73e8e 73 res1 = strtok(NULL, " ");
bfictorie 0:8cdad1c73e8e 74 //port
bfictorie 0:8cdad1c73e8e 75 if (res1 != NULL) {
bfictorie 0:8cdad1c73e8e 76 port = res1;
bfictorie 0:8cdad1c73e8e 77 } else {
bfictorie 0:8cdad1c73e8e 78 port = "80";
bfictorie 0:8cdad1c73e8e 79 }
bfictorie 0:8cdad1c73e8e 80
bfictorie 0:8cdad1c73e8e 81 if (res != NULL) {
bfictorie 0:8cdad1c73e8e 82 ip_domain = res;
bfictorie 0:8cdad1c73e8e 83
bfictorie 0:8cdad1c73e8e 84 //if we use ethernet, we must decode ip address or use dnsresolver
bfictorie 0:8cdad1c73e8e 85 #ifdef TARGET_LPC1768
bfictorie 0:8cdad1c73e8e 86 if (netif == ETH) {
bfictorie 0:8cdad1c73e8e 87 strcpy(buf, res);
bfictorie 0:8cdad1c73e8e 88
bfictorie 0:8cdad1c73e8e 89 //we try to decode the ip address
bfictorie 0:8cdad1c73e8e 90 if (buf[0] >= '0' && buf[0] <= '9') {
bfictorie 0:8cdad1c73e8e 91 res = strtok(buf, ".");
bfictorie 0:8cdad1c73e8e 92 int i = 0;
bfictorie 0:8cdad1c73e8e 93 int ip[4];
bfictorie 0:8cdad1c73e8e 94 while (res != NULL) {
bfictorie 0:8cdad1c73e8e 95 ip[i] = atoi(res);
bfictorie 0:8cdad1c73e8e 96 res = strtok(NULL, ".");
bfictorie 0:8cdad1c73e8e 97 i++;
bfictorie 0:8cdad1c73e8e 98 }
bfictorie 0:8cdad1c73e8e 99 server_ip = new IpAddr(ip[0], ip[1], ip[2], ip[3]);
bfictorie 0:8cdad1c73e8e 100 #ifdef DEBUG
bfictorie 0:8cdad1c73e8e 101 printf("Connecting to Sever %i.%i.%i.%i...\r\n",(*server_ip)[0],(*server_ip)[1],(*server_ip)[2],(*server_ip)[3]);
bfictorie 0:8cdad1c73e8e 102 #endif
bfictorie 0:8cdad1c73e8e 103 }
bfictorie 0:8cdad1c73e8e 104 }
bfictorie 0:8cdad1c73e8e 105 #endif //target
bfictorie 0:8cdad1c73e8e 106 }
bfictorie 0:8cdad1c73e8e 107 }
bfictorie 0:8cdad1c73e8e 108 }
bfictorie 0:8cdad1c73e8e 109
bfictorie 0:8cdad1c73e8e 110 bool Websocket::connect() {
bfictorie 0:8cdad1c73e8e 111 char cmd[50];
bfictorie 0:8cdad1c73e8e 112 #ifdef TARGET_LPC1768
bfictorie 0:8cdad1c73e8e 113 if (netif == ETH) {
bfictorie 0:8cdad1c73e8e 114 Host server (*server_ip, atoi(port.c_str()));
bfictorie 0:8cdad1c73e8e 115 sprintf(cmd, "Just before sock->close();\r\n");
bfictorie 0:8cdad1c73e8e 116 sock->send(cmd, strlen(cmd));
bfictorie 0:8cdad1c73e8e 117 //sock->close();
bfictorie 0:8cdad1c73e8e 118 TCPSocketErr bindErr = sock->connect(server);
bfictorie 0:8cdad1c73e8e 119 if (bindErr) {
bfictorie 0:8cdad1c73e8e 120 #ifdef DEBUG
bfictorie 0:8cdad1c73e8e 121 printf("\r\nERROR binderr: %d\r\n", bindErr);
bfictorie 0:8cdad1c73e8e 122 #endif
bfictorie 0:8cdad1c73e8e 123 return false;
bfictorie 0:8cdad1c73e8e 124 }
bfictorie 0:8cdad1c73e8e 125
bfictorie 0:8cdad1c73e8e 126 //Timer tmr;
bfictorie 0:8cdad1c73e8e 127 //tmr.start();
bfictorie 0:8cdad1c73e8e 128
bfictorie 0:8cdad1c73e8e 129 //Timer stop;
bfictorie 0:8cdad1c73e8e 130 //stop.start();
bfictorie 0:8cdad1c73e8e 131
bfictorie 0:8cdad1c73e8e 132 #ifdef DEBUG
bfictorie 0:8cdad1c73e8e 133 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());
bfictorie 0:8cdad1c73e8e 134 #endif
bfictorie 0:8cdad1c73e8e 135 return true;
bfictorie 0:8cdad1c73e8e 136 }
bfictorie 0:8cdad1c73e8e 137 #endif //target
bfictorie 0:8cdad1c73e8e 138 //the program shouldn't be here
bfictorie 0:8cdad1c73e8e 139 return false;
bfictorie 0:8cdad1c73e8e 140 }
bfictorie 0:8cdad1c73e8e 141
bfictorie 0:8cdad1c73e8e 142 void Websocket::sendLength(uint32_t len) {
bfictorie 0:8cdad1c73e8e 143 if (len < 126) {
bfictorie 0:8cdad1c73e8e 144 sendChar(len | (1 << 7));
bfictorie 0:8cdad1c73e8e 145 } else if (len < 65535) {
bfictorie 0:8cdad1c73e8e 146 sendChar(126 | (1 << 7));
bfictorie 0:8cdad1c73e8e 147 sendChar(len & 0xff);
bfictorie 0:8cdad1c73e8e 148 sendChar((len >> 8) & 0xff);
bfictorie 0:8cdad1c73e8e 149 } else {
bfictorie 0:8cdad1c73e8e 150 sendChar(127 | (1 << 7));
bfictorie 0:8cdad1c73e8e 151 for (int i = 0; i < 8; i++) {
bfictorie 0:8cdad1c73e8e 152 sendChar((len >> i * 8) & 0xff);
bfictorie 0:8cdad1c73e8e 153 }
bfictorie 0:8cdad1c73e8e 154 }
bfictorie 0:8cdad1c73e8e 155 }
bfictorie 0:8cdad1c73e8e 156
bfictorie 0:8cdad1c73e8e 157 void Websocket::sendChar(uint8_t c) {
bfictorie 0:8cdad1c73e8e 158 #ifdef TARGET_LPC1768
bfictorie 0:8cdad1c73e8e 159 if (netif == ETH) {
bfictorie 0:8cdad1c73e8e 160 Net::poll();
bfictorie 0:8cdad1c73e8e 161 sock->send((const char *)&c, 1);
bfictorie 0:8cdad1c73e8e 162 }
bfictorie 0:8cdad1c73e8e 163 #endif
bfictorie 0:8cdad1c73e8e 164 }
bfictorie 0:8cdad1c73e8e 165
bfictorie 0:8cdad1c73e8e 166 void Websocket::send(char * str) {
bfictorie 0:8cdad1c73e8e 167 #ifdef TARGET_LPC1768
bfictorie 0:8cdad1c73e8e 168 if (netif == ETH) {
bfictorie 0:8cdad1c73e8e 169 Net::poll();
bfictorie 0:8cdad1c73e8e 170 sock->send(str, strlen(str));
bfictorie 0:8cdad1c73e8e 171 }
bfictorie 0:8cdad1c73e8e 172 #endif //target
bfictorie 0:8cdad1c73e8e 173 }
bfictorie 0:8cdad1c73e8e 174
bfictorie 0:8cdad1c73e8e 175 bool Websocket::read(char * message) {
bfictorie 0:8cdad1c73e8e 176 int i = 0;
bfictorie 0:8cdad1c73e8e 177 uint32_t len_msg;
bfictorie 0:8cdad1c73e8e 178 char opcode = 0;
bfictorie 0:8cdad1c73e8e 179 char mask[4] = { 0, 0, 0, 0 };
bfictorie 0:8cdad1c73e8e 180 Timer tmr;
bfictorie 0:8cdad1c73e8e 181
bfictorie 0:8cdad1c73e8e 182 #ifdef TARGET_LPC1768
bfictorie 0:8cdad1c73e8e 183 if (netif == ETH) {
bfictorie 0:8cdad1c73e8e 184
bfictorie 0:8cdad1c73e8e 185 uint32_t index = 0;
bfictorie 0:8cdad1c73e8e 186 Net::poll();
bfictorie 0:8cdad1c73e8e 187
bfictorie 0:8cdad1c73e8e 188 if (new_msg) {
bfictorie 0:8cdad1c73e8e 189 tmr.start();
bfictorie 0:8cdad1c73e8e 190 // read the opcode
bfictorie 0:8cdad1c73e8e 191 while (true) {
bfictorie 0:8cdad1c73e8e 192 if (tmr.read() > 3) {
bfictorie 0:8cdad1c73e8e 193 return false;
bfictorie 0:8cdad1c73e8e 194 }
bfictorie 0:8cdad1c73e8e 195 opcode = eth_rx[index++];
bfictorie 0:8cdad1c73e8e 196 if (opcode == 0x81) {
bfictorie 0:8cdad1c73e8e 197 break;
bfictorie 0:8cdad1c73e8e 198 }
bfictorie 0:8cdad1c73e8e 199 }
bfictorie 0:8cdad1c73e8e 200 #ifdef DEBUG
bfictorie 0:8cdad1c73e8e 201 printf("opcode: 0x%X\r\n", opcode);
bfictorie 0:8cdad1c73e8e 202 #endif
bfictorie 0:8cdad1c73e8e 203
bfictorie 0:8cdad1c73e8e 204 len_msg = eth_rx[index++] & 0x7f;
bfictorie 0:8cdad1c73e8e 205 if (len_msg == 126) {
bfictorie 0:8cdad1c73e8e 206 len_msg = eth_rx[index++];
bfictorie 0:8cdad1c73e8e 207 len_msg += eth_rx[index++] << 8;
bfictorie 0:8cdad1c73e8e 208 } else if (len_msg == 127) {
bfictorie 0:8cdad1c73e8e 209 len_msg = 0;
bfictorie 0:8cdad1c73e8e 210 for (int i = 0; i < 8; i++) {
bfictorie 0:8cdad1c73e8e 211 len_msg += eth_rx[index++] << i*8;
bfictorie 0:8cdad1c73e8e 212 }
bfictorie 0:8cdad1c73e8e 213 }
bfictorie 0:8cdad1c73e8e 214 if (len_msg == 0) {
bfictorie 0:8cdad1c73e8e 215 return false;
bfictorie 0:8cdad1c73e8e 216 }
bfictorie 0:8cdad1c73e8e 217 #ifdef DEBUG
bfictorie 0:8cdad1c73e8e 218 printf("length: %d\r\n", len_msg);
bfictorie 0:8cdad1c73e8e 219 #endif
bfictorie 0:8cdad1c73e8e 220 if ((len_msg & 0x80)) {
bfictorie 0:8cdad1c73e8e 221 for (int i = 0; i < 4; i++)
bfictorie 0:8cdad1c73e8e 222 mask[i] = eth_rx[index++];
bfictorie 0:8cdad1c73e8e 223 }
bfictorie 0:8cdad1c73e8e 224
bfictorie 0:8cdad1c73e8e 225 for (i = 0; i < len_msg; i++) {
bfictorie 0:8cdad1c73e8e 226 message[i] = eth_rx[index++];// ^ mask[i % 4];
bfictorie 0:8cdad1c73e8e 227 }
bfictorie 0:8cdad1c73e8e 228
bfictorie 0:8cdad1c73e8e 229 message[len_msg] = 0;
bfictorie 0:8cdad1c73e8e 230 new_msg = false;
bfictorie 0:8cdad1c73e8e 231 return true;
bfictorie 0:8cdad1c73e8e 232 }
bfictorie 0:8cdad1c73e8e 233 return false;
bfictorie 0:8cdad1c73e8e 234 }
bfictorie 0:8cdad1c73e8e 235 #endif //target
bfictorie 0:8cdad1c73e8e 236 //the program shouldn't be here
bfictorie 0:8cdad1c73e8e 237 return false;
bfictorie 0:8cdad1c73e8e 238 }
bfictorie 0:8cdad1c73e8e 239
bfictorie 0:8cdad1c73e8e 240 bool Websocket::close() {
bfictorie 0:8cdad1c73e8e 241
bfictorie 0:8cdad1c73e8e 242 #ifdef TARGET_LPC1768
bfictorie 0:8cdad1c73e8e 243 if (netif == ETH) {
bfictorie 0:8cdad1c73e8e 244
bfictorie 0:8cdad1c73e8e 245 if (sock->close())
bfictorie 0:8cdad1c73e8e 246 return false;
bfictorie 0:8cdad1c73e8e 247 return true;
bfictorie 0:8cdad1c73e8e 248 }
bfictorie 0:8cdad1c73e8e 249 #endif //target
bfictorie 0:8cdad1c73e8e 250 //the program shouldn't be here
bfictorie 0:8cdad1c73e8e 251 return false;
bfictorie 0:8cdad1c73e8e 252 }
bfictorie 0:8cdad1c73e8e 253
bfictorie 0:8cdad1c73e8e 254 bool Websocket::connected() {
bfictorie 0:8cdad1c73e8e 255 #ifdef TARGET_LPC1768
bfictorie 0:8cdad1c73e8e 256 if (netif == ETH) {
bfictorie 0:8cdad1c73e8e 257 return eth_connected;
bfictorie 0:8cdad1c73e8e 258 }
bfictorie 0:8cdad1c73e8e 259 #endif //target
bfictorie 0:8cdad1c73e8e 260 //the program shouldn't be here
bfictorie 0:8cdad1c73e8e 261 return false;
bfictorie 0:8cdad1c73e8e 262 }
bfictorie 0:8cdad1c73e8e 263
bfictorie 0:8cdad1c73e8e 264 std::string Websocket::getPath() {
bfictorie 0:8cdad1c73e8e 265 return path;
bfictorie 0:8cdad1c73e8e 266 }
bfictorie 0:8cdad1c73e8e 267
bfictorie 0:8cdad1c73e8e 268 #ifdef TARGET_LPC1768
bfictorie 0:8cdad1c73e8e 269 void Websocket::onTCPSocketEvent(TCPSocketEvent e) {
bfictorie 0:8cdad1c73e8e 270 if (e == TCPSOCKET_CONNECTED) {
bfictorie 0:8cdad1c73e8e 271 eth_connected = true;
bfictorie 0:8cdad1c73e8e 272 #ifdef DEBUG
bfictorie 0:8cdad1c73e8e 273 printf("TCP Socket Connected\r\n");
bfictorie 0:8cdad1c73e8e 274 #endif
bfictorie 0:8cdad1c73e8e 275 } else if (e == TCPSOCKET_WRITEABLE) {
bfictorie 0:8cdad1c73e8e 276 } else if (e == TCPSOCKET_READABLE) {
bfictorie 0:8cdad1c73e8e 277 int len = sock->recv(eth_rx, 512);
bfictorie 0:8cdad1c73e8e 278 eth_rx[len] = 0;
bfictorie 0:8cdad1c73e8e 279 new_msg = true;
bfictorie 0:8cdad1c73e8e 280 if (!response_server_eth) {
bfictorie 0:8cdad1c73e8e 281 string checking;
bfictorie 0:8cdad1c73e8e 282 size_t found = string::npos;
bfictorie 0:8cdad1c73e8e 283 checking = eth_rx;
bfictorie 0:8cdad1c73e8e 284 found = checking.find("DdLWT/1JcX+nQFHebYP+rqEx5xI=");
bfictorie 0:8cdad1c73e8e 285 if (found != string::npos)
bfictorie 0:8cdad1c73e8e 286 response_server_eth = true;
bfictorie 0:8cdad1c73e8e 287 }
bfictorie 0:8cdad1c73e8e 288 } else {
bfictorie 0:8cdad1c73e8e 289 #ifdef DEBUG
bfictorie 0:8cdad1c73e8e 290 printf("TCP Socket Fail\r\n");
bfictorie 0:8cdad1c73e8e 291 #endif
bfictorie 0:8cdad1c73e8e 292 eth_connected = false;
bfictorie 0:8cdad1c73e8e 293 }
bfictorie 0:8cdad1c73e8e 294 }
bfictorie 0:8cdad1c73e8e 295 #endif //target