155#define MEDIA_WEBSOCKET_OPTIMAL_FRAME_SIZE "MEDIA_WEBSOCKET_OPTIMAL_FRAME_SIZE" 
  156#define MEDIA_WEBSOCKET_CONNECTION_ID "MEDIA_WEBSOCKET_CONNECTION_ID" 
  157#define INCOMING_CONNECTION_ID "INCOMING" 
  159#define ANSWER_CHANNEL "ANSWER" 
  160#define HANGUP_CHANNEL "HANGUP" 
  161#define START_MEDIA_BUFFERING "START_MEDIA_BUFFERING" 
  162#define STOP_MEDIA_BUFFERING "STOP_MEDIA_BUFFERING" 
  163#define FLUSH_MEDIA "FLUSH_MEDIA" 
  164#define GET_DRIVER_STATUS "GET_STATUS" 
  165#define REPORT_QUEUE_DRAINED "REPORT_QUEUE_DRAINED" 
  166#define PAUSE_MEDIA "PAUSE_MEDIA" 
  167#define CONTINUE_MEDIA "CONTINUE_MEDIA" 
  169#define MEDIA_START "MEDIA_START" 
  170#define MEDIA_XON "MEDIA_XON" 
  171#define MEDIA_XOFF "MEDIA_XOFF" 
  172#define QUEUE_DRAINED "QUEUE_DRAINED" 
  173#define DRIVER_STATUS "STATUS" 
  174#define MEDIA_BUFFERING_COMPLETED "MEDIA_BUFFERING_COMPLETED" 
  175#define DTMF_END "DTMF_END" 
  177#define QUEUE_LENGTH_MAX 1000 
  178#define QUEUE_LENGTH_XOFF_LEVEL 900 
  179#define QUEUE_LENGTH_XON_LEVEL 800 
  180#define MAX_TEXT_MESSAGE_LEN MIN(128, (AST_WEBSOCKET_MAX_RX_PAYLOAD_SIZE - 1)) 
  192    .description = 
"Media over WebSocket Channel Driver",
 
 
  241        ast_debug(4, 
"%s: WebSocket sending MEDIA_XON\n",
 
  257            ast_debug(4, 
"%s: WebSocket sending QUEUE_DRAINED\n",
 
  287            ast_debug(4, 
"%s: WebSocket sending %s\n",
 
 
  378        slin_frame = native_frame;
 
  397        char *old_data = slin_frame->
data.
ptr;
 
  398        int old_len = slin_frame->
datalen;
 
  399        int old_offset = slin_frame->
offset;
 
  400        ast_debug(4, 
"%s: WebSocket read short frame. Expected %d got %d.  Filling with silence\n",
 
  411        memcpy(slin_frame->
data.
ptr, old_data, old_len);
 
 
  424    char *buffer, 
size_t len)
 
  448            ast_debug(4, 
"%s: WebSocket sending %s\n",
 
 
  481    ast_debug(4, 
"%s: Queued '%s' option frame\n",
 
 
  488    char *payload, uint64_t payload_len)
 
  494        ast_log(
LOG_WARNING, 
"%s: WebSocket TEXT message of length %d exceeds maximum length of %d\n",
 
  505    memcpy(command, payload, payload_len); 
 
  506    command[payload_len] = 
'\0';
 
  509    ast_debug(4, 
"%s: WebSocket %s command received\n",
 
  520            ast_debug(4, 
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
 
  537            ast_debug(4, 
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
 
  542        ast_debug(4, 
"%s: WebSocket %s '%s' with %d bytes in leftover_data.\n",
 
  556        if (res <= 0 || !option) {
 
  566            ast_debug(4, 
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
 
  582            ast_debug(4, 
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
 
  594        res = 
ast_asprintf(&
status, 
"%s channel_id:%s queue_length:%d xon_level:%d xoff_level:%d queue_full:%s bulk_media:%s media_paused:%s",
 
  603        if (res <= 0 || !
status) {
 
  607            ast_debug(4, 
"%s: WebSocket status: %s\n",
 
  615            ast_debug(4, 
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
 
  625            ast_debug(4, 
"%s: WebSocket in passthrough mode. Ignoring %s command.\n",
 
 
  642    char *payload, uint64_t payload_len)
 
  644    char *next_frame_ptr = 
NULL;
 
  645    size_t bytes_read = 0;
 
  647    size_t bytes_left = 0;
 
  653            ast_debug(4, 
"%s: WebSocket queue is full. Ignoring incoming binary message.\n",
 
  659    next_frame_ptr = payload;
 
  679        size_t bytes_avail_to_copy = 
MIN(bytes_needed_for_frame, payload_len);
 
  685        memcpy(append_ptr, payload, bytes_avail_to_copy);
 
  691        if (bytes_avail_to_copy < bytes_needed_for_frame) {
 
  692            ast_debug(4, 
"%s: Leftover data %d bytes but only %d new bytes available of %d needed. Appending and waiting for next message.\n",
 
  708        payload_len -= bytes_avail_to_copy;
 
  709        next_frame_ptr = payload + bytes_avail_to_copy;
 
  711        ast_debug(5, 
"%s: --- BR: %4d  FQ: %4d  PL: %4d  LOL: %3d  P: %p  NFP: %p  OFF: %4d  NPL: %4d  BAC: %3d\n",
 
  715            (
int)(payload_len + bytes_avail_to_copy),
 
  719            (
int)(next_frame_ptr - payload),
 
  721            (
int)bytes_avail_to_copy
 
  732    bytes_left = payload_len;
 
  748        ast_debug(5, 
"%s: +++ BR: %4d  FQ: %4d  PL: %4d  LOL: %3d  P: %p  NFP: %p  OFF: %4d  BL: %4d\n",
 
  756            (
int)(next_frame_ptr - payload),
 
 
  768    uint64_t payload_len = 0;
 
  769    char *payload = 
NULL;
 
  801        &opcode, &fragmented);
 
  814        ast_debug(5, 
"%s: WebSocket closed by remote\n",
 
  820        ast_debug(5, 
"%s: WebSocket frame type %d not supported. Ignoring.\n",
 
 
  851    res = 
ast_asprintf(&command, 
"%s connection_id:%s channel:%s channel_id:%s format:%s optimal_frame_size:%d ptime:%d", 
MEDIA_START,
 
  855        instance->optimal_frame_size, instance->native_codec->default_ms);
 
  856    if (res <= 0 || !command) {
 
  870    if (!instance->no_auto_answer) {
 
 
  900        ast_log(
LOG_WARNING, 
"%s: This WebSocket channel only supports AST_FRAME_VOICE frames\n",
 
  906        ast_log(
LOG_WARNING, 
"%s: This WebSocket channel only supports the '%s' format, not '%s'\n",
 
 
  946    ast_debug(3, 
"%s: WebSocket call requested to %s. cid: %s\n",
 
  962        IPPROTO_TCP, TCP_NODELAY, (
char *) &nodelay, 
sizeof(nodelay)) < 0) {
 
  966    ast_debug(3, 
"%s: WebSocket connection to %s established\n",
 
 
  992    if (instance->
timer) {
 
 
 1082    instance->type = ws_type;
 
 1085        if (!instance->client) {
 
 1087                chan_name, instance->connection_id);
 
 1101    instance->native_format = fmt;
 
 1114    if (instance->native_codec->minimum_bytes <= 10) {
 
 1115        instance->passthrough = 1;
 
 1116        instance->optimal_frame_size = 0;
 
 1118        instance->optimal_frame_size =
 
 1119            (instance->native_codec->default_ms * instance->native_codec->minimum_bytes)
 
 1120                / instance->native_codec->minimum_ms;
 
 1121        instance->leftover_data = 
ast_calloc(1, instance->optimal_frame_size);
 
 1122        if (!instance->leftover_data) {
 
 1128        "%s: WebSocket channel native format '%s' Sample rate: %d ptime: %dms minms: %u  minbytes: %u passthrough: %d optimal_frame_size: %d\n",
 
 1134        instance->passthrough,
 
 1135        instance->optimal_frame_size);
 
 1148            proxy->connection_id);
 
 1151    ast_debug(3, 
"%s: WebSocket instance created and linked\n", proxy->connection_id);
 
 
 1170    ast_debug(3, 
"%s: WebSocket channel slin format '%s' Sample rate: %d ptime: %dms\n",
 
 1177        ast_log(
LOG_ERROR, 
"%s: Unable to build translator path from '%s' to '%s'\n",
 
 
 1214    if (!instance->
timer) {
 
 1219    ast_debug(3, 
"%s: WebSocket timer rate %d\n",
 
 
 1233    char *pkt_size = 
NULL;
 
 
 1312    const char *requestor_name = requestor ? 
ast_channel_name(requestor) : 
"no channel";
 
 1314    ast_debug(3, 
"%s: WebSocket channel requested\n",
 
 1318        ast_log(
LOG_ERROR, 
"%s: A connection id is required for the 'WebSocket' channel\n",
 
 1326        ast_log(
LOG_ERROR, 
"%s: connection_id is required for the 'WebSocket' channel\n",
 
 1335            requestor_name, 
args.options);
 
 1341        ast_debug(3, 
"%s: Using specified format %s\n",
 
 1349        ast_debug(3, 
"%s: Using format %s from requesting channel\n",
 
 1356            requestor_name, 
args.connection_id);
 
 1368    if (!instance->passthrough) {
 
 1378                "%s: URI parameters are not allowed for 'WebSocket/INCOMING' channels\n",
 
 1383        ast_debug(3, 
"%s: Using URI parameters '%s'\n",
 
 1387            ast_log(
LOG_ERROR, 
"%s: Invalid URI parameters '%s' in WebSocket/%s dial string\n",
 
 1389                args.connection_id);
 
 1394        comma = instance->uri_params;
 
 1402        while ((comma = strchr(comma,
','))) {
 
 1405        ast_debug(3, 
"%s: Using final URI '%s'\n", requestor_name, instance->uri_params);
 
 1409        requestor, 0, 
"WebSocket/%s/%p", 
args.connection_id, instance);
 
 1415    ast_debug(3, 
"%s: WebSocket channel %s allocated for connection %s\n",
 
 1417        instance->connection_id);
 
 1419    instance->channel = 
ao2_bump(chan);
 
 1454    ast_debug(3, 
"%s: WebSocket channel created to %s\n",
 
 
 1479    ast_debug(3, 
"%s: WebSocket call hangup. cid: %s\n",
 
 
 1514        if (res <= 0 || !command) {
 
 
 1543    const char *connection_id = 
NULL;
 
 1547    ast_debug(3, 
"WebSocket established\n");
 
 1549    for (v = upgrade_headers; v; v = v->
next) {
 
 1552    for (v = get_params; v; v = v->
next) {
 
 1585        IPPROTO_TCP, TCP_NODELAY, (
char *) &nodelay, 
sizeof(nodelay)) < 0) {
 
 
 1621    int destroy_get_params = (get_params == 
NULL);
 
 1625    ast_debug(2, 
"URI: %s Starting\n", uri);
 
 1639        ast_http_error(ser, 404, 
"Not found", 
"WebSocket instance not found");
 
 1646    if (instance->websocket) {
 
 1649        ast_http_error(ser, 409, 
"Conflict", 
"Another websocket connection exists for this connection id");
 
 1660    for (v = get_params; v; v = v->
next) {
 
 1670        get_params, headers);
 
 1671    if (destroy_get_params) {
 
 
 1682    .description = 
"Media over Websocket",
 
 
 1730        instance_proxy_sort_fn, instance_proxy_cmp_fn);
 
 1733            "Failed to allocate the chan_websocket instance registry\n");
 
 
 1762    .
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_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 MEDIA_BUFFERING_COMPLETED
#define QUEUE_LENGTH_XON_LEVEL
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 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 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 int read_from_ws_and_queue(struct websocket_pvt *instance)
static int webchan_send_dtmf_text(struct ast_channel *ast, char digit, unsigned int duration)
static struct ast_http_uri http_uri
#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)
#define START_MEDIA_BUFFERING
static int set_channel_timer(struct websocket_pvt *instance)
#define QUEUE_LENGTH_XOFF_LEVEL
static const struct ast_app_option websocket_options[128]
static struct ao2_container * instances
#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 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 int unload_module(void)
Function called when our module is unloaded.
#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 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)
#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)
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.
#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.
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)
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
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
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.
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 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
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 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.