107#define MEDIA_WEBSOCKET_OPTIMAL_FRAME_SIZE "MEDIA_WEBSOCKET_OPTIMAL_FRAME_SIZE"
108#define MEDIA_WEBSOCKET_CONNECTION_ID "MEDIA_WEBSOCKET_CONNECTION_ID"
109#define INCOMING_CONNECTION_ID "INCOMING"
111#define ANSWER_CHANNEL "ANSWER"
112#define HANGUP_CHANNEL "HANGUP"
113#define START_MEDIA_BUFFERING "START_MEDIA_BUFFERING"
114#define STOP_MEDIA_BUFFERING "STOP_MEDIA_BUFFERING"
115#define MARK_MEDIA "MARK_MEDIA"
116#define FLUSH_MEDIA "FLUSH_MEDIA"
117#define GET_DRIVER_STATUS "GET_STATUS"
118#define REPORT_QUEUE_DRAINED "REPORT_QUEUE_DRAINED"
119#define PAUSE_MEDIA "PAUSE_MEDIA"
120#define CONTINUE_MEDIA "CONTINUE_MEDIA"
122#define QUEUE_LENGTH_MAX 1000
123#define QUEUE_LENGTH_XOFF_LEVEL 900
124#define QUEUE_LENGTH_XON_LEVEL 800
125#define MAX_TEXT_MESSAGE_LEN MIN(128, (AST_WEBSOCKET_MAX_RX_PAYLOAD_SIZE - 1))
137 .description =
"Media over WebSocket Channel Driver",
174 char *payload =
NULL;
191#define _create_event_MEDIA_XON(_instance) _create_event_nodata(_instance, "MEDIA_XON");
192#define _create_event_MEDIA_XOFF(_instance) _create_event_nodata(_instance, "MEDIA_XOFF");
193#define _create_event_QUEUE_DRAINED(_instance) _create_event_nodata(_instance, "QUEUE_DRAINED");
202 char *payload =
NULL;
206 "event",
"MEDIA_START",
222 ast_asprintf(&payload,
"%s %s:%s %s:%s %s:%s %s:%s %s:%d %s:%d",
244 char *payload =
NULL;
247 "event",
"MEDIA_BUFFERING_COMPLETED",
249 "correlation_id",
S_OR(
id,
"")
258 "MEDIA_BUFFERING_COMPLETED",
274 char *payload =
NULL;
277 "event",
"MEDIA_MARK_PROCESSED",
279 "correlation_id",
S_OR(
id,
"")
288 "MEDIA_MARK_PROCESSED",
304 char *payload =
NULL;
331 char *payload =
NULL;
350 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",
372 char *payload =
NULL;
373 char *error_text =
NULL;
377 va_start(ap, format);
380 if (res < 0 || !error_text) {
388 "error_text", error_text);
396 ast_asprintf(&payload,
"%s channel_id:%s error_text:%s",
408#define create_event(_instance, _event, ...) \
409 _create_event_ ## _event(_instance, ##__VA_ARGS__)
415#define send_event(_instance, _event, ...) \
418 char *_payload = _create_event_ ## _event(_instance, ##__VA_ARGS__); \
420 _res = ast_websocket_write_string(_instance->websocket, _payload); \
422 ast_log(LOG_ERROR, "%s: Unable to send event %s\n", \
423 ast_channel_name(instance->channel), _payload); \
425 ast_debug(4, "%s: Sent %s\n", \
426 ast_channel_name(instance->channel), _payload); \
428 ast_free(_payload); \
473 ast_debug(4,
"%s: WebSocket sending MEDIA_XON\n",
489 ast_debug(4,
"%s: WebSocket sending QUEUE_DRAINED\n",
610 slin_frame = native_frame;
629 char *old_data = slin_frame->
data.
ptr;
630 int old_len = slin_frame->
datalen;
631 int old_offset = slin_frame->
offset;
632 ast_debug(4,
"%s: WebSocket read short frame. Expected %d got %d. Filling with silence\n",
643 memcpy(slin_frame->
data.
ptr, old_data, old_len);
656 char *buffer,
size_t len)
711 ast_debug(4,
"%s: Queued '%s' option frame\n",
730 const char *command =
NULL;
738 send_event(instance, ERROR,
"Unable to parse JSON command");
744 data = strchr(buffer,
' ');
759 send_event(instance, ERROR,
"%s not supported in passthrough mode", command);
760 ast_debug(4,
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
781 send_event(instance, ERROR,
"%s not supported in passthrough mode", command);
782 ast_debug(4,
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
787 ast_debug(4,
"%s: WebSocket %s '%s' with %d bytes in leftover_data.\n",
799 option =
create_event(instance, MEDIA_BUFFERING_COMPLETED,
id);
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",
828 option =
create_event(instance, MEDIA_MARK_PROCESSED,
id);
839 send_event(instance, ERROR,
"FLUSH_MEDIA not supported in passthrough mode");
840 ast_debug(4,
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
856 send_event(instance, ERROR,
"%s not supported in passthrough mode", command);
857 ast_debug(4,
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
871 send_event(instance, ERROR,
"%s not supported in passthrough mode", command);
872 ast_debug(4,
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
882 send_event(instance, ERROR,
"%s not supported in passthrough mode", command);
883 ast_debug(4,
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
900 char *payload, uint64_t payload_len)
904 if (payload_len == 0) {
911 ast_log(
LOG_WARNING,
"%s: WebSocket TEXT message of length %d exceeds maximum length of %d\n",
922 memcpy(command, payload, payload_len);
923 command[payload_len] =
'\0';
933 char *payload, uint64_t payload_len)
935 char *next_frame_ptr =
NULL;
936 size_t bytes_read = 0;
938 size_t bytes_left = 0;
944 ast_debug(4,
"%s: WebSocket queue is full. Ignoring incoming binary message.\n",
950 next_frame_ptr = payload;
970 size_t bytes_avail_to_copy =
MIN(bytes_needed_for_frame, payload_len);
976 memcpy(append_ptr, payload, bytes_avail_to_copy);
982 if (bytes_avail_to_copy < bytes_needed_for_frame) {
983 ast_debug(4,
"%s: Leftover data %d bytes but only %d new bytes available of %d needed. Appending and waiting for next message.\n",
999 payload_len -= bytes_avail_to_copy;
1000 next_frame_ptr = payload + bytes_avail_to_copy;
1002 ast_debug(5,
"%s: --- BR: %4d FQ: %4d PL: %4d LOL: %3d P: %p NFP: %p OFF: %4d NPL: %4d BAC: %3d\n",
1006 (
int)(payload_len + bytes_avail_to_copy),
1010 (
int)(next_frame_ptr - payload),
1012 (
int)bytes_avail_to_copy
1023 bytes_left = payload_len;
1039 ast_debug(5,
"%s: +++ BR: %4d FQ: %4d PL: %4d LOL: %3d P: %p NFP: %p OFF: %4d BL: %4d\n",
1047 (
int)(next_frame_ptr - payload),
1050 memcpy(instance->
leftover_data, next_frame_ptr, bytes_left);
1059 uint64_t payload_len = 0;
1060 char *payload =
NULL;
1065 if (!instance || !instance->
websocket) {
1092 &opcode, &fragmented);
1105 ast_debug(5,
"%s: WebSocket closed by remote\n",
1111 ast_debug(5,
"%s: WebSocket frame type %d not supported. Ignoring.\n",
1142 if (!instance->no_auto_answer) {
1165 if (!instance || !instance->
websocket) {
1176 ast_log(
LOG_WARNING,
"%s: This WebSocket channel only supports AST_FRAME_VOICE frames\n",
1182 ast_log(
LOG_WARNING,
"%s: This WebSocket channel only supports the '%s' format, not '%s'\n",
1222 ast_debug(3,
"%s: WebSocket call requested to %s. cid: %s\n",
1238 IPPROTO_TCP, TCP_NODELAY, (
char *) &nodelay,
sizeof(nodelay)) < 0) {
1242 ast_debug(3,
"%s: WebSocket connection to %s established\n",
1268 if (instance->
timer) {
1358 instance->type = ws_type;
1361 if (!instance->client) {
1363 chan_name, instance->connection_id);
1377 instance->native_format = fmt;
1390 if (instance->native_codec->minimum_bytes <= 10) {
1391 instance->passthrough = 1;
1392 instance->optimal_frame_size = 0;
1394 instance->optimal_frame_size =
1395 (instance->native_codec->default_ms * instance->native_codec->minimum_bytes)
1396 / instance->native_codec->minimum_ms;
1397 instance->leftover_data =
ast_calloc(1, instance->optimal_frame_size);
1398 if (!instance->leftover_data) {
1404 "%s: WebSocket channel native format '%s' Sample rate: %d ptime: %dms minms: %u minbytes: %u passthrough: %d optimal_frame_size: %d\n",
1410 instance->passthrough,
1411 instance->optimal_frame_size);
1424 proxy->connection_id);
1427 ast_debug(3,
"%s: WebSocket instance created and linked\n", proxy->connection_id);
1446 ast_debug(3,
"%s: WebSocket channel slin format '%s' Sample rate: %d ptime: %dms\n",
1453 ast_log(
LOG_ERROR,
"%s: Unable to build translator path from '%s' to '%s'\n",
1490 if (!instance->
timer) {
1495 ast_debug(3,
"%s: WebSocket timer rate %d\n",
1509 char *pkt_size =
NULL;
1597 ast_debug(3,
"%s: WebSocket channel requested\n",
1601 ast_log(
LOG_ERROR,
"%s: A connection id is required for the 'WebSocket' channel\n",
1609 ast_log(
LOG_ERROR,
"%s: connection_id is required for the 'WebSocket' channel\n",
1618 requestor_name,
args.options);
1635 requestor_name,
args.connection_id);
1639 ast_debug(3,
"%s: Using format %s from %s\n",
1651 if (!instance->passthrough) {
1661 "%s: URI parameters are not allowed for 'WebSocket/INCOMING' channels\n",
1666 ast_debug(3,
"%s: Using URI parameters '%s'\n",
1670 ast_log(
LOG_ERROR,
"%s: Invalid URI parameters '%s' in WebSocket/%s dial string\n",
1672 args.connection_id);
1677 comma = instance->uri_params;
1685 while ((comma = strchr(comma,
','))) {
1688 ast_debug(3,
"%s: Using final URI '%s'\n", requestor_name, instance->uri_params);
1695 ast_log(
LOG_WARNING,
"%s: 'f/control message format' dialstring parameter value missing or invalid. "
1696 "Defaulting to 'plain-text'\n",
1700 }
else if (global_cfg) {
1701 instance->control_msg_format = global_cfg->control_msg_format;
1705 requestor, 0,
"WebSocket/%s/%p",
args.connection_id, instance);
1711 ast_debug(3,
"%s: WebSocket channel %s allocated for connection %s\n",
1713 instance->connection_id);
1715 instance->channel =
ao2_bump(chan);
1750 ast_debug(3,
"%s: WebSocket channel created to %s\n",
1775 ast_debug(3,
"%s: WebSocket call hangup. cid: %s\n",
1824 const char *connection_id =
NULL;
1828 ast_debug(3,
"WebSocket established\n");
1830 for (v = upgrade_headers; v; v = v->
next) {
1833 for (v = get_params; v; v = v->
next) {
1866 IPPROTO_TCP, TCP_NODELAY, (
char *) &nodelay,
sizeof(nodelay)) < 0) {
1902 int destroy_get_params = (get_params ==
NULL);
1906 ast_debug(2,
"URI: %s Starting\n", uri);
1920 ast_http_error(ser, 404,
"Not found",
"WebSocket instance not found");
1927 if (instance->websocket) {
1930 ast_http_error(ser, 409,
"Conflict",
"Another websocket connection exists for this connection id");
1941 for (v = get_params; v; v = v->
next) {
1951 get_params, headers);
1952 if (destroy_get_params) {
1963 .description =
"Media over Websocket",
1984 "control_mesage_format. Must be 'plain-text' or 'json'\n",
2004 sizeof(*cfg),
NULL);
2017 ast_debug(1,
"control_msg_format: %s\n",
2025 ast_debug(2,
"Initializing Websocket Client Configuration\n");
2033 "chan_websocket.conf,criteria=type=global,single_object=yes,explicit_name=global");
2036 ast_log(
LOG_ERROR,
"Failed to register chan_websocket global object with sorcery\n");
2072 ast_debug(2,
"Reloading chan_websocket configuration\n");
2102 instance_proxy_sort_fn, instance_proxy_cmp_fn);
2105 "Failed to allocate the chan_websocket instance registry\n");
2135 .
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
static int set_instance_translator(struct websocket_pvt *instance)
#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 MEDIA_WEBSOCKET_CONNECTION_ID
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 void * read_thread_handler(void *obj)
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 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)
void * ast_channel_tech_pvt(const struct ast_channel *chan)
struct ast_format * ast_channel_rawreadformat(struct ast_channel *chan)
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)
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.
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.
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.
void ast_channel_set_fd(struct ast_channel *chan, int which, int fd)
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.
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.
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_BINARY
@ AST_WEBSOCKET_OPCODE_CLOSE
@ AST_WEBSOCKET_OPCODE_TEXT
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.
#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.
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, ...).
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.
int ast_wait_for_input(int fd, int ms)
#define ARRAY_IN_BOUNDS(v, a)
Checks to see if value is within the bounds of the given array.
#define ast_pthread_create_detached_background(a, b, c, d)
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.