Arianna autonomous DAQ firmware
Dependencies: mbed SDFileSystemFilinfo AriSnProtocol NetServicesMin AriSnComm MODSERIAL PowerControlClkPatch DS1820OW
Websocket.h@3:24c5f0f50bf1, 2012-07-31 (annotated)
- Committer:
- uci1
- Date:
- Tue Jul 31 04:59:16 2012 +0000
- Revision:
- 3:24c5f0f50bf1
- Parent:
- 2:e67f7c158087
- Child:
- 6:6f002d202f59
Test bench version. Communications not completed. Debugging output present. But will read the local config file and save events that can be used for testing.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
uci1 | 0:664899e0b988 | 1 | /** |
uci1 | 0:664899e0b988 | 2 | * @author Samuel Mokrani |
uci1 | 0:664899e0b988 | 3 | * |
uci1 | 0:664899e0b988 | 4 | * @section LICENSE |
uci1 | 0:664899e0b988 | 5 | * |
uci1 | 0:664899e0b988 | 6 | * Copyright (c) 2011 mbed |
uci1 | 0:664899e0b988 | 7 | * |
uci1 | 0:664899e0b988 | 8 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
uci1 | 0:664899e0b988 | 9 | * of this software and associated documentation files (the "Software"), to deal |
uci1 | 0:664899e0b988 | 10 | * in the Software without restriction, including without limitation the rights |
uci1 | 0:664899e0b988 | 11 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
uci1 | 0:664899e0b988 | 12 | * copies of the Software, and to permit persons to whom the Software is |
uci1 | 0:664899e0b988 | 13 | * furnished to do so, subject to the following conditions: |
uci1 | 0:664899e0b988 | 14 | * |
uci1 | 0:664899e0b988 | 15 | * The above copyright notice and this permission notice shall be included in |
uci1 | 0:664899e0b988 | 16 | * all copies or substantial portions of the Software. |
uci1 | 0:664899e0b988 | 17 | * |
uci1 | 0:664899e0b988 | 18 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
uci1 | 0:664899e0b988 | 19 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
uci1 | 0:664899e0b988 | 20 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
uci1 | 0:664899e0b988 | 21 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
uci1 | 0:664899e0b988 | 22 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
uci1 | 0:664899e0b988 | 23 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
uci1 | 0:664899e0b988 | 24 | * THE SOFTWARE. |
uci1 | 0:664899e0b988 | 25 | * |
uci1 | 0:664899e0b988 | 26 | * @section DESCRIPTION |
uci1 | 0:664899e0b988 | 27 | * Simple websocket client |
uci1 | 0:664899e0b988 | 28 | * |
uci1 | 0:664899e0b988 | 29 | */ |
uci1 | 0:664899e0b988 | 30 | |
uci1 | 0:664899e0b988 | 31 | #ifndef WEBSOCKET_H |
uci1 | 0:664899e0b988 | 32 | #define WEBSOCKET_H |
uci1 | 0:664899e0b988 | 33 | |
uci1 | 0:664899e0b988 | 34 | #include "mbed.h" |
uci1 | 0:664899e0b988 | 35 | //#include "Wifly.h" |
uci1 | 0:664899e0b988 | 36 | #include <string> |
uci1 | 0:664899e0b988 | 37 | |
uci1 | 0:664899e0b988 | 38 | |
uci1 | 0:664899e0b988 | 39 | #ifdef TARGET_LPC1768 |
uci1 | 0:664899e0b988 | 40 | #include "EthernetNetIf.h" |
uci1 | 0:664899e0b988 | 41 | #include "TCPSocket.h" |
uci1 | 0:664899e0b988 | 42 | #include "dnsresolve.h" |
uci1 | 0:664899e0b988 | 43 | #endif //target |
uci1 | 0:664899e0b988 | 44 | |
uci1 | 3:24c5f0f50bf1 | 45 | #define RX_BUF_SIZE 1024 |
uci1 | 3:24c5f0f50bf1 | 46 | #define RX_RECV_BYTES 512 |
uci1 | 0:664899e0b988 | 47 | |
uci1 | 0:664899e0b988 | 48 | /** Websocket client Class. |
uci1 | 0:664899e0b988 | 49 | * |
uci1 | 0:664899e0b988 | 50 | * Warning: you must use a wifi module (Wifly RN131-C) or an ethernet network to use this class |
uci1 | 0:664899e0b988 | 51 | * |
uci1 | 0:664899e0b988 | 52 | * Example (wifi network): |
uci1 | 0:664899e0b988 | 53 | * @code |
uci1 | 0:664899e0b988 | 54 | * #include "mbed.h" |
uci1 | 0:664899e0b988 | 55 | * #include "Wifly.h" |
uci1 | 0:664899e0b988 | 56 | * #include "Websocket.h" |
uci1 | 0:664899e0b988 | 57 | * |
uci1 | 0:664899e0b988 | 58 | * DigitalOut l1(LED1); |
uci1 | 0:664899e0b988 | 59 | * |
uci1 | 0:664899e0b988 | 60 | * //Here, we create an instance, with pins 9 and 10 connecting to the |
uci1 | 0:664899e0b988 | 61 | * //WiFly's TX and RX pins, and pin 21 to RESET. We are connecting to the |
uci1 | 0:664899e0b988 | 62 | * //"mbed" network, password "password", and we are using WPA. |
uci1 | 0:664899e0b988 | 63 | * Wifly wifly(p9, p10, p21, "mbed", "password", true); |
uci1 | 0:664899e0b988 | 64 | * |
uci1 | 0:664899e0b988 | 65 | * //Here, we create a Websocket instance in 'wo' (write-only) mode |
uci1 | 0:664899e0b988 | 66 | * //on the 'samux' channel |
uci1 | 0:664899e0b988 | 67 | * Websocket ws("ws://sockets.mbed.org/ws/samux/wo", &wifly); |
uci1 | 0:664899e0b988 | 68 | * |
uci1 | 0:664899e0b988 | 69 | * |
uci1 | 0:664899e0b988 | 70 | * int main() { |
uci1 | 0:664899e0b988 | 71 | * while (1) { |
uci1 | 0:664899e0b988 | 72 | * |
uci1 | 0:664899e0b988 | 73 | * //we connect the network |
uci1 | 0:664899e0b988 | 74 | * while (!wifly.join()) { |
uci1 | 0:664899e0b988 | 75 | * wifly.reset(); |
uci1 | 0:664899e0b988 | 76 | * } |
uci1 | 0:664899e0b988 | 77 | * |
uci1 | 0:664899e0b988 | 78 | * //we connect to the websocket server |
uci1 | 0:664899e0b988 | 79 | * while (!ws.connect()); |
uci1 | 0:664899e0b988 | 80 | * |
uci1 | 0:664899e0b988 | 81 | * while (1) { |
uci1 | 0:664899e0b988 | 82 | * wait(0.5); |
uci1 | 0:664899e0b988 | 83 | * |
uci1 | 0:664899e0b988 | 84 | * //Send Hello world |
uci1 | 0:664899e0b988 | 85 | * ws.send("Hello World! over Wifi"); |
uci1 | 0:664899e0b988 | 86 | * |
uci1 | 0:664899e0b988 | 87 | * // show that we are alive |
uci1 | 0:664899e0b988 | 88 | * l1 = !l1; |
uci1 | 0:664899e0b988 | 89 | * } |
uci1 | 0:664899e0b988 | 90 | * } |
uci1 | 0:664899e0b988 | 91 | * } |
uci1 | 0:664899e0b988 | 92 | * @endcode |
uci1 | 0:664899e0b988 | 93 | * |
uci1 | 0:664899e0b988 | 94 | * |
uci1 | 0:664899e0b988 | 95 | * |
uci1 | 0:664899e0b988 | 96 | * Example (ethernet network): |
uci1 | 0:664899e0b988 | 97 | * @code |
uci1 | 0:664899e0b988 | 98 | * #include "mbed.h" |
uci1 | 0:664899e0b988 | 99 | * #include "Websocket.h" |
uci1 | 0:664899e0b988 | 100 | * |
uci1 | 0:664899e0b988 | 101 | * Timer tmr; |
uci1 | 0:664899e0b988 | 102 | * |
uci1 | 0:664899e0b988 | 103 | * //Here, we create a Websocket instance in 'wo' (write-only) mode |
uci1 | 0:664899e0b988 | 104 | * //on the 'samux' channel |
uci1 | 0:664899e0b988 | 105 | * Websocket ws("ws://sockets.mbed.org/ws/samux/wo"); |
uci1 | 0:664899e0b988 | 106 | * |
uci1 | 0:664899e0b988 | 107 | * int main() { |
uci1 | 0:664899e0b988 | 108 | * while (1) { |
uci1 | 0:664899e0b988 | 109 | * |
uci1 | 0:664899e0b988 | 110 | * while (!ws.connect()); |
uci1 | 0:664899e0b988 | 111 | * |
uci1 | 0:664899e0b988 | 112 | * tmr.start(); |
uci1 | 0:664899e0b988 | 113 | * while (1) { |
uci1 | 0:664899e0b988 | 114 | * if (tmr.read() > 0.5) { |
uci1 | 0:664899e0b988 | 115 | * ws.send("Hello World! over Ethernet"); |
uci1 | 0:664899e0b988 | 116 | * tmr.start(); |
uci1 | 0:664899e0b988 | 117 | * } |
uci1 | 0:664899e0b988 | 118 | * Net::poll(); |
uci1 | 0:664899e0b988 | 119 | * } |
uci1 | 0:664899e0b988 | 120 | * } |
uci1 | 0:664899e0b988 | 121 | * } |
uci1 | 0:664899e0b988 | 122 | * @endcode |
uci1 | 0:664899e0b988 | 123 | */ |
uci1 | 0:664899e0b988 | 124 | class Websocket |
uci1 | 0:664899e0b988 | 125 | { |
uci1 | 0:664899e0b988 | 126 | public: |
uci1 | 0:664899e0b988 | 127 | /** |
uci1 | 0:664899e0b988 | 128 | * Constructor |
uci1 | 0:664899e0b988 | 129 | * |
uci1 | 0:664899e0b988 | 130 | * @param url The Websocket url in the form "ws://ip_domain[:port]/path" (by default: port = 80) |
uci1 | 0:664899e0b988 | 131 | * @param wifi pointer to a wifi module (the communication will be establish by this module) |
uci1 | 0:664899e0b988 | 132 | */ |
uci1 | 0:664899e0b988 | 133 | // Websocket(char * url, Wifly * wifi); |
uci1 | 0:664899e0b988 | 134 | |
uci1 | 0:664899e0b988 | 135 | #ifdef TARGET_LPC1768 |
uci1 | 0:664899e0b988 | 136 | /** |
uci1 | 0:664899e0b988 | 137 | * Constructor for an ethernet communication |
uci1 | 0:664899e0b988 | 138 | * |
uci1 | 0:664899e0b988 | 139 | * @param url The Websocket url in the form "ws://ip_domain[:port]/path" (by default: port = 80) |
uci1 | 0:664899e0b988 | 140 | */ |
uci1 | 0:664899e0b988 | 141 | Websocket(char * url); |
uci1 | 0:664899e0b988 | 142 | #endif //target |
uci1 | 0:664899e0b988 | 143 | |
uci1 | 0:664899e0b988 | 144 | /** |
uci1 | 0:664899e0b988 | 145 | * Connect to the websocket url |
uci1 | 0:664899e0b988 | 146 | * |
uci1 | 0:664899e0b988 | 147 | *@return true if the connection is established, false otherwise |
uci1 | 0:664899e0b988 | 148 | */ |
uci1 | 3:24c5f0f50bf1 | 149 | bool connect(const uint32_t timeout); |
uci1 | 0:664899e0b988 | 150 | |
uci1 | 0:664899e0b988 | 151 | /** |
uci1 | 0:664899e0b988 | 152 | * Send a string according to the websocket format |
uci1 | 0:664899e0b988 | 153 | * |
uci1 | 0:664899e0b988 | 154 | * @param str string to be sent |
uci1 | 0:664899e0b988 | 155 | */ |
uci1 | 3:24c5f0f50bf1 | 156 | void send(const char * str); |
uci1 | 0:664899e0b988 | 157 | |
uci1 | 0:664899e0b988 | 158 | // CJR: add ones for binary data |
uci1 | 3:24c5f0f50bf1 | 159 | bool sendBinary(const char* str, const uint32_t len, char* const bbuf); |
uci1 | 3:24c5f0f50bf1 | 160 | bool sendBinary(const char* hbuf, const uint32_t hlen, FILE* f, const uint32_t nbytes, |
uci1 | 3:24c5f0f50bf1 | 161 | char* const bbuf); |
uci1 | 0:664899e0b988 | 162 | |
uci1 | 0:664899e0b988 | 163 | /** |
uci1 | 0:664899e0b988 | 164 | * Read a websocket message |
uci1 | 0:664899e0b988 | 165 | * |
uci1 | 0:664899e0b988 | 166 | * @param message pointer to the string to be read (null if drop frame) |
uci1 | 0:664899e0b988 | 167 | * |
uci1 | 0:664899e0b988 | 168 | * @return true if a string has been read, false otherwise |
uci1 | 0:664899e0b988 | 169 | */ |
uci1 | 3:24c5f0f50bf1 | 170 | bool read(char * message, uint32_t& len_msg, const uint32_t maxlen, |
uci1 | 3:24c5f0f50bf1 | 171 | const uint32_t timeout, |
uci1 | 3:24c5f0f50bf1 | 172 | char* const bbuf, const uint32_t bbsize); |
uci1 | 0:664899e0b988 | 173 | |
uci1 | 0:664899e0b988 | 174 | /** |
uci1 | 0:664899e0b988 | 175 | * To see if there is a websocket connection active |
uci1 | 0:664899e0b988 | 176 | * |
uci1 | 0:664899e0b988 | 177 | * @return true if there is a connection active |
uci1 | 0:664899e0b988 | 178 | */ |
uci1 | 0:664899e0b988 | 179 | bool connected(); |
uci1 | 0:664899e0b988 | 180 | |
uci1 | 0:664899e0b988 | 181 | /** |
uci1 | 0:664899e0b988 | 182 | * Close the websocket connection |
uci1 | 0:664899e0b988 | 183 | * |
uci1 | 0:664899e0b988 | 184 | * @return true if the connection has been closed, false otherwise |
uci1 | 0:664899e0b988 | 185 | */ |
uci1 | 0:664899e0b988 | 186 | bool close(); |
uci1 | 0:664899e0b988 | 187 | |
uci1 | 0:664899e0b988 | 188 | /** |
uci1 | 0:664899e0b988 | 189 | * Accessor: get path from the websocket url |
uci1 | 0:664899e0b988 | 190 | * |
uci1 | 0:664899e0b988 | 191 | * @return path |
uci1 | 0:664899e0b988 | 192 | */ |
uci1 | 0:664899e0b988 | 193 | std::string getPath(); |
uci1 | 0:664899e0b988 | 194 | |
uci1 | 0:664899e0b988 | 195 | enum Type { |
uci1 | 0:664899e0b988 | 196 | WIF, |
uci1 | 0:664899e0b988 | 197 | ETH |
uci1 | 0:664899e0b988 | 198 | }; |
uci1 | 0:664899e0b988 | 199 | |
uci1 | 0:664899e0b988 | 200 | |
uci1 | 0:664899e0b988 | 201 | private: |
uci1 | 0:664899e0b988 | 202 | |
uci1 | 3:24c5f0f50bf1 | 203 | bool sendBinaryDirect(const char* str, const uint32_t len); |
uci1 | 3:24c5f0f50bf1 | 204 | bool sendBinaryDirect(const char* hbuf, const uint32_t hlen, FILE* f, const uint32_t nbytes); |
uci1 | 3:24c5f0f50bf1 | 205 | bool sendBinaryB64txt(const char* str, const uint32_t len, char* const bbuf); |
uci1 | 3:24c5f0f50bf1 | 206 | bool sendBinaryB64txt(const char* hbuf, const uint32_t hlen, FILE* f, const uint32_t nbytes, |
uci1 | 3:24c5f0f50bf1 | 207 | char* const bbuf); |
uci1 | 3:24c5f0f50bf1 | 208 | |
uci1 | 0:664899e0b988 | 209 | void fillFields(char * url); |
uci1 | 0:664899e0b988 | 210 | void sendOpcode(uint8_t opcode); |
uci1 | 0:664899e0b988 | 211 | void sendLength(uint32_t len); |
uci1 | 0:664899e0b988 | 212 | void sendMask(); |
uci1 | 0:664899e0b988 | 213 | int sendChar(uint8_t c); |
uci1 | 0:664899e0b988 | 214 | |
uci1 | 0:664899e0b988 | 215 | std::string ip_domain; |
uci1 | 0:664899e0b988 | 216 | std::string path; |
uci1 | 0:664899e0b988 | 217 | std::string port; |
uci1 | 0:664899e0b988 | 218 | |
uci1 | 0:664899e0b988 | 219 | // Wifly * wifi; |
uci1 | 0:664899e0b988 | 220 | |
uci1 | 0:664899e0b988 | 221 | #ifdef TARGET_LPC1768 |
uci1 | 0:664899e0b988 | 222 | void onTCPSocketEvent(TCPSocketEvent e); |
uci1 | 0:664899e0b988 | 223 | bool eth_connected; |
uci1 | 0:664899e0b988 | 224 | bool eth_readable; |
uci1 | 0:664899e0b988 | 225 | bool eth_writeable; |
uci1 | 3:24c5f0f50bf1 | 226 | char eth_rx[RX_BUF_SIZE]; |
uci1 | 0:664899e0b988 | 227 | bool response_server_eth; |
uci1 | 0:664899e0b988 | 228 | bool new_msg; |
uci1 | 0:664899e0b988 | 229 | |
uci1 | 0:664899e0b988 | 230 | EthernetNetIf * eth; |
uci1 | 0:664899e0b988 | 231 | TCPSocket * sock; |
uci1 | 0:664899e0b988 | 232 | IpAddr * server_ip; |
uci1 | 0:664899e0b988 | 233 | #endif //target |
uci1 | 0:664899e0b988 | 234 | |
uci1 | 0:664899e0b988 | 235 | Type netif; |
uci1 | 3:24c5f0f50bf1 | 236 | |
uci1 | 3:24c5f0f50bf1 | 237 | static const bool kUseB64; |
uci1 | 0:664899e0b988 | 238 | }; |
uci1 | 0:664899e0b988 | 239 | |
uci1 | 0:664899e0b988 | 240 | #endif |