Websocket client. You can only use this class with a Wifly module. If you want to use websockets over ethernet, take a look at the Websocket class.

Committer:
samux
Date:
Thu Oct 20 09:41:56 2011 +0000
Revision:
2:06909bc328c0
Parent:
0:08afdb5fb5ca

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
samux 0:08afdb5fb5ca 1 #include "Websocket.h"
samux 0:08afdb5fb5ca 2 #include <string>
samux 0:08afdb5fb5ca 3
samux 0:08afdb5fb5ca 4 Websocket::Websocket(char * url, Wifly * wifi) {
samux 0:08afdb5fb5ca 5 this->wifi = wifi;
samux 0:08afdb5fb5ca 6 netif = WIF;
samux 0:08afdb5fb5ca 7 fillFields(url);
samux 0:08afdb5fb5ca 8 }
samux 0:08afdb5fb5ca 9
samux 0:08afdb5fb5ca 10
samux 0:08afdb5fb5ca 11 void Websocket::fillFields(char * url) {
samux 0:08afdb5fb5ca 12 char *res = NULL;
samux 0:08afdb5fb5ca 13 char *res1 = NULL;
samux 0:08afdb5fb5ca 14
samux 0:08afdb5fb5ca 15 char buf[50];
samux 0:08afdb5fb5ca 16 strcpy(buf, url);
samux 0:08afdb5fb5ca 17
samux 0:08afdb5fb5ca 18 res = strtok(buf, ":");
samux 0:08afdb5fb5ca 19 if (strcmp(res, "ws")) {
samux 0:08afdb5fb5ca 20 #ifdef DEBUG
samux 0:08afdb5fb5ca 21 printf("\r\nFormat error: please use: \"ws://ip-or-domain[:port]/path\"\r\n\r\n");
samux 0:08afdb5fb5ca 22 #endif
samux 0:08afdb5fb5ca 23 } else {
samux 0:08afdb5fb5ca 24 //ip_domain and port
samux 0:08afdb5fb5ca 25 res = strtok(NULL, "/");
samux 0:08afdb5fb5ca 26
samux 0:08afdb5fb5ca 27 //path
samux 0:08afdb5fb5ca 28 res1 = strtok(NULL, " ");
samux 0:08afdb5fb5ca 29 if (res1 != NULL)
samux 0:08afdb5fb5ca 30 path = res1;
samux 0:08afdb5fb5ca 31
samux 0:08afdb5fb5ca 32 //ip_domain
samux 0:08afdb5fb5ca 33 res = strtok(res, ":");
samux 0:08afdb5fb5ca 34
samux 0:08afdb5fb5ca 35 //port
samux 0:08afdb5fb5ca 36 res1 = strtok(NULL, " ");
samux 0:08afdb5fb5ca 37 //port
samux 0:08afdb5fb5ca 38 port = (res1 != NULL) ? res1 : "80";
samux 0:08afdb5fb5ca 39
samux 0:08afdb5fb5ca 40 if (res != NULL)
samux 0:08afdb5fb5ca 41 ip_domain = res;
samux 0:08afdb5fb5ca 42 }
samux 0:08afdb5fb5ca 43 }
samux 0:08afdb5fb5ca 44
samux 0:08afdb5fb5ca 45
samux 0:08afdb5fb5ca 46 bool Websocket::connect() {
samux 0:08afdb5fb5ca 47 char cmd[50];
samux 0:08afdb5fb5ca 48 if (netif == WIF) {
samux 0:08afdb5fb5ca 49 wifi->send("exit\r", "NO");
samux 0:08afdb5fb5ca 50 //enter in cmd mode
samux 0:08afdb5fb5ca 51 while (!wifi->send("$$$", "CMD")) {
samux 0:08afdb5fb5ca 52 #ifdef DEBUG
samux 0:08afdb5fb5ca 53 printf("cannot enter in CMD mode\r\n");
samux 0:08afdb5fb5ca 54 #endif
samux 0:08afdb5fb5ca 55 wifi->exit();
samux 0:08afdb5fb5ca 56 }
samux 0:08afdb5fb5ca 57
samux 0:08afdb5fb5ca 58
samux 0:08afdb5fb5ca 59 //open the connection
samux 0:08afdb5fb5ca 60 sprintf(cmd, "open %s %s\r\n", ip_domain.c_str(), port.c_str());
samux 0:08afdb5fb5ca 61 if (!wifi->send(cmd, "OPEN*")) {
samux 0:08afdb5fb5ca 62 #ifdef DEBUG
samux 0:08afdb5fb5ca 63 printf("Websocket::connect cannot open\r\n");
samux 0:08afdb5fb5ca 64 #endif
samux 0:08afdb5fb5ca 65 return false;
samux 0:08afdb5fb5ca 66 }
samux 0:08afdb5fb5ca 67
samux 0:08afdb5fb5ca 68
samux 0:08afdb5fb5ca 69 //send websocket HTTP header
samux 0:08afdb5fb5ca 70 sprintf(cmd, "GET /%s HTTP/1.1\r\n", path.c_str());
samux 0:08afdb5fb5ca 71 wifi->send(cmd, "NO");
samux 0:08afdb5fb5ca 72
samux 0:08afdb5fb5ca 73 sprintf(cmd, "Host: %s:%s\r\n", ip_domain.c_str(), port.c_str());
samux 0:08afdb5fb5ca 74 wifi->send(cmd, "NO");
samux 0:08afdb5fb5ca 75
samux 0:08afdb5fb5ca 76 wifi->send("Upgrade: WebSocket\r\n", "NO");
samux 0:08afdb5fb5ca 77
samux 0:08afdb5fb5ca 78 sprintf(cmd, "Origin: http:%s:%s\r\n", ip_domain.c_str(), port.c_str());
samux 0:08afdb5fb5ca 79 wifi->send(cmd, "NO");
samux 0:08afdb5fb5ca 80
samux 0:08afdb5fb5ca 81
samux 0:08afdb5fb5ca 82 wifi->send("Connection: Upgrade\r\n", "NO");
samux 0:08afdb5fb5ca 83 wifi->send("Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n", "NO");
samux 0:08afdb5fb5ca 84 wifi->send("Sec-WebSocket-key2: 12998 5 Y3 1 .P00\r\n\r\n", "NO");
samux 0:08afdb5fb5ca 85 if (!wifi->send("^n:ds[4U", "8jKS'y:G*Co,Wxa-"))
samux 0:08afdb5fb5ca 86 return false;
samux 0:08afdb5fb5ca 87 #ifdef DEBUG
samux 0:08afdb5fb5ca 88 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());
samux 0:08afdb5fb5ca 89 #endif
samux 0:08afdb5fb5ca 90 return true;
samux 0:08afdb5fb5ca 91 }
samux 0:08afdb5fb5ca 92 //the program shouldn't be here
samux 0:08afdb5fb5ca 93 return false;
samux 0:08afdb5fb5ca 94 }
samux 0:08afdb5fb5ca 95
samux 0:08afdb5fb5ca 96 void Websocket::send(char * str) {
samux 0:08afdb5fb5ca 97 if (netif == WIF) {
samux 0:08afdb5fb5ca 98 wifi->putc('\x00');
samux 0:08afdb5fb5ca 99 wifi->send(str, "NO");
samux 0:08afdb5fb5ca 100 wifi->putc('\xff');
samux 0:08afdb5fb5ca 101 }
samux 0:08afdb5fb5ca 102 }
samux 0:08afdb5fb5ca 103
samux 0:08afdb5fb5ca 104 bool Websocket::read(char * message) {
samux 0:08afdb5fb5ca 105 int i = 0;
samux 0:08afdb5fb5ca 106
samux 0:08afdb5fb5ca 107 if (netif == WIF) {
samux 0:08afdb5fb5ca 108 if (!wifi->read(message))
samux 0:08afdb5fb5ca 109 return false;
samux 0:08afdb5fb5ca 110
samux 0:08afdb5fb5ca 111 //we check if the first byte is 0x00
samux 0:08afdb5fb5ca 112 if (message == NULL || message[0] != 0x00) {
samux 0:08afdb5fb5ca 113 message = NULL;
samux 0:08afdb5fb5ca 114 return false;
samux 0:08afdb5fb5ca 115 }
samux 0:08afdb5fb5ca 116
samux 0:08afdb5fb5ca 117 while (message[i + 1] != 0xff && i < strlen(message + 1))
samux 0:08afdb5fb5ca 118 i++;
samux 0:08afdb5fb5ca 119
samux 0:08afdb5fb5ca 120 if (message[i+1] == 0xff) {
samux 0:08afdb5fb5ca 121 message[i+1] = 0;
samux 0:08afdb5fb5ca 122 memcpy(message, message + 1, strlen(message + 1) + 1);
samux 0:08afdb5fb5ca 123 return true;
samux 0:08afdb5fb5ca 124 } else {
samux 0:08afdb5fb5ca 125 message = NULL;
samux 0:08afdb5fb5ca 126 return false;
samux 0:08afdb5fb5ca 127 }
samux 0:08afdb5fb5ca 128 }
samux 0:08afdb5fb5ca 129 //the program shouldn't be here
samux 0:08afdb5fb5ca 130 return false;
samux 0:08afdb5fb5ca 131 }
samux 0:08afdb5fb5ca 132
samux 0:08afdb5fb5ca 133 bool Websocket::close() {
samux 0:08afdb5fb5ca 134 if (netif == WIF) {
samux 0:08afdb5fb5ca 135 if (!wifi->cmdMode()) {
samux 0:08afdb5fb5ca 136 #ifdef DEBUG
samux 0:08afdb5fb5ca 137 printf("Websocket::close: cannot enter in cmd mode\r\n");
samux 0:08afdb5fb5ca 138 #endif
samux 0:08afdb5fb5ca 139 return false;
samux 0:08afdb5fb5ca 140 }
samux 0:08afdb5fb5ca 141
samux 0:08afdb5fb5ca 142 wifi->send("close\r", "NO");
samux 0:08afdb5fb5ca 143
samux 0:08afdb5fb5ca 144 if (!wifi->exit())
samux 0:08afdb5fb5ca 145 return false;
samux 0:08afdb5fb5ca 146 }
samux 0:08afdb5fb5ca 147 //the program shouldn't be here
samux 0:08afdb5fb5ca 148 return false;
samux 0:08afdb5fb5ca 149 }
samux 0:08afdb5fb5ca 150
samux 0:08afdb5fb5ca 151
samux 0:08afdb5fb5ca 152
samux 0:08afdb5fb5ca 153 bool Websocket::connected() {
samux 0:08afdb5fb5ca 154 if (netif == WIF) {
samux 0:08afdb5fb5ca 155 char str[10];
samux 0:08afdb5fb5ca 156
samux 0:08afdb5fb5ca 157 wait(0.25);
samux 0:08afdb5fb5ca 158 if (!wifi->cmdMode()) {
samux 0:08afdb5fb5ca 159 #ifdef DEBUG
samux 0:08afdb5fb5ca 160 printf("Websocket::connected: cannot enter in cmd mode\r\n");
samux 0:08afdb5fb5ca 161 #endif
samux 0:08afdb5fb5ca 162 return false;
samux 0:08afdb5fb5ca 163 }
samux 0:08afdb5fb5ca 164 wait(0.25);
samux 0:08afdb5fb5ca 165
samux 0:08afdb5fb5ca 166 wifi->send("show c\r\n", "NO", str);
samux 0:08afdb5fb5ca 167
samux 0:08afdb5fb5ca 168 if (str[3] == '1') {
samux 0:08afdb5fb5ca 169 if (!wifi->exit()) {
samux 0:08afdb5fb5ca 170 #ifdef DEBUG
samux 0:08afdb5fb5ca 171 printf("Websocket::connected: cannot exit\r\n");
samux 0:08afdb5fb5ca 172 #endif
samux 0:08afdb5fb5ca 173 return false;
samux 0:08afdb5fb5ca 174 }
samux 0:08afdb5fb5ca 175 return true;
samux 0:08afdb5fb5ca 176 }
samux 0:08afdb5fb5ca 177 if (!wifi->exit()) {
samux 0:08afdb5fb5ca 178 #ifdef DEBUG
samux 0:08afdb5fb5ca 179 printf("Websocket::connected: cannot exit\r\n");
samux 0:08afdb5fb5ca 180 #endif
samux 0:08afdb5fb5ca 181 }
samux 0:08afdb5fb5ca 182 return false;
samux 0:08afdb5fb5ca 183 }
samux 0:08afdb5fb5ca 184 //the program shouldn't be here
samux 0:08afdb5fb5ca 185 return false;
samux 0:08afdb5fb5ca 186 }
samux 0:08afdb5fb5ca 187
samux 0:08afdb5fb5ca 188 std::string Websocket::getPath()
samux 0:08afdb5fb5ca 189 {
samux 0:08afdb5fb5ca 190 return path;
samux 0:08afdb5fb5ca 191 }
samux 0:08afdb5fb5ca 192
samux 0:08afdb5fb5ca 193
samux 0:08afdb5fb5ca 194
samux 0:08afdb5fb5ca 195