00001 /* 00002 * Asterisk -- An open source telephony toolkit. 00003 * 00004 * Copyright (C) 2012, Digium, Inc. 00005 * 00006 * Joshua Colp <jcolp@digium.com> 00007 * 00008 * See http://www.asterisk.org for more information about 00009 * the Asterisk project. Please do not directly contact 00010 * any of the maintainers of this project for assistance; 00011 * the project provides a web site, mailing lists and IRC 00012 * channels for your use. 00013 * 00014 * This program is free software, distributed under the terms of 00015 * the GNU General Public License Version 2. See the LICENSE file 00016 * at the top of the source tree. 00017 */ 00018 00019 #ifndef _ASTERISK_HTTP_WEBSOCKET_H 00020 #define _ASTERISK_HTTP_WEBSOCKET_H 00021 00022 #include "asterisk/optional_api.h" 00023 00024 /*! \brief Default websocket write timeout, in ms */ 00025 #define AST_DEFAULT_WEBSOCKET_WRITE_TIMEOUT 100 00026 00027 /*! 00028 * \file http_websocket.h 00029 * \brief Support for WebSocket connections within the Asterisk HTTP server. 00030 * 00031 * \author Joshua Colp <jcolp@digium.com> 00032 * 00033 */ 00034 00035 /*! \brief WebSocket operation codes */ 00036 enum ast_websocket_opcode { 00037 AST_WEBSOCKET_OPCODE_TEXT = 0x1, /*!< Text frame */ 00038 AST_WEBSOCKET_OPCODE_BINARY = 0x2, /*!< Binary frame */ 00039 AST_WEBSOCKET_OPCODE_PING = 0x9, /*!< Request that the other side respond with a pong */ 00040 AST_WEBSOCKET_OPCODE_PONG = 0xA, /*!< Response to a ping */ 00041 AST_WEBSOCKET_OPCODE_CLOSE = 0x8, /*!< Connection is being closed */ 00042 AST_WEBSOCKET_OPCODE_CONTINUATION = 0x0, /*!< Continuation of a previous frame */ 00043 }; 00044 00045 /*! 00046 * \brief Opaque structure for WebSocket sessions 00047 */ 00048 struct ast_websocket; 00049 00050 /*! 00051 * \brief Callback for when a new connection for a sub-protocol is established 00052 * 00053 * \param session A WebSocket session structure 00054 * \param parameters Parameters extracted from the request URI 00055 * \param headers Headers included in the request 00056 * 00057 * \note Once called the ownership of the session is transferred to the sub-protocol handler. It 00058 * is responsible for closing and cleaning up. 00059 * 00060 */ 00061 typedef void (*ast_websocket_callback)(struct ast_websocket *session, struct ast_variable *parameters, struct ast_variable *headers); 00062 00063 /*! 00064 * \brief Add a sub-protocol handler to the server 00065 * 00066 * \param name Name of the sub-protocol to register 00067 * \param callback Callback called when a new connection requesting the sub-protocol is established 00068 * 00069 * \retval 0 success 00070 * \retval -1 if sub-protocol handler could not be registered 00071 */ 00072 AST_OPTIONAL_API(int, ast_websocket_add_protocol, (const char *name, ast_websocket_callback callback), {return -1;}); 00073 00074 /*! 00075 * \brief Remove a sub-protocol handler from the server 00076 * 00077 * \param name Name of the sub-protocol to unregister 00078 * \param callback Callback that was previously registered with the sub-protocol 00079 * 00080 * \retval 0 success 00081 * \retval -1 if sub-protocol was not found or if callback did not match 00082 */ 00083 AST_OPTIONAL_API(int, ast_websocket_remove_protocol, (const char *name, ast_websocket_callback callback), {return -1;}); 00084 00085 /*! 00086 * \brief Read a WebSocket frame and handle it 00087 * 00088 * \param session Pointer to the WebSocket session 00089 * \param payload Pointer to a char* which will be populated with a pointer to the payload if present 00090 * \param payload_len Pointer to a uint64_t which will be populated with the length of the payload if present 00091 * \param opcode Pointer to an enum which will be populated with the opcode of the frame 00092 * \param fragmented Pointer to an int which is set to 1 if payload is fragmented and 0 if not 00093 * 00094 * \retval -1 on error 00095 * \retval 0 on success 00096 * 00097 * \note Once an AST_WEBSOCKET_OPCODE_CLOSE opcode is received the socket will be closed 00098 */ 00099 AST_OPTIONAL_API(int, ast_websocket_read, (struct ast_websocket *session, char **payload, uint64_t *payload_len, enum ast_websocket_opcode *opcode, int *fragmented), {return -1;}); 00100 00101 /*! 00102 * \brief Construct and transmit a WebSocket frame 00103 * 00104 * \param session Pointer to the WebSocket session 00105 * \param opcode WebSocket operation code to place in the frame 00106 * \param payload Optional pointer to a payload to add to the frame 00107 * \param actual_length Length of the payload (0 if no payload) 00108 * 00109 * \retval 0 if successfully written 00110 * \retval -1 if error occurred 00111 */ 00112 AST_OPTIONAL_API(int, ast_websocket_write, (struct ast_websocket *session, enum ast_websocket_opcode opcode, char *payload, uint64_t actual_length), {return -1;}); 00113 00114 /*! 00115 * \brief Close a WebSocket session by sending a message with the CLOSE opcode and an optional code 00116 * 00117 * \param session Pointer to the WebSocket session 00118 * \param reason Reason code for closing the session as defined in the RFC 00119 * 00120 * \retval 0 if successfully written 00121 * \retval -1 if error occurred 00122 */ 00123 AST_OPTIONAL_API(int, ast_websocket_close, (struct ast_websocket *session, uint16_t reason), {return -1;}); 00124 00125 /*! 00126 * \brief Enable multi-frame reconstruction up to a certain number of bytes 00127 * 00128 * \param session Pointer to the WebSocket session 00129 * \param bytes If a reconstructed payload exceeds the specified number of bytes the payload will be returned 00130 * and upon reception of the next multi-frame a new reconstructed payload will begin. 00131 */ 00132 AST_OPTIONAL_API(void, ast_websocket_reconstruct_enable, (struct ast_websocket *session, size_t bytes), {return;}); 00133 00134 /*! 00135 * \brief Disable multi-frame reconstruction 00136 * 00137 * \param session Pointer to the WebSocket session 00138 * 00139 * \note If reconstruction is disabled each message that is part of a multi-frame message will be sent up to 00140 * the user when ast_websocket_read is called. 00141 */ 00142 AST_OPTIONAL_API(void, ast_websocket_reconstruct_disable, (struct ast_websocket *session), {return;}); 00143 00144 /*! 00145 * \brief Increase the reference count for a WebSocket session 00146 * 00147 * \param session Pointer to the WebSocket session 00148 */ 00149 AST_OPTIONAL_API(void, ast_websocket_ref, (struct ast_websocket *session), {return;}); 00150 00151 /*! 00152 * \brief Decrease the reference count for a WebSocket session 00153 * 00154 * \param session Pointer to the WebSocket session 00155 */ 00156 AST_OPTIONAL_API(void, ast_websocket_unref, (struct ast_websocket *session), {return;}); 00157 00158 /*! 00159 * \brief Get the file descriptor for a WebSocket session. 00160 * 00161 * \retval file descriptor 00162 * 00163 * \note You must *not* directly read from or write to this file descriptor. It should only be used for polling. 00164 */ 00165 AST_OPTIONAL_API(int, ast_websocket_fd, (struct ast_websocket *session), {return -1;}); 00166 00167 /*! 00168 * \brief Get the remote address for a WebSocket connected session. 00169 * 00170 * \retval ast_sockaddr Remote address 00171 */ 00172 AST_OPTIONAL_API(struct ast_sockaddr *, ast_websocket_remote_address, (struct ast_websocket *session), {return NULL;}); 00173 00174 /*! 00175 * \brief Get whether the WebSocket session is using a secure transport or not. 00176 * 00177 * \retval 0 if unsecure 00178 * \retval 1 if secure 00179 */ 00180 AST_OPTIONAL_API(int, ast_websocket_is_secure, (struct ast_websocket *session), {return -1;}); 00181 00182 /*! 00183 * \brief Set the socket of a WebSocket session to be non-blocking. 00184 * 00185 * \retval 0 on success 00186 * \retval -1 on failure 00187 */ 00188 AST_OPTIONAL_API(int, ast_websocket_set_nonblock, (struct ast_websocket *session), {return -1;}); 00189 00190 /*! 00191 * \brief Set the timeout on a non-blocking WebSocket session. 00192 * 00193 * \since 11.11.0 00194 * 00195 * \retval 0 on success 00196 * \retval -1 on failure 00197 */ 00198 AST_OPTIONAL_API(int, ast_websocket_set_timeout, (struct ast_websocket *session, int timeout), {return -1;}); 00199 00200 #endif