websocket client

Fork of WebSocketClient by Samuel Mokrani

Committer:
kanehara
Date:
Thu Feb 04 15:49:27 2016 +0000
Revision:
9:6275000e9224
Parent:
8:a909ee26be2d
fix the newline character.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kanehara 9:6275000e9224 1 /**
kanehara 9:6275000e9224 2 * @author Samuel Mokrani
kanehara 9:6275000e9224 3 *
kanehara 9:6275000e9224 4 * @section LICENSE
kanehara 9:6275000e9224 5 *
kanehara 9:6275000e9224 6 * Copyright (c) 2011 mbed
kanehara 9:6275000e9224 7 *
kanehara 9:6275000e9224 8 * Permission is hereby granted, free of charge, to any person obtaining a copy
kanehara 9:6275000e9224 9 * of this software and associated documentation files (the "Software"), to deal
kanehara 9:6275000e9224 10 * in the Software without restriction, including without limitation the rights
kanehara 9:6275000e9224 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
kanehara 9:6275000e9224 12 * copies of the Software, and to permit persons to whom the Software is
kanehara 9:6275000e9224 13 * furnished to do so, subject to the following conditions:
kanehara 9:6275000e9224 14 *
kanehara 9:6275000e9224 15 * The above copyright notice and this permission notice shall be included in
kanehara 9:6275000e9224 16 * all copies or substantial portions of the Software.
kanehara 9:6275000e9224 17 *
kanehara 9:6275000e9224 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
kanehara 9:6275000e9224 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
kanehara 9:6275000e9224 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
kanehara 9:6275000e9224 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
kanehara 9:6275000e9224 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
kanehara 9:6275000e9224 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
kanehara 9:6275000e9224 24 * THE SOFTWARE.
kanehara 9:6275000e9224 25 *
kanehara 9:6275000e9224 26 * @section DESCRIPTION
kanehara 9:6275000e9224 27 * Simple websocket client
kanehara 9:6275000e9224 28 *
kanehara 9:6275000e9224 29 */
kanehara 9:6275000e9224 30
kanehara 9:6275000e9224 31 #ifndef WEBSOCKET_H
kanehara 9:6275000e9224 32 #define WEBSOCKET_H
kanehara 9:6275000e9224 33
kanehara 9:6275000e9224 34 #include "mbed.h"
kanehara 9:6275000e9224 35
kanehara 9:6275000e9224 36 #include "TCPSocketConnection.h"
kanehara 9:6275000e9224 37
kanehara 9:6275000e9224 38 /** Websocket client Class.
kanehara 9:6275000e9224 39 *
kanehara 9:6275000e9224 40 * Example (ethernet network):
kanehara 9:6275000e9224 41 * @code
kanehara 9:6275000e9224 42 * #include "mbed.h"
kanehara 9:6275000e9224 43 * #include "EthernetInterface.h"
kanehara 9:6275000e9224 44 * #include "Websocket.h"
kanehara 9:6275000e9224 45 *
kanehara 9:6275000e9224 46 * int main() {
kanehara 9:6275000e9224 47 * EthernetInterface eth;
kanehara 9:6275000e9224 48 * eth.init(); //Use DHCP
kanehara 9:6275000e9224 49 * eth.connect();
kanehara 9:6275000e9224 50 * printf("IP Address is %s\n\r", eth.getIPAddress());
kanehara 9:6275000e9224 51 *
kanehara 9:6275000e9224 52 * Websocket ws("ws://sockets.mbed.org:443/ws/demo/rw");
kanehara 9:6275000e9224 53 * ws.connect();
kanehara 9:6275000e9224 54 *
kanehara 9:6275000e9224 55 * while (1) {
kanehara 9:6275000e9224 56 * int res = ws.send("WebSocket Hello World!");
kanehara 9:6275000e9224 57 *
kanehara 9:6275000e9224 58 * if (ws.read(recv)) {
kanehara 9:6275000e9224 59 * printf("rcv: %s\r\n", recv);
kanehara 9:6275000e9224 60 * }
kanehara 9:6275000e9224 61 *
kanehara 9:6275000e9224 62 * wait(0.1);
kanehara 9:6275000e9224 63 * }
kanehara 9:6275000e9224 64 * }
kanehara 9:6275000e9224 65 * @endcode
kanehara 9:6275000e9224 66 */
kanehara 9:6275000e9224 67
kanehara 9:6275000e9224 68 class Websocket
kanehara 9:6275000e9224 69 {
kanehara 9:6275000e9224 70 public:
kanehara 9:6275000e9224 71 class MemBuf {
kanehara 9:6275000e9224 72 public:
kanehara 9:6275000e9224 73 static const int maxsize = 1024; // more than 200
kanehara 9:6275000e9224 74 char mem[maxsize];
kanehara 9:6275000e9224 75 char* ptr;
kanehara 9:6275000e9224 76 ssize_t size;
kanehara 9:6275000e9224 77
kanehara 9:6275000e9224 78 MemBuf () {
kanehara 9:6275000e9224 79 init ();
kanehara 9:6275000e9224 80 };
kanehara 9:6275000e9224 81 ~MemBuf () {};
kanehara 9:6275000e9224 82 void init () {
kanehara 9:6275000e9224 83 ptr = mem;
kanehara 9:6275000e9224 84 size = 0;
kanehara 9:6275000e9224 85 };
kanehara 9:6275000e9224 86 size_t alloc (size_t s) {
kanehara 9:6275000e9224 87 if (maxsize - (ptr - mem + size) >= s) {
kanehara 9:6275000e9224 88 return s;
kanehara 9:6275000e9224 89 } else {
kanehara 9:6275000e9224 90 memmove (mem, ptr, size);
kanehara 9:6275000e9224 91 ptr = mem;
kanehara 9:6275000e9224 92 if (maxsize - size >= s) {
kanehara 9:6275000e9224 93 return s;
kanehara 9:6275000e9224 94 } else {
kanehara 9:6275000e9224 95 return maxsize - size;
kanehara 9:6275000e9224 96 }
kanehara 9:6275000e9224 97 }
kanehara 9:6275000e9224 98 };
kanehara 9:6275000e9224 99 void skip (size_t s) {
kanehara 9:6275000e9224 100 ptr += s;
kanehara 9:6275000e9224 101 size -= s;
kanehara 9:6275000e9224 102 };
kanehara 9:6275000e9224 103 void skipTo (char* p) {
kanehara 9:6275000e9224 104 size -= p - ptr;
kanehara 9:6275000e9224 105 ptr = p;
kanehara 9:6275000e9224 106 };
kanehara 9:6275000e9224 107 };
kanehara 9:6275000e9224 108
kanehara 9:6275000e9224 109 /**
kanehara 9:6275000e9224 110 * Constructor
kanehara 9:6275000e9224 111 *
kanehara 9:6275000e9224 112 * @param url The Websocket url in the form "ws://ip_domain[:port]/path" (by default: port = 80)
kanehara 9:6275000e9224 113 */
kanehara 9:6275000e9224 114 Websocket(const char * url);
kanehara 9:6275000e9224 115 ~Websocket ();
kanehara 9:6275000e9224 116
kanehara 9:6275000e9224 117 void setFnPing (void (*fn)());
kanehara 9:6275000e9224 118
kanehara 9:6275000e9224 119 /**
kanehara 9:6275000e9224 120 * Connect to the websocket url
kanehara 9:6275000e9224 121 *
kanehara 9:6275000e9224 122 *@return true if the connection is established, false otherwise
kanehara 9:6275000e9224 123 */
kanehara 9:6275000e9224 124 bool connect();
kanehara 9:6275000e9224 125
kanehara 9:6275000e9224 126 /**
kanehara 9:6275000e9224 127 * Send a string according to the websocket format (see rfc 6455)
kanehara 9:6275000e9224 128 *
kanehara 9:6275000e9224 129 * @param str string to be sent
kanehara 9:6275000e9224 130 *
kanehara 9:6275000e9224 131 * @returns the number of bytes sent
kanehara 9:6275000e9224 132 */
kanehara 9:6275000e9224 133 int sendOp(uint8_t opcode, size_t len, char* str);
kanehara 9:6275000e9224 134 int send(char * str);
kanehara 9:6275000e9224 135 int sendBin(size_t len, char* str);
kanehara 9:6275000e9224 136
kanehara 9:6275000e9224 137 /**
kanehara 9:6275000e9224 138 * Read a websocket message
kanehara 9:6275000e9224 139 *
kanehara 9:6275000e9224 140 * @param message pointer to the string to be read (null if drop frame)
kanehara 9:6275000e9224 141 *
kanehara 9:6275000e9224 142 * @return true if a websocket frame has been read
kanehara 9:6275000e9224 143 */
kanehara 9:6275000e9224 144 bool read(char * message, size_t& size);
kanehara 9:6275000e9224 145
kanehara 9:6275000e9224 146 /**
kanehara 9:6275000e9224 147 * To see if there is a websocket connection active
kanehara 9:6275000e9224 148 *
kanehara 9:6275000e9224 149 * @return true if there is a connection active
kanehara 9:6275000e9224 150 */
kanehara 9:6275000e9224 151 bool is_connected();
kanehara 9:6275000e9224 152
kanehara 9:6275000e9224 153 /**
kanehara 9:6275000e9224 154 * Close the websocket connection
kanehara 9:6275000e9224 155 *
kanehara 9:6275000e9224 156 * @return true if the connection has been closed, false otherwise
kanehara 9:6275000e9224 157 */
kanehara 9:6275000e9224 158 bool close();
kanehara 9:6275000e9224 159
kanehara 9:6275000e9224 160 /*
kanehara 9:6275000e9224 161 * Accessor: get path from the websocket url
kanehara 9:6275000e9224 162 *
kanehara 9:6275000e9224 163 * @return path
kanehara 9:6275000e9224 164 */
kanehara 9:6275000e9224 165 char* getPath();
kanehara 9:6275000e9224 166
kanehara 9:6275000e9224 167 private:
kanehara 9:6275000e9224 168
kanehara 9:6275000e9224 169 void fillFields(const char * url);
kanehara 9:6275000e9224 170 int parseURL(const char* url, char* scheme, size_t maxSchemeLen, char* host, size_t maxHostLen, uint16_t* port, char* path, size_t maxPathLen); //Parse URL
kanehara 9:6275000e9224 171 int sendOpcode(uint8_t opcode, char * msg);
kanehara 9:6275000e9224 172 int sendLength(uint32_t len, char * msg);
kanehara 9:6275000e9224 173 int sendMask(char * msg);
kanehara 9:6275000e9224 174 int readChar(char * pC, bool block = true);
kanehara 9:6275000e9224 175
kanehara 9:6275000e9224 176 char scheme[8];
kanehara 9:6275000e9224 177 uint16_t port;
kanehara 9:6275000e9224 178 char host[32];
kanehara 9:6275000e9224 179 char path[64];
kanehara 9:6275000e9224 180 void (*fnPing)();
kanehara 9:6275000e9224 181
kanehara 9:6275000e9224 182 TCPSocketConnection socket;
kanehara 9:6275000e9224 183 MemBuf membuf;
kanehara 9:6275000e9224 184
kanehara 9:6275000e9224 185 int read(char * buf, int len, int min_len = -1);
kanehara 9:6275000e9224 186 int write(char * buf, int len);
kanehara 9:6275000e9224 187
kanehara 9:6275000e9224 188 uint32_t readLenFrame (char* mask);
kanehara 9:6275000e9224 189 bool readBinFrame (char * message, size_t& size);
kanehara 9:6275000e9224 190 bool readPing ();
kanehara 9:6275000e9224 191 };
kanehara 9:6275000e9224 192
kanehara 9:6275000e9224 193 #endif