Files
asterisk/res/ari/ari_websockets.h
George Joseph 1c0d552155 ARI Outbound Websockets
Asterisk can now establish websocket sessions _to_ your ARI applications
as well as accepting websocket sessions _from_ them.
Full details: http://s.asterisk.net/ari-outbound-ws

Code change summary:
* Added an ast_vector_string_join() function,
* Added ApplicationRegistered and ApplicationUnregistered ARI events.
* Converted res/ari/config.c to use sorcery to process ari.conf.
* Added the "outbound-websocket" ARI config object.
* Refactored res/ari/ari_websockets.c to handle outbound websockets.
* Refactored res/ari/cli.c for the sorcery changeover.
* Updated res/res_stasis.c for the sorcery changeover.
* Updated apps/app_stasis.c to allow initiating per-call outbound websockets.
* Added CLI commands to manage ARI websockets.
* Added the new "outbound-websocket" object to ari.conf.sample.
* Moved the ARI XML documentation out of res_ari.c into res/ari/ari_doc.xml

UserNote: Asterisk can now establish websocket sessions _to_ your ARI applications
as well as accepting websocket sessions _from_ them.
Full details: http://s.asterisk.net/ari-outbound-ws
2025-06-02 16:35:27 +00:00

124 lines
4.9 KiB
C

/*
* Asterisk -- An open source telephony toolkit.
*
* Copyright (C) 2013, Digium, Inc.
*
* David M. Lee, II <dlee@digium.com>
*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2. See the LICENSE file
* at the top of the source tree.
*/
#ifndef ARI_WEBSOCKETS_H_
#define ARI_WEBSOCKETS_H_
/*! \file
*
* \brief Internal API's for websockets.
* \author David M. Lee, II <dlee@digium.com>
*/
#include "asterisk/http.h"
#include "asterisk/json.h"
#include "asterisk/vector.h"
#include "asterisk/websocket_client.h"
struct ast_ari_events_event_websocket_args;
/* Forward-declare websocket structs. This avoids including http_websocket.h,
* which causes optional_api stuff to happen, which makes optional_api more
* difficult to debug. */
struct ast_websocket;
/*
* Since we create a "stasis-<appname>" dialplan context for each
* stasis app, we need to make sure that the total length will be
* <= AST_MAX_CONTEXT
*/
#define STASIS_CONTEXT_PREFIX "stasis-"
#define STASIS_CONTEXT_PREFIX_LEN (sizeof(STASIS_CONTEXT_PREFIX) - 1)
#define ARI_MAX_APP_NAME_LEN (AST_MAX_CONTEXT - STASIS_CONTEXT_PREFIX_LEN)
struct ari_ws_session {
enum ast_websocket_type type; /*!< The type of websocket session. */
struct ast_websocket *ast_ws_session; /*!< The parent websocket session. */
int (*validator)(struct ast_json *); /*!< The message validator. */
struct ast_vector_string websocket_apps; /*!< List of Stasis apps registered to
the websocket session. */
int subscribe_all; /*!< Flag indicating if all events are subscribed to. */
AST_VECTOR(, struct ast_json *) message_queue; /*!< Container for holding delayed messages. */
char *app_name; /*!< The name of the Stasis application. */
char *remote_addr; /*!< The remote address. */
struct ari_conf_outbound_websocket *owc; /*!< The outbound websocket configuration. */
pthread_t thread; /*!< The thread that handles the websocket. */
char *channel_id; /*!< The channel id for per-call websocket. */
char *channel_name; /*!< The channel name for per-call websocket. */
int stasis_end_sent; /*!< Flag indicating if the StasisEnd message was sent. */
int connected; /*!< Flag indicating if the websocket is connected. */
int closing; /*!< Flag indicating if the session is closing. */
char session_id[]; /*!< The id for the websocket session. */
};
struct ao2_container* ari_websocket_get_sessions(void);
struct ari_ws_session *ari_websocket_get_session(const char *session_id);
struct ari_ws_session *ari_websocket_get_session_by_app(const char *app_name);
const char *ari_websocket_type_to_str(enum ast_websocket_type type);
void ari_websocket_shutdown(struct ari_ws_session *session);
void ari_websocket_shutdown_all(void);
int ari_outbound_websocket_start(struct ari_conf_outbound_websocket *owc);
/*!
* \internal
* \brief Send a JSON event to a websocket.
*
* \param ari_ws_session ARI websocket session
* \param app_name Application name
* \param message JSON message
* \param debug_app Debug flag for application
*/
void ari_websocket_send_event(struct ari_ws_session *ari_ws_session,
const char *app_name, struct ast_json *message, int debug_app);
/*!
* \internal
* \brief Process an ARI REST over Websocket request
*
* \param ari_ws_session ARI websocket session
* \param remote_addr Remote address for log messages
* \param upgrade_headers HTTP headers from the upgrade request
* \param app_name Application name
* \param msg JSON Request message
* \retval 0 on success, -1 on failure
*/
int ari_websocket_process_request(struct ari_ws_session *ast_ws_session,
const char *remote_addr, struct ast_variable *upgrade_headers,
const char *app_name, struct ast_json *msg);
/*!
* \brief Wrapper for invoking the websocket code for an incoming connection.
*
* \param ws_server WebSocket server to invoke.
* \param ser HTTP session.
* \param uri Requested URI.
* \param method Requested HTTP method.
* \param get_params Parsed query parameters.
* \param headers Parsed HTTP headers.
*/
void ari_handle_websocket(struct ast_tcptls_session_instance *ser,
const char *uri, enum ast_http_method method,
struct ast_variable *get_params,
struct ast_variable *headers);
int ari_websocket_unload_module(void);
int ari_websocket_load_module(int is_enabled);
#endif /* ARI_WEBSOCKETS_H_ */