112#define WS_TIMER_FDNO (AST_EXTENDED_FDS + 1)
113#define WS_WEBSOCKET_FDNO (AST_EXTENDED_FDS + 2)
115#define MEDIA_WEBSOCKET_OPTIMAL_FRAME_SIZE "MEDIA_WEBSOCKET_OPTIMAL_FRAME_SIZE"
116#define MEDIA_WEBSOCKET_CONNECTION_ID "MEDIA_WEBSOCKET_CONNECTION_ID"
117#define INCOMING_CONNECTION_ID "INCOMING"
119#define ANSWER_CHANNEL "ANSWER"
120#define HANGUP_CHANNEL "HANGUP"
121#define START_MEDIA_BUFFERING "START_MEDIA_BUFFERING"
122#define STOP_MEDIA_BUFFERING "STOP_MEDIA_BUFFERING"
123#define MARK_MEDIA "MARK_MEDIA"
124#define FLUSH_MEDIA "FLUSH_MEDIA"
125#define GET_DRIVER_STATUS "GET_STATUS"
126#define REPORT_QUEUE_DRAINED "REPORT_QUEUE_DRAINED"
127#define PAUSE_MEDIA "PAUSE_MEDIA"
128#define CONTINUE_MEDIA "CONTINUE_MEDIA"
130#define QUEUE_LENGTH_MAX 1000
131#define QUEUE_LENGTH_XOFF_LEVEL 900
132#define QUEUE_LENGTH_XON_LEVEL 800
133#define MAX_TEXT_MESSAGE_LEN MIN(128, (AST_WEBSOCKET_MAX_RX_PAYLOAD_SIZE - 1))
146#define websocket_request_hangup(_instance, _cause, _tech) \
147 _websocket_request_hangup(_instance, _cause, _tech, __LINE__, __FUNCTION__)
151 .description =
"Media over WebSocket Channel Driver",
188 char *payload =
NULL;
205#define _create_event_MEDIA_XON(_instance) _create_event_nodata(_instance, "MEDIA_XON");
206#define _create_event_MEDIA_XOFF(_instance) _create_event_nodata(_instance, "MEDIA_XOFF");
207#define _create_event_QUEUE_DRAINED(_instance) _create_event_nodata(_instance, "QUEUE_DRAINED");
216 char *payload =
NULL;
220 "event",
"MEDIA_START",
236 ast_asprintf(&payload,
"%s %s:%s %s:%s %s:%s %s:%s %s:%d %s:%d",
258 char *payload =
NULL;
261 "event",
"MEDIA_BUFFERING_COMPLETED",
263 "correlation_id",
S_OR(
id,
"")
272 "MEDIA_BUFFERING_COMPLETED",
288 char *payload =
NULL;
291 "event",
"MEDIA_MARK_PROCESSED",
293 "correlation_id",
S_OR(
id,
"")
302 "MEDIA_MARK_PROCESSED",
318 char *payload =
NULL;
345 char *payload =
NULL;
364 ast_asprintf(&payload,
"%s channel_id:%s queue_length:%d xon_level:%d xoff_level:%d queue_full:%s bulk_media:%s media_paused:%s",
386 char *payload =
NULL;
387 char *error_text =
NULL;
391 va_start(ap, format);
394 if (res < 0 || !error_text) {
402 "error_text", error_text);
410 ast_asprintf(&payload,
"%s channel_id:%s error_text:%s",
422#define create_event(_instance, _event, ...) \
423 _create_event_ ## _event(_instance, ##__VA_ARGS__)
429#define send_event(_instance, _event, ...) \
432 char *_payload = _create_event_ ## _event(_instance, ##__VA_ARGS__); \
433 if (_payload && _instance->websocket) { \
434 _res = ast_websocket_write_string(_instance->websocket, _payload); \
436 ast_log(LOG_ERROR, "%s: Unable to send event %s\n", \
437 ast_channel_name(instance->channel), _payload); \
439 ast_debug(3, "%s: Sent %s\n", \
440 ast_channel_name(instance->channel), _payload); \
442 ast_free(_payload); \
487 ast_debug(4,
"%s: WebSocket sending MEDIA_XON\n",
503 ast_debug(4,
"%s: WebSocket sending QUEUE_DRAINED\n",
642 slin_frame = native_frame;
661 char *old_data = slin_frame->
data.
ptr;
662 int old_len = slin_frame->
datalen;
663 int old_offset = slin_frame->
offset;
664 ast_debug(4,
"%s: WebSocket read short frame. Expected %d got %d. Filling with silence\n",
675 memcpy(slin_frame->
data.
ptr, old_data, old_len);
688 char *buffer,
size_t len)
743 ast_debug(4,
"%s: Queued '%s' option frame\n",
762 const char *command =
NULL;
770 send_event(instance, ERROR,
"Unable to parse JSON command");
776 data = strchr(buffer,
' ');
791 send_event(instance, ERROR,
"%s not supported in passthrough mode", command);
792 ast_debug(4,
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
813 send_event(instance, ERROR,
"%s not supported in passthrough mode", command);
814 ast_debug(4,
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
819 ast_debug(4,
"%s: WebSocket %s '%s' with %d bytes in leftover_data.\n",
831 option =
create_event(instance, MEDIA_BUFFERING_COMPLETED,
id);
845 send_event(instance, ERROR,
"%s not supported in passthrough mode", command);
846 ast_debug(4,
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
860 option =
create_event(instance, MEDIA_MARK_PROCESSED,
id);
871 send_event(instance, ERROR,
"FLUSH_MEDIA not supported in passthrough mode");
872 ast_debug(4,
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
888 send_event(instance, ERROR,
"%s not supported in passthrough mode", command);
889 ast_debug(4,
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
903 send_event(instance, ERROR,
"%s not supported in passthrough mode", command);
904 ast_debug(4,
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
914 send_event(instance, ERROR,
"%s not supported in passthrough mode", command);
915 ast_debug(4,
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
932 char *payload, uint64_t payload_len)
936 if (payload_len == 0) {
943 ast_log(
LOG_WARNING,
"%s: WebSocket TEXT message of length %d exceeds maximum length of %d\n",
954 memcpy(command, payload, payload_len);
955 command[payload_len] =
'\0';
965 char *payload, uint64_t payload_len)
967 char *next_frame_ptr =
NULL;
968 size_t bytes_read = 0;
970 size_t bytes_left = 0;
976 ast_debug(4,
"%s: WebSocket queue is full. Ignoring incoming binary message.\n",
982 next_frame_ptr = payload;
1002 size_t bytes_avail_to_copy =
MIN(bytes_needed_for_frame, payload_len);
1008 memcpy(append_ptr, payload, bytes_avail_to_copy);
1014 if (bytes_avail_to_copy < bytes_needed_for_frame) {
1015 ast_debug(4,
"%s: Leftover data %d bytes but only %d new bytes available of %d needed. Appending and waiting for next message.\n",
1031 payload_len -= bytes_avail_to_copy;
1032 next_frame_ptr = payload + bytes_avail_to_copy;
1034 ast_debug(5,
"%s: --- BR: %4d FQ: %4d PL: %4d LOL: %3d P: %p NFP: %p OFF: %4d NPL: %4d BAC: %3d\n",
1038 (
int)(payload_len + bytes_avail_to_copy),
1042 (
int)(next_frame_ptr - payload),
1044 (
int)bytes_avail_to_copy
1055 bytes_left = payload_len;
1071 ast_debug(5,
"%s: +++ BR: %4d FQ: %4d PL: %4d LOL: %3d P: %p NFP: %p OFF: %4d BL: %4d\n",
1079 (
int)(next_frame_ptr - payload),
1082 memcpy(instance->
leftover_data, next_frame_ptr, bytes_left);
1091 uint64_t payload_len = 0;
1092 char *payload =
NULL;
1104 &opcode, &fragmented);
1107 ast_debug(3,
"%s: WebSocket read error\n",
1124 ast_debug(3,
"%s: WebSocket closed by remote\n",
1147 ast_debug(3,
"%s: WebSocket connection with %s established\n",
1151 IPPROTO_TCP, TCP_NODELAY, (
char *) &nodelay,
sizeof(nodelay)) < 0) {
1183 if (!instance || !instance->
channel) {
1186 ast_debug(3,
"%s:%s: Hangup requested from %s line %d. cause: %s(%d) tech_cause: %s(%d)",
1202 if (!instance || !instance->
websocket) {
1213 ast_log(
LOG_WARNING,
"%s: This WebSocket channel only supports AST_FRAME_VOICE frames\n",
1219 ast_log(
LOG_WARNING,
"%s: This WebSocket channel only supports the '%s' format, not '%s'\n",
1262 ast_debug(3,
"%s: WebSocket call requested to %s. cid: %s\n",
1293 if (instance->
timer) {
1384 instance->type = ws_type;
1387 if (!instance->client) {
1389 chan_name, instance->connection_id);
1403 instance->native_format = fmt;
1416 if (instance->native_codec->minimum_bytes <= 10) {
1417 instance->passthrough = 1;
1418 instance->optimal_frame_size = 0;
1420 instance->optimal_frame_size =
1421 (instance->native_codec->default_ms * instance->native_codec->minimum_bytes)
1422 / instance->native_codec->minimum_ms;
1423 instance->leftover_data =
ast_calloc(1, instance->optimal_frame_size);
1424 if (!instance->leftover_data) {
1430 "%s: WebSocket channel native format '%s' Sample rate: %d ptime: %dms minms: %u minbytes: %u passthrough: %d optimal_frame_size: %d\n",
1436 instance->passthrough,
1437 instance->optimal_frame_size);
1450 proxy->connection_id);
1453 ast_debug(3,
"%s: WebSocket instance created and linked\n", proxy->connection_id);
1472 ast_debug(3,
"%s: WebSocket channel slin format '%s' Sample rate: %d ptime: %dms\n",
1479 ast_log(
LOG_ERROR,
"%s: Unable to build translator path from '%s' to '%s'\n",
1516 if (!instance->
timer) {
1521 ast_debug(3,
"%s: WebSocket timer rate %d\n",
1535 char *pkt_size =
NULL;
1623 ast_debug(3,
"%s: WebSocket channel requested\n",
1627 ast_log(
LOG_ERROR,
"%s: A connection id is required for the 'WebSocket' channel\n",
1635 ast_log(
LOG_ERROR,
"%s: connection_id is required for the 'WebSocket' channel\n",
1644 requestor_name,
args.options);
1661 requestor_name,
args.connection_id);
1665 ast_debug(3,
"%s: Using format %s from %s\n",
1677 if (!instance->passthrough) {
1687 "%s: URI parameters are not allowed for 'WebSocket/INCOMING' channels\n",
1692 ast_debug(3,
"%s: Using URI parameters '%s'\n",
1696 ast_log(
LOG_ERROR,
"%s: Invalid URI parameters '%s' in WebSocket/%s dial string\n",
1698 args.connection_id);
1703 comma = instance->uri_params;
1711 while ((comma = strchr(comma,
','))) {
1714 ast_debug(3,
"%s: Using final URI '%s'\n", requestor_name, instance->uri_params);
1721 ast_log(
LOG_WARNING,
"%s: 'f/control message format' dialstring parameter value missing or invalid. "
1722 "Defaulting to 'plain-text'\n",
1726 }
else if (global_cfg) {
1727 instance->control_msg_format = global_cfg->control_msg_format;
1731 requestor, 0,
"WebSocket/%s/%p",
args.connection_id, instance);
1739 ast_debug(3,
"%s: WebSocket channel %s allocated for connection %s\n",
1741 instance->connection_id);
1743 instance->channel =
ao2_bump(chan);
1778 ast_debug(3,
"%s: WebSocket channel created to %s\n",
1803 ast_debug(3,
"%s: WebSocket call hangup. cid: %s\n",
1844 const char *connection_id =
NULL;
1847 ast_debug(3,
"WebSocket established\n");
1849 for (v = upgrade_headers; v; v = v->
next) {
1852 for (v = get_params; v; v = v->
next) {
1917 int destroy_get_params = (get_params ==
NULL);
1921 ast_debug(2,
"URI: %s Starting\n", uri);
1935 ast_http_error(ser, 404,
"Not found",
"WebSocket instance not found");
1942 if (instance->websocket) {
1945 ast_http_error(ser, 409,
"Conflict",
"Another websocket connection exists for this connection id");
1956 for (v = get_params; v; v = v->
next) {
1966 get_params, headers);
1967 if (destroy_get_params) {
1978 .description =
"Media over Websocket",
1999 "control_mesage_format. Must be 'plain-text' or 'json'\n",
2019 sizeof(*cfg),
NULL);
2032 ast_debug(1,
"control_msg_format: %s\n",
2040 ast_debug(2,
"Initializing Websocket Client Configuration\n");
2048 "chan_websocket.conf,criteria=type=global,single_object=yes,explicit_name=global");
2051 ast_log(
LOG_ERROR,
"Failed to register chan_websocket global object with sorcery\n");
2087 ast_debug(2,
"Reloading chan_websocket configuration\n");
2117 instance_proxy_sort_fn, instance_proxy_cmp_fn);
2120 "Failed to allocate the chan_websocket instance registry\n");
2150 .
requires =
"res_http_websocket,res_websocket_client",
Asterisk main include file. File version handling, generic pbx functions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ast_vasprintf(ret, fmt, ap)
A wrapper for vasprintf()
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
#define ast_calloc(num, len)
A wrapper for calloc()
#define ao2_weakproxy_set_object(weakproxy, obj, flags)
Associate weakproxy with obj.
int ao2_weakproxy_subscribe(void *weakproxy, ao2_weakproxy_notification_cb cb, void *data, int flags)
Request notification when weakproxy points to NULL.
@ AO2_ALLOC_OPT_LOCK_RWLOCK
#define AO2_STRING_FIELD_CMP_FN(stype, field)
Creates a compare function for a structure string field.
#define ao2_unlink(container, obj)
Remove an object from a container.
#define ao2_link_flags(container, obj, flags)
Add an object to a container.
#define AO2_STRING_FIELD_SORT_FN(stype, field)
Creates a sort function for a structure string field.
#define ao2_weakproxy_find(c, arg, flags, tag)
Perform an ao2_find on a container with ao2_weakproxy objects, returning the real object.
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
#define ao2_weakproxy_alloc(data_size, destructor_fn)
Allocate an ao2_weakproxy object.
#define AO2_STRING_FIELD_HASH_FN(stype, field)
Creates a hash function for a structure string field.
@ OBJ_NOLOCK
Assume that the ao2_container is already locked.
@ OBJ_SEARCH_KEY
The arg parameter is a search key, but is not an object.
#define ao2_alloc(data_size, destructor_fn)
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Allocate and initialize a hash container with the desired number of buckets.
@ AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE
Replace objects with duplicate keys in container.
Internal Asterisk hangup causes.
#define AST_CAUSE_FAILURE
#define AST_CAUSE_NETWORK_OUT_OF_ORDER
#define AST_CAUSE_NO_ROUTE_DESTINATION
static int set_instance_translator(struct websocket_pvt *instance)
static void _websocket_request_hangup(struct websocket_pvt *instance, int ast_cause, enum ast_websocket_status_code tech_cause, int line, const char *function)
#define QUEUE_LENGTH_XON_LEVEL
#define send_event(_instance, _event,...)
Use this macro to create and send events passing in any event-specific parameters.
static int incoming_ws_http_callback(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_params, struct ast_variable *headers)
static void instance_proxy_cb(void *weakproxy, void *data)
static struct ast_frame * dequeue_frame(struct websocket_pvt *instance)
static void * global_alloc(const char *name)
static const char * control_msg_format_to_str(enum webchan_control_msg_format value)
static int validate_uri_parameters(const char *uri_params)
static int webchan_write(struct ast_channel *ast, struct ast_frame *f)
Function called when we should write a frame to the channel.
static char * _create_event_MEDIA_BUFFERING_COMPLETED(struct websocket_pvt *instance, const char *id)
static const char * msg_format_map[]
static int webchan_hangup(struct ast_channel *ast)
static struct ast_channel_tech websocket_tech
static struct ast_frame * webchan_read(struct ast_channel *ast)
@ OPT_ARG_WS_NO_AUTO_ANSWER
#define websocket_request_hangup(_instance, _cause, _tech)
#define MEDIA_WEBSOCKET_CONNECTION_ID
#define WS_WEBSOCKET_FDNO
static char * _create_event_MEDIA_MARK_PROCESSED(struct websocket_pvt *instance, const char *id)
static int read_from_ws_and_queue(struct websocket_pvt *instance)
webchan_control_msg_format
@ WEBCHAN_CONTROL_MSG_FORMAT_JSON
@ WEBCHAN_CONTROL_MSG_FORMAT_PLAIN
@ WEBCHAN_CONTROL_MSG_FORMAT_INVALID
static int handle_command(struct websocket_pvt *instance, char *buffer)
static int global_control_message_format_from_str(const struct aco_option *opt, struct ast_variable *var, void *obj)
static int webchan_send_dtmf_text(struct ast_channel *ast, char digit, unsigned int duration)
static struct ast_http_uri http_uri
static int reload_module(void)
#define GET_DRIVER_STATUS
static int set_channel_variables(struct websocket_pvt *instance)
static int process_text_message(struct websocket_pvt *instance, char *payload, uint64_t payload_len)
static void websocket_destructor(void *data)
static int queue_frame_from_buffer(struct websocket_pvt *instance, char *buffer, size_t len)
static struct ast_sorcery * sorcery
#define START_MEDIA_BUFFERING
static int set_channel_timer(struct websocket_pvt *instance)
static char * _create_event_STATUS(struct websocket_pvt *instance)
static char * _create_event_DTMF_END(struct websocket_pvt *instance, const char digit)
#define QUEUE_LENGTH_XOFF_LEVEL
static const struct ast_app_option websocket_options[128]
#define create_event(_instance, _event,...)
Use this macro to create events passing in any event-specific parameters.
static struct ao2_container * instances
static char * _create_event_ERROR(struct websocket_pvt *instance, const char *format,...)
#define MEDIA_WEBSOCKET_OPTIMAL_FRAME_SIZE
static void set_channel_format(struct websocket_pvt *instance, struct ast_format *fmt)
#define INCOMING_CONNECTION_ID
static struct websocket_pvt * websocket_new(const char *chan_name, const char *connection_id, struct ast_format *fmt)
#define REPORT_QUEUE_DRAINED
#define STOP_MEDIA_BUFFERING
static int load_module(void)
Function called when our module is loaded.
static int webchan_call(struct ast_channel *ast, const char *dest, int timeout)
static enum webchan_control_msg_format control_msg_format_from_str(const char *value)
static int process_binary_message(struct websocket_pvt *instance, char *payload, uint64_t payload_len)
static int set_instance_silence_frame(struct websocket_pvt *instance)
static struct ast_websocket_server * ast_ws_server
static char * _create_event_MEDIA_START(struct websocket_pvt *instance)
static int unload_module(void)
Function called when our module is unloaded.
static int global_control_message_format_to_str(const void *obj, const intptr_t *args, char **buf)
#define MAX_TEXT_MESSAGE_LEN
static void incoming_ws_established_cb(struct ast_websocket *ast_ws_session, struct ast_variable *get_params, struct ast_variable *upgrade_headers)
static int websocket_handoff_to_channel(struct websocket_pvt *instance)
static struct ast_channel * webchan_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
static char * _create_event_nodata(struct websocket_pvt *instance, char *event)
static int load_config(void)
static int global_apply(const struct ast_sorcery *sorcery, void *obj)
static int queue_option_frame(struct websocket_pvt *instance, char *buffer)
General Asterisk PBX channel definitions.
const char * ast_channel_name(const struct ast_channel *chan)
int ast_channel_tech_hangupcause(const struct ast_channel *chan)
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_format * ast_channel_rawreadformat(struct ast_channel *chan)
void ast_channel_tech_hangupcause_set(struct ast_channel *chan, int value)
struct varshead * ast_channel_varshead(struct ast_channel *chan)
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
int ast_channel_fdno(const struct ast_channel *chan)
void ast_channel_unregister(const struct ast_channel_tech *tech)
Unregister a channel technology.
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
Queue a control frame without payload.
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
Sets read format on channel chan.
int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
Queue a hangup frame with hangupcause set.
void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_tech_pvt_set(struct ast_channel *chan, void *value)
void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
int ast_channel_register(const struct ast_channel_tech *tech)
Register a channel technology (a new channel driver) Called by a channel module to register the kind ...
#define ast_channel_unref(c)
Decrease channel reference count.
const char * ast_cause2str(int cause) attribute_pure
Gives the string form of a given cause code.
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
@ AST_FLAG_DISABLE_DEVSTATE_CACHE
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
void ast_channel_tech_set(struct ast_channel *chan, const struct ast_channel_tech *value)
#define ast_channel_unlock(chan)
void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
struct ast_format * ast_channel_readformat(struct ast_channel *chan)
@ OPT_NOOP_T
Type for a default handler that should do nothing.
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static int uuid(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
ast_http_method
HTTP Request methods known by Asterisk.
void ast_http_uri_unlink(struct ast_http_uri *urihandler)
Unregister a URI handler.
void ast_http_error(struct ast_tcptls_session_instance *ser, int status, const char *title, const char *text)
Send HTTP error message and close socket.
int ast_http_uri_link(struct ast_http_uri *urihandler)
Register a URI handler.
Support for WebSocket connections within the Asterisk HTTP server and client WebSocket connections to...
int AST_OPTIONAL_API_NAME() ast_websocket_write(struct ast_websocket *session, enum ast_websocket_opcode opcode, char *payload, uint64_t payload_size)
Construct and transmit a WebSocket frame.
ast_websocket_status_code
Websocket Status Codes from RFC-6455.
@ AST_WEBSOCKET_STATUS_UNSUPPORTED_DATA
@ AST_WEBSOCKET_STATUS_NORMAL
@ AST_WEBSOCKET_STATUS_GOING_AWAY
@ AST_WEBSOCKET_STATUS_INTERNAL_ERROR
int AST_OPTIONAL_API_NAME() ast_websocket_server_add_protocol2(struct ast_websocket_server *server, struct ast_websocket_protocol *protocol)
Add a sub-protocol handler to the given server.
int AST_OPTIONAL_API_NAME() ast_websocket_write_string(struct ast_websocket *ws, const char *buf)
Construct and transmit a WebSocket frame containing string data.
struct ast_sockaddr *AST_OPTIONAL_API_NAME() ast_websocket_remote_address(struct ast_websocket *session)
Get the remote address for a WebSocket connected session.
int AST_OPTIONAL_API_NAME() ast_websocket_uri_cb(struct ast_tcptls_session_instance *ser, const struct ast_http_uri *urih, const char *uri, enum ast_http_method method, struct ast_variable *get_vars, struct ast_variable *headers)
Callback suitable for use with a ast_http_uri.
ast_websocket_result
Result code for a websocket client.
int AST_OPTIONAL_API_NAME() ast_websocket_fd(struct ast_websocket *session)
Get the file descriptor for a WebSocket session.
ast_websocket_opcode
WebSocket operation codes.
@ AST_WEBSOCKET_OPCODE_PING
@ AST_WEBSOCKET_OPCODE_PONG
@ AST_WEBSOCKET_OPCODE_BINARY
@ AST_WEBSOCKET_OPCODE_CLOSE
@ AST_WEBSOCKET_OPCODE_TEXT
const char *AST_OPTIONAL_API_NAME() ast_websocket_status_to_str(enum ast_websocket_status_code code)
Convert a websocket status code to a string.
ast_websocket_type
WebSocket connection/configuration types.
struct ast_websocket_protocol *AST_OPTIONAL_API_NAME() ast_websocket_sub_protocol_alloc(const char *name)
Allocate a websocket sub-protocol instance.
int AST_OPTIONAL_API_NAME() ast_websocket_read(struct ast_websocket *session, char **payload, uint64_t *payload_len, enum ast_websocket_opcode *opcode, int *fragmented)
Read a WebSocket frame and handle it.
int AST_OPTIONAL_API_NAME() ast_websocket_close(struct ast_websocket *session, uint16_t reason)
Close a WebSocket session by sending a message with the CLOSE opcode and an optional code.
struct ast_websocket_server *AST_OPTIONAL_API_NAME() ast_websocket_server_create(void)
Creates a ast_websocket_server.
void AST_OPTIONAL_API_NAME() ast_websocket_unref(struct ast_websocket *session)
Decrease the reference count for a WebSocket session.
const char *AST_OPTIONAL_API_NAME() ast_websocket_result_to_str(enum ast_websocket_result result)
Convert a websocket result code to a string.
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
#define AST_APP_ARG(name)
Define an application argument.
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
#define AST_NONSTANDARD_APP_ARGS(args, parse, sep)
Performs the 'nonstandard' argument separation process for an application.
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
const char * ast_variable_find_in_list(const struct ast_variable *list, const char *variable)
Gets the value of a variable from a variable list by name.
#define ast_variable_new(name, value, filename)
#define ast_variable_list_append(head, new_var)
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Asterisk internal frame definitions.
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
void ast_frame_free(struct ast_frame *frame, int cache)
Frees a frame or list of frames.
#define ast_frdup(fr)
Copies a frame.
#define AST_FRAME_SET_BUFFER(fr, _base, _ofs, _datalen)
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
struct ast_frame ast_null_frame
#define ast_debug(level,...)
Log a DEBUG message.
Asterisk JSON abstraction layer.
#define ast_json_object_string_get(object, key)
Get a string field from a JSON object.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
struct ast_json * ast_json_load_buf(const char *buffer, size_t buflen, struct ast_json_error *error)
Parse buffer with known length into a JSON object or array.
struct ast_json * ast_json_channel_vars(struct varshead *channelvars)
Construct a JSON object from a ast_var_t list.
char * ast_json_dump_string_format(struct ast_json *root, enum ast_json_encoding_format format)
Encode a JSON value to a string.
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
#define AST_LIST_LOCK(head)
Locks a list.
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
#define AST_LIST_UNLOCK(head)
Attempts to unlock a list.
#define AST_LIST_HEAD(name, type)
Defines a structure to be used to hold a list of specified type.
Asterisk locking-related definitions:
#define SCOPED_AO2WRLOCK(varname, obj)
scoped lock specialization for ao2 write locks.
#define SCOPED_LOCK(varname, lock, lockfunc, unlockfunc)
Scoped Locks.
Asterisk module definitions.
#define AST_MODULE_INFO(keystr, flags_to_set, desc, fields...)
@ AST_MODPRI_CHANNEL_DRIVER
@ AST_MODULE_SUPPORT_CORE
#define ASTERISK_GPL_KEY
The text the key() function should return.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Core PBX routines and definitions.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name.
Sorcery Data Access Layer API.
#define ast_sorcery_unref(sorcery)
Decrease the reference count of a sorcery structure.
#define ast_sorcery_object_field_register_nodoc(sorcery, type, name, default_val, opt_type, flags,...)
Register a field within an object without documentation.
#define ast_sorcery_register_cust(object, option, def_value)
Register a custom field within an object.
void ast_sorcery_load(const struct ast_sorcery *sorcery)
Inform any wizards to load persistent objects.
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
#define ast_sorcery_object_register(sorcery, type, alloc, transform, apply)
Register an object type.
void ast_sorcery_reload(const struct ast_sorcery *sorcery)
Inform any wizards to reload persistent objects.
void * ast_sorcery_generic_alloc(size_t size, ao2_destructor_fn destructor)
Allocate a generic sorcery capable object.
#define ast_sorcery_apply_default(sorcery, type, name, data)
#define ast_sorcery_open()
Open a new sorcery structure.
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
static force_inline int attribute_pure ast_strlen_zero(const char *s)
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
char * ast_strsep(char **s, const char sep, uint32_t flags)
Act like strsep but ignore separators inside quotes.
Structure to pass both assignedid values to channel drivers.
Structure to describe a channel "technology", ie a channel driver See for examples:
struct ast_format_cap * capabilities
Main Channel structure associated with a channel.
Represents a media codec within Asterisk.
unsigned int sample_rate
Sample rate (number of samples carried in a second)
unsigned int minimum_bytes
Length in bytes of the data payload of a minimum_ms frame.
unsigned int default_ms
Default length of media carried (in milliseconds) in a frame.
int(* samples_count)(struct ast_frame *frame)
Retrieve the number of samples in a frame.
unsigned int minimum_ms
Minimum length of media that can be carried (in milliseconds) in a frame.
Structure used to handle boolean flags.
struct ast_format * format
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
enum ast_frame_type frametype
union ast_frame::@239 data
Definition of a URI handler.
ast_http_callback callback
JSON parsing error information.
Abstract JSON element (object, array, string, int, ...).
Socket address structure.
Full structure for sorcery.
describes a server instance
Default structure for translators, with the basic fields and buffers, all allocated as part of the sa...
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
A websocket protocol implementation.
ast_websocket_callback session_established
Callback called when a new session is established. Mandatory.
Structure for a WebSocket server.
Structure definition for session.
char connection_id[0]
The name of the module owning this sorcery instance.
enum webchan_control_msg_format control_msg_format
struct ast_format * native_format
struct websocket_pvt::@145 frame_queue
struct ast_channel * channel
struct ast_codec * slin_codec
int bulk_media_in_progress
enum webchan_control_msg_format control_msg_format
enum ast_websocket_type type
struct ast_format * slin_format
pthread_t outbound_read_thread
struct ast_codec * native_codec
struct ast_websocket_client * client
struct ast_websocket * websocket
struct ast_trans_pvt * translator
static struct aco_type global
Timing source management.
void ast_timer_close(struct ast_timer *handle)
Close an opened timing handle.
int ast_timer_ack(const struct ast_timer *handle, unsigned int quantity)
Acknowledge a timer event.
int ast_timer_set_rate(const struct ast_timer *handle, unsigned int rate)
Set the timing tick rate.
enum ast_timer_event ast_timer_get_event(const struct ast_timer *handle)
Retrieve timing event.
struct ast_timer * ast_timer_open(void)
Open a timer.
@ AST_TIMING_EVENT_EXPIRED
int ast_timer_fd(const struct ast_timer *handle)
Get a poll()-able file descriptor for a timer.
Support for translation of data formats. translate.c.
struct ast_frame * ast_translate(struct ast_trans_pvt *tr, struct ast_frame *f, int consume)
translates one or more frames Apply an input frame into the translator and receive zero or one output...
void ast_translator_free_path(struct ast_trans_pvt *tr)
Frees a translator path Frees the given translator path structure.
struct ast_trans_pvt * ast_translator_build_path(struct ast_format *dest, struct ast_format *source)
Builds a translator path Build a path (possibly NULL) from source to dest.
#define ast_test_flag(p, flag)
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define ARRAY_IN_BOUNDS(v, a)
Checks to see if value is within the bounds of the given array.
#define ast_set_flag(p, flag)
int ast_uri_verify_encoded(const char *string)
Verify if a string is valid as a URI component.
Universally unique identifier support.
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
void ast_websocket_client_add_uri_params(struct ast_websocket_client *wc, const char *uri_params)
Add additional parameters to the URI.
struct ast_websocket_client * ast_websocket_client_retrieve_by_id(const char *id)
Retrieve a websocket client object by ID.
struct ast_websocket * ast_websocket_client_connect(struct ast_websocket_client *wc, void *lock_obj, const char *display_name, enum ast_websocket_result *result)
Connect to a websocket server using the configured authentication, retry and TLS options.