Asterisk - The Open Source Telephony Project GIT-master-7e7a603
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"
Include dependency graph for resource_channels.c:

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. More...
 
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. More...
 
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

◆ ari_channel_thread()

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.

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}
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
int pbx_exec(struct ast_channel *c, struct ast_app *app, const char *data)
Execute an application.
Definition: pbx_app.c:471
struct ast_app * pbx_findapp(const char *app)
Look up an application.
Definition: ael_main.c:165
#define NULL
Definition: resample.c:96
static void chan_data_destroy(struct ari_channel_thread_data *chan_data)
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
struct ast_str * stasis_stuff
struct ast_channel * chan
ast_app: A registered application
Definition: pbx_app.c:45

References ast_log, ast_str_buffer(), ari_channel_thread_data::chan, chan_data_destroy(), LOG_ERROR, NULL, pbx_exec(), pbx_findapp(), and ari_channel_thread_data::stasis_stuff.

Referenced by ast_ari_channels_create().

◆ ari_channels_handle_originate_with_id()

static struct ast_channel * ari_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

Definition at line 1063 of file resource_channels.c.

1078{
1079 char *dialtech;
1080 char *dialdevice = NULL;
1081 struct ast_dial *dial;
1082 char *caller_id = NULL;
1083 char *cid_num = NULL;
1084 char *cid_name = NULL;
1085 char *stuff;
1086 struct ast_channel *other = NULL;
1087 struct ast_channel *chan = NULL;
1089 struct ast_assigned_ids assignedids = {
1090 .uniqueid = args_channel_id,
1091 .uniqueid2 = args_other_channel_id,
1092 };
1093 struct ari_origination *origination;
1094 pthread_t thread;
1095 struct ast_format_cap *format_cap = NULL;
1096
1097 if ((assignedids.uniqueid && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid))
1098 || (assignedids.uniqueid2 && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid2))) {
1099 ast_ari_response_error(response, 400, "Bad Request",
1100 "Uniqueid length exceeds maximum of %d", AST_MAX_PUBLIC_UNIQUEID);
1101 return NULL;
1102 }
1103
1104 if (ast_strlen_zero(args_endpoint)) {
1105 ast_ari_response_error(response, 400, "Bad Request",
1106 "Endpoint must be specified");
1107 return NULL;
1108 }
1109
1110 if (!ast_strlen_zero(args_originator) && !ast_strlen_zero(args_formats)) {
1111 ast_ari_response_error(response, 400, "Bad Request",
1112 "Originator and formats can't both be specified");
1113 return NULL;
1114 }
1115
1116 dialtech = ast_strdupa(args_endpoint);
1117 if ((stuff = strchr(dialtech, '/'))) {
1118 *stuff++ = '\0';
1119 dialdevice = stuff;
1120 }
1121
1122 if (ast_strlen_zero(dialtech) || ast_strlen_zero(dialdevice)) {
1123 ast_ari_response_error(response, 400, "Bad Request",
1124 "Invalid endpoint specified");
1125 return NULL;
1126 }
1127
1128 if (!ast_strlen_zero(args_app)) {
1129 RAII_VAR(struct ast_str *, appdata, ast_str_create(64), ast_free);
1130
1131 if (!appdata) {
1133 return NULL;
1134 }
1135
1136 ast_str_set(&appdata, 0, "%s", args_app);
1137 if (!ast_strlen_zero(args_app_args)) {
1138 ast_str_append(&appdata, 0, ",%s", args_app_args);
1139 }
1140
1141 origination = ast_calloc(1, sizeof(*origination) + ast_str_size(appdata) + 1);
1142 if (!origination) {
1144 return NULL;
1145 }
1146
1147 strcpy(origination->appdata, ast_str_buffer(appdata));
1148 } else if (!ast_strlen_zero(args_extension)) {
1149 origination = ast_calloc(1, sizeof(*origination) + 1);
1150 if (!origination) {
1152 return NULL;
1153 }
1154
1155 ast_copy_string(origination->context, S_OR(args_context, "default"), sizeof(origination->context));
1156 ast_copy_string(origination->exten, args_extension, sizeof(origination->exten));
1157
1158 if (!ast_strlen_zero(args_label)) {
1159 /* A label was provided in the request, use that */
1160 int ipri = 1;
1161 if (sscanf(args_label, "%30d", &ipri) != 1) {
1162 ipri = ast_findlabel_extension(chan, origination->context, origination->exten, args_label, args_caller_id);
1163
1164 if (ipri == -1) {
1165 ast_log(AST_LOG_ERROR, "Requested label: %s can not be found in context: %s\n", args_label, args_context);
1166 ast_ari_response_error(response, 404, "Not Found", "Requested label can not be found");
1167 return NULL;
1168 }
1169 } else {
1170 ast_debug(3, "Numeric value provided for label, jumping to that priority\n");
1171 }
1172
1173 if (ipri == 0) {
1174 ast_log(AST_LOG_ERROR, "Invalid priority label '%s' specified for extension %s in context: %s\n",
1175 args_label, args_extension, args_context);
1176 ast_ari_response_error(response, 400, "Bad Request", "Requested priority is illegal");
1177 return NULL;
1178 }
1179
1180 /* Our priority was provided by a label */
1181 origination->priority = ipri;
1182 } else {
1183 /* No label provided, use provided priority */
1184 origination->priority = args_priority ? args_priority : 1;
1185 }
1186
1187 origination->appdata[0] = '\0';
1188 } else {
1189 ast_ari_response_error(response, 400, "Bad Request",
1190 "Application or extension must be specified");
1191 return NULL;
1192 }
1193
1194 dial = ast_dial_create();
1195 if (!dial) {
1197 ast_free(origination);
1198 return NULL;
1199 }
1200 ast_dial_set_user_data(dial, origination);
1201
1202 if (ast_dial_append(dial, dialtech, dialdevice, &assignedids)) {
1204 ast_dial_destroy(dial);
1205 ast_free(origination);
1206 return NULL;
1207 }
1208
1209 if (args_timeout > 0) {
1210 ast_dial_set_global_timeout(dial, args_timeout * 1000);
1211 } else if (args_timeout == -1) {
1213 } else {
1214 ast_dial_set_global_timeout(dial, 30000);
1215 }
1216
1217 if (!ast_strlen_zero(args_caller_id)) {
1218 caller_id = ast_strdupa(args_caller_id);
1219 ast_callerid_parse(caller_id, &cid_name, &cid_num);
1220
1221 if (ast_is_shrinkable_phonenumber(cid_num)) {
1222 ast_shrink_phone_number(cid_num);
1223 }
1224 }
1225
1226 if (!ast_strlen_zero(args_originator)) {
1227 other = ast_channel_get_by_name(args_originator);
1228 if (!other) {
1230 response, 400, "Bad Request",
1231 "Provided originator channel was not found");
1232 ast_dial_destroy(dial);
1233 ast_free(origination);
1234 return NULL;
1235 }
1236 }
1237
1238 if (!ast_strlen_zero(args_formats)) {
1239 char *format_name;
1240 char *formats_copy = ast_strdupa(args_formats);
1241
1244 ast_dial_destroy(dial);
1245 ast_free(origination);
1246 ast_channel_cleanup(other);
1247 return NULL;
1248 }
1249
1250 while ((format_name = ast_strip(strsep(&formats_copy, ",")))) {
1251 struct ast_format *fmt = ast_format_cache_get(format_name);
1252
1253 if (!fmt || ast_format_cap_append(format_cap, fmt, 0)) {
1254 if (!fmt) {
1256 response, 400, "Bad Request",
1257 "Provided format (%s) was not found", format_name);
1258 } else {
1260 }
1261 ast_dial_destroy(dial);
1262 ast_free(origination);
1263 ast_channel_cleanup(other);
1264 ao2_ref(format_cap, -1);
1265 ao2_cleanup(fmt);
1266 return NULL;
1267 }
1268 ao2_ref(fmt, -1);
1269 }
1270 }
1271
1272 if (ast_dial_prerun(dial, other, format_cap)) {
1274 ast_ari_response_error(response, 409, "Conflict",
1275 "Channel with given unique ID already exists");
1276 } else {
1278 }
1279 ast_dial_destroy(dial);
1280 ast_free(origination);
1281 ast_channel_cleanup(other);
1282 return NULL;
1283 }
1284
1285 ast_channel_cleanup(other);
1286 ao2_cleanup(format_cap);
1287
1288 chan = ast_dial_get_channel(dial, 0);
1289 if (!chan) {
1291 ast_dial_destroy(dial);
1292 ast_free(origination);
1293 return NULL;
1294 }
1295
1296 if (!ast_strlen_zero(cid_num) || !ast_strlen_zero(cid_name)) {
1298
1299 /*
1300 * It seems strange to set the CallerID on an outgoing call leg
1301 * to whom we are calling, but this function's callers are doing
1302 * various Originate methods. This call leg goes to the local
1303 * user. Once the called party answers, the dialplan needs to
1304 * be able to access the CallerID from the CALLERID function as
1305 * if the called party had placed this call.
1306 */
1307 ast_set_callerid(chan, cid_num, cid_name, cid_num);
1308
1310 if (!ast_strlen_zero(cid_num)) {
1311 connected.id.number.valid = 1;
1312 connected.id.number.str = (char *) cid_num;
1314 }
1315 if (!ast_strlen_zero(cid_name)) {
1316 connected.id.name.valid = 1;
1317 connected.id.name.str = (char *) cid_name;
1319 }
1321 }
1322
1323 ast_channel_lock(chan);
1324 if (variables) {
1325 ast_set_variables(chan, variables);
1326 }
1328
1329 if (!ast_strlen_zero(args_app)) {
1330 struct ast_channel *local_peer;
1331
1332 stasis_app_subscribe_channel(args_app, chan);
1333
1334 /* Subscribe to the Local channel peer also. */
1335 local_peer = ast_local_get_peer(chan);
1336 if (local_peer) {
1337 stasis_app_subscribe_channel(args_app, local_peer);
1338 ast_channel_unref(local_peer);
1339 }
1340 }
1341
1343 ast_channel_unlock(chan);
1344
1345 /* Before starting the async dial bump the ref in case the dial quickly goes away and takes
1346 * the reference with it
1347 */
1348 ast_channel_ref(chan);
1349
1352 ast_dial_destroy(dial);
1353 ast_free(origination);
1354 } else {
1356 }
1357
1358 return chan;
1359}
pthread_t thread
Definition: app_sla.c:329
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_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_alloc_failed(struct ast_ari_response *response)
Fill in response with a 500 message for allocation failures.
Definition: res_ari.c:298
#define ast_free(a)
Definition: astmm.h:180
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
int ast_callerid_parse(char *instr, char **name, char **location)
Destructively parse inbuf into name and location (or number)
Definition: callerid.c:1162
void ast_shrink_phone_number(char *n)
Shrink a phone number in place to just digits (more accurately it just removes ()'s,...
Definition: callerid.c:1101
int ast_is_shrinkable_phonenumber(const char *exten)
Check if a string consists only of digits and + # ( ) - . (meaning it can be cleaned with ast_shrink_...
Definition: callerid.c:1157
#define AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED
Definition: callerid.h:437
#define AST_MAX_PUBLIC_UNIQUEID
Definition: channel.h:147
enum ast_channel_error ast_channel_errno(void)
Get error code for latest channel operation.
Definition: channel.c:10961
void ast_channel_set_connected_line(struct ast_channel *chan, const struct ast_party_connected_line *connected, const struct ast_set_party_connected_line *update)
Set the connected line information in the Asterisk channel.
Definition: channel.c:8308
#define ast_channel_lock(chan)
Definition: channel.h:2922
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
struct ast_flags * ast_channel_flags(struct ast_channel *chan)
@ AST_CHANNEL_ERROR_ID_EXISTS
Definition: channel.h:4797
#define ast_channel_ref(c)
Increase channel reference count.
Definition: channel.h:2947
struct ast_party_connected_line * ast_channel_connected(struct ast_channel *chan)
const char * ast_channel_uniqueid(const struct ast_channel *chan)
void ast_set_callerid(struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
Set caller ID number, name and ANI and generate AMI event.
Definition: channel.c:7334
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
@ AST_FLAG_ORIGINATED
Definition: channel.h:1039
void ast_party_connected_line_set_init(struct ast_party_connected_line *init, const struct ast_party_connected_line *guide)
Initialize the given connected line structure using the given guide for a set update operation.
Definition: channel.c:2045
#define ast_channel_cleanup(c)
Cleanup a channel reference.
Definition: channel.h:2969
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
#define ast_channel_unlock(chan)
Definition: channel.h:2923
struct ast_channel * ast_local_get_peer(struct ast_channel *ast)
Get the other local channel in the pair.
Definition: core_local.c:276
int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
Append a channel.
Definition: dial.c:280
struct ast_dial * ast_dial_create(void)
New dialing structure.
Definition: dial.c:223
void ast_dial_set_user_data(struct ast_dial *dial, void *user_data)
Set user data on a dial structure.
Definition: dial.c:1274
int ast_dial_prerun(struct ast_dial *dial, struct ast_channel *chan, struct ast_format_cap *cap)
Request all appended channels, but do not dial.
Definition: dial.c:431
void ast_dial_set_global_timeout(struct ast_dial *dial, int timeout)
Set the maximum time (globally) allowed for trying to ring phones.
Definition: dial.c:1284
struct ast_channel * ast_dial_get_channel(struct ast_dial *dial, int num)
Get the dialing channel, if prerun has been executed.
Definition: dial.c:1258
int ast_dial_destroy(struct ast_dial *dial)
Destroys a dialing structure.
Definition: dial.c:1091
char connected
Definition: eagi_proxy.c:82
#define ast_format_cache_get(name)
Retrieve a named format from the cache.
Definition: format_cache.h:278
@ AST_FORMAT_CAP_FLAG_DEFAULT
Definition: format_cap.h:38
#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
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,...
char * strsep(char **str, const char *delims)
#define AST_LOG_ERROR
#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
static void * ari_originate_dial(void *data)
Thread which dials and executes upon answer.
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_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.
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
#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
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:425
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition: strings.h:223
size_t ast_str_size(const struct ast_str *buf)
Returns the current maximum length (without reallocation) of the current buffer.
Definition: strings.h:742
Structure used for origination.
char appdata[0]
Application data to pass to Stasis application.
char exten[AST_MAX_EXTENSION]
Dialplan extension.
char context[AST_MAX_CONTEXT]
Dialplan context.
int priority
Dialplan priority.
Structure to pass both assignedid values to channel drivers.
Definition: channel.h:604
const char * uniqueid2
Definition: channel.h:606
const char * uniqueid
Definition: channel.h:605
Structure representing a snapshot of channel state.
Main Channel structure associated with a channel.
struct ast_channel_snapshot * snapshot
Main dialing structure. Contains global options, channels being dialed, and more!
Definition: dial.c:48
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
Definition of a media format.
Definition: format.c:43
Connected Line/Party information.
Definition: channel.h:456
Support for dynamic strings.
Definition: strings.h:623
#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_pthread_create_detached(a, b, c, d)
Definition: utils.h:588
#define ast_set_flag(p, flag)
Definition: utils.h:70

References ao2_cleanup, ao2_ref, ari_origination::appdata, ari_originate_dial(), ast_ari_response_alloc_failed(), ast_ari_response_error(), ast_ari_response_ok(), ast_callerid_parse(), ast_calloc, ast_channel_cleanup, ast_channel_connected(), ast_channel_errno(), AST_CHANNEL_ERROR_ID_EXISTS, ast_channel_flags(), ast_channel_get_by_name(), ast_channel_lock, ast_channel_ref, ast_channel_set_connected_line(), ast_channel_snapshot_get_latest(), ast_channel_snapshot_to_json(), ast_channel_uniqueid(), ast_channel_unlock, ast_channel_unref, ast_copy_string(), ast_debug, ast_dial_append(), ast_dial_create(), ast_dial_destroy(), ast_dial_get_channel(), ast_dial_prerun(), ast_dial_set_global_timeout(), ast_dial_set_user_data(), ast_findlabel_extension(), AST_FLAG_ORIGINATED, ast_format_cache_get, ast_format_cap_alloc, ast_format_cap_append, AST_FORMAT_CAP_FLAG_DEFAULT, ast_free, ast_is_shrinkable_phonenumber(), ast_local_get_peer(), ast_log, AST_LOG_ERROR, AST_MAX_PUBLIC_UNIQUEID, ast_party_connected_line_set_init(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, ast_pthread_create_detached, ast_set_callerid(), ast_set_flag, ast_set_variables(), ast_shrink_phone_number(), ast_str_append(), ast_str_buffer(), ast_str_create, ast_str_set(), ast_str_size(), ast_strdupa, ast_strip(), ast_strlen_zero(), connected, ari_origination::context, ari_origination::exten, NULL, ari_origination::priority, RAII_VAR, S_OR, ast_channel::snapshot, stasis_app_subscribe_channel(), strsep(), thread, ast_assigned_ids::uniqueid, and ast_assigned_ids::uniqueid2.

Referenced by ast_ari_channels_originate(), ast_ari_channels_originate_with_id(), external_media_audiosocket_tcp(), and external_media_rtp_udp().

◆ ari_channels_handle_play()

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

Definition at line 636 of file resource_channels.c.

645{
646 RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
647 RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
648 RAII_VAR(struct stasis_app_playback *, playback, NULL, ao2_cleanup);
649 RAII_VAR(char *, playback_url, NULL, ast_free);
650 struct ast_json *json;
651 const char *language;
652
653 ast_assert(response != NULL);
654
655 control = find_control(response, args_channel_id);
656 if (control == NULL) {
657 /* Response filled in by find_control */
658 return;
659 }
660
661 if (channel_state_invalid(control, response)) {
662 return;
663 }
664
665 snapshot = stasis_app_control_get_snapshot(control);
666 if (!snapshot) {
668 response, 404, "Not Found",
669 "Channel not found");
670 return;
671 }
672
673 if (args_skipms < 0) {
675 response, 400, "Bad Request",
676 "skipms cannot be negative");
677 return;
678 }
679
680 if (args_offsetms < 0) {
682 response, 400, "Bad Request",
683 "offsetms cannot be negative");
684 return;
685 }
686
687 language = S_OR(args_lang, snapshot->base->language);
688
689 playback = stasis_app_control_play_uri(control, args_media, args_media_count, language,
690 args_channel_id, STASIS_PLAYBACK_TARGET_CHANNEL, args_skipms, args_offsetms, args_playback_id);
691 if (!playback) {
693 response, 500, "Internal Server Error",
694 "Failed to queue media for playback");
695 return;
696 }
697
698 if (ast_asprintf(&playback_url, "/playbacks/%s",
699 stasis_app_playback_get_id(playback)) == -1) {
700 playback_url = NULL;
702 response, 500, "Internal Server Error",
703 "Out of memory");
704 return;
705 }
706
707 json = stasis_app_playback_to_json(playback);
708 if (!json) {
710 response, 500, "Internal Server Error",
711 "Out of memory");
712 return;
713 }
714
715 ast_ari_response_created(response, playback_url, json);
716}
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
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:267
static char language[MAX_LANGUAGE]
Definition: chan_iax2.c:324
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.
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 * stasis_app_control_get_snapshot(const struct stasis_app_control *control)
Returns the most recent snapshot for the associated channel.
Definition: control.c:880
@ STASIS_PLAYBACK_TARGET_CHANNEL
struct stasis_app_playback * stasis_app_control_play_uri(struct stasis_app_control *control, const char **media, size_t media_count, const char *language, const char *target_id, enum stasis_app_playback_target_type target_type, int skipms, long offsetms, const char *id)
Play a file to the control's channel.
struct ast_json * stasis_app_playback_to_json(const struct stasis_app_playback *playback)
Convert a playback to its JSON representation.
const char * stasis_app_playback_get_id(struct stasis_app_playback *playback)
Gets the unique id of a playback object.
Abstract JSON element (object, array, string, int, ...).
#define ast_assert(a)
Definition: utils.h:739

References ao2_cleanup, ast_ari_response_created(), ast_ari_response_error(), ast_asprintf, ast_assert, ast_free, channel_state_invalid(), find_control(), language, NULL, RAII_VAR, S_OR, stasis_app_control_get_snapshot(), stasis_app_control_play_uri(), stasis_app_playback_get_id(), stasis_app_playback_to_json(), and STASIS_PLAYBACK_TARGET_CHANNEL.

Referenced by ast_ari_channels_play(), and ast_ari_channels_play_with_id().

◆ ari_channels_handle_snoop_channel()

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

Definition at line 1572 of file resource_channels.c.

1580{
1581 enum stasis_app_snoop_direction spy, whisper;
1582 RAII_VAR(struct ast_channel *, chan, NULL, ast_channel_cleanup);
1583 RAII_VAR(struct ast_channel *, snoop, NULL, ast_channel_cleanup);
1584 RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
1585
1586 ast_assert(response != NULL);
1587
1588 if (ast_strlen_zero(args_spy) || !strcmp(args_spy, "none")) {
1590 } else if (!strcmp(args_spy, "both")) {
1592 } else if (!strcmp(args_spy, "out")) {
1594 } else if (!strcmp(args_spy, "in")) {
1596 } else {
1598 response, 400, "Bad Request",
1599 "Invalid direction specified for spy");
1600 return;
1601 }
1602
1603 if (ast_strlen_zero(args_whisper) || !strcmp(args_whisper, "none")) {
1605 } else if (!strcmp(args_whisper, "both")) {
1607 } else if (!strcmp(args_whisper, "out")) {
1609 } else if (!strcmp(args_whisper, "in")) {
1610 whisper = STASIS_SNOOP_DIRECTION_IN;
1611 } else {
1613 response, 400, "Bad Request",
1614 "Invalid direction specified for whisper");
1615 return;
1616 }
1617
1620 response, 400, "Bad Request",
1621 "Direction must be specified for at least spy or whisper");
1622 return;
1623 } else if (ast_strlen_zero(args_app)) {
1625 response, 400, "Bad Request",
1626 "Application name is required");
1627 return;
1628 }
1629
1630 chan = ast_channel_get_by_name(args_channel_id);
1631 if (chan == NULL) {
1633 response, 404, "Channel Not Found",
1634 "Provided channel was not found");
1635 return;
1636 }
1637
1638 snoop = stasis_app_control_snoop(chan, spy, whisper, args_app, args_app_args,
1639 args_snoop_id);
1640 if (snoop == NULL) {
1642 response, 500, "Internal error",
1643 "Snoop channel could not be created");
1644 return;
1645 }
1646
1649}
struct ast_channel * stasis_app_control_snoop(struct ast_channel *chan, enum stasis_app_snoop_direction spy, enum stasis_app_snoop_direction whisper, const char *app, const char *app_args, const char *snoop_id)
Create a snoop on the provided channel.
stasis_app_snoop_direction
Directions for audio stream flow.
@ STASIS_SNOOP_DIRECTION_IN
Audio stream in from the channel.
@ STASIS_SNOOP_DIRECTION_OUT
Audio stream out to the channel.
@ STASIS_SNOOP_DIRECTION_NONE
No direction.
@ STASIS_SNOOP_DIRECTION_BOTH
Audio stream to AND from the channel.

References ao2_cleanup, ast_ari_response_error(), ast_ari_response_ok(), ast_assert, ast_channel_cleanup, ast_channel_get_by_name(), ast_channel_snapshot_get_latest(), ast_channel_snapshot_to_json(), ast_channel_uniqueid(), ast_strlen_zero(), NULL, RAII_VAR, stasis_app_control_snoop(), STASIS_SNOOP_DIRECTION_BOTH, STASIS_SNOOP_DIRECTION_IN, STASIS_SNOOP_DIRECTION_NONE, and STASIS_SNOOP_DIRECTION_OUT.

Referenced by ast_ari_channels_snoop_channel(), and ast_ari_channels_snoop_channel_with_id().

◆ ari_originate_dial()

static void * ari_originate_dial ( void *  data)
static

Thread which dials and executes upon answer.

Definition at line 1013 of file resource_channels.c.

1014{
1015 struct ast_dial *dial = data;
1016 struct ari_origination *origination = ast_dial_get_user_data(dial);
1017 enum ast_dial_result res;
1018
1019 res = ast_dial_run(dial, NULL, 0);
1020 if (res != AST_DIAL_RESULT_ANSWERED) {
1021 goto end;
1022 }
1023
1024 if (!ast_strlen_zero(origination->appdata)) {
1025 struct ast_app *app = pbx_findapp("Stasis");
1026
1027 if (app) {
1028 ast_verb(4, "Launching Stasis(%s) on %s\n", origination->appdata,
1030 pbx_exec(ast_dial_answered(dial), app, origination->appdata);
1031 } else {
1032 ast_log(LOG_WARNING, "No such application 'Stasis'\n");
1033 }
1034 } else {
1035 struct ast_channel *answered = ast_dial_answered(dial);
1036
1037 if (!ast_strlen_zero(origination->context)) {
1038 ast_channel_context_set(answered, origination->context);
1039 }
1040
1041 if (!ast_strlen_zero(origination->exten)) {
1042 ast_channel_exten_set(answered, origination->exten);
1043 }
1044
1045 if (origination->priority > 0) {
1046 ast_channel_priority_set(answered, origination->priority);
1047 }
1048
1049 if (ast_pbx_run(answered)) {
1050 ast_log(LOG_ERROR, "Failed to start PBX on %s\n", ast_channel_name(answered));
1051 } else {
1052 /* PBX will have taken care of hanging up, so we steal the answered channel so dial doesn't do it */
1054 }
1055 }
1056
1057end:
1058 ast_dial_destroy(dial);
1059 ast_free(origination);
1060 return NULL;
1061}
static const char app[]
Definition: app_adsiprog.c:56
void ast_channel_exten_set(struct ast_channel *chan, const char *value)
const char * ast_channel_name(const struct ast_channel *chan)
void ast_channel_context_set(struct ast_channel *chan, const char *value)
void ast_channel_priority_set(struct ast_channel *chan, int value)
ast_dial_result
List of return codes for dial run API calls.
Definition: dial.h:54
@ AST_DIAL_RESULT_ANSWERED
Definition: dial.h:61
struct ast_channel * ast_dial_answered(struct ast_dial *dial)
Return channel that answered.
Definition: dial.c:977
enum ast_dial_result ast_dial_run(struct ast_dial *dial, struct ast_channel *chan, int async)
Execute dialing synchronously or asynchronously.
Definition: dial.c:935
struct ast_channel * ast_dial_answered_steal(struct ast_dial *dial)
Steal the channel that answered.
Definition: dial.c:989
void * ast_dial_get_user_data(struct ast_dial *dial)
Return the user data on a dial structure.
Definition: dial.c:1279
char * end
Definition: eagi_proxy.c:73
#define ast_verb(level,...)
#define LOG_WARNING
enum ast_pbx_result ast_pbx_run(struct ast_channel *c)
Execute the PBX in the current thread.
Definition: pbx.c:4755

References app, ari_origination::appdata, ast_channel_context_set(), ast_channel_exten_set(), ast_channel_name(), ast_channel_priority_set(), ast_dial_answered(), ast_dial_answered_steal(), ast_dial_destroy(), ast_dial_get_user_data(), AST_DIAL_RESULT_ANSWERED, ast_dial_run(), ast_free, ast_log, ast_pbx_run(), ast_strlen_zero(), ast_verb, ari_origination::context, end, ari_origination::exten, LOG_ERROR, LOG_WARNING, NULL, pbx_exec(), pbx_findapp(), and ari_origination::priority.

Referenced by ari_channels_handle_originate_with_id().

◆ ast_ari_channels_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.

Parameters
headersHTTP headers
argsSwagger parameters
[out]responseHTTP response

Definition at line 338 of file resource_channels.c.

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
361}
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_answer(struct stasis_app_control *control)
Answer the channel associated with this control.
const char * args

References ao2_cleanup, args, ast_ari_response_error(), ast_ari_response_no_content(), channel_state_invalid(), find_control(), NULL, RAII_VAR, and stasis_app_control_answer().

Referenced by ast_ari_channels_answer_cb().

◆ ast_ari_channels_continue_in_dialplan()

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.

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
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:409

References ao2_cleanup, args, ast_ari_response_alloc_failed(), ast_ari_response_error(), ast_ari_response_no_content(), ast_assert, ast_debug, ast_findlabel_extension(), ast_log, AST_LOG_ERROR, ast_strlen_zero(), channel_state_invalid(), voicemailpwcheck::context, find_control(), NULL, RAII_VAR, S_OR, stasis_app_control_continue(), and stasis_app_control_get_snapshot().

Referenced by ast_ari_channels_continue_in_dialplan_cb().

◆ ast_ari_channels_create()

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.

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
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) {
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
1928
1931 chan_data_destroy(chan_data);
1932 } else {
1934 }
1935
1936 ao2_ref(snapshot, -1);
1937}
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
struct ast_format_cap * ast_channel_nativeformats(const struct ast_channel *chan)
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
@ AST_MEDIA_TYPE_AUDIO
Definition: codec.h:32
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_variables_destroy(struct ast_variable *var)
Free variable list.
Definition: extconf.c:1262
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
static int save_dialstring(struct ast_channel *chan, const char *dialstring)
Save dialstring onto a channel datastore.
static int json_to_ast_variables(struct ast_ari_response *response, struct ast_json *json_variables, struct ast_variable **variables)
static void * ari_channel_thread(void *data)
Thread that owns stasis-created channel.
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.

References ao2_bump, ao2_cleanup, ao2_ref, 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_ERROR_ID_EXISTS, ast_channel_get_by_name(), ast_channel_nativeformats(), ast_channel_snapshot_get_latest(), ast_channel_snapshot_to_json(), ast_channel_uniqueid(), 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_MEDIA_TYPE_AUDIO, ast_pthread_create_detached, ast_request(), ast_set_variables(), ast_str_append(), ast_str_create, ast_strdupa, ast_strip(), ast_strlen_zero(), ast_variables_destroy(), ari_channel_thread_data::chan, chan_data_destroy(), json_to_ast_variables(), NULL, RAII_VAR, save_dialstring(), stasis_app_subscribe_channel(), ari_channel_thread_data::stasis_stuff, strsep(), thread, ast_assigned_ids::uniqueid, and ast_assigned_ids::uniqueid2.

Referenced by ast_ari_channels_create_cb().

◆ ast_ari_channels_dial()

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.

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);
1999
2000 /* Copy over callerid information */
2002
2004
2006
2007 ast_channel_language_set(callee, ast_channel_language(caller));
2010 ast_channel_musicclass_set(callee, ast_channel_musicclass(caller));
2011
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
2026}
@ AST_CHANNEL_REQUESTOR_BRIDGE_PEER
Definition: channel.h:1477
const char * ast_channel_musicclass(const struct ast_channel *chan)
struct ast_party_redirecting * ast_channel_redirecting(struct ast_channel *chan)
unsigned short ast_channel_transfercapability(const struct ast_channel *chan)
#define ast_channel_lock_both(chan1, chan2)
Lock two channels.
Definition: channel.h:2929
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_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
ast_channel_adsicpe
Definition: channel.h:868
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
struct ast_party_dialed * ast_channel_dialed(struct ast_channel *chan)
const char * ast_channel_language(const struct ast_channel *chan)
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_party_caller * ast_channel_caller(struct ast_channel *chan)
void ast_channel_transfercapability_set(struct ast_channel *chan, unsigned short value)
void ast_channel_adsicpe_set(struct ast_channel *chan, enum ast_channel_adsicpe value)
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
ast_channel_state
ast_channel states
Definition: channelstate.h:35
@ AST_STATE_DOWN
Definition: channelstate.h:36
@ AST_STATE_RESERVED
Definition: channelstate.h:37
void ast_channel_stage_snapshot_done(struct ast_channel *chan)
Clear flag to indicate channel snapshot is being staged, and publish snapshot.
void ast_channel_stage_snapshot(struct ast_channel *chan)
Set flag to indicate channel snapshot is being staged.
int ast_max_forwards_decrement(struct ast_channel *chan)
Decrement the max forwards count for a particular channel.
Definition: max_forwards.c:135
static char * restore_dialstring(struct ast_channel *chan)
Retrieve the dialstring from the channel datastore.
int stasis_app_control_dial(struct stasis_app_control *control, const char *dialstring, unsigned int timeout)
Dial a channel.
Definition: control.c:1686
int transit_network_select
Transit Network Select.
Definition: channel.h:397

References ao2_cleanup, args, ast_ari_response_alloc_failed(), ast_ari_response_error(), ast_ari_response_no_content(), ast_channel_adsicpe_set(), ast_channel_caller(), ast_channel_cleanup, ast_channel_connected(), ast_channel_datastore_inherit(), ast_channel_dialed(), ast_channel_get_by_name(), ast_channel_inherit_variables(), ast_channel_language(), ast_channel_lock, ast_channel_lock_both, ast_channel_musicclass(), ast_channel_redirecting(), ast_channel_req_accountcodes(), AST_CHANNEL_REQUESTOR_BRIDGE_PEER, ast_channel_stage_snapshot(), ast_channel_stage_snapshot_done(), ast_channel_transfercapability(), ast_channel_transfercapability_set(), ast_channel_unlock, ast_connected_line_copy_from_caller(), ast_max_forwards_decrement(), ast_party_redirecting_copy(), AST_STATE_DOWN, AST_STATE_RESERVED, ast_strdupa, ast_strlen_zero(), find_control(), NULL, RAII_VAR, restore_dialstring(), stasis_app_control_dial(), and ast_party_dialed::transit_network_select.

Referenced by ast_ari_channels_dial_cb().

◆ ast_ari_channels_external_media()

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.

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}
@ PARSE_PORT_REQUIRE
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
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)
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.

References args, ast_ari_channels_external_media_parse_body(), ast_ari_response_error(), ast_assert, ast_json_object_get(), ast_sockaddr_split_hostport(), ast_strdupa, ast_strlen_zero(), external_media_audiosocket_tcp(), external_media_rtp_udp(), json_to_ast_variables(), NULL, and PARSE_PORT_REQUIRE.

Referenced by ast_ari_channels_external_media_cb().

◆ ast_ari_channels_get()

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.

891{
892 struct ast_channel_snapshot *snapshot;
893
894 snapshot = ast_channel_snapshot_get_latest(args->channel_id);
895 if (!snapshot) {
897 response, 404, "Not Found",
898 "Channel not found");
899 return;
900 }
901
902 ast_ari_response_ok(response,
904 ao2_ref(snapshot, -1);
905}

References ao2_ref, args, ast_ari_response_error(), ast_ari_response_ok(), ast_channel_snapshot_get_latest(), ast_channel_snapshot_to_json(), and NULL.

Referenced by ast_ari_channels_get_cb().

◆ ast_ari_channels_get_channel_var()

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.

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}
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
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
const char * ast_str_retrieve_variable(struct ast_str **buf, ssize_t maxlen, struct ast_channel *chan, struct varshead *headp, const char *var)
int value
Definition: syslog.c:37

References ao2_cleanup, args, ast_ari_response_alloc_failed(), ast_ari_response_error(), ast_ari_response_ok(), ast_assert, ast_channel_cleanup, ast_channel_get_by_name(), ast_free, ast_func_read2(), ast_json_pack(), ast_json_ref(), ast_json_unref(), ast_str_buffer(), ast_str_create, ast_str_retrieve_variable(), ast_strlen_zero(), NULL, RAII_VAR, S_OR, and value.

Referenced by ast_ari_channels_get_channel_var_cb().

◆ ast_ari_channels_hangup()

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.

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
954}
#define AST_CAUSE_NORMAL
Definition: causes.h:151
int ast_softhangup(struct ast_channel *chan, int cause)
Softly hangup up a channel.
Definition: channel.c:2471
@ AST_SOFTHANGUP_EXPLICIT
Definition: channel.h:1148
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
static int convert_reason_to_hangup_code(const char *reason)
Return the corresponded hangup code of the given reason.

References ao2_cleanup, args, ast_ari_response_error(), ast_ari_response_no_content(), AST_CAUSE_NORMAL, ast_channel_get_by_name(), ast_channel_hangupcause_set(), ast_softhangup(), AST_SOFTHANGUP_EXPLICIT, ast_strlen_zero(), convert_reason_to_hangup_code(), NULL, and RAII_VAR.

Referenced by ast_ari_channels_hangup_cb().

◆ ast_ari_channels_hold()

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.

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
531
533}
void stasis_app_control_hold(struct stasis_app_control *control)
Place the channel associated with the control on hold.
Definition: control.c:768

References ao2_cleanup, args, ast_ari_response_no_content(), channel_state_invalid(), find_control(), NULL, RAII_VAR, and stasis_app_control_hold().

Referenced by ast_ari_channels_hold_cb().

◆ ast_ari_channels_list()

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.

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}
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
struct ao2_container * ast_channel_cache_all(void)
int ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
Definition: json.c:378
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
Definition: json.c:362
struct stasis_message_sanitizer * stasis_app_get_sanitizer(void)
Get the Stasis message sanitizer for app_stasis applications.
Definition: res_stasis.c:2271
Generic container type.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
Structure containing callbacks for Stasis message sanitization.
Definition: stasis.h:200
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

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

Referenced by ast_ari_channels_list_cb().

◆ ast_ari_channels_move()

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.

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
274}
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:471

References ao2_cleanup, args, ast_ari_response_error(), ast_ari_response_no_content(), find_control(), NULL, RAII_VAR, and stasis_app_control_move().

Referenced by ast_ari_channels_move_cb().

◆ ast_ari_channels_mute()

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.

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")) {
429 } else if (!strcmp(args->direction, "out")) {
431 } else if (!strcmp(args->direction, "both")) {
433 } else {
435 response, 400, "Bad Request",
436 "Invalid direction specified");
437 return;
438 }
439
440 stasis_app_control_mute(control, direction, frametype);
441
443}
#define AST_MUTE_DIRECTION_READ
Definition: channel.h:4712
#define AST_MUTE_DIRECTION_WRITE
Definition: channel.h:4713
direction
ast_frame_type
Frame types.
@ AST_FRAME_VOICE
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:651

References ao2_cleanup, args, ast_ari_response_error(), ast_ari_response_no_content(), AST_FRAME_VOICE, AST_MUTE_DIRECTION_READ, AST_MUTE_DIRECTION_WRITE, ast_strlen_zero(), channel_state_invalid(), find_control(), NULL, RAII_VAR, and stasis_app_control_mute().

Referenced by ast_ari_channels_mute_cb().

◆ ast_ari_channels_originate()

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.

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
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}
static struct ast_channel * ari_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)
int ast_ari_channels_originate_parse_body(struct ast_json *body, struct ast_ari_channels_originate_args *args)
Body parsing function for /channels.

References args, ari_channels_handle_originate_with_id(), ast_ari_channels_originate_parse_body(), ast_channel_cleanup, ast_json_object_get(), ast_variables_destroy(), json_to_ast_variables(), and NULL.

Referenced by ast_ari_channels_originate_cb().

◆ ast_ari_channels_originate_with_id()

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.

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
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}
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}.

References args, ari_channels_handle_originate_with_id(), ast_ari_channels_originate_with_id_parse_body(), ast_channel_cleanup, ast_json_object_get(), ast_variables_destroy(), json_to_ast_variables(), and NULL.

Referenced by ast_ari_channels_originate_with_id_cb().

◆ ast_ari_channels_play()

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.

721{
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}
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)

References args, and ari_channels_handle_play().

Referenced by ast_ari_channels_play_cb().

◆ ast_ari_channels_play_with_id()

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.

736{
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}

References args, and ari_channels_handle_play().

Referenced by ast_ari_channels_play_with_id_cb().

◆ ast_ari_channels_record()

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.

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;
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
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:
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,
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}
#define ast_malloc(len)
A wrapper for malloc()
Definition: astmm.h:191
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
@ AST_RECORD_IF_EXISTS_ERROR
int errno
struct stasis_app_recording_options * stasis_app_recording_options_create(const char *name, const char *format)
Allocate a recording options object.
struct ast_json * stasis_app_recording_to_json(const struct stasis_app_recording *recording)
Construct a JSON model of a recording.
struct stasis_app_recording * stasis_app_control_record(struct stasis_app_control *control, struct stasis_app_recording_options *options)
Record media from a channel.
enum ast_record_if_exists stasis_app_recording_if_exists_parse(const char *str)
Parse a string into the if_exists enum.
#define STASIS_APP_RECORDING_TERMINATE_INVALID
char stasis_app_recording_termination_parse(const char *str)
Parse a string into the recording termination enum.
#define ast_string_field_build(x, field, fmt, args...)
Set a field to a complex (built) value.
Definition: stringfields.h:555
static struct test_options options
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
const struct ast_flags ast_uri_http
Definition: utils.c:719

References ao2_cleanup, args, ast_ari_response_created(), ast_ari_response_error(), ast_asprintf, ast_assert, ast_free, ast_get_format_for_file_ext(), ast_log, ast_malloc, AST_RECORD_IF_EXISTS_ERROR, ast_string_field_build, ast_uri_encode(), ast_uri_http, errno, find_control(), LOG_WARNING, NULL, options, RAII_VAR, stasis_app_control_record(), stasis_app_recording_if_exists_parse(), stasis_app_recording_options_create(), STASIS_APP_RECORDING_TERMINATE_INVALID, stasis_app_recording_termination_parse(), and stasis_app_recording_to_json().

Referenced by ast_ari_channels_record_cb().

◆ ast_ari_channels_redirect()

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.

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
336}
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:520

References ao2_cleanup, args, ast_ari_response_error(), ast_ari_response_no_content(), ast_channel_snapshot_get_latest(), ast_strdupa, ast_strlen_zero(), channel_state_invalid(), find_control(), NULL, RAII_VAR, and stasis_app_control_redirect().

Referenced by ast_ari_channels_redirect_cb().

◆ ast_ari_channels_ring()

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.

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
379
381}
int stasis_app_control_ring(struct stasis_app_control *control)
Indicate ringing to the channel associated with this control.
Definition: control.c:612

References ao2_cleanup, args, ast_ari_response_no_content(), channel_state_invalid(), find_control(), NULL, RAII_VAR, and stasis_app_control_ring().

Referenced by ast_ari_channels_ring_cb().

◆ ast_ari_channels_ring_stop()

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.

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
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:627

References ao2_cleanup, args, ast_ari_response_no_content(), channel_state_invalid(), find_control(), NULL, RAII_VAR, and stasis_app_control_ring_stop().

Referenced by ast_ari_channels_ring_stop_cb().

◆ ast_ari_channels_rtpstatistics()

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.

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}
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
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:4097
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:2219
Structure to describe a channel "technology", ie a channel driver See for examples:
Definition: channel.h:628
const char *const type
Definition: channel.h:629
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:775

References ao2_cleanup, args, ast_ari_response_error(), ast_ari_response_ok(), ast_channel_cleanup, ast_channel_get_by_name(), ast_channel_lock, ast_channel_tech(), ast_channel_unlock, ast_rtp_instance_get_glue(), ast_rtp_instance_get_stats_all_json(), ast_rtp_glue::get_rtp_info, NULL, RAII_VAR, and ast_channel_tech::type.

Referenced by ast_ari_channels_rtpstatistics_cb().

◆ ast_ari_channels_send_dtmf()

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.

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
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:585

References ao2_cleanup, args, ast_ari_response_error(), ast_ari_response_no_content(), ast_strlen_zero(), channel_state_invalid(), find_control(), NULL, RAII_VAR, and stasis_app_control_dtmf().

Referenced by ast_ari_channels_send_dtmf_cb().

◆ ast_ari_channels_set_channel_var()

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.

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
1570}
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:731

References ao2_cleanup, args, ast_ari_response_error(), ast_ari_response_no_content(), ast_assert, ast_strlen_zero(), find_control(), NULL, RAII_VAR, and stasis_app_control_set_channel_var().

Referenced by ast_ari_channels_set_channel_var_cb().

◆ ast_ari_channels_snoop_channel()

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.

1654{
1656 args->channel_id,
1657 args->spy,
1658 args->whisper,
1659 args->app,
1660 args->app_args,
1661 args->snoop_id,
1662 response);
1663}
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)

References args, and ari_channels_handle_snoop_channel().

Referenced by ast_ari_channels_snoop_channel_cb().

◆ ast_ari_channels_snoop_channel_with_id()

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.

1668{
1670 args->channel_id,
1671 args->spy,
1672 args->whisper,
1673 args->app,
1674 args->app_args,
1675 args->snoop_id,
1676 response);
1677}

References args, and ari_channels_handle_snoop_channel().

Referenced by ast_ari_channels_snoop_channel_with_id_cb().

◆ ast_ari_channels_start_moh()

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.

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);
574}
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:800

References ao2_cleanup, args, ast_ari_response_no_content(), channel_state_invalid(), find_control(), NULL, RAII_VAR, and stasis_app_control_moh_start().

Referenced by ast_ari_channels_start_moh_cb().

◆ ast_ari_channels_start_silence()

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.

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
614}
void stasis_app_control_silence_start(struct stasis_app_control *control)
Start playing silence to a channel.
Definition: control.c:852

References ao2_cleanup, args, ast_ari_response_no_content(), channel_state_invalid(), find_control(), NULL, RAII_VAR, and stasis_app_control_silence_start().

Referenced by ast_ari_channels_start_silence_cb().

◆ ast_ari_channels_stop_moh()

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.

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
594}
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:818

References ao2_cleanup, args, ast_ari_response_no_content(), channel_state_invalid(), find_control(), NULL, RAII_VAR, and stasis_app_control_moh_stop().

Referenced by ast_ari_channels_stop_moh_cb().

◆ ast_ari_channels_stop_silence()

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.

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
634}
void stasis_app_control_silence_stop(struct stasis_app_control *control)
Stop playing silence to a channel.
Definition: control.c:875

References ao2_cleanup, args, ast_ari_response_no_content(), channel_state_invalid(), find_control(), NULL, RAII_VAR, and stasis_app_control_silence_stop().

Referenced by ast_ari_channels_stop_silence_cb().

◆ ast_ari_channels_unhold()

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.

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
552
554}
void stasis_app_control_unhold(struct stasis_app_control *control)
Remove the channel associated with the control from hold.
Definition: control.c:781

References ao2_cleanup, args, ast_ari_response_no_content(), channel_state_invalid(), find_control(), NULL, RAII_VAR, and stasis_app_control_unhold().

Referenced by ast_ari_channels_unhold_cb().

◆ ast_ari_channels_unmute()

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.

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")) {
471 } else if (!strcmp(args->direction, "out")) {
473 } else if (!strcmp(args->direction, "both")) {
475 } else {
477 response, 400, "Bad Request",
478 "Invalid direction specified");
479 return;
480 }
481
482 stasis_app_control_unmute(control, direction, frametype);
483
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:679

References ao2_cleanup, args, ast_ari_response_error(), ast_ari_response_no_content(), AST_FRAME_VOICE, AST_MUTE_DIRECTION_READ, AST_MUTE_DIRECTION_WRITE, ast_strlen_zero(), channel_state_invalid(), find_control(), NULL, RAII_VAR, and stasis_app_control_unmute().

Referenced by ast_ari_channels_unmute_cb().

◆ chan_data_destroy()

static void chan_data_destroy ( struct ari_channel_thread_data chan_data)
static

Definition at line 1684 of file resource_channels.c.

1685{
1686 ast_free(chan_data->stasis_stuff);
1687 ast_hangup(chan_data->chan);
1688 ast_free(chan_data);
1689}
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
Definition: channel.c:2541

References ast_free, ast_hangup(), ari_channel_thread_data::chan, and ari_channel_thread_data::stasis_stuff.

Referenced by ari_channel_thread(), and ast_ari_channels_create().

◆ channel_state_invalid()

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.

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}
@ AST_STATE_RINGING
Definition: channelstate.h:41
enum ast_channel_state state

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 ari_channels_handle_play(), 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().

◆ convert_reason_to_hangup_code()

static int convert_reason_to_hangup_code ( const char *  reason)
static

Return the corresponded hangup code of the given reason.

Definition at line 53 of file resource_channels.c.

54{
55 if (!strcmp(reason, "normal")) {
56 return AST_CAUSE_NORMAL;
57 } else if (!strcmp(reason, "busy")) {
58 return AST_CAUSE_BUSY;
59 } else if (!strcmp(reason, "congestion")) {
61 } else if (!strcmp(reason, "no_answer")) {
62 return AST_CAUSE_NOANSWER;
63 } else if (!strcmp(reason, "timeout")) {
65 } else if (!strcmp(reason, "rejected")) {
67 } else if (!strcmp(reason, "unallocated")) {
69 } else if (!strcmp(reason, "normal_unspecified")) {
71 } else if (!strcmp(reason, "number_incomplete")) {
73 } else if (!strcmp(reason, "codec_mismatch")) {
75 } else if (!strcmp(reason, "interworking")) {
77 } else if (!strcmp(reason, "failure")) {
78 return AST_CAUSE_FAILURE;
79 } else if(!strcmp(reason, "answered_elsewhere")) {
81 }
82
83 return -1;
84}
#define AST_CAUSE_CONGESTION
Definition: causes.h:153
#define AST_CAUSE_UNALLOCATED
Definition: causes.h:98
#define AST_CAUSE_INTERWORKING
Definition: causes.h:146
#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
Definition: causes.h:130
#define AST_CAUSE_INVALID_NUMBER_FORMAT
Definition: causes.h:116
#define AST_CAUSE_FAILURE
Definition: causes.h:150
#define AST_CAUSE_NO_USER_RESPONSE
Definition: causes.h:108
#define AST_CAUSE_CALL_REJECTED
Definition: causes.h:111
#define AST_CAUSE_ANSWERED_ELSEWHERE
Definition: causes.h:114
#define AST_CAUSE_NORMAL_UNSPECIFIED
Definition: causes.h:119
#define AST_CAUSE_NOANSWER
Definition: causes.h:152
#define AST_CAUSE_BUSY
Definition: causes.h:149

References AST_CAUSE_ANSWERED_ELSEWHERE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_FAILURE, AST_CAUSE_INTERWORKING, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NOANSWER, AST_CAUSE_NORMAL, AST_CAUSE_NORMAL_UNSPECIFIED, and AST_CAUSE_UNALLOCATED.

Referenced by ast_ari_channels_hangup().

◆ external_media_audiosocket_tcp()

static void external_media_audiosocket_tcp ( struct ast_ari_channels_external_media_args args,
struct ast_variable variables,
struct ast_ari_response response 
)
static

Definition at line 2132 of file resource_channels.c.

2135{
2136 size_t endpoint_len;
2137 char *endpoint;
2138 struct ast_channel *chan;
2139 struct varshead *vars;
2140
2141 if (ast_strlen_zero(args->data)) {
2142 ast_ari_response_error(response, 400, "Bad Request", "data can not be empty");
2143 return;
2144 }
2145
2146 endpoint_len = strlen("AudioSocket/") + strlen(args->external_host) + 1 + strlen(args->data) + 1;
2147 endpoint = ast_alloca(endpoint_len);
2148 /* The UUID is stored in the arbitrary data field */
2149 snprintf(endpoint, endpoint_len, "AudioSocket/%s/%s", args->external_host, args->data);
2150
2152 endpoint,
2153 NULL,
2154 NULL,
2155 0,
2156 NULL,
2157 args->app,
2158 args->data,
2159 NULL,
2160 0,
2161 variables,
2162 args->channel_id,
2163 NULL,
2164 NULL,
2165 args->format,
2166 response);
2167 ast_variables_destroy(variables);
2168
2169 if (!chan) {
2170 return;
2171 }
2172
2173 ast_channel_lock(chan);
2174 vars = ast_channel_varshead(chan);
2175 if (vars && !AST_LIST_EMPTY(vars)) {
2176 ast_json_object_set(response->message, "channelvars", ast_json_channel_vars(vars));
2177 }
2178 ast_channel_unlock(chan);
2179 ast_channel_unref(chan);
2180}
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:288
struct varshead * ast_channel_varshead(struct ast_channel *chan)
int ast_json_object_set(struct ast_json *object, const char *key, struct ast_json *value)
Set a field in a JSON object.
Definition: json.c:414
struct ast_json * ast_json_channel_vars(struct varshead *channelvars)
Construct a JSON object from a ast_var_t list.
Definition: json.c:864
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:450
struct ast_json * message
Definition: ari.h:94

References args, ari_channels_handle_originate_with_id(), ast_alloca, ast_ari_response_error(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_channel_varshead(), ast_json_channel_vars(), ast_json_object_set(), AST_LIST_EMPTY, ast_strlen_zero(), ast_variables_destroy(), ast_ari_response::message, and NULL.

Referenced by ast_ari_channels_external_media().

◆ external_media_rtp_udp()

static int external_media_rtp_udp ( struct ast_ari_channels_external_media_args args,
struct ast_variable variables,
struct ast_ari_response response 
)
static

Definition at line 2084 of file resource_channels.c.

2087{
2088 char *endpoint;
2089 struct ast_channel *chan;
2090 struct varshead *vars;
2091
2092 if (ast_asprintf(&endpoint, "UnicastRTP/%s/c(%s)",
2093 args->external_host,
2094 args->format) == -1) {
2095 return 1;
2096 }
2097
2099 endpoint,
2100 NULL,
2101 NULL,
2102 0,
2103 NULL,
2104 args->app,
2105 args->data,
2106 NULL,
2107 0,
2108 variables,
2109 args->channel_id,
2110 NULL,
2111 NULL,
2112 args->format,
2113 response);
2114 ast_variables_destroy(variables);
2115
2116 ast_free(endpoint);
2117
2118 if (!chan) {
2119 return 1;
2120 }
2121
2122 ast_channel_lock(chan);
2123 vars = ast_channel_varshead(chan);
2124 if (vars && !AST_LIST_EMPTY(vars)) {
2125 ast_json_object_set(response->message, "channelvars", ast_json_channel_vars(vars));
2126 }
2127 ast_channel_unlock(chan);
2128 ast_channel_unref(chan);
2129 return 0;
2130}

References args, ari_channels_handle_originate_with_id(), ast_asprintf, ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_channel_varshead(), ast_free, ast_json_channel_vars(), ast_json_object_set(), AST_LIST_EMPTY, ast_variables_destroy(), ast_ari_response::message, and NULL.

Referenced by ast_ari_channels_external_media().

◆ find_control()

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.

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}
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

References ao2_cleanup, ao2_ref, ast_ari_response_error(), ast_assert, ast_channel_get_by_name(), NULL, RAII_VAR, and stasis_app_control_find_by_channel_id().

Referenced by ari_channels_handle_play(), 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().

◆ json_to_ast_variables()

static int json_to_ast_variables ( struct ast_ari_response response,
struct ast_json json_variables,
struct ast_variable **  variables 
)
static

Definition at line 1373 of file resource_channels.c.

1374{
1376
1377 res = ast_json_to_ast_variables(json_variables, variables);
1378 switch (res) {
1380 return 0;
1382 ast_ari_response_error(response, 400, "Bad Request",
1383 "Only string values in the 'variables' object allowed");
1384 break;
1387 break;
1388 }
1389 ast_log(AST_LOG_ERROR, "Unable to convert 'variables' in JSON body to channel variables\n");
1390
1391 return -1;
1392}
ast_json_to_ast_vars_code
Definition: json.h:1109
@ AST_JSON_TO_AST_VARS_CODE_INVALID_TYPE
Conversion failed because invalid value type supplied.
Definition: json.h:1116
@ AST_JSON_TO_AST_VARS_CODE_SUCCESS
Conversion successful.
Definition: json.h:1111
@ AST_JSON_TO_AST_VARS_CODE_OOM
Conversion failed because of allocation failure. (Out Of Memory)
Definition: json.h:1118
enum ast_json_to_ast_vars_code ast_json_to_ast_variables(struct ast_json *json_variables, struct ast_variable **variables)
Convert a ast_json list of key/value pair tuples into a ast_variable list.
Definition: json.c:818

References ast_ari_response_alloc_failed(), ast_ari_response_error(), ast_json_to_ast_variables(), AST_JSON_TO_AST_VARS_CODE_INVALID_TYPE, AST_JSON_TO_AST_VARS_CODE_OOM, AST_JSON_TO_AST_VARS_CODE_SUCCESS, ast_log, and AST_LOG_ERROR.

Referenced by ast_ari_channels_create(), ast_ari_channels_external_media(), ast_ari_channels_originate(), and ast_ari_channels_originate_with_id().

◆ restore_dialstring()

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.

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}
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
struct ast_datastore_info dialstring_info
Structure for a data store object.
Definition: datastore.h:64
void * data
Definition: datastore.h:66

References ast_channel_datastore_find(), ast_datastore::data, dialstring_info, and NULL.

Referenced by ast_ari_channels_dial().

◆ save_dialstring()

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.

1733{
1734 struct ast_datastore *datastore;
1735
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
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2385
#define ast_datastore_alloc(info, uid)
Definition: datastore.h:85
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:68

References ast_channel_datastore_add(), ast_channel_lock, ast_channel_unlock, ast_datastore_alloc, ast_datastore_free(), ast_strdup, ast_datastore::data, dialstring_info, and NULL.

Referenced by ast_ari_channels_create().

Variable Documentation

◆ dialstring_info

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

Definition at line 1717 of file resource_channels.c.

Referenced by restore_dialstring(), and save_dialstring().