Asterisk - The Open Source Telephony Project  21.4.1
Data Structures | Functions | Variables
resource_channels.c File Reference

Implementation for ARI stubs. More...

#include "asterisk.h"
#include "asterisk/file.h"
#include "asterisk/pbx.h"
#include "asterisk/bridge.h"
#include "asterisk/callerid.h"
#include "asterisk/stasis_app.h"
#include "asterisk/stasis_app_playback.h"
#include "asterisk/stasis_app_recording.h"
#include "asterisk/stasis_app_snoop.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/causes.h"
#include "asterisk/format_cache.h"
#include "asterisk/core_local.h"
#include "asterisk/dial.h"
#include "asterisk/max_forwards.h"
#include "asterisk/rtp_engine.h"
#include "resource_channels.h"
#include <limits.h>
#include "asterisk/config.h"
#include "asterisk/netsock2.h"

Go to the source code of this file.

Data Structures

struct  ari_channel_thread_data
 
struct  ari_origination
 Structure used for origination. More...
 

Functions

static void * ari_channel_thread (void *data)
 Thread that owns stasis-created channel. More...
 
static struct ast_channelari_channels_handle_originate_with_id (const char *args_endpoint, const char *args_extension, const char *args_context, long args_priority, const char *args_label, const char *args_app, const char *args_app_args, const char *args_caller_id, int args_timeout, struct ast_variable *variables, const char *args_channel_id, const char *args_other_channel_id, const char *args_originator, const char *args_formats, struct ast_ari_response *response)
 
static void ari_channels_handle_play (const char *args_channel_id, const char **args_media, size_t args_media_count, const char *args_lang, int args_offsetms, int args_skipms, const char *args_playback_id, struct ast_ari_response *response)
 
static void ari_channels_handle_snoop_channel (const char *args_channel_id, const char *args_spy, const char *args_whisper, const char *args_app, const char *args_app_args, const char *args_snoop_id, struct ast_ari_response *response)
 
static void * ari_originate_dial (void *data)
 Thread which dials and executes upon answer.
 
void ast_ari_channels_answer (struct ast_variable *headers, struct ast_ari_channels_answer_args *args, struct ast_ari_response *response)
 Answer a channel. More...
 
void ast_ari_channels_continue_in_dialplan (struct ast_variable *headers, struct ast_ari_channels_continue_in_dialplan_args *args, struct ast_ari_response *response)
 Exit application; continue execution in the dialplan. More...
 
void ast_ari_channels_create (struct ast_variable *headers, struct ast_ari_channels_create_args *args, struct ast_ari_response *response)
 Create channel. More...
 
void ast_ari_channels_dial (struct ast_variable *headers, struct ast_ari_channels_dial_args *args, struct ast_ari_response *response)
 Dial a created channel. More...
 
void ast_ari_channels_external_media (struct ast_variable *headers, struct ast_ari_channels_external_media_args *args, struct ast_ari_response *response)
 Start an External Media session. More...
 
void ast_ari_channels_get (struct ast_variable *headers, struct ast_ari_channels_get_args *args, struct ast_ari_response *response)
 Channel details. More...
 
void ast_ari_channels_get_channel_var (struct ast_variable *headers, struct ast_ari_channels_get_channel_var_args *args, struct ast_ari_response *response)
 Get the value of a channel variable or function. More...
 
void ast_ari_channels_hangup (struct ast_variable *headers, struct ast_ari_channels_hangup_args *args, struct ast_ari_response *response)
 Delete (i.e. hangup) a channel. More...
 
void ast_ari_channels_hold (struct ast_variable *headers, struct ast_ari_channels_hold_args *args, struct ast_ari_response *response)
 Hold a channel. More...
 
void ast_ari_channels_list (struct ast_variable *headers, struct ast_ari_channels_list_args *args, struct ast_ari_response *response)
 List all active channels in Asterisk. More...
 
void ast_ari_channels_move (struct ast_variable *headers, struct ast_ari_channels_move_args *args, struct ast_ari_response *response)
 Move the channel from one Stasis application to another. More...
 
void ast_ari_channels_mute (struct ast_variable *headers, struct ast_ari_channels_mute_args *args, struct ast_ari_response *response)
 Mute a channel. More...
 
void ast_ari_channels_originate (struct ast_variable *headers, struct ast_ari_channels_originate_args *args, struct ast_ari_response *response)
 Create a new channel (originate). More...
 
void ast_ari_channels_originate_with_id (struct ast_variable *headers, struct ast_ari_channels_originate_with_id_args *args, struct ast_ari_response *response)
 Create a new channel (originate with id). More...
 
void ast_ari_channels_play (struct ast_variable *headers, struct ast_ari_channels_play_args *args, struct ast_ari_response *response)
 Start playback of media. More...
 
void ast_ari_channels_play_with_id (struct ast_variable *headers, struct ast_ari_channels_play_with_id_args *args, struct ast_ari_response *response)
 Start playback of media and specify the playbackId. More...
 
void ast_ari_channels_record (struct ast_variable *headers, struct ast_ari_channels_record_args *args, struct ast_ari_response *response)
 Start a recording. More...
 
void ast_ari_channels_redirect (struct ast_variable *headers, struct ast_ari_channels_redirect_args *args, struct ast_ari_response *response)
 Redirect the channel to a different location. More...
 
void ast_ari_channels_ring (struct ast_variable *headers, struct ast_ari_channels_ring_args *args, struct ast_ari_response *response)
 Indicate ringing to a channel. More...
 
void ast_ari_channels_ring_stop (struct ast_variable *headers, struct ast_ari_channels_ring_stop_args *args, struct ast_ari_response *response)
 Stop ringing indication on a channel if locally generated. More...
 
void ast_ari_channels_rtpstatistics (struct ast_variable *headers, struct ast_ari_channels_rtpstatistics_args *args, struct ast_ari_response *response)
 RTP stats on a channel. More...
 
void ast_ari_channels_send_dtmf (struct ast_variable *headers, struct ast_ari_channels_send_dtmf_args *args, struct ast_ari_response *response)
 Send provided DTMF to a given channel. More...
 
void ast_ari_channels_set_channel_var (struct ast_variable *headers, struct ast_ari_channels_set_channel_var_args *args, struct ast_ari_response *response)
 Set the value of a channel variable or function. More...
 
void ast_ari_channels_snoop_channel (struct ast_variable *headers, struct ast_ari_channels_snoop_channel_args *args, struct ast_ari_response *response)
 Start snooping. More...
 
void ast_ari_channels_snoop_channel_with_id (struct ast_variable *headers, struct ast_ari_channels_snoop_channel_with_id_args *args, struct ast_ari_response *response)
 Start snooping. More...
 
void ast_ari_channels_start_moh (struct ast_variable *headers, struct ast_ari_channels_start_moh_args *args, struct ast_ari_response *response)
 Play music on hold to a channel. More...
 
void ast_ari_channels_start_silence (struct ast_variable *headers, struct ast_ari_channels_start_silence_args *args, struct ast_ari_response *response)
 Play silence to a channel. More...
 
void ast_ari_channels_stop_moh (struct ast_variable *headers, struct ast_ari_channels_stop_moh_args *args, struct ast_ari_response *response)
 Stop playing music on hold to a channel. More...
 
void ast_ari_channels_stop_silence (struct ast_variable *headers, struct ast_ari_channels_stop_silence_args *args, struct ast_ari_response *response)
 Stop playing silence to a channel. More...
 
void ast_ari_channels_unhold (struct ast_variable *headers, struct ast_ari_channels_unhold_args *args, struct ast_ari_response *response)
 Remove a channel from hold. More...
 
void ast_ari_channels_unmute (struct ast_variable *headers, struct ast_ari_channels_unmute_args *args, struct ast_ari_response *response)
 Unmute a channel. More...
 
static void chan_data_destroy (struct ari_channel_thread_data *chan_data)
 
static int channel_state_invalid (struct stasis_app_control *control, struct ast_ari_response *response)
 Ensure channel is in a state that allows operation to be performed. More...
 
static int convert_reason_to_hangup_code (const char *reason)
 Return the corresponded hangup code of the given reason.
 
static void external_media_audiosocket_tcp (struct ast_ari_channels_external_media_args *args, struct ast_variable *variables, struct ast_ari_response *response)
 
static int external_media_rtp_udp (struct ast_ari_channels_external_media_args *args, struct ast_variable *variables, struct ast_ari_response *response)
 
static struct stasis_app_controlfind_control (struct ast_ari_response *response, const char *channel_id)
 Finds the control object for a channel, filling the response with an error, if appropriate. More...
 
static int json_to_ast_variables (struct ast_ari_response *response, struct ast_json *json_variables, struct ast_variable **variables)
 
static char * restore_dialstring (struct ast_channel *chan)
 Retrieve the dialstring from the channel datastore. More...
 
static int save_dialstring (struct ast_channel *chan, const char *dialstring)
 Save dialstring onto a channel datastore. More...
 

Variables

struct ast_datastore_info dialstring_info
 

Detailed Description

Implementation for ARI stubs.

Author
David M. Lee, II dlee@.nosp@m.digi.nosp@m.um.co.nosp@m.m

Definition in file resource_channels.c.

Function Documentation

static void* ari_channel_thread ( void *  data)
static

Thread that owns stasis-created channel.

The channel enters into a Stasis application immediately upon creation. In this way, the channel can be manipulated by the Stasis application. Once the channel exits the Stasis application, it is hung up.

Definition at line 1698 of file resource_channels.c.

References ast_str_buffer(), pbx_exec(), and pbx_findapp().

Referenced by ast_ari_channels_create().

1699 {
1700  struct ari_channel_thread_data *chan_data = data;
1701  struct ast_app *stasis_app;
1702 
1703  stasis_app = pbx_findapp("Stasis");
1704  if (!stasis_app) {
1705  ast_log(LOG_ERROR, "Stasis dialplan application is not registered");
1706  chan_data_destroy(chan_data);
1707  return NULL;
1708  }
1709 
1710  pbx_exec(chan_data->chan, stasis_app, ast_str_buffer(chan_data->stasis_stuff));
1711 
1712  chan_data_destroy(chan_data);
1713 
1714  return NULL;
1715 }
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx_app.c:471
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
ast_app: A registered application
Definition: pbx_app.c:45
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: ael_main.c:165
void ast_ari_channels_answer ( struct ast_variable headers,
struct ast_ari_channels_answer_args args,
struct ast_ari_response response 
)

Answer a channel.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 338 of file resource_channels.c.

References ast_ari_response_error(), ast_ari_response_no_content(), ast_ari_channels_answer_args::channel_id, channel_state_invalid(), find_control(), RAII_VAR, and stasis_app_control_answer().

Referenced by ast_ari_channels_answer_cb().

341 {
342  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
343 
344  control = find_control(response, args->channel_id);
345  if (control == NULL) {
346  return;
347  }
348 
349  if (channel_state_invalid(control, response)) {
350  return;
351  }
352 
353  if (stasis_app_control_answer(control) != 0) {
355  response, 500, "Internal Server Error",
356  "Failed to answer channel");
357  return;
358  }
359 
360  ast_ari_response_no_content(response);
361 }
static int channel_state_invalid(struct stasis_app_control *control, struct ast_ari_response *response)
Ensure channel is in a state that allows operation to be performed.
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
static struct stasis_app_control * find_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
int stasis_app_control_answer(struct stasis_app_control *control)
Answer the channel associated with this control.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_ari_channels_continue_in_dialplan ( struct ast_variable headers,
struct ast_ari_channels_continue_in_dialplan_args args,
struct ast_ari_response response 
)

Exit application; continue execution in the dialplan.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 180 of file resource_channels.c.

References ast_ari_response_alloc_failed(), ast_ari_response_error(), ast_ari_response_no_content(), ast_debug, ast_findlabel_extension(), ast_ari_channels_continue_in_dialplan_args::channel_id, channel_state_invalid(), ast_ari_channels_continue_in_dialplan_args::context, ast_ari_channels_continue_in_dialplan_args::extension, find_control(), ast_ari_channels_continue_in_dialplan_args::label, ast_ari_channels_continue_in_dialplan_args::priority, RAII_VAR, S_OR, stasis_app_control_continue(), and stasis_app_control_get_snapshot().

Referenced by ast_ari_channels_continue_in_dialplan_cb().

184 {
185  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
186  RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
187  int ipri;
188  const char *context;
189  const char *exten;
190 
191  ast_assert(response != NULL);
192 
193  control = find_control(response, args->channel_id);
194  if (control == NULL) {
195  return;
196  }
197 
198  if (channel_state_invalid(control, response)) {
199  return;
200  }
201 
202  snapshot = stasis_app_control_get_snapshot(control);
203  if (!snapshot) {
204  ast_ari_response_error(response, 404, "Not Found", "Channel not found");
205  return;
206  }
207 
208  if (ast_strlen_zero(args->context)) {
209  context = snapshot->dialplan->context;
210  exten = S_OR(args->extension, snapshot->dialplan->exten);
211  } else {
212  context = args->context;
213  exten = S_OR(args->extension, "s");
214  }
215 
216  if (!ast_strlen_zero(args->label)) {
217  /* A label was provided in the request, use that */
218 
219  if (sscanf(args->label, "%30d", &ipri) != 1) {
220  ipri = ast_findlabel_extension(NULL, context, exten, args->label, NULL);
221  if (ipri == -1) {
222  ast_log(AST_LOG_ERROR, "Requested label: %s can not be found in context: %s\n", args->label, context);
223  ast_ari_response_error(response, 404, "Not Found", "Requested label can not be found");
224  return;
225  }
226  } else {
227  ast_debug(3, "Numeric value provided for label, jumping to that priority\n");
228  }
229 
230  if (ipri == 0) {
231  ast_log(AST_LOG_ERROR, "Invalid priority label '%s' specified for extension %s in context: %s\n",
232  args->label, exten, context);
233  ast_ari_response_error(response, 400, "Bad Request", "Requested priority is illegal");
234  return;
235  }
236 
237  } else if (args->priority) {
238  /* No label provided, use provided priority */
239  ipri = args->priority;
240  } else if (ast_strlen_zero(args->context) && ast_strlen_zero(args->extension)) {
241  /* Special case. No exten, context, or priority provided, then move on to the next priority */
242  ipri = snapshot->dialplan->priority + 1;
243  } else {
244  ipri = 1;
245  }
246 
247 
248  if (stasis_app_control_continue(control, context, exten, ipri)) {
250  return;
251  }
252 
253  ast_ari_response_no_content(response);
254 }
int stasis_app_control_continue(struct stasis_app_control *control, const char *context, const char *extension, int priority)
Exit res_stasis and continue execution in the dialplan.
Definition: control.c:411
Structure representing a snapshot of channel state.
void ast_ari_response_alloc_failed(struct ast_ari_response *response)
Fill in response with a 500 message for allocation failures.
Definition: res_ari.c:298
#define ast_debug(level,...)
Log a DEBUG message.
int ast_findlabel_extension(struct ast_channel *c, const char *context, const char *exten, const char *label, const char *callerid)
Find the priority of an extension that has the specified label.
Definition: pbx.c:4180
struct ast_channel_snapshot * stasis_app_control_get_snapshot(const struct stasis_app_control *control)
Returns the most recent snapshot for the associated channel.
Definition: control.c:882
static int channel_state_invalid(struct stasis_app_control *control, struct ast_ari_response *response)
Ensure channel is in a state that allows operation to be performed.
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
static struct stasis_app_control * find_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:80
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_ari_channels_create ( struct ast_variable headers,
struct ast_ari_channels_create_args args,
struct ast_ari_response response 
)

Create channel.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 1778 of file resource_channels.c.

References ao2_bump, ao2_ref, ast_ari_channels_create_args::app, ast_ari_channels_create_args::app_args, ari_channel_thread(), ast_ari_channels_create_parse_body(), ast_ari_response_alloc_failed(), ast_ari_response_error(), ast_ari_response_ok(), ast_calloc, ast_channel_cleanup, ast_channel_errno(), ast_channel_get_by_name(), ast_channel_snapshot_get_latest(), ast_channel_snapshot_to_json(), ast_format_cache_get, ast_format_cap_alloc, ast_format_cap_append, ast_format_cap_append_by_type(), AST_FORMAT_CAP_FLAG_DEFAULT, ast_json_object_get(), ast_request(), ast_set_variables(), ast_str_append(), ast_str_create, ast_strdupa, ast_strip(), ast_variables_destroy(), ast_ari_channels_create_args::channel_id, ast_ari_channels_create_args::endpoint, ast_ari_channels_create_args::formats, ast_ari_channels_create_args::originator, ast_ari_channels_create_args::other_channel_id, RAII_VAR, save_dialstring(), stasis_app_subscribe_channel(), thread, and ast_ari_channels_create_args::variables.

Referenced by ast_ari_channels_create_cb().

1781 {
1782  RAII_VAR(struct ast_variable *, variables, NULL, ast_variables_destroy);
1783  struct ast_assigned_ids assignedids;
1784  struct ari_channel_thread_data *chan_data;
1785  struct ast_channel_snapshot *snapshot;
1786  pthread_t thread;
1787  char *dialtech;
1788  char *dialdevice = NULL;
1789  char *stuff;
1790  int cause;
1791  struct ast_format_cap *request_cap;
1792  struct ast_channel *originator;
1793 
1794  /* Parse any query parameters out of the body parameter */
1795  if (args->variables) {
1796  struct ast_json *json_variables;
1797 
1799  json_variables = ast_json_object_get(args->variables, "variables");
1800  if (json_variables
1801  && json_to_ast_variables(response, json_variables, &variables)) {
1802  return;
1803  }
1804  }
1805 
1806  assignedids.uniqueid = args->channel_id;
1807  assignedids.uniqueid2 = args->other_channel_id;
1808 
1809  if (!ast_strlen_zero(args->originator) && !ast_strlen_zero(args->formats)) {
1810  ast_ari_response_error(response, 400, "Bad Request",
1811  "Originator and formats can't both be specified");
1812  return;
1813  }
1814 
1815  if (ast_strlen_zero(args->endpoint)) {
1816  ast_ari_response_error(response, 400, "Bad Request",
1817  "Endpoint must be specified");
1818  return;
1819  }
1820 
1821  chan_data = ast_calloc(1, sizeof(*chan_data));
1822  if (!chan_data) {
1824  return;
1825  }
1826 
1827  chan_data->stasis_stuff = ast_str_create(32);
1828  if (!chan_data->stasis_stuff) {
1830  chan_data_destroy(chan_data);
1831  return;
1832  }
1833 
1834  ast_str_append(&chan_data->stasis_stuff, 0, "%s", args->app);
1835  if (!ast_strlen_zero(args->app_args)) {
1836  ast_str_append(&chan_data->stasis_stuff, 0, ",%s", args->app_args);
1837  }
1838 
1839  dialtech = ast_strdupa(args->endpoint);
1840  if ((stuff = strchr(dialtech, '/'))) {
1841  *stuff++ = '\0';
1842  dialdevice = stuff;
1843  }
1844 
1845  if (ast_strlen_zero(dialtech) || ast_strlen_zero(dialdevice)) {
1846  ast_ari_response_error(response, 400, "Bad Request",
1847  "Invalid endpoint specified");
1848  chan_data_destroy(chan_data);
1849  return;
1850  }
1851 
1852  originator = ast_channel_get_by_name(args->originator);
1853  if (originator) {
1854  request_cap = ao2_bump(ast_channel_nativeformats(originator));
1855  if (!ast_strlen_zero(args->app)) {
1856  stasis_app_subscribe_channel(args->app, originator);
1857  }
1858  } else if (!ast_strlen_zero(args->formats)) {
1859  char *format_name;
1860  char *formats_copy = ast_strdupa(args->formats);
1861 
1862  if (!(request_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
1864  chan_data_destroy(chan_data);
1865  return;
1866  }
1867 
1868  while ((format_name = ast_strip(strsep(&formats_copy, ",")))) {
1869  struct ast_format *fmt = ast_format_cache_get(format_name);
1870 
1871  if (!fmt || ast_format_cap_append(request_cap, fmt, 0)) {
1872  if (!fmt) {
1874  response, 400, "Bad Request",
1875  "Provided format (%s) was not found", format_name);
1876  } else {
1878  }
1879  ao2_ref(request_cap, -1);
1880  ao2_cleanup(fmt);
1881  chan_data_destroy(chan_data);
1882  return;
1883  }
1884  ao2_ref(fmt, -1);
1885  }
1886  } else {
1887  if (!(request_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
1889  chan_data_destroy(chan_data);
1890  return;
1891  }
1892 
1893  ast_format_cap_append_by_type(request_cap, AST_MEDIA_TYPE_AUDIO);
1894  }
1895 
1896  chan_data->chan = ast_request(dialtech, request_cap, &assignedids, originator, dialdevice, &cause);
1897  ao2_cleanup(request_cap);
1898 
1899  if (!chan_data->chan) {
1900  if (ast_channel_errno() == AST_CHANNEL_ERROR_ID_EXISTS) {
1901  ast_ari_response_error(response, 409, "Conflict",
1902  "Channel with given unique ID already exists");
1903  } else {
1905  }
1906  ast_channel_cleanup(originator);
1907  chan_data_destroy(chan_data);
1908  return;
1909  }
1910 
1911  if (!ast_strlen_zero(args->app)) {
1912  stasis_app_subscribe_channel(args->app, chan_data->chan);
1913  }
1914 
1915  if (variables) {
1916  ast_set_variables(chan_data->chan, variables);
1917  }
1918 
1919  ast_channel_cleanup(originator);
1920 
1921  if (save_dialstring(chan_data->chan, stuff)) {
1923  chan_data_destroy(chan_data);
1924  return;
1925  }
1926 
1927  snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan_data->chan));
1928 
1929  if (ast_pthread_create_detached(&thread, NULL, ari_channel_thread, chan_data)) {
1931  chan_data_destroy(chan_data);
1932  } else {
1933  ast_ari_response_ok(response, ast_channel_snapshot_to_json(snapshot, NULL));
1934  }
1935 
1936  ao2_ref(snapshot, -1);
1937 }
Main Channel structure associated with a channel.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
int ast_ari_channels_create_parse_body(struct ast_json *body, struct ast_ari_channels_create_args *args)
Body parsing function for /channels/create.
Structure for variables, used for configurations and for channel variables.
pthread_t thread
Definition: app_sla.c:329
Structure representing a snapshot of channel state.
void ast_set_variables(struct ast_channel *chan, struct ast_variable *vars)
adds a list of channel variables to a channel
Definition: channel.c:8115
Structure to pass both assignedid values to channel drivers.
Definition: channel.h:604
Definition of a media format.
Definition: format.c:43
static void * ari_channel_thread(void *data)
Thread that owns stasis-created channel.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
int ast_format_cap_append_by_type(struct ast_format_cap *cap, enum ast_media_type type)
Add all codecs Asterisk knows about for a specific type to the capabilities structure.
Definition: format_cap.c:216
void ast_ari_response_alloc_failed(struct ast_ari_response *response)
Fill in response with a 500 message for allocation failures.
Definition: res_ari.c:298
#define ast_format_cache_get(name)
Retrieve a named format from the cache.
Definition: format_cache.h:278
struct ast_channel * ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause)
Requests a channel.
Definition: channel.c:6354
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
static int save_dialstring(struct ast_channel *chan, const char *dialstring)
Save dialstring onto a channel datastore.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
void ast_ari_response_ok(struct ast_ari_response *response, struct ast_json *message)
Fill in an OK (200) ast_ari_response.
Definition: res_ari.c:276
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969
#define ast_format_cap_append(cap, format, framing)
Add format capability to capabilities structure.
Definition: format_cap.h:99
#define ast_format_cap_alloc(flags)
Allocate a new ast_format_cap structure.
Definition: format_cap.h:49
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
enum stasis_app_subscribe_res stasis_app_subscribe_channel(const char *app_name, struct ast_channel *chan)
Directly subscribe an application to a channel.
Definition: res_stasis.c:1991
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object...
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
Abstract JSON element (object, array, string, int, ...).
enum ast_channel_error ast_channel_errno(void)
Get error code for latest channel operation.
Definition: channel.c:10961
struct ast_json * ast_channel_snapshot_to_json(const struct ast_channel_snapshot *snapshot, const struct stasis_message_sanitizer *sanitize)
Build a JSON object from a ast_channel_snapshot.
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
void ast_ari_channels_dial ( struct ast_variable headers,
struct ast_ari_channels_dial_args args,
struct ast_ari_response response 
)

Dial a created channel.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 1939 of file resource_channels.c.

References ast_ari_response_alloc_failed(), ast_ari_response_error(), ast_ari_response_no_content(), ast_channel_cleanup, ast_channel_datastore_inherit(), ast_channel_get_by_name(), ast_channel_inherit_variables(), ast_channel_lock_both, ast_channel_req_accountcodes(), AST_CHANNEL_REQUESTOR_BRIDGE_PEER, ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_connected_line_copy_from_caller(), ast_party_redirecting_copy(), AST_STATE_DOWN, AST_STATE_RESERVED, ast_strdupa, ast_ari_channels_dial_args::caller, ast_ari_channels_dial_args::channel_id, find_control(), RAII_VAR, restore_dialstring(), stasis_app_control_dial(), ast_ari_channels_dial_args::timeout, and ast_party_dialed::transit_network_select.

Referenced by ast_ari_channels_dial_cb().

1942 {
1943  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
1944  RAII_VAR(struct ast_channel *, caller, NULL, ast_channel_cleanup);
1945  RAII_VAR(struct ast_channel *, callee, NULL, ast_channel_cleanup);
1946  char *dialstring;
1947 
1948  control = find_control(response, args->channel_id);
1949  if (control == NULL) {
1950  /* Response filled in by find_control */
1951  return;
1952  }
1953 
1954  caller = ast_channel_get_by_name(args->caller);
1955 
1956  callee = ast_channel_get_by_name(args->channel_id);
1957  if (!callee) {
1958  ast_ari_response_error(response, 404, "Not Found",
1959  "Callee not found");
1960  return;
1961  }
1962 
1963  if (ast_channel_state(callee) != AST_STATE_DOWN
1964  && ast_channel_state(callee) != AST_STATE_RESERVED) {
1965  ast_ari_response_error(response, 409, "Conflict",
1966  "Channel is not in the 'Down' state");
1967  return;
1968  }
1969 
1970  /* XXX This is straight up copied from main/dial.c. It's probably good
1971  * to separate this to some common method.
1972  */
1973  if (caller) {
1974  ast_channel_lock_both(caller, callee);
1975  } else {
1976  ast_channel_lock(callee);
1977  }
1978 
1979  dialstring = restore_dialstring(callee);
1980  if (!dialstring) {
1981  ast_channel_unlock(callee);
1982  if (caller) {
1983  ast_channel_unlock(caller);
1984  }
1985  ast_ari_response_error(response, 409, "Conflict",
1986  "Dialing a channel not created by ARI");
1987  return;
1988  }
1989  /* Make a copy of the dialstring just in case some jerk tries to hang up the
1990  * channel before we can actually dial
1991  */
1992  dialstring = ast_strdupa(dialstring);
1993 
1995  if (caller) {
1996  ast_channel_inherit_variables(caller, callee);
1997  ast_channel_datastore_inherit(caller, callee);
1998  ast_max_forwards_decrement(callee);
1999 
2000  /* Copy over callerid information */
2001  ast_party_redirecting_copy(ast_channel_redirecting(callee), ast_channel_redirecting(caller));
2002 
2003  ast_channel_dialed(callee)->transit_network_select = ast_channel_dialed(caller)->transit_network_select;
2004 
2005  ast_connected_line_copy_from_caller(ast_channel_connected(callee), ast_channel_caller(caller));
2006 
2007  ast_channel_language_set(callee, ast_channel_language(caller));
2009  if (ast_strlen_zero(ast_channel_musicclass(callee)))
2010  ast_channel_musicclass_set(callee, ast_channel_musicclass(caller));
2011 
2012  ast_channel_adsicpe_set(callee, ast_channel_adsicpe(caller));
2013  ast_channel_transfercapability_set(callee, ast_channel_transfercapability(caller));
2014  ast_channel_unlock(caller);
2015  }
2016 
2018  ast_channel_unlock(callee);
2019 
2020  if (stasis_app_control_dial(control, dialstring, args->timeout)) {
2022  return;
2023  }
2024 
2025  ast_ari_response_no_content(response);
2026 }
Main Channel structure associated with a channel.
ast_channel_state
ast_channel states
Definition: channelstate.h:35
void ast_ari_response_alloc_failed(struct ast_ari_response *response)
Fill in response with a 500 message for allocation failures.
Definition: res_ari.c:298
static char * restore_dialstring(struct ast_channel *chan)
Retrieve the dialstring from the channel datastore.
int ast_channel_datastore_inherit(struct ast_channel *from, struct ast_channel *to)
Inherit datastores from a parent to a child.
Definition: channel.c:2368
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969
int stasis_app_control_dial(struct stasis_app_control *control, const char *dialstring, unsigned int timeout)
Dial a channel.
Definition: control.c:1688
void ast_channel_req_accountcodes(struct ast_channel *chan, const struct ast_channel *requestor, enum ast_channel_requestor_relationship relationship)
Setup new channel accountcodes from the requestor channel after ast_request().
Definition: channel.c:6434
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
void ast_channel_inherit_variables(const struct ast_channel *parent, struct ast_channel *child)
Inherits channel variable from parent to child channel.
Definition: channel.c:6771
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2929
int transit_network_select
Transit Network Select.
Definition: channel.h:397
static struct stasis_app_control * find_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
void ast_connected_line_copy_from_caller(struct ast_party_connected_line *dest, const struct ast_party_caller *src)
Copy the caller information to the connected line information.
Definition: channel.c:8293
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_party_redirecting_copy(struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
Copy the source redirecting information to the destination redirecting.
Definition: channel.c:2135
void ast_ari_channels_external_media ( struct ast_variable headers,
struct ast_ari_channels_external_media_args args,
struct ast_ari_response response 
)

Start an External Media session.

Create a channel to an External Media source/sink.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 2185 of file resource_channels.c.

References ast_ari_channels_external_media_args::app, ast_ari_channels_external_media_parse_body(), ast_ari_response_error(), ast_json_object_get(), ast_sockaddr_split_hostport(), ast_strdupa, ast_ari_channels_external_media_args::connection_type, ast_ari_channels_external_media_args::direction, ast_ari_channels_external_media_args::encapsulation, ast_ari_channels_external_media_args::external_host, ast_ari_channels_external_media_args::format, ast_ari_channels_external_media_args::transport, and ast_ari_channels_external_media_args::variables.

Referenced by ast_ari_channels_external_media_cb().

2187 {
2188  struct ast_variable *variables = NULL;
2189  char *external_host;
2190  char *host = NULL;
2191  char *port = NULL;
2192 
2193  ast_assert(response != NULL);
2194 
2195  /* Parse any query parameters out of the body parameter */
2196  if (args->variables) {
2197  struct ast_json *json_variables;
2198 
2200  json_variables = ast_json_object_get(args->variables, "variables");
2201  if (json_variables
2202  && json_to_ast_variables(response, json_variables, &variables)) {
2203  return;
2204  }
2205  }
2206 
2207  if (ast_strlen_zero(args->app)) {
2208  ast_ari_response_error(response, 400, "Bad Request", "app cannot be empty");
2209  return;
2210  }
2211 
2212  if (ast_strlen_zero(args->external_host)) {
2213  ast_ari_response_error(response, 400, "Bad Request", "external_host cannot be empty");
2214  return;
2215  }
2216 
2217  external_host = ast_strdupa(args->external_host);
2218  if (!ast_sockaddr_split_hostport(external_host, &host, &port, PARSE_PORT_REQUIRE)) {
2219  ast_ari_response_error(response, 400, "Bad Request", "external_host must be <host>:<port>");
2220  return;
2221  }
2222 
2223  if (ast_strlen_zero(args->format)) {
2224  ast_ari_response_error(response, 400, "Bad Request", "format cannot be empty");
2225  return;
2226  }
2227 
2228  if (ast_strlen_zero(args->encapsulation)) {
2229  args->encapsulation = "rtp";
2230  }
2231  if (ast_strlen_zero(args->transport)) {
2232  args->transport = "udp";
2233  }
2234  if (ast_strlen_zero(args->connection_type)) {
2235  args->connection_type = "client";
2236  }
2237  if (ast_strlen_zero(args->direction)) {
2238  args->direction = "both";
2239  }
2240 
2241  if (strcasecmp(args->encapsulation, "rtp") == 0 && strcasecmp(args->transport, "udp") == 0) {
2242  if (external_media_rtp_udp(args, variables, response)) {
2244  response, 500, "Internal Server Error",
2245  "An internal error prevented this request from being handled");
2246  }
2247  } else if (strcasecmp(args->encapsulation, "audiosocket") == 0 && strcasecmp(args->transport, "tcp") == 0) {
2248  external_media_audiosocket_tcp(args, variables, response);
2249  } else {
2251  response, 501, "Not Implemented",
2252  "The encapsulation and/or transport is not supported");
2253  }
2254 }
int ast_ari_channels_external_media_parse_body(struct ast_json *body, struct ast_ari_channels_external_media_args *args)
Body parsing function for /channels/externalMedia.
Structure for variables, used for configurations and for channel variables.
int ast_sockaddr_split_hostport(char *str, char **host, char **port, int flags)
Splits a string into its host and port components.
Definition: netsock2.c:164
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
Abstract JSON element (object, array, string, int, ...).
void ast_ari_channels_get ( struct ast_variable headers,
struct ast_ari_channels_get_args args,
struct ast_ari_response response 
)

Channel details.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 888 of file resource_channels.c.

References ao2_ref, ast_ari_response_error(), ast_ari_response_ok(), ast_channel_snapshot_get_latest(), ast_channel_snapshot_to_json(), and ast_ari_channels_get_args::channel_id.

Referenced by ast_ari_channels_get_cb().

891 {
892  struct ast_channel_snapshot *snapshot;
893 
895  if (!snapshot) {
897  response, 404, "Not Found",
898  "Channel not found");
899  return;
900  }
901 
902  ast_ari_response_ok(response,
903  ast_channel_snapshot_to_json(snapshot, NULL));
904  ao2_ref(snapshot, -1);
905 }
Structure representing a snapshot of channel state.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
void ast_ari_response_ok(struct ast_ari_response *response, struct ast_json *message)
Fill in an OK (200) ast_ari_response.
Definition: res_ari.c:276
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object...
struct ast_json * ast_channel_snapshot_to_json(const struct ast_channel_snapshot *snapshot, const struct stasis_message_sanitizer *sanitize)
Build a JSON object from a ast_channel_snapshot.
void ast_ari_channels_get_channel_var ( struct ast_variable headers,
struct ast_ari_channels_get_channel_var_args args,
struct ast_ari_response response 
)

Get the value of a channel variable or function.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 1472 of file resource_channels.c.

References ast_ari_response_alloc_failed(), ast_ari_response_error(), ast_ari_response_ok(), ast_channel_cleanup, ast_channel_get_by_name(), ast_func_read2(), ast_json_pack(), ast_json_ref(), ast_json_unref(), ast_str_buffer(), ast_str_create, ast_str_retrieve_variable(), ast_ari_channels_get_channel_var_args::channel_id, RAII_VAR, S_OR, and ast_ari_channels_get_channel_var_args::variable.

Referenced by ast_ari_channels_get_channel_var_cb().

1475 {
1476  RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
1477  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
1478  RAII_VAR(struct ast_str *, value, ast_str_create(32), ast_free);
1479  RAII_VAR(struct ast_channel *, channel, NULL, ast_channel_cleanup);
1480 
1481  ast_assert(response != NULL);
1482 
1483  if (!value) {
1485  return;
1486  }
1487 
1488  if (ast_strlen_zero(args->variable)) {
1490  response, 400, "Bad Request",
1491  "Variable name is required");
1492  return;
1493  }
1494 
1495  if (ast_strlen_zero(args->channel_id)) {
1497  response, 400, "Bad Request",
1498  "Channel ID is required");
1499  return;
1500  }
1501 
1502  channel = ast_channel_get_by_name(args->channel_id);
1503  if (!channel) {
1505  response, 404, "Channel Not Found",
1506  "Provided channel was not found");
1507  return;
1508  }
1509 
1510  /* You may be tempted to lock the channel you're about to read from. You
1511  * would be wrong. Some dialplan functions put the channel into
1512  * autoservice, which deadlocks if the channel is already locked.
1513  * ast_str_retrieve_variable() does its own locking, and the dialplan
1514  * functions need to as well. We should be fine without the lock.
1515  */
1516 
1517  if (args->variable[strlen(args->variable) - 1] == ')') {
1518  if (ast_func_read2(channel, args->variable, &value, 0)) {
1520  response, 500, "Error With Function",
1521  "Unable to read provided function");
1522  return;
1523  }
1524  } else {
1525  if (!ast_str_retrieve_variable(&value, 0, channel, NULL, args->variable)) {
1527  response, 404, "Variable Not Found",
1528  "Provided variable was not found");
1529  return;
1530  }
1531  }
1532 
1533  if (!(json = ast_json_pack("{s: s}", "value", S_OR(ast_str_buffer(value), "")))) {
1535  return;
1536  }
1537 
1538  ast_ari_response_ok(response, ast_json_ref(json));
1539 }
Main Channel structure associated with a channel.
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
int ast_func_read2(struct ast_channel *chan, const char *function, struct ast_str **str, ssize_t maxlen)
executes a read operation on a function
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
void ast_ari_response_alloc_failed(struct ast_ari_response *response)
Fill in response with a 500 message for allocation failures.
Definition: res_ari.c:298
void ast_ari_response_ok(struct ast_ari_response *response, struct ast_json *message)
Fill in an OK (200) ast_ari_response.
Definition: res_ari.c:276
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969
Support for dynamic strings.
Definition: strings.h:623
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
const char * ast_str_retrieve_variable(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, struct varshead *headp, const char *var)
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:80
Abstract JSON element (object, array, string, int, ...).
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
void ast_ari_channels_hangup ( struct ast_variable headers,
struct ast_ari_channels_hangup_args args,
struct ast_ari_response response 
)

Delete (i.e. hangup) a channel.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 907 of file resource_channels.c.

References ast_ari_response_error(), ast_ari_response_no_content(), ast_channel_get_by_name(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, ast_ari_channels_hangup_args::channel_id, convert_reason_to_hangup_code(), RAII_VAR, ast_ari_channels_hangup_args::reason, and ast_ari_channels_hangup_args::reason_code.

Referenced by ast_ari_channels_hangup_cb().

910 {
911  RAII_VAR(struct ast_channel *, chan, NULL, ao2_cleanup);
912  int cause;
913 
914  chan = ast_channel_get_by_name(args->channel_id);
915  if (chan == NULL) {
917  response, 404, "Not Found",
918  "Channel not found");
919  return;
920  }
921 
922  if (!ast_strlen_zero(args->reason) && !ast_strlen_zero(args->reason_code)) {
923  ast_ari_response_error(response, 400, "Bad Request",
924  "The reason and reason_code can't both be specified");
925  return;
926  }
927 
928  if (!ast_strlen_zero(args->reason_code)) {
929  /* reason_code allows any hangup code */
930  if (sscanf(args->reason_code, "%30d", &cause) != 1) {
932  response, 400, "Invalid Reason Code",
933  "Invalid reason for hangup reason code provided");
934  return;
935  }
936  } else if (!ast_strlen_zero(args->reason)) {
937  /* reason allows only listed hangup reason */
938  cause = convert_reason_to_hangup_code(args->reason);
939  if (cause == -1) {
941  response, 400, "Invalid Reason",
942  "Invalid reason for hangup reason provided");
943  return;
944  }
945  } else {
946  /* not specified. set default hangup */
947  cause = AST_CAUSE_NORMAL;
948  }
949 
950  ast_channel_hangupcause_set(chan, cause);
952 
953  ast_ari_response_no_content(response);
954 }
Main Channel structure associated with a channel.
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
Definition: channel.c:2471
static int convert_reason_to_hangup_code(const char *reason)
Return the corresponded hangup code of the given reason.
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_ari_channels_hold ( struct ast_variable headers,
struct ast_ari_channels_hold_args args,
struct ast_ari_response response 
)

Hold a channel.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 514 of file resource_channels.c.

References ast_ari_response_no_content(), ast_ari_channels_hold_args::channel_id, channel_state_invalid(), find_control(), RAII_VAR, and stasis_app_control_hold().

Referenced by ast_ari_channels_hold_cb().

517 {
518  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
519 
520  control = find_control(response, args->channel_id);
521  if (control == NULL) {
522  /* Response filled in by find_control */
523  return;
524  }
525 
526  if (channel_state_invalid(control, response)) {
527  return;
528  }
529 
530  stasis_app_control_hold(control);
531 
532  ast_ari_response_no_content(response);
533 }
void stasis_app_control_hold(struct stasis_app_control *control)
Place the channel associated with the control on hold.
Definition: control.c:770
static int channel_state_invalid(struct stasis_app_control *control, struct ast_ari_response *response)
Ensure channel is in a state that allows operation to be performed.
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
static struct stasis_app_control * find_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_ari_channels_list ( struct ast_variable headers,
struct ast_ari_channels_list_args args,
struct ast_ari_response response 
)

List all active channels in Asterisk.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 956 of file resource_channels.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_ref, ast_ari_response_alloc_failed(), ast_ari_response_ok(), ast_channel_snapshot_to_json(), ast_json_array_append(), ast_json_array_create(), ast_json_ref(), ast_json_unref(), stasis_message_sanitizer::channel_snapshot, RAII_VAR, and stasis_app_get_sanitizer().

Referenced by ast_ari_channels_list_cb().

959 {
960  RAII_VAR(struct ao2_container *, snapshots, NULL, ao2_cleanup);
961  RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
962  struct ao2_iterator i;
963  void *obj;
965 
966  snapshots = ast_channel_cache_all();
967 
968  json = ast_json_array_create();
969  if (!json) {
971  return;
972  }
973 
974  i = ao2_iterator_init(snapshots, 0);
975  while ((obj = ao2_iterator_next(&i))) {
976  struct ast_channel_snapshot *snapshot = obj;
977  int r;
978 
979  if (sanitize && sanitize->channel_snapshot
980  && sanitize->channel_snapshot(snapshot)) {
981  ao2_ref(snapshot, -1);
982  continue;
983  }
984 
986  json, ast_channel_snapshot_to_json(snapshot, NULL));
987  if (r != 0) {
990  ao2_ref(snapshot, -1);
991  return;
992  }
993  ao2_ref(snapshot, -1);
994  }
996 
997  ast_ari_response_ok(response, ast_json_ref(json));
998 }
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
int(* channel_snapshot)(const struct ast_channel_snapshot *snapshot)
Callback which determines whether a channel should be sanitized from a message based on the channel's...
Definition: stasis.h:221
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
Structure representing a snapshot of channel state.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
void ast_ari_response_alloc_failed(struct ast_ari_response *response)
Fill in response with a 500 message for allocation failures.
Definition: res_ari.c:298
Structure containing callbacks for Stasis message sanitization.
Definition: stasis.h:200
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
void ast_ari_response_ok(struct ast_ari_response *response, struct ast_json *message)
Fill in an OK (200) ast_ari_response.
Definition: res_ari.c:276
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
Definition: json.c:362
int ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
Definition: json.c:378
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2271
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
Abstract JSON element (object, array, string, int, ...).
Generic container type.
struct ast_json * ast_channel_snapshot_to_json(const struct ast_channel_snapshot *snapshot, const struct stasis_message_sanitizer *sanitize)
Build a JSON object from a ast_channel_snapshot.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ast_ari_channels_move ( struct ast_variable headers,
struct ast_ari_channels_move_args args,
struct ast_ari_response response 
)

Move the channel from one Stasis application to another.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 256 of file resource_channels.c.

References ast_ari_channels_move_args::app, ast_ari_channels_move_args::app_args, ast_ari_response_error(), ast_ari_response_no_content(), ast_ari_channels_move_args::channel_id, find_control(), RAII_VAR, and stasis_app_control_move().

Referenced by ast_ari_channels_move_cb().

259 {
260  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
261 
262  control = find_control(response, args->channel_id);
263  if (!control) {
264  return;
265  }
266 
267  if (stasis_app_control_move(control, args->app, args->app_args)) {
268  ast_ari_response_error(response, 500, "Internal Server Error",
269  "Failed to switch Stasis applications");
270  return;
271  }
272 
273  ast_ari_response_no_content(response);
274 }
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
int stasis_app_control_move(struct stasis_app_control *control, const char *app_name, const char *app_args)
Exit res_stasis and move to another Stasis application.
Definition: control.c:473
static struct stasis_app_control * find_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_ari_channels_mute ( struct ast_variable headers,
struct ast_ari_channels_mute_args args,
struct ast_ari_response response 
)

Mute a channel.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 403 of file resource_channels.c.

References ast_ari_response_error(), ast_ari_response_no_content(), AST_FRAME_VOICE, ast_ari_channels_mute_args::channel_id, channel_state_invalid(), ast_ari_channels_mute_args::direction, find_control(), RAII_VAR, and stasis_app_control_mute().

Referenced by ast_ari_channels_mute_cb().

406 {
407  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
408  unsigned int direction = 0;
409  enum ast_frame_type frametype = AST_FRAME_VOICE;
410 
411  control = find_control(response, args->channel_id);
412  if (control == NULL) {
413  return;
414  }
415 
416  if (channel_state_invalid(control, response)) {
417  return;
418  }
419 
420  if (ast_strlen_zero(args->direction)) {
422  response, 400, "Bad Request",
423  "Direction is required");
424  return;
425  }
426 
427  if (!strcmp(args->direction, "in")) {
428  direction = AST_MUTE_DIRECTION_READ;
429  } else if (!strcmp(args->direction, "out")) {
430  direction = AST_MUTE_DIRECTION_WRITE;
431  } else if (!strcmp(args->direction, "both")) {
432  direction = AST_MUTE_DIRECTION_READ | AST_MUTE_DIRECTION_WRITE;
433  } else {
435  response, 400, "Bad Request",
436  "Invalid direction specified");
437  return;
438  }
439 
440  stasis_app_control_mute(control, direction, frametype);
441 
442  ast_ari_response_no_content(response);
443 }
int stasis_app_control_mute(struct stasis_app_control *control, unsigned int direction, enum ast_frame_type frametype)
Mute the channel associated with this control.
Definition: control.c:653
ast_frame_type
Frame types.
static int channel_state_invalid(struct stasis_app_control *control, struct ast_ari_response *response)
Ensure channel is in a state that allows operation to be performed.
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
static struct stasis_app_control * find_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_ari_channels_originate ( struct ast_variable headers,
struct ast_ari_channels_originate_args args,
struct ast_ari_response response 
)

Create a new channel (originate).

The new channel is created immediately and a snapshot of it returned. If a Stasis application is provided it will be automatically subscribed to the originated channel for further events and updates.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 1433 of file resource_channels.c.

References ast_ari_channels_originate_args::app, ast_ari_channels_originate_args::app_args, ast_ari_channels_originate_parse_body(), ast_channel_cleanup, ast_json_object_get(), ast_variables_destroy(), ast_ari_channels_originate_args::caller_id, ast_ari_channels_originate_args::channel_id, ast_ari_channels_originate_args::context, ast_ari_channels_originate_args::endpoint, ast_ari_channels_originate_args::extension, ast_ari_channels_originate_args::formats, ast_ari_channels_originate_args::label, ast_ari_channels_originate_args::originator, ast_ari_channels_originate_args::other_channel_id, ast_ari_channels_originate_args::priority, ast_ari_channels_originate_args::timeout, and ast_ari_channels_originate_args::variables.

Referenced by ast_ari_channels_originate_cb().

1436 {
1437  struct ast_variable *variables = NULL;
1438  struct ast_channel *chan;
1439 
1440  /* Parse any query parameters out of the body parameter */
1441  if (args->variables) {
1442  struct ast_json *json_variables;
1443 
1445  json_variables = ast_json_object_get(args->variables, "variables");
1446  if (json_variables
1447  && json_to_ast_variables(response, json_variables, &variables)) {
1448  return;
1449  }
1450  }
1451 
1452  chan = ari_channels_handle_originate_with_id(
1453  args->endpoint,
1454  args->extension,
1455  args->context,
1456  args->priority,
1457  args->label,
1458  args->app,
1459  args->app_args,
1460  args->caller_id,
1461  args->timeout,
1462  variables,
1463  args->channel_id,
1464  args->other_channel_id,
1465  args->originator,
1466  args->formats,
1467  response);
1468  ast_channel_cleanup(chan);
1469  ast_variables_destroy(variables);
1470 }
Main Channel structure associated with a channel.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
Structure for variables, used for configurations and for channel variables.
int ast_ari_channels_originate_parse_body(struct ast_json *body, struct ast_ari_channels_originate_args *args)
Body parsing function for /channels.
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
Abstract JSON element (object, array, string, int, ...).
void ast_ari_channels_originate_with_id ( struct ast_variable headers,
struct ast_ari_channels_originate_with_id_args args,
struct ast_ari_response response 
)

Create a new channel (originate with id).

The new channel is created immediately and a snapshot of it returned. If a Stasis application is provided it will be automatically subscribed to the originated channel for further events and updates.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 1394 of file resource_channels.c.

References ast_ari_channels_originate_with_id_args::app, ast_ari_channels_originate_with_id_args::app_args, ast_ari_channels_originate_with_id_parse_body(), ast_channel_cleanup, ast_json_object_get(), ast_variables_destroy(), ast_ari_channels_originate_with_id_args::caller_id, ast_ari_channels_originate_with_id_args::channel_id, ast_ari_channels_originate_with_id_args::context, ast_ari_channels_originate_with_id_args::endpoint, ast_ari_channels_originate_with_id_args::extension, ast_ari_channels_originate_with_id_args::formats, ast_ari_channels_originate_with_id_args::label, ast_ari_channels_originate_with_id_args::originator, ast_ari_channels_originate_with_id_args::other_channel_id, ast_ari_channels_originate_with_id_args::priority, ast_ari_channels_originate_with_id_args::timeout, and ast_ari_channels_originate_with_id_args::variables.

Referenced by ast_ari_channels_originate_with_id_cb().

1397 {
1398  struct ast_variable *variables = NULL;
1399  struct ast_channel *chan;
1400 
1401  /* Parse any query parameters out of the body parameter */
1402  if (args->variables) {
1403  struct ast_json *json_variables;
1404 
1406  json_variables = ast_json_object_get(args->variables, "variables");
1407  if (json_variables
1408  && json_to_ast_variables(response, json_variables, &variables)) {
1409  return;
1410  }
1411  }
1412 
1413  chan = ari_channels_handle_originate_with_id(
1414  args->endpoint,
1415  args->extension,
1416  args->context,
1417  args->priority,
1418  args->label,
1419  args->app,
1420  args->app_args,
1421  args->caller_id,
1422  args->timeout,
1423  variables,
1424  args->channel_id,
1425  args->other_channel_id,
1426  args->originator,
1427  args->formats,
1428  response);
1429  ast_channel_cleanup(chan);
1430  ast_variables_destroy(variables);
1431 }
Main Channel structure associated with a channel.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
Structure for variables, used for configurations and for channel variables.
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969
int ast_ari_channels_originate_with_id_parse_body(struct ast_json *body, struct ast_ari_channels_originate_with_id_args *args)
Body parsing function for /channels/{channelId}.
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
Abstract JSON element (object, array, string, int, ...).
void ast_ari_channels_play ( struct ast_variable headers,
struct ast_ari_channels_play_args args,
struct ast_ari_response response 
)

Start playback of media.

The media URI may be any of a number of URI's. Currently sound:, recording:, number:, digits:, characters:, and tone: URI's are supported. This operation creates a playback resource that can be used to control the playback of media (pause, rewind, fast forward, etc.)

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 718 of file resource_channels.c.

References ast_ari_channels_play_args::channel_id, ast_ari_channels_play_args::lang, ast_ari_channels_play_args::media, ast_ari_channels_play_args::media_count, ast_ari_channels_play_args::offsetms, ast_ari_channels_play_args::playback_id, and ast_ari_channels_play_args::skipms.

Referenced by ast_ari_channels_play_cb().

721 {
722  ari_channels_handle_play(
723  args->channel_id,
724  args->media,
725  args->media_count,
726  args->lang,
727  args->offsetms,
728  args->skipms,
729  args->playback_id,
730  response);
731 }
void ast_ari_channels_play_with_id ( struct ast_variable headers,
struct ast_ari_channels_play_with_id_args args,
struct ast_ari_response response 
)

Start playback of media and specify the playbackId.

The media URI may be any of a number of URI's. Currently sound:, recording:, number:, digits:, characters:, and tone: URI's are supported. This operation creates a playback resource that can be used to control the playback of media (pause, rewind, fast forward, etc.)

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 733 of file resource_channels.c.

References ast_ari_channels_play_with_id_args::channel_id, ast_ari_channels_play_with_id_args::lang, ast_ari_channels_play_with_id_args::media, ast_ari_channels_play_with_id_args::media_count, ast_ari_channels_play_with_id_args::offsetms, ast_ari_channels_play_with_id_args::playback_id, and ast_ari_channels_play_with_id_args::skipms.

Referenced by ast_ari_channels_play_with_id_cb().

736 {
737  ari_channels_handle_play(
738  args->channel_id,
739  args->media,
740  args->media_count,
741  args->lang,
742  args->offsetms,
743  args->skipms,
744  args->playback_id,
745  response);
746 }
void ast_ari_channels_record ( struct ast_variable headers,
struct ast_ari_channels_record_args args,
struct ast_ari_response response 
)

Start a recording.

Record audio from a channel. Note that this will not capture audio sent to the channel. The bridge itself has a record feature if that's what you want.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 748 of file resource_channels.c.

References ast_ari_response_created(), ast_ari_response_error(), ast_asprintf, ast_get_format_for_file_ext(), ast_malloc, AST_RECORD_IF_EXISTS_ERROR, ast_string_field_build, ast_uri_encode(), ast_ari_channels_record_args::beep, ast_ari_channels_record_args::channel_id, find_control(), ast_ari_channels_record_args::format, ast_ari_channels_record_args::if_exists, ast_ari_channels_record_args::max_duration_seconds, ast_ari_channels_record_args::max_silence_seconds, ast_ari_channels_record_args::name, RAII_VAR, stasis_app_control_record(), stasis_app_recording_if_exists_parse(), stasis_app_recording_options_create(), stasis_app_recording_termination_parse(), stasis_app_recording_to_json(), and ast_ari_channels_record_args::terminate_on.

Referenced by ast_ari_channels_record_cb().

751 {
752  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
753  RAII_VAR(struct stasis_app_recording *, recording, NULL, ao2_cleanup);
754  RAII_VAR(char *, recording_url, NULL, ast_free);
755  struct ast_json *json;
756  RAII_VAR(struct stasis_app_recording_options *, options, NULL,
757  ao2_cleanup);
758  RAII_VAR(char *, uri_encoded_name, NULL, ast_free);
759  size_t uri_name_maxlen;
760 
761  ast_assert(response != NULL);
762 
763  if (args->max_duration_seconds < 0) {
765  response, 400, "Bad Request",
766  "max_duration_seconds cannot be negative");
767  return;
768  }
769 
770  if (args->max_silence_seconds < 0) {
772  response, 400, "Bad Request",
773  "max_silence_seconds cannot be negative");
774  return;
775  }
776 
777  control = find_control(response, args->channel_id);
778  if (control == NULL) {
779  /* Response filled in by find_control */
780  return;
781  }
782 
783  options = stasis_app_recording_options_create(args->name, args->format);
784  if (options == NULL) {
786  response, 500, "Internal Server Error",
787  "Out of memory");
788  }
789  ast_string_field_build(options, target, "channel:%s", args->channel_id);
790  options->max_silence_seconds = args->max_silence_seconds;
791  options->max_duration_seconds = args->max_duration_seconds;
792  options->terminate_on =
794  options->if_exists =
796  options->beep = args->beep;
797 
798  if (options->terminate_on == STASIS_APP_RECORDING_TERMINATE_INVALID) {
800  response, 400, "Bad Request",
801  "terminateOn invalid");
802  return;
803  }
804 
805  if (options->if_exists == AST_RECORD_IF_EXISTS_ERROR) {
807  response, 400, "Bad Request",
808  "ifExists invalid");
809  return;
810  }
811 
812  if (!ast_get_format_for_file_ext(options->format)) {
814  response, 422, "Unprocessable Entity",
815  "specified format is unknown on this system");
816  return;
817  }
818 
819  recording = stasis_app_control_record(control, options);
820  if (recording == NULL) {
821  switch(errno) {
822  case EINVAL:
823  /* While the arguments are invalid, we should have
824  * caught them prior to calling record.
825  */
827  response, 500, "Internal Server Error",
828  "Error parsing request");
829  break;
830  case EEXIST:
831  ast_ari_response_error(response, 409, "Conflict",
832  "Recording '%s' already exists and can not be overwritten",
833  args->name);
834  break;
835  case ENOMEM:
837  response, 500, "Internal Server Error",
838  "Out of memory");
839  break;
840  case EPERM:
842  response, 400, "Bad Request",
843  "Recording name invalid");
844  break;
845  default:
846  ast_log(LOG_WARNING,
847  "Unrecognized recording error: %s\n",
848  strerror(errno));
850  response, 500, "Internal Server Error",
851  "Internal Server Error");
852  break;
853  }
854  return;
855  }
856 
857  uri_name_maxlen = strlen(args->name) * 3;
858  uri_encoded_name = ast_malloc(uri_name_maxlen);
859  if (!uri_encoded_name) {
861  response, 500, "Internal Server Error",
862  "Out of memory");
863  return;
864  }
865  ast_uri_encode(args->name, uri_encoded_name, uri_name_maxlen,
866  ast_uri_http);
867 
868  if (ast_asprintf(&recording_url, "/recordings/live/%s",
869  uri_encoded_name) == -1) {
870  recording_url = NULL;
872  response, 500, "Internal Server Error",
873  "Out of memory");
874  return;
875  }
876 
877  json = stasis_app_recording_to_json(recording);
878  if (!json) {
880  response, 500, "Internal Server Error",
881  "Out of memory");
882  return;
883  }
884 
885  ast_ari_response_created(response, recording_url, json);
886 }
void ast_ari_response_created(struct ast_ari_response *response, const char *url, struct ast_json *message)
Fill in a Created (201) ast_ari_response.
Definition: res_ari.c:305
char * ast_uri_encode(const char *string, char *outbuf, int buflen, struct ast_flags spec)
Turn text string to URI-encoded XX version.
Definition: utils.c:723
char stasis_app_recording_termination_parse(const char *str)
Parse a string into the recording termination enum.
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
struct ast_json * stasis_app_recording_to_json(const struct stasis_app_recording *recording)
Construct a JSON model of a recording.
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
enum ast_record_if_exists stasis_app_recording_if_exists_parse(const char *str)
Parse a string into the if_exists enum.
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
struct stasis_app_recording_options * stasis_app_recording_options_create(const char *name, const char *format)
Allocate a recording options object.
struct ast_format * ast_get_format_for_file_ext(const char *file_ext)
Get the ast_format associated with the given file extension.
Definition: file.c:2006
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:555
static struct stasis_app_control * find_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
Abstract JSON element (object, array, string, int, ...).
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
struct stasis_app_recording * stasis_app_control_record(struct stasis_app_control *control, struct stasis_app_recording_options *options)
Record media from a channel.
void ast_ari_channels_redirect ( struct ast_variable headers,
struct ast_ari_channels_redirect_args args,
struct ast_ari_response response 
)

Redirect the channel to a different location.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 276 of file resource_channels.c.

References ast_ari_response_error(), ast_ari_response_no_content(), ast_channel_snapshot_get_latest(), ast_strdupa, ast_ari_channels_redirect_args::channel_id, channel_state_invalid(), ast_ari_channels_redirect_args::endpoint, find_control(), RAII_VAR, and stasis_app_control_redirect().

Referenced by ast_ari_channels_redirect_cb().

279 {
280  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
281  RAII_VAR(struct ast_channel_snapshot *, chan_snapshot, NULL, ao2_cleanup);
282  char *tech;
283  char *resource;
284  int tech_len;
285 
286  control = find_control(response, args->channel_id);
287  if (!control) {
288  return;
289  }
290 
291  if (channel_state_invalid(control, response)) {
292  return;
293  }
294 
295  if (ast_strlen_zero(args->endpoint)) {
296  ast_ari_response_error(response, 400, "Not Found",
297  "Required parameter 'endpoint' not provided.");
298  return;
299  }
300 
301  tech = ast_strdupa(args->endpoint);
302  if (!(resource = strchr(tech, '/')) || !(tech_len = resource - tech)) {
303  ast_ari_response_error(response, 422, "Unprocessable Entity",
304  "Endpoint parameter '%s' does not contain tech/resource", args->endpoint);
305  return;
306  }
307 
308  *resource++ = '\0';
309  if (ast_strlen_zero(resource)) {
310  ast_ari_response_error(response, 422, "Unprocessable Entity",
311  "No resource provided in endpoint parameter '%s'", args->endpoint);
312  return;
313  }
314 
315  chan_snapshot = ast_channel_snapshot_get_latest(args->channel_id);
316  if (!chan_snapshot) {
317  ast_ari_response_error(response, 500, "Internal Server Error",
318  "Unable to find channel snapshot for '%s'", args->channel_id);
319  return;
320  }
321 
322  if (strncasecmp(chan_snapshot->base->type, tech, tech_len)) {
323  ast_ari_response_error(response, 422, "Unprocessable Entity",
324  "Endpoint technology '%s' does not match channel technology '%s'",
325  tech, chan_snapshot->base->type);
326  return;
327  }
328 
329  if (stasis_app_control_redirect(control, resource)) {
330  ast_ari_response_error(response, 500, "Internal Server Error",
331  "Failed to redirect channel");
332  return;
333  }
334 
335  ast_ari_response_no_content(response);
336 }
Structure representing a snapshot of channel state.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
int stasis_app_control_redirect(struct stasis_app_control *control, const char *endpoint)
Redirect a channel in res_stasis to a particular endpoint.
Definition: control.c:522
static int channel_state_invalid(struct stasis_app_control *control, struct ast_ari_response *response)
Ensure channel is in a state that allows operation to be performed.
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
static struct stasis_app_control * find_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object...
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_ari_channels_ring ( struct ast_variable headers,
struct ast_ari_channels_ring_args args,
struct ast_ari_response response 
)

Indicate ringing to a channel.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 363 of file resource_channels.c.

References ast_ari_response_no_content(), ast_ari_channels_ring_args::channel_id, channel_state_invalid(), find_control(), RAII_VAR, and stasis_app_control_ring().

Referenced by ast_ari_channels_ring_cb().

366 {
367  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
368 
369  control = find_control(response, args->channel_id);
370  if (control == NULL) {
371  return;
372  }
373 
374  if (channel_state_invalid(control, response)) {
375  return;
376  }
377 
378  stasis_app_control_ring(control);
379 
380  ast_ari_response_no_content(response);
381 }
int stasis_app_control_ring(struct stasis_app_control *control)
Indicate ringing to the channel associated with this control.
Definition: control.c:614
static int channel_state_invalid(struct stasis_app_control *control, struct ast_ari_response *response)
Ensure channel is in a state that allows operation to be performed.
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
static struct stasis_app_control * find_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_ari_channels_ring_stop ( struct ast_variable headers,
struct ast_ari_channels_ring_stop_args args,
struct ast_ari_response response 
)

Stop ringing indication on a channel if locally generated.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 383 of file resource_channels.c.

References ast_ari_response_no_content(), ast_ari_channels_ring_stop_args::channel_id, channel_state_invalid(), find_control(), RAII_VAR, and stasis_app_control_ring_stop().

Referenced by ast_ari_channels_ring_stop_cb().

386 {
387  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
388 
389  control = find_control(response, args->channel_id);
390  if (control == NULL) {
391  return;
392  }
393 
394  if (channel_state_invalid(control, response)) {
395  return;
396  }
397 
399 
400  ast_ari_response_no_content(response);
401 }
int stasis_app_control_ring_stop(struct stasis_app_control *control)
Stop locally generated ringing on the channel associated with this control.
Definition: control.c:629
static int channel_state_invalid(struct stasis_app_control *control, struct ast_ari_response *response)
Ensure channel is in a state that allows operation to be performed.
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
static struct stasis_app_control * find_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_ari_channels_rtpstatistics ( struct ast_variable headers,
struct ast_ari_channels_rtpstatistics_args args,
struct ast_ari_response response 
)

RTP stats on a channel.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 2028 of file resource_channels.c.

References ast_ari_response_error(), ast_ari_response_ok(), ast_channel_cleanup, ast_channel_get_by_name(), ast_rtp_instance_get_glue(), ast_rtp_instance_get_stats_all_json(), ast_ari_channels_rtpstatistics_args::channel_id, ast_rtp_glue::get_rtp_info, and RAII_VAR.

Referenced by ast_ari_channels_rtpstatistics_cb().

2031 {
2032  RAII_VAR(struct ast_channel *, chan, NULL, ast_channel_cleanup);
2033  RAII_VAR(struct ast_rtp_instance *, rtp, NULL, ao2_cleanup);
2034  struct ast_json *j_res;
2035  const struct ast_channel_tech *tech;
2036  struct ast_rtp_glue *glue;
2037 
2038  chan = ast_channel_get_by_name(args->channel_id);
2039  if (!chan) {
2040  ast_ari_response_error(response, 404, "Not Found",
2041  "Channel not found");
2042  return;
2043  }
2044 
2045  ast_channel_lock(chan);
2046  tech = ast_channel_tech(chan);
2047  if (!tech) {
2048  ast_channel_unlock(chan);
2049  ast_ari_response_error(response, 404, "Not Found",
2050  "Channel's tech not found");
2051  return;
2052  }
2053 
2054  glue = ast_rtp_instance_get_glue(tech->type);
2055  if (!glue) {
2056  ast_channel_unlock(chan);
2057  ast_ari_response_error(response, 403, "Forbidden",
2058  "Unsupported channel type");
2059  return;
2060  }
2061 
2062  glue->get_rtp_info(chan, &rtp);
2063  if (!rtp) {
2064  ast_channel_unlock(chan);
2065  ast_ari_response_error(response, 404, "Not Found",
2066  "RTP info not found");
2067  return;
2068  }
2069 
2071  if (!j_res) {
2072  ast_channel_unlock(chan);
2073  ast_ari_response_error(response, 404, "Not Found",
2074  "Statistics not found");
2075  return;
2076  }
2077 
2078  ast_channel_unlock(chan);
2079  ast_ari_response_ok(response, j_res);
2080 
2081  return;
2082 }
Main Channel structure associated with a channel.
struct ast_json * ast_rtp_instance_get_stats_all_json(struct ast_rtp_instance *instance)
Retrieve statistics about an RTP instance in json format.
Definition: rtp_engine.c:4213
enum ast_rtp_glue_result(* get_rtp_info)(struct ast_channel *chan, struct ast_rtp_instance **instance)
Callback for retrieving the RTP instance carrying audio.
Definition: rtp_engine.h:782
void ast_ari_response_ok(struct ast_ari_response *response, struct ast_json *message)
Fill in an OK (200) ast_ari_response.
Definition: res_ari.c:276
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969
Structure to describe a channel "technology", ie a channel driver See for examples: ...
Definition: channel.h:628
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
Abstract JSON element (object, array, string, int, ...).
struct ast_rtp_glue * ast_rtp_instance_get_glue(const char *type)
Get the RTP glue that binds a channel to the RTP engine.
Definition: rtp_engine.c:2330
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_ari_channels_send_dtmf ( struct ast_variable headers,
struct ast_ari_channels_send_dtmf_args args,
struct ast_ari_response response 
)

Send provided DTMF to a given channel.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 487 of file resource_channels.c.

References ast_ari_channels_send_dtmf_args::after, ast_ari_response_error(), ast_ari_response_no_content(), ast_ari_channels_send_dtmf_args::before, ast_ari_channels_send_dtmf_args::between, ast_ari_channels_send_dtmf_args::channel_id, channel_state_invalid(), ast_ari_channels_send_dtmf_args::dtmf, ast_ari_channels_send_dtmf_args::duration, find_control(), RAII_VAR, and stasis_app_control_dtmf().

Referenced by ast_ari_channels_send_dtmf_cb().

490 {
491  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
492 
493  control = find_control(response, args->channel_id);
494  if (control == NULL) {
495  return;
496  }
497 
498  if (channel_state_invalid(control, response)) {
499  return;
500  }
501 
502  if (ast_strlen_zero(args->dtmf)) {
504  response, 400, "Bad Request",
505  "DTMF is required");
506  return;
507  }
508 
509  stasis_app_control_dtmf(control, args->dtmf, args->before, args->between, args->duration, args->after);
510 
511  ast_ari_response_no_content(response);
512 }
int stasis_app_control_dtmf(struct stasis_app_control *control, const char *dtmf, int before, int between, unsigned int duration, int after)
Send DTMF to the channel associated with this control.
Definition: control.c:587
static int channel_state_invalid(struct stasis_app_control *control, struct ast_ari_response *response)
Ensure channel is in a state that allows operation to be performed.
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
static struct stasis_app_control * find_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_ari_channels_set_channel_var ( struct ast_variable headers,
struct ast_ari_channels_set_channel_var_args args,
struct ast_ari_response response 
)

Set the value of a channel variable or function.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 1541 of file resource_channels.c.

References ast_ari_response_error(), ast_ari_response_no_content(), ast_ari_channels_set_channel_var_args::channel_id, find_control(), RAII_VAR, stasis_app_control_set_channel_var(), ast_ari_channels_set_channel_var_args::value, and ast_ari_channels_set_channel_var_args::variable.

Referenced by ast_ari_channels_set_channel_var_cb().

1544 {
1545  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
1546 
1547  ast_assert(response != NULL);
1548 
1549  if (ast_strlen_zero(args->variable)) {
1551  response, 400, "Bad Request",
1552  "Variable name is required");
1553  return;
1554  }
1555 
1556  control = find_control(response, args->channel_id);
1557  if (control == NULL) {
1558  /* response filled in by find_control */
1559  return;
1560  }
1561 
1562  if (stasis_app_control_set_channel_var(control, args->variable, args->value)) {
1564  response, 400, "Bad Request",
1565  "Failed to execute function");
1566  return;
1567  }
1568 
1569  ast_ari_response_no_content(response);
1570 }
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
static struct stasis_app_control * find_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
int stasis_app_control_set_channel_var(struct stasis_app_control *control, const char *variable, const char *value)
Set a variable on the channel associated with this control to value.
Definition: control.c:733
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_ari_channels_snoop_channel ( struct ast_variable headers,
struct ast_ari_channels_snoop_channel_args args,
struct ast_ari_response response 
)

Start snooping.

Snoop (spy/whisper) on a specific channel.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 1651 of file resource_channels.c.

References ast_ari_channels_snoop_channel_args::app, ast_ari_channels_snoop_channel_args::app_args, ast_ari_channels_snoop_channel_args::channel_id, ast_ari_channels_snoop_channel_args::snoop_id, ast_ari_channels_snoop_channel_args::spy, and ast_ari_channels_snoop_channel_args::whisper.

Referenced by ast_ari_channels_snoop_channel_cb().

1654 {
1655  ari_channels_handle_snoop_channel(
1656  args->channel_id,
1657  args->spy,
1658  args->whisper,
1659  args->app,
1660  args->app_args,
1661  args->snoop_id,
1662  response);
1663 }
void ast_ari_channels_snoop_channel_with_id ( struct ast_variable headers,
struct ast_ari_channels_snoop_channel_with_id_args args,
struct ast_ari_response response 
)

Start snooping.

Snoop (spy/whisper) on a specific channel.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 1665 of file resource_channels.c.

References ast_ari_channels_snoop_channel_with_id_args::app, ast_ari_channels_snoop_channel_with_id_args::app_args, ast_ari_channels_snoop_channel_with_id_args::channel_id, ast_ari_channels_snoop_channel_with_id_args::snoop_id, ast_ari_channels_snoop_channel_with_id_args::spy, and ast_ari_channels_snoop_channel_with_id_args::whisper.

Referenced by ast_ari_channels_snoop_channel_with_id_cb().

1668 {
1669  ari_channels_handle_snoop_channel(
1670  args->channel_id,
1671  args->spy,
1672  args->whisper,
1673  args->app,
1674  args->app_args,
1675  args->snoop_id,
1676  response);
1677 }
void ast_ari_channels_start_moh ( struct ast_variable headers,
struct ast_ari_channels_start_moh_args args,
struct ast_ari_response response 
)

Play music on hold to a channel.

Using media operations such as /play on a channel playing MOH in this manner will suspend MOH without resuming automatically. If continuing music on hold is desired, the stasis application must reinitiate music on hold.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 556 of file resource_channels.c.

References ast_ari_response_no_content(), ast_ari_channels_start_moh_args::channel_id, channel_state_invalid(), find_control(), ast_ari_channels_start_moh_args::moh_class, RAII_VAR, and stasis_app_control_moh_start().

Referenced by ast_ari_channels_start_moh_cb().

559 {
560  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
561 
562  control = find_control(response, args->channel_id);
563  if (control == NULL) {
564  /* Response filled in by find_control */
565  return;
566  }
567 
568  if (channel_state_invalid(control, response)) {
569  return;
570  }
571 
572  stasis_app_control_moh_start(control, args->moh_class);
573  ast_ari_response_no_content(response);
574 }
static int channel_state_invalid(struct stasis_app_control *control, struct ast_ari_response *response)
Ensure channel is in a state that allows operation to be performed.
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
static struct stasis_app_control * find_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
void stasis_app_control_moh_start(struct stasis_app_control *control, const char *moh_class)
Play music on hold to a channel (does not affect hold status)
Definition: control.c:802
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_ari_channels_start_silence ( struct ast_variable headers,
struct ast_ari_channels_start_silence_args args,
struct ast_ari_response response 
)

Play silence to a channel.

Using media operations such as /play on a channel playing silence in this manner will suspend silence without resuming automatically.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 596 of file resource_channels.c.

References ast_ari_response_no_content(), ast_ari_channels_start_silence_args::channel_id, channel_state_invalid(), find_control(), RAII_VAR, and stasis_app_control_silence_start().

Referenced by ast_ari_channels_start_silence_cb().

599 {
600  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
601 
602  control = find_control(response, args->channel_id);
603  if (control == NULL) {
604  /* Response filled in by find_control */
605  return;
606  }
607 
608  if (channel_state_invalid(control, response)) {
609  return;
610  }
611 
613  ast_ari_response_no_content(response);
614 }
static int channel_state_invalid(struct stasis_app_control *control, struct ast_ari_response *response)
Ensure channel is in a state that allows operation to be performed.
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
static struct stasis_app_control * find_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
void stasis_app_control_silence_start(struct stasis_app_control *control)
Start playing silence to a channel.
Definition: control.c:854
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_ari_channels_stop_moh ( struct ast_variable headers,
struct ast_ari_channels_stop_moh_args args,
struct ast_ari_response response 
)

Stop playing music on hold to a channel.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 576 of file resource_channels.c.

References ast_ari_response_no_content(), ast_ari_channels_stop_moh_args::channel_id, channel_state_invalid(), find_control(), RAII_VAR, and stasis_app_control_moh_stop().

Referenced by ast_ari_channels_stop_moh_cb().

579 {
580  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
581 
582  control = find_control(response, args->channel_id);
583  if (control == NULL) {
584  /* Response filled in by find_control */
585  return;
586  }
587 
588  if (channel_state_invalid(control, response)) {
589  return;
590  }
591 
593  ast_ari_response_no_content(response);
594 }
static int channel_state_invalid(struct stasis_app_control *control, struct ast_ari_response *response)
Ensure channel is in a state that allows operation to be performed.
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
static struct stasis_app_control * find_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
void stasis_app_control_moh_stop(struct stasis_app_control *control)
Stop playing music on hold to a channel (does not affect hold status)
Definition: control.c:820
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_ari_channels_stop_silence ( struct ast_variable headers,
struct ast_ari_channels_stop_silence_args args,
struct ast_ari_response response 
)

Stop playing silence to a channel.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 616 of file resource_channels.c.

References ast_ari_response_no_content(), ast_ari_channels_stop_silence_args::channel_id, channel_state_invalid(), find_control(), RAII_VAR, and stasis_app_control_silence_stop().

Referenced by ast_ari_channels_stop_silence_cb().

619 {
620  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
621 
622  control = find_control(response, args->channel_id);
623  if (control == NULL) {
624  /* Response filled in by find_control */
625  return;
626  }
627 
628  if (channel_state_invalid(control, response)) {
629  return;
630  }
631 
633  ast_ari_response_no_content(response);
634 }
void stasis_app_control_silence_stop(struct stasis_app_control *control)
Stop playing silence to a channel.
Definition: control.c:877
static int channel_state_invalid(struct stasis_app_control *control, struct ast_ari_response *response)
Ensure channel is in a state that allows operation to be performed.
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
static struct stasis_app_control * find_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_ari_channels_unhold ( struct ast_variable headers,
struct ast_ari_channels_unhold_args args,
struct ast_ari_response response 
)

Remove a channel from hold.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 535 of file resource_channels.c.

References ast_ari_response_no_content(), ast_ari_channels_unhold_args::channel_id, channel_state_invalid(), find_control(), RAII_VAR, and stasis_app_control_unhold().

Referenced by ast_ari_channels_unhold_cb().

538 {
539  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
540 
541  control = find_control(response, args->channel_id);
542  if (control == NULL) {
543  /* Response filled in by find_control */
544  return;
545  }
546 
547  if (channel_state_invalid(control, response)) {
548  return;
549  }
550 
551  stasis_app_control_unhold(control);
552 
553  ast_ari_response_no_content(response);
554 }
static int channel_state_invalid(struct stasis_app_control *control, struct ast_ari_response *response)
Ensure channel is in a state that allows operation to be performed.
void stasis_app_control_unhold(struct stasis_app_control *control)
Remove the channel associated with the control from hold.
Definition: control.c:783
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
static struct stasis_app_control * find_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
void ast_ari_channels_unmute ( struct ast_variable headers,
struct ast_ari_channels_unmute_args args,
struct ast_ari_response response 
)

Unmute a channel.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 445 of file resource_channels.c.

References ast_ari_response_error(), ast_ari_response_no_content(), AST_FRAME_VOICE, ast_ari_channels_unmute_args::channel_id, channel_state_invalid(), ast_ari_channels_unmute_args::direction, find_control(), RAII_VAR, and stasis_app_control_unmute().

Referenced by ast_ari_channels_unmute_cb().

448 {
449  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
450  unsigned int direction = 0;
451  enum ast_frame_type frametype = AST_FRAME_VOICE;
452 
453  control = find_control(response, args->channel_id);
454  if (control == NULL) {
455  return;
456  }
457 
458  if (channel_state_invalid(control, response)) {
459  return;
460  }
461 
462  if (ast_strlen_zero(args->direction)) {
464  response, 400, "Bad Request",
465  "Direction is required");
466  return;
467  }
468 
469  if (!strcmp(args->direction, "in")) {
470  direction = AST_MUTE_DIRECTION_READ;
471  } else if (!strcmp(args->direction, "out")) {
472  direction = AST_MUTE_DIRECTION_WRITE;
473  } else if (!strcmp(args->direction, "both")) {
474  direction = AST_MUTE_DIRECTION_READ | AST_MUTE_DIRECTION_WRITE;
475  } else {
477  response, 400, "Bad Request",
478  "Invalid direction specified");
479  return;
480  }
481 
482  stasis_app_control_unmute(control, direction, frametype);
483 
484  ast_ari_response_no_content(response);
485 }
int stasis_app_control_unmute(struct stasis_app_control *control, unsigned int direction, enum ast_frame_type frametype)
Unmute the channel associated with this control.
Definition: control.c:681
ast_frame_type
Frame types.
static int channel_state_invalid(struct stasis_app_control *control, struct ast_ari_response *response)
Ensure channel is in a state that allows operation to be performed.
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
static struct stasis_app_control * find_control(struct ast_ari_response *response, const char *channel_id)
Finds the control object for a channel, filling the response with an error, if appropriate.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
static int channel_state_invalid ( struct stasis_app_control control,
struct ast_ari_response response 
)
static

Ensure channel is in a state that allows operation to be performed.

Since Asterisk 14, it has been possible for down channels, as well as unanswered outbound channels to enter Stasis. While some operations are fine to perform on such channels, operations that

  • Attempt to manipulate channel state
  • Attempt to play media
  • Attempt to control the channel's location in the dialplan

are invalid. This function can be used to determine if the channel is in an appropriate state.

Note
When this function returns an error, the HTTP response is taken care of.
Parameters
controlThe app control
responseResponse to fill in if there is an error
Return values
0Channel is in a valid state. Continue on!
non-zeroChannel is in an invalid state. Bail!

Definition at line 108 of file resource_channels.c.

References ao2_ref, ast_ari_response_error(), AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_RINGING, stasis_app_control_get_snapshot(), and ast_channel_snapshot::state.

Referenced by ast_ari_channels_answer(), ast_ari_channels_continue_in_dialplan(), ast_ari_channels_hold(), ast_ari_channels_mute(), ast_ari_channels_redirect(), ast_ari_channels_ring(), ast_ari_channels_ring_stop(), ast_ari_channels_send_dtmf(), ast_ari_channels_start_moh(), ast_ari_channels_start_silence(), ast_ari_channels_stop_moh(), ast_ari_channels_stop_silence(), ast_ari_channels_unhold(), and ast_ari_channels_unmute().

110 {
111  struct ast_channel_snapshot *snapshot;
112 
113  snapshot = stasis_app_control_get_snapshot(control);
114  if (!snapshot) {
115  ast_ari_response_error(response, 404, "Not Found", "Channel not found");
116  return -1;
117  }
118 
119  /* These channel states apply only to outbound channels:
120  * - Down: Channel has been created, and nothing else has been done
121  * - Reserved: For a PRI, an underlying B-channel is reserved,
122  * but the channel is not yet dialed
123  * - Ringing: The channel has been dialed.
124  *
125  * This does not affect inbound channels. Inbound channels, when they
126  * enter the dialplan, are in the "Ring" state. If they have already
127  * been answered, then they are in the "Up" state.
128  */
129  if (snapshot->state == AST_STATE_DOWN
130  || snapshot->state == AST_STATE_RESERVED
131  || snapshot->state == AST_STATE_RINGING) {
132  ast_ari_response_error(response, 412, "Precondition Failed",
133  "Channel in invalid state");
134  ao2_ref(snapshot, -1);
135 
136  return -1;
137  }
138 
139  ao2_ref(snapshot, -1);
140 
141  return 0;
142 }
Structure representing a snapshot of channel state.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
struct ast_channel_snapshot * stasis_app_control_get_snapshot(const struct stasis_app_control *control)
Returns the most recent snapshot for the associated channel.
Definition: control.c:882
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
enum ast_channel_state state
static struct stasis_app_control* find_control ( struct ast_ari_response response,
const char *  channel_id 
)
static

Finds the control object for a channel, filling the response with an error, if appropriate.

Parameters
[out]responseResponse to fill with an error if control is not found.
channel_idID of the channel to lookup.
Returns
Channel control object.
Return values
NULLif control object does not exist.

Definition at line 152 of file resource_channels.c.

References ao2_ref, ast_ari_response_error(), ast_channel_get_by_name(), RAII_VAR, and stasis_app_control_find_by_channel_id().

Referenced by ast_ari_channels_answer(), ast_ari_channels_continue_in_dialplan(), ast_ari_channels_dial(), ast_ari_channels_hold(), ast_ari_channels_move(), ast_ari_channels_mute(), ast_ari_channels_record(), ast_ari_channels_redirect(), ast_ari_channels_ring(), ast_ari_channels_ring_stop(), ast_ari_channels_send_dtmf(), ast_ari_channels_set_channel_var(), ast_ari_channels_start_moh(), ast_ari_channels_start_silence(), ast_ari_channels_stop_moh(), ast_ari_channels_stop_silence(), ast_ari_channels_unhold(), and ast_ari_channels_unmute().

155 {
156  RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
157 
158  ast_assert(response != NULL);
159 
160  control = stasis_app_control_find_by_channel_id(channel_id);
161  if (control == NULL) {
162  /* Distinguish between 404 and 409 errors */
163  RAII_VAR(struct ast_channel *, chan, NULL, ao2_cleanup);
164  chan = ast_channel_get_by_name(channel_id);
165  if (chan == NULL) {
166  ast_ari_response_error(response, 404, "Not Found",
167  "Channel not found");
168  return NULL;
169  }
170 
171  ast_ari_response_error(response, 409, "Conflict",
172  "Channel not in Stasis application");
173  return NULL;
174  }
175 
176  ao2_ref(control, +1);
177  return control;
178 }
Main Channel structure associated with a channel.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
struct stasis_app_control * stasis_app_control_find_by_channel_id(const char *channel_id)
Returns the handler for the channel with the given id.
Definition: res_stasis.c:349
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
static char* restore_dialstring ( struct ast_channel chan)
static

Retrieve the dialstring from the channel datastore.

Precondition
chan is locked
Parameters
chanChannel that was previously created in ARI
Return values
NULLFailed to find datastore
non-NULLThe dialstring

Definition at line 1766 of file resource_channels.c.

References ast_channel_datastore_find(), and ast_datastore::data.

Referenced by ast_ari_channels_dial().

1767 {
1768  struct ast_datastore *datastore;
1769 
1770  datastore = ast_channel_datastore_find(chan, &dialstring_info, NULL);
1771  if (!datastore) {
1772  return NULL;
1773  }
1774 
1775  return datastore->data;
1776 }
Structure for a data store object.
Definition: datastore.h:64
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2399
void * data
Definition: datastore.h:66
static int save_dialstring ( struct ast_channel chan,
const char *  dialstring 
)
static

Save dialstring onto a channel datastore.

This will later be retrieved when it comes time to actually dial the channel

Parameters
chanThe channel on which to save the dialstring
dialstringThe dialstring to save
Return values
0on success.
-1on error.

Definition at line 1732 of file resource_channels.c.

References ast_channel_datastore_add(), ast_datastore_free(), ast_strdup, and ast_datastore::data.

Referenced by ast_ari_channels_create().

1733 {
1734  struct ast_datastore *datastore;
1735 
1736  datastore = ast_datastore_alloc(&dialstring_info, NULL);
1737  if (!datastore) {
1738  return -1;
1739  }
1740 
1741  datastore->data = ast_strdup(dialstring);
1742  if (!datastore->data) {
1743  ast_datastore_free(datastore);
1744  return -1;
1745  }
1746 
1747  ast_channel_lock(chan);
1748  if (ast_channel_datastore_add(chan, datastore)) {
1749  ast_channel_unlock(chan);
1750  ast_datastore_free(datastore);
1751  return -1;
1752  }
1753  ast_channel_unlock(chan);
1754 
1755  return 0;
1756 }
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
Structure for a data store object.
Definition: datastore.h:64
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68
void * data
Definition: datastore.h:66
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385

Variable Documentation

struct ast_datastore_info dialstring_info
Initial value:
= {
.type = "ARI Dialstring",
.destroy = ast_free_ptr,
}
void ast_free_ptr(void *ptr)
free() wrapper
Definition: main/astmm.c:1739

Definition at line 1717 of file resource_channels.c.