WebSocket client library
Websocket.cpp@4:1d3e630b8f9c, 2011-08-15 (annotated)
- Committer:
- samux
- Date:
- Mon Aug 15 11:34:05 2011 +0000
- Revision:
- 4:1d3e630b8f9c
- Parent:
- 3:9b00db719afa
- Child:
- 6:01a1eb7c0145
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
samux | 0:21fe3b05249f | 1 | #include "Websocket.h" |
samux | 0:21fe3b05249f | 2 | |
samux | 0:21fe3b05249f | 3 | Websocket::Websocket(char * url, int port, Wifly * wifi) |
samux | 0:21fe3b05249f | 4 | { |
samux | 0:21fe3b05249f | 5 | char *res = NULL; |
samux | 0:21fe3b05249f | 6 | char buf[30]; |
samux | 0:21fe3b05249f | 7 | strcpy(buf, url); |
samux | 0:21fe3b05249f | 8 | |
samux | 0:21fe3b05249f | 9 | res = strtok(buf, ":"); |
samux | 0:21fe3b05249f | 10 | if (strcmp(res, "ws")) |
samux | 0:21fe3b05249f | 11 | { |
samux | 0:21fe3b05249f | 12 | this->ip_domain = NULL; |
samux | 0:21fe3b05249f | 13 | this->path = NULL; |
samux | 0:21fe3b05249f | 14 | printf("\r\nFormat error: please use: \"ws://ip-or-domain/path\"\r\n\r\n"); |
samux | 0:21fe3b05249f | 15 | } |
samux | 0:21fe3b05249f | 16 | else |
samux | 0:21fe3b05249f | 17 | { |
samux | 0:21fe3b05249f | 18 | res = strtok(NULL, ":"); |
samux | 0:21fe3b05249f | 19 | res = strtok(res, "/"); |
samux | 0:21fe3b05249f | 20 | if(res != NULL) |
samux | 0:21fe3b05249f | 21 | { |
samux | 0:21fe3b05249f | 22 | ip_domain = (char *) malloc (sizeof(char) * strlen(res)); |
samux | 0:21fe3b05249f | 23 | strcpy(this->ip_domain, res); |
samux | 0:21fe3b05249f | 24 | } |
samux | 0:21fe3b05249f | 25 | res = strtok(NULL, " "); |
samux | 0:21fe3b05249f | 26 | if(res != NULL) |
samux | 0:21fe3b05249f | 27 | { |
samux | 0:21fe3b05249f | 28 | path = (char *) malloc (sizeof(char) * strlen(res)); |
samux | 0:21fe3b05249f | 29 | strcpy(this->path, res); |
samux | 0:21fe3b05249f | 30 | } |
samux | 0:21fe3b05249f | 31 | |
samux | 0:21fe3b05249f | 32 | this->port = port; |
samux | 0:21fe3b05249f | 33 | this->wifi = wifi; |
samux | 0:21fe3b05249f | 34 | |
samux | 0:21fe3b05249f | 35 | } |
samux | 0:21fe3b05249f | 36 | } |
samux | 0:21fe3b05249f | 37 | |
samux | 0:21fe3b05249f | 38 | bool Websocket::connect() |
samux | 0:21fe3b05249f | 39 | { |
samux | 0:21fe3b05249f | 40 | char cmd[50]; |
samux | 0:21fe3b05249f | 41 | wifi->Send("exit\r", "NO"); |
samux | 0:21fe3b05249f | 42 | //enter in cmd mode |
samux | 0:21fe3b05249f | 43 | while(!wifi->Send("$$$", "CMD")) |
samux | 0:21fe3b05249f | 44 | { |
samux | 0:21fe3b05249f | 45 | printf("cannot enter in CMD mode\r\n"); |
samux | 0:21fe3b05249f | 46 | wifi->exit(); |
samux | 0:21fe3b05249f | 47 | } |
samux | 0:21fe3b05249f | 48 | |
samux | 0:21fe3b05249f | 49 | |
samux | 0:21fe3b05249f | 50 | //open the connection |
samux | 0:21fe3b05249f | 51 | sprintf(cmd, "open %s %d\r\n", ip_domain, port); |
samux | 0:21fe3b05249f | 52 | if(!wifi->Send(cmd, "OPEN")) |
samux | 0:21fe3b05249f | 53 | { |
samux | 0:21fe3b05249f | 54 | printf("Websocket::connect cannot open\r\n"); |
samux | 0:21fe3b05249f | 55 | return false; |
samux | 0:21fe3b05249f | 56 | } |
samux | 0:21fe3b05249f | 57 | |
samux | 0:21fe3b05249f | 58 | |
samux | 0:21fe3b05249f | 59 | //send websocket HTTP header |
samux | 0:21fe3b05249f | 60 | sprintf(cmd, "GET /%s HTTP/1.1\r\n", path); |
samux | 0:21fe3b05249f | 61 | wifi->Send(cmd, "NO"); |
samux | 0:21fe3b05249f | 62 | |
samux | 0:21fe3b05249f | 63 | sprintf(cmd, "Host: %s:%d\r\n", ip_domain, port); |
samux | 0:21fe3b05249f | 64 | wifi->Send(cmd, "NO"); |
samux | 0:21fe3b05249f | 65 | |
samux | 0:21fe3b05249f | 66 | wifi->Send("Upgrade: WebSocket\r\n", "NO"); |
samux | 0:21fe3b05249f | 67 | |
samux | 0:21fe3b05249f | 68 | sprintf(cmd, "Origin: http:%s:%d\r\n", ip_domain, port); |
samux | 0:21fe3b05249f | 69 | wifi->Send(cmd, "NO"); |
samux | 0:21fe3b05249f | 70 | |
samux | 0:21fe3b05249f | 71 | |
samux | 0:21fe3b05249f | 72 | wifi->Send("Connection: Upgrade\r\n", "NO"); |
samux | 0:21fe3b05249f | 73 | wifi->Send("Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n", "NO"); |
samux | 0:21fe3b05249f | 74 | wifi->Send("Sec-WebSocket-key2: 12998 5 Y3 1 .P00\r\n\r\n", "NO"); |
samux | 0:21fe3b05249f | 75 | if(!wifi->Send("^n:ds[4U", "8jKS'y:G*Co,Wxa-")) |
samux | 0:21fe3b05249f | 76 | return false; |
samux | 0:21fe3b05249f | 77 | |
samux | 0:21fe3b05249f | 78 | printf("\r\nip_domain: %s\r\npath: /%s\r\nport: %d\r\n\r\n",this->ip_domain, this->path, this->port); |
samux | 0:21fe3b05249f | 79 | return true; |
samux | 0:21fe3b05249f | 80 | } |
samux | 0:21fe3b05249f | 81 | |
samux | 0:21fe3b05249f | 82 | void Websocket::Send(char * str) |
samux | 0:21fe3b05249f | 83 | { |
samux | 0:21fe3b05249f | 84 | char cmd[100]; |
samux | 0:21fe3b05249f | 85 | wifi->putc('\x00'); |
samux | 2:4a841609a3a3 | 86 | sprintf(cmd, "%s%c", str, '\xff'); |
samux | 0:21fe3b05249f | 87 | wifi->Send(cmd, "NO"); |
samux | 0:21fe3b05249f | 88 | } |
samux | 0:21fe3b05249f | 89 | |
samux | 0:21fe3b05249f | 90 | bool Websocket::read(char * message) |
samux | 0:21fe3b05249f | 91 | { |
samux | 0:21fe3b05249f | 92 | int i = 0; |
samux | 0:21fe3b05249f | 93 | char char_read; |
samux | 0:21fe3b05249f | 94 | |
samux | 0:21fe3b05249f | 95 | if (!wifi->readable()) |
samux | 0:21fe3b05249f | 96 | { |
samux | 0:21fe3b05249f | 97 | message = NULL; |
samux | 0:21fe3b05249f | 98 | return false; |
samux | 0:21fe3b05249f | 99 | } |
samux | 0:21fe3b05249f | 100 | |
samux | 0:21fe3b05249f | 101 | if (wifi->getc() != 0x00) |
samux | 0:21fe3b05249f | 102 | { |
samux | 0:21fe3b05249f | 103 | message = NULL; |
samux | 0:21fe3b05249f | 104 | return false; |
samux | 0:21fe3b05249f | 105 | } |
samux | 0:21fe3b05249f | 106 | |
samux | 0:21fe3b05249f | 107 | while ( (char_read = wifi->getc()) != 0xff) |
samux | 0:21fe3b05249f | 108 | message[i++] = char_read; |
samux | 0:21fe3b05249f | 109 | |
samux | 0:21fe3b05249f | 110 | return true; |
samux | 0:21fe3b05249f | 111 | } |
samux | 0:21fe3b05249f | 112 | |
samux | 0:21fe3b05249f | 113 | bool Websocket::close() |
samux | 0:21fe3b05249f | 114 | { |
samux | 0:21fe3b05249f | 115 | if(!wifi->CmdMode()) |
samux | 0:21fe3b05249f | 116 | { |
samux | 0:21fe3b05249f | 117 | printf("Websocket::close: cannot enter in cmd mode\r\n"); |
samux | 0:21fe3b05249f | 118 | return false; |
samux | 0:21fe3b05249f | 119 | } |
samux | 0:21fe3b05249f | 120 | |
samux | 0:21fe3b05249f | 121 | wifi->Send("close\r", "NO"); |
samux | 0:21fe3b05249f | 122 | |
samux | 0:21fe3b05249f | 123 | if(!wifi->exit()) |
samux | 0:21fe3b05249f | 124 | return false; |
samux | 0:21fe3b05249f | 125 | |
samux | 0:21fe3b05249f | 126 | return true; |
samux | 0:21fe3b05249f | 127 | } |
samux | 0:21fe3b05249f | 128 | |
samux | 0:21fe3b05249f | 129 | |
samux | 0:21fe3b05249f | 130 | |
samux | 0:21fe3b05249f | 131 | bool Websocket::connected() |
samux | 0:21fe3b05249f | 132 | { |
samux | 3:9b00db719afa | 133 | char str[10]; |
samux | 0:21fe3b05249f | 134 | |
samux | 3:9b00db719afa | 135 | wait(0.25); |
samux | 0:21fe3b05249f | 136 | if(!wifi->CmdMode()) |
samux | 0:21fe3b05249f | 137 | { |
samux | 0:21fe3b05249f | 138 | printf("Websocket::connected: cannot enter in cmd mode\r\n"); |
samux | 0:21fe3b05249f | 139 | return false; |
samux | 0:21fe3b05249f | 140 | } |
samux | 3:9b00db719afa | 141 | wait(0.25); |
samux | 0:21fe3b05249f | 142 | |
samux | 3:9b00db719afa | 143 | wifi->Send("show c\r\n", "NO"); |
samux | 3:9b00db719afa | 144 | wifi->read(str); |
samux | 3:9b00db719afa | 145 | |
samux | 3:9b00db719afa | 146 | if(str[3] == '1') |
samux | 3:9b00db719afa | 147 | { |
samux | 0:21fe3b05249f | 148 | if(!wifi->exit()) |
samux | 3:9b00db719afa | 149 | { |
samux | 3:9b00db719afa | 150 | printf("Websocket::connected: cannot exit\r\n"); |
samux | 0:21fe3b05249f | 151 | return false; |
samux | 3:9b00db719afa | 152 | } |
samux | 0:21fe3b05249f | 153 | return true; |
samux | 0:21fe3b05249f | 154 | } |
samux | 4:1d3e630b8f9c | 155 | if(!wifi->exit()) |
samux | 4:1d3e630b8f9c | 156 | printf("Websocket::connected: cannot exit\r\n"); |
samux | 3:9b00db719afa | 157 | return false; |
samux | 0:21fe3b05249f | 158 | |
samux | 0:21fe3b05249f | 159 | } |