|
| 1 | +/** @file |
| 2 | + * @brief Websocket API |
| 3 | + * |
| 4 | + * An API for applications to setup websocket connections |
| 5 | + */ |
| 6 | + |
| 7 | +/* |
| 8 | + * Copyright (c) 2019 Intel Corporation |
| 9 | + * |
| 10 | + * SPDX-License-Identifier: Apache-2.0 |
| 11 | + */ |
| 12 | + |
| 13 | +#ifndef ZEPHYR_INCLUDE_NET_WEBSOCKET_H_ |
| 14 | +#define ZEPHYR_INCLUDE_NET_WEBSOCKET_H_ |
| 15 | + |
| 16 | +#include <kernel.h> |
| 17 | + |
| 18 | +#include <net/net_ip.h> |
| 19 | +#include <net/http_parser.h> |
| 20 | +#include <net/http_client.h> |
| 21 | + |
| 22 | +#ifdef __cplusplus |
| 23 | +extern "C" { |
| 24 | +#endif |
| 25 | + |
| 26 | +/** |
| 27 | + * @brief Websocket API |
| 28 | + * @defgroup websocket Websocket API |
| 29 | + * @ingroup networking |
| 30 | + * @{ |
| 31 | + */ |
| 32 | + |
| 33 | +/** Message type values. Returned in websocket_recv_msg() */ |
| 34 | +#define WEBSOCKET_FLAG_FINAL 0x00000001 /**< Final frame */ |
| 35 | +#define WEBSOCKET_FLAG_TEXT 0x00000002 /**< Textual data */ |
| 36 | +#define WEBSOCKET_FLAG_BINARY 0x00000004 /**< Binary data */ |
| 37 | +#define WEBSOCKET_FLAG_CLOSE 0x00000008 /**< Closing connection */ |
| 38 | +#define WEBSOCKET_FLAG_PING 0x00000010 /**< Ping message */ |
| 39 | +#define WEBSOCKET_FLAG_PONG 0x00000011 /**< Pong message */ |
| 40 | + |
| 41 | +enum websocket_opcode { |
| 42 | + WEBSOCKET_OPCODE_CONTINUE = 0x00, |
| 43 | + WEBSOCKET_OPCODE_DATA_TEXT = 0x01, |
| 44 | + WEBSOCKET_OPCODE_DATA_BINARY = 0x02, |
| 45 | + WEBSOCKET_OPCODE_CLOSE = 0x08, |
| 46 | + WEBSOCKET_OPCODE_PING = 0x09, |
| 47 | + WEBSOCKET_OPCODE_PONG = 0x0A, |
| 48 | +}; |
| 49 | + |
| 50 | +/** |
| 51 | + * @typedef websocket_connect_cb_t |
| 52 | + * @brief Callback called after Websocket connection is established. |
| 53 | + * |
| 54 | + * @param sock Websocket id |
| 55 | + * @param req HTTP handshake request |
| 56 | + * @param user_data A valid pointer on some user data or NULL |
| 57 | + * |
| 58 | + * @return 0 if ok, <0 if there is an error and connection should be aborted |
| 59 | + */ |
| 60 | +typedef int (*websocket_connect_cb_t)(int ws_sock, struct http_request *req, |
| 61 | + void *user_data); |
| 62 | + |
| 63 | +/** |
| 64 | + * Websocket client connection request. This contains all the data that is |
| 65 | + * needed when doing a Websocket connection request. |
| 66 | + */ |
| 67 | +struct websocket_request { |
| 68 | + /** Host of the Websocket server when doing HTTP handshakes. */ |
| 69 | + const char *host; |
| 70 | + |
| 71 | + /** URL of the Websocket. */ |
| 72 | + const char *url; |
| 73 | + |
| 74 | + /** User supplied callback function to call when optional headers need |
| 75 | + * to be sent. This can be NULL, in which case the optional_headers |
| 76 | + * field in http_request is used. The idea of this optional_headers |
| 77 | + * callback is to allow user to send more HTTP header data that is |
| 78 | + * practical to store in allocated memory. |
| 79 | + */ |
| 80 | + http_header_cb_t optional_headers_cb; |
| 81 | + |
| 82 | + /** A NULL terminated list of any optional headers that |
| 83 | + * should be added to the HTTP request. May be NULL. |
| 84 | + * If the optional_headers_cb is specified, then this field is ignored. |
| 85 | + */ |
| 86 | + const char **optional_headers; |
| 87 | + |
| 88 | + /** User supplied callback function to call when a connection is |
| 89 | + * established. |
| 90 | + */ |
| 91 | + websocket_connect_cb_t cb; |
| 92 | + |
| 93 | + /** User supplied list of callback functions if the calling application |
| 94 | + * wants to know the parsing status or the HTTP fields during the |
| 95 | + * handshake. This is optional parameter and normally not needed but |
| 96 | + * is useful if the caller wants to know something about |
| 97 | + * the fields that the server is sending. |
| 98 | + */ |
| 99 | + const struct http_parser_settings *http_cb; |
| 100 | + |
| 101 | + /** User supplied buffer where HTTP connection data is stored */ |
| 102 | + u8_t *tmp_buf; |
| 103 | + |
| 104 | + /** Length of the user supplied temp buffer */ |
| 105 | + size_t tmp_buf_len; |
| 106 | +}; |
| 107 | + |
| 108 | +/** |
| 109 | + * @brief Connect to a server that provides Websocket service. The callback is |
| 110 | + * called after connection is established. The returned value is a new socket |
| 111 | + * descriptor that can be used to send / receive data using the BSD socket API. |
| 112 | + * |
| 113 | + * @param http_sock Socket id to the server. Note that this socket is used to do |
| 114 | + * HTTP handshakes etc. The actual Websocket connectivity is done via the |
| 115 | + * returned websocket id. Note that the http_sock must not be closed |
| 116 | + * after this function returns as it is used to deliver the Websocket |
| 117 | + * packets to the Websocket server. |
| 118 | + * @param req Websocket request. User should allocate and fill the request |
| 119 | + * data. |
| 120 | + * @param timeout Max timeout to wait for the connection. The timeout value |
| 121 | + * cannot be 0 as there would be no time to receive the data. |
| 122 | + * @param user_data User specified data that is passed to the callback. |
| 123 | + * |
| 124 | + * @return Websocket id to be used when sending/receiving Websocket data. |
| 125 | + */ |
| 126 | +int websocket_connect(int http_sock, struct websocket_request *req, |
| 127 | + s32_t timeout, void *user_data); |
| 128 | + |
| 129 | +/** |
| 130 | + * @brief Send websocket msg to peer. |
| 131 | + * |
| 132 | + * @details The function will automatically add websocket header to the |
| 133 | + * message. |
| 134 | + * |
| 135 | + * @param ws_sock Websocket id returned by websocket_connect(). |
| 136 | + * @param payload Websocket data to send. |
| 137 | + * @param payload_len Length of the data to be sent. |
| 138 | + * @param opcode Operation code (text, binary, ping, pong, close) |
| 139 | + * @param mask Mask the data, see RFC 6455 for details |
| 140 | + * @param final Is this final message for this message send. If final == false, |
| 141 | + * then the first message must have valid opcode and subsequent messages |
| 142 | + * must have opcode WEBSOCKET_OPCODE_CONTINUE. If final == true and this |
| 143 | + * is the only message, then opcode should have proper opcode (text or |
| 144 | + * binary) set. |
| 145 | + * @param timeout How long to try to send the message. |
| 146 | + * |
| 147 | + * @return <0 if error, >=0 amount of bytes sent |
| 148 | + */ |
| 149 | +int websocket_send_msg(int ws_sock, const u8_t *payload, size_t payload_len, |
| 150 | + enum websocket_opcode opcode, bool mask, bool final, |
| 151 | + s32_t timeout); |
| 152 | + |
| 153 | +/** |
| 154 | + * @brief Receive websocket msg from peer. |
| 155 | + * |
| 156 | + * @details The function will automatically remove websocket header from the |
| 157 | + * message. |
| 158 | + * |
| 159 | + * @param ws_sock Websocket id returned by websocket_connect(). |
| 160 | + * @param buf Buffer where websocket data is read. |
| 161 | + * @param buf_len Length of the data buffer. |
| 162 | + * @param message_type Type of the message. |
| 163 | + * @param remaining How much there is data left in the message after this read. |
| 164 | + * @param timeout How long to try to receive the message. |
| 165 | + * |
| 166 | + * @return <0 if error, >=0 amount of bytes received |
| 167 | + */ |
| 168 | +int websocket_recv_msg(int ws_sock, u8_t *buf, size_t buf_len, |
| 169 | + u32_t *message_type, u64_t *remaining, s32_t timeout); |
| 170 | + |
| 171 | +/** |
| 172 | + * @brief Close websocket. |
| 173 | + * |
| 174 | + * @details One must call websocket_connect() after this call to re-establish |
| 175 | + * the connection. |
| 176 | + * |
| 177 | + * @param ws_sock Websocket id returned by websocket_connect(). |
| 178 | + */ |
| 179 | +int websocket_disconnect(int ws_sock); |
| 180 | + |
| 181 | +#if defined(CONFIG_WEBSOCKET_CLIENT) |
| 182 | +void websocket_init(void); |
| 183 | +#else |
| 184 | +static inline void websocket_init(void) |
| 185 | +{ |
| 186 | +} |
| 187 | +#endif |
| 188 | + |
| 189 | +#ifdef __cplusplus |
| 190 | +} |
| 191 | +#endif |
| 192 | + |
| 193 | +/** |
| 194 | + * @} |
| 195 | + */ |
| 196 | + |
| 197 | +#endif /* ZEPHYR_INCLUDE_NET_WEBSOCKET_H_ */ |
0 commit comments