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 /*! 00025 * \file http_websocket.h 00026 * \brief Support for WebSocket connections within the Asterisk HTTP server. 00027 * 00028 * \author Joshua Colp <jcolp@digium.com> 00029 * 00030 */ 00031 00032 /*! \brief WebSocket operation codes */ 00033 enum ast_websocket_opcode { 00034 AST_WEBSOCKET_OPCODE_TEXT = 0x1, /*!< Text frame */ 00035 AST_WEBSOCKET_OPCODE_BINARY = 0x2, /*!< Binary frame */ 00036 AST_WEBSOCKET_OPCODE_PING = 0x9, /*!< Request that the other side respond with a pong */ 00037 AST_WEBSOCKET_OPCODE_PONG = 0xA, /*!< Response to a ping */ 00038 AST_WEBSOCKET_OPCODE_CLOSE = 0x8, /*!< Connection is being closed */ 00039 AST_WEBSOCKET_OPCODE_CONTINUATION = 0x0, /*!< Continuation of a previous frame */ 00040 }; 00041 00042 /*! 00043 * \brief Opaque structure for WebSocket sessions 00044 */ 00045 struct ast_websocket; 00046 00047 /*! 00048 * \brief Callback for when a new connection for a sub-protocol is established 00049 * 00050 * \param session A WebSocket session structure 00051 * \param parameters Parameters extracted from the request URI 00052 * \param headers Headers included in the request 00053 * 00054 * \note Once called the ownership of the session is transferred to the sub-protocol handler. It 00055 * is responsible for closing and cleaning up. 00056 * 00057 */ 00058 typedef void (*ast_websocket_callback)(struct ast_websocket *session, struct ast_variable *parameters, struct ast_variable *headers); 00059 00060 /*! 00061 * \brief Add a sub-protocol handler to the server 00062 * 00063 * \param name Name of the sub-protocol to register 00064 * \param callback Callback called when a new connection requesting the sub-protocol is established 00065 * 00066 * \retval 0 success 00067 * \retval -1 if sub-protocol handler could not be registered 00068 */ 00069 AST_OPTIONAL_API(int, ast_websocket_add_protocol, (const char *name, ast_websocket_callback callback), {return -1;}); 00070 00071 /*! 00072 * \brief Remove a sub-protocol handler from the server 00073 * 00074 * \param name Name of the sub-protocol to unregister 00075 * \param callback Callback that was previously registered with the sub-protocol 00076 * 00077 * \retval 0 success 00078 * \retval -1 if sub-protocol was not found or if callback did not match 00079 */ 00080 AST_OPTIONAL_API(int, ast_websocket_remove_protocol, (const char *name, ast_websocket_callback callback), {return -1;}); 00081 00082 /*! 00083 * \brief Read a WebSocket frame and handle it 00084 * 00085 * \param session Pointer to the WebSocket session 00086 * \param payload Pointer to a char* which will be populated with a pointer to the payload if present 00087 * \param payload_len Pointer to a uint64_t which will be populated with the length of the payload if present 00088 * \param opcode Pointer to an enum which will be populated with the opcode of the frame 00089 * \param fragmented Pointer to an int which is set to 1 if payload is fragmented and 0 if not 00090 * 00091 * \retval -1 on error 00092 * \retval 0 on success 00093 * 00094 * \note Once an AST_WEBSOCKET_OPCODE_CLOSE opcode is received the socket will be closed 00095 */ 00096 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;}); 00097 00098 /*! 00099 * \brief Construct and transmit a WebSocket frame 00100 * 00101 * \param session Pointer to the WebSocket session 00102 * \param opcode WebSocket operation code to place in the frame 00103 * \param payload Optional pointer to a payload to add to the frame 00104 * \param actual_length Length of the payload (0 if no payload) 00105 * 00106 * \retval 0 if successfully written 00107 * \retval -1 if error occurred 00108 */ 00109 AST_OPTIONAL_API(int, ast_websocket_write, (struct ast_websocket *session, enum ast_websocket_opcode opcode, char *payload, uint64_t actual_length), {return -1;}); 00110 00111 /*! 00112 * \brief Close a WebSocket session by sending a message with the CLOSE opcode and an optional code 00113 * 00114 * \param session Pointer to the WebSocket session 00115 * \param reason Reason code for closing the session as defined in the RFC 00116 * 00117 * \retval 0 if successfully written 00118 * \retval -1 if error occurred 00119 */ 00120 AST_OPTIONAL_API(int, ast_websocket_close, (struct ast_websocket *session, uint16_t reason), {return -1;}); 00121 00122 /*! 00123 * \brief Enable multi-frame reconstruction up to a certain number of bytes 00124 * 00125 * \param session Pointer to the WebSocket session 00126 * \param bytes If a reconstructed payload exceeds the specified number of bytes the payload will be returned 00127 * and upon reception of the next multi-frame a new reconstructed payload will begin. 00128 */ 00129 AST_OPTIONAL_API(void, ast_websocket_reconstruct_enable, (struct ast_websocket *session, size_t bytes), {return;}); 00130 00131 /*! 00132 * \brief Disable multi-frame reconstruction 00133 * 00134 * \param session Pointer to the WebSocket session 00135 * 00136 * \note If reconstruction is disabled each message that is part of a multi-frame message will be sent up to 00137 * the user when ast_websocket_read is called. 00138 */ 00139 AST_OPTIONAL_API(void, ast_websocket_reconstruct_disable, (struct ast_websocket *session), {return;}); 00140 00141 /*! 00142 * \brief Increase the reference count for a WebSocket session 00143 * 00144 * \param session Pointer to the WebSocket session 00145 */ 00146 AST_OPTIONAL_API(void, ast_websocket_ref, (struct ast_websocket *session), {return;}); 00147 00148 /*! 00149 * \brief Decrease the reference count for a WebSocket session 00150 * 00151 * \param session Pointer to the WebSocket session 00152 */ 00153 AST_OPTIONAL_API(void, ast_websocket_unref, (struct ast_websocket *session), {return;}); 00154 00155 /*! 00156 * \brief Get the file descriptor for a WebSocket session. 00157 * 00158 * \retval file descriptor 00159 * 00160 * \note You must *not* directly read from or write to this file descriptor. It should only be used for polling. 00161 */ 00162 AST_OPTIONAL_API(int, ast_websocket_fd, (struct ast_websocket *session), {return -1;}); 00163 00164 /*! 00165 * \brief Get the remote address for a WebSocket connected session. 00166 * 00167 * \retval ast_sockaddr Remote address 00168 */ 00169 AST_OPTIONAL_API(struct ast_sockaddr *, ast_websocket_remote_address, (struct ast_websocket *session), {return NULL;}); 00170 00171 /*! 00172 * \brief Get whether the WebSocket session is using a secure transport or not. 00173 * 00174 * \retval 0 if unsecure 00175 * \retval 1 if secure 00176 */ 00177 AST_OPTIONAL_API(int, ast_websocket_is_secure, (struct ast_websocket *session), {return -1;}); 00178 00179 /*! 00180 * \brief Set the socket of a WebSocket session to be non-blocking. 00181 * 00182 * \retval 0 on success 00183 * \retval -1 on failure 00184 */ 00185 AST_OPTIONAL_API(int, ast_websocket_set_nonblock, (struct ast_websocket *session), {return -1;}); 00186 00187 #endif