" Message - text of the message\n";
static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, char *cid_num,
- const struct ast_channel *requestor);
+ const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor);
static struct ast_channel *mbl_request(const char *type, struct ast_format_cap *cap,
- const struct ast_channel *requestor, const char *data, int *cause);
+ const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
static int mbl_call(struct ast_channel *ast, const char *dest, int timeout);
static int mbl_hangup(struct ast_channel *ast);
static int mbl_answer(struct ast_channel *ast);
*/
static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, char *cid_num,
- const struct ast_channel *requestor)
+ const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
struct ast_channel *chn;
ast_dsp_digitreset(pvt->dsp);
chn = ast_channel_alloc(1, state, cid_num, pvt->id, 0, 0, pvt->context,
- requestor ? ast_channel_linkedid(requestor) : "", 0,
+ assignedids, requestor, 0,
"Mobile/%s-%04lx", pvt->id, ast_random() & 0xffff);
if (!chn) {
goto e_return;
}
static struct ast_channel *mbl_request(const char *type, struct ast_format_cap *cap,
- const struct ast_channel *requestor, const char *data, int *cause)
+ const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
struct ast_channel *chn = NULL;
}
ast_mutex_lock(&pvt->lock);
- chn = mbl_new(AST_STATE_DOWN, pvt, NULL, requestor);
+ chn = mbl_new(AST_STATE_DOWN, pvt, NULL, assignedids, requestor);
ast_mutex_unlock(&pvt->lock);
if (!chn) {
ast_log(LOG_WARNING, "Unable to allocate channel structure.\n");
ast_debug(1, "[%s] error parsing CLIP: %s\n", pvt->id, buf);
}
- if (!(chan = mbl_new(AST_STATE_RING, pvt, clip, NULL))) {
+ if (!(chan = mbl_new(AST_STATE_RING, pvt, clip, NULL, NULL))) {
ast_log(LOG_ERROR, "[%s] unable to allocate channel for incoming call\n", pvt->id);
hfp_send_chup(pvt->hfp);
msg_queue_push(pvt, AT_OK, AT_CHUP);
pvt->incoming_sms = 0;
/* XXX this channel probably does not need to be associated with this pvt */
- if (!(chan = mbl_new(AST_STATE_DOWN, pvt, NULL, NULL))) {
+ if (!(chan = mbl_new(AST_STATE_DOWN, pvt, NULL, NULL, NULL))) {
ast_debug(1, "[%s] error creating sms message channel, disconnecting\n", pvt->id);
return -1;
}
pvt->incoming = 1;
- if (!(chan = mbl_new(AST_STATE_UP, pvt, NULL, NULL))) {
+ if (!(chan = mbl_new(AST_STATE_UP, pvt, NULL, NULL, NULL))) {
ast_log(LOG_ERROR, "[%s] unable to allocate channel for incoming call\n", pvt->id);
ast_mutex_unlock(&pvt->lock);
goto e_cleanup;
/* Channel Definition */
static struct ast_channel *ooh323_request(const char *type, struct ast_format_cap *cap,
- const struct ast_channel *requestor, const char *data, int *cause);
+ const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
static int ooh323_digit_begin(struct ast_channel *ast, char digit);
static int ooh323_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int ooh323_call(struct ast_channel *ast, const char *dest, int timeout);
static struct ast_channel *ooh323_new(struct ooh323_pvt *i, int state,
- const char *host, struct ast_format_cap *cap, const char *linkedid)
+ const char *host, struct ast_format_cap *cap,
+ const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
struct ast_channel *ch = NULL;
struct ast_format tmpfmt;
ast_mutex_unlock(&i->lock);
ast_mutex_lock(&ooh323c_cn_lock);
ch = ast_channel_alloc(1, state, i->callerid_num, i->callerid_name,
- i->accountcode, i->exten, i->context, linkedid, i->amaflags,
+ i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags,
"OOH323/%s-%ld", host, callnumber);
callnumber++;
ast_mutex_unlock(&ooh323c_cn_lock);
Possible data values - peername, exten/peername, exten@ip
*/
static struct ast_channel *ooh323_request(const char *type, struct ast_format_cap *cap,
- const struct ast_channel *requestor, const char *data, int *cause)
+ const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
struct ast_channel *chan = NULL;
chan = ooh323_new(p, AST_STATE_DOWN, p->username, cap,
- requestor ? ast_channel_linkedid(requestor) : NULL);
+ assignedids, requestor);
ast_mutex_unlock(&p->lock);
ooh323c_set_capability_for_call(call, &p->prefs, p->cap, p->dtmfmode, p->dtmfcodec,
p->t38support, p->g729onlyA);
/* Incoming call */
- c = ooh323_new(p, AST_STATE_RING, p->username, 0, NULL);
+ c = ooh323_new(p, AST_STATE_RING, p->username, 0, NULL, NULL);
if(!c) {
ast_mutex_unlock(&p->lock);
ast_log(LOG_ERROR, "Could not create ast_channel\n");
bridge = bridge_base_init(bridge, AST_BRIDGE_CAPABILITY_HOLDING,
AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
| AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM | AST_BRIDGE_FLAG_TRANSFER_PROHIBITED,
- "AgentPool", NULL);
+ "AgentPool", NULL, NULL);
bridge = bridge_register(bridge);
return bridge;
}
AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
| AST_BRIDGE_FLAG_SWAP_INHIBIT_TO | AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM
| AST_BRIDGE_FLAG_TRANSFER_PROHIBITED | AST_BRIDGE_FLAG_DISSOLVE_EMPTY,
- APP_NAME, bridge_name);
+ APP_NAME, bridge_name, NULL);
if (!bridge) {
return NULL;
}
snprintf(tmp, sizeof(tmp), "%d", status);
ast_str_append(&tmp_availstat, 0, "%s%s", ast_str_strlen(tmp_availstat) ? "&" : "", tmp);
- if ((inuse <= 1) && (tempchan = ast_request(tech, ast_channel_nativeformats(chan), chan, number, &status))) {
+ if ((inuse <= 1) && (tempchan = ast_request(tech, ast_channel_nativeformats(chan), NULL, chan, number, &status))) {
ast_str_append(&tmp_availchan, 0, "%s%s", ast_str_strlen(tmp_availchan) ? "&" : "", ast_channel_name(tempchan));
snprintf(tmp, sizeof(tmp), "%s/%s", tech, number);
ast_format_cap_add(cap, ast_format_set(&format, AST_FORMAT_SLINEAR, 0));
- conference->record_chan = ast_request("CBRec", cap, NULL,
+ conference->record_chan = ast_request("CBRec", cap, NULL, NULL,
conference->name, NULL);
cap = ast_format_cap_destroy(cap);
if (!conference->record_chan) {
/* Create an actual bridge that will do the audio mixing */
conference->bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_MULTIMIX,
AST_BRIDGE_FLAG_MASQUERADE_ONLY | AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY,
- app, conference_name);
+ app, conference_name, NULL);
if (!conference->bridge) {
ao2_ref(conference, -1);
conference = NULL;
return -1;
}
ast_format_cap_add(cap, ast_format_set(&format, AST_FORMAT_SLINEAR, 0));
- conference->playback_chan = ast_request("CBAnn", cap, NULL,
+ conference->playback_chan = ast_request("CBAnn", cap, NULL, NULL,
conference->name, NULL);
cap = ast_format_cap_destroy(cap);
if (!conference->playback_chan) {
cause = AST_CAUSE_BUSY;
} else {
/* Setup parameters */
- c = o->chan = ast_request(tech, ast_channel_nativeformats(in), in, stuff, &cause);
+ c = o->chan = ast_request(tech, ast_channel_nativeformats(in), NULL, in, stuff, &cause);
if (c) {
if (single && !caller_entertained) {
ast_channel_make_compatible(in, o->chan);
AST_LIST_UNLOCK(dialed_interfaces);
}
- tc = ast_request(tmp->tech, ast_channel_nativeformats(chan), chan, tmp->number, &cause);
+ tc = ast_request(tmp->tech, ast_channel_nativeformats(chan), NULL, chan, tmp->number, &cause);
if (!tc) {
/* If we can't, just go on to the next call */
ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n",
? "/n" : "/m");
}
- outbound = ast_request("Local", ast_channel_nativeformats(caller), caller,
+ outbound = ast_request("Local", ast_channel_nativeformats(caller), NULL, caller,
tmpuser->dialarg, &dg);
if (!outbound) {
ast_log(LOG_WARNING, "Unable to allocate a channel for Local/%s cause: %s\n",
cnf->dahdiconf = dahdic.confno;
/* Setup a new channel for playback of audio files */
- cnf->chan = ast_request("DAHDI", cap_slin, chan, "pseudo", NULL);
+ cnf->chan = ast_request("DAHDI", cap_slin, NULL, chan, "pseudo", NULL);
if (cnf->chan) {
ast_set_read_format_by_id(cnf->chan, AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(cnf->chan, AST_FORMAT_SLINEAR);
}
ast_mutex_lock(&conf->recordthreadlock);
- if ((conf->recordthread == AST_PTHREADT_NULL) && ast_test_flag64(confflags, CONFFLAG_RECORDCONF) && ((conf->lchan = ast_request("DAHDI", cap_slin, chan, "pseudo", NULL)))) {
+ if ((conf->recordthread == AST_PTHREADT_NULL) && ast_test_flag64(confflags, CONFFLAG_RECORDCONF) && ((conf->lchan = ast_request("DAHDI", cap_slin, NULL, chan, "pseudo", NULL)))) {
ast_set_read_format_by_id(conf->lchan, AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(conf->lchan, AST_FORMAT_SLINEAR);
dahdic->chan = 0;
ast_mutex_lock(&conf->recordthreadlock);
if ((conf->recordthread == AST_PTHREADT_NULL) && ast_test_flag64(confflags, CONFFLAG_RECORDCONF) &&
- ((conf->lchan = ast_request("DAHDI", cap_slin, chan, "pseudo", NULL)))) {
+ ((conf->lchan = ast_request("DAHDI", cap_slin, NULL, chan, "pseudo", NULL)))) {
ast_set_read_format_by_id(conf->lchan, AST_FORMAT_SLINEAR);
ast_set_write_format_by_id(conf->lchan, AST_FORMAT_SLINEAR);
dahdic.chan = 0;
tech_data = ast_strdupa(station->device);
tech = strsep(&tech_data, "/");
- if (ast_dial_append(dial, tech, tech_data) == -1) {
+ if (ast_dial_append(dial, tech, tech_data, NULL) == -1) {
ast_dial_destroy(dial);
return -1;
}
tech_data = ast_strdupa(trunk_ref->trunk->device);
tech = strsep(&tech_data, "/");
- if (ast_dial_append(dial, tech, tech_data) == -1) {
+ if (ast_dial_append(dial, tech, tech_data, NULL) == -1) {
ast_mutex_lock(args->cond_lock);
ast_cond_signal(args->cond);
ast_mutex_unlock(args->cond_lock);
break;
}
- chan = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, NULL, NULL, 0, 0, "MeetMeTest");
+ chan = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, "MeetMeTest");
if (!chan) {
ast_test_status_update(test, "Channel allocation failed\n");
return AST_TEST_FAIL;
ast_pbx_outgoing_exten(chantech, cap_slin, chandata,
timeout * 1000, args.arg1, exten, priority, &outgoing_status, 0, NULL,
- NULL, NULL, NULL, NULL, 0);
+ NULL, NULL, NULL, NULL, 0, NULL);
} else if (!strcasecmp(args.type, "app")) {
ast_debug(1, "Originating call to '%s/%s' and connecting them to %s(%s)\n",
chantech, chandata, args.arg1, S_OR(args.arg2, ""));
ast_pbx_outgoing_app(chantech, cap_slin, chandata,
timeout * 1000, args.arg1, args.arg2, &outgoing_status, 0, NULL,
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL, NULL, NULL);
} else {
ast_log(LOG_ERROR, "Incorrect type, it should be 'exten' or 'app': %s\n",
args.type);
}
/* Append technology and resource */
- if (ast_dial_append(dial, tech, resource) == -1) {
+ if (ast_dial_append(dial, tech, resource, NULL) == -1) {
ast_log(LOG_ERROR, "Failed to add %s to outbound dial\n", tech);
ast_dial_destroy(dial);
continue;
}
/* Request the peer */
- tmp->chan = ast_request(tech, ast_channel_nativeformats(qe->chan), qe->chan, location, &status);
+ tmp->chan = ast_request(tech, ast_channel_nativeformats(qe->chan), NULL, qe->chan, location, &status);
if (!tmp->chan) { /* If we can't, just go on to the next call */
ao2_lock(qe->parent);
qe->parent->rrpos++;
ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", inchan_name, tech, stuff, ochan_name);
/* Setup parameters */
- o->chan = ast_request(tech, ast_channel_nativeformats(in), in, stuff, &status);
+ o->chan = ast_request(tech, ast_channel_nativeformats(in), NULL, in, stuff, &status);
if (!o->chan) {
ast_log(LOG_NOTICE,
"Forwarding failed to create channel to dial '%s/%s'\n",
break;
}
- if (!(test_channel1 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
+ if (!(test_channel1 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, NULL,
NULL, NULL, 0, 0, "TestChannel1"))) {
goto exit_vmsayname_test;
}
doomed->bridge = NULL;
}
-static struct ast_channel *announce_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+static struct ast_channel *announce_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
struct ast_channel *chan;
const char *conf_name = data;
ao2_ref(pvt->bridge, +1);
chan = ast_unreal_new_channels(&pvt->base, conf_announce_get_tech(),
- AST_STATE_UP, AST_STATE_UP, NULL, NULL, requestor, NULL);
+ AST_STATE_UP, AST_STATE_UP, NULL, NULL, assignedids, requestor, NULL);
if (chan) {
ast_answer(pvt->base.owner);
ast_answer(pvt->base.chan);
return 0;
}
-static struct ast_channel *rec_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+static struct ast_channel *rec_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
struct ast_channel *chan;
struct ast_format format;
const char *conf_name = data;
- chan = ast_channel_alloc(1, AST_STATE_UP, NULL, NULL, NULL, NULL, NULL, NULL, 0,
+ chan = ast_channel_alloc(1, AST_STATE_UP, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0,
"CBRec/conf-%s-uid-%d",
conf_name, (int) ast_random());
if (!chan) {
static int mute = 0;
static int noaudiocapture = 0;
-static struct ast_channel *alsa_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
+static struct ast_channel *alsa_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
static int alsa_digit(struct ast_channel *c, char digit, unsigned int duration);
static int alsa_text(struct ast_channel *c, const char *text);
static int alsa_hangup(struct ast_channel *c);
return res;
}
-static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state, const char *linkedid)
+static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
struct ast_channel *tmp = NULL;
- if (!(tmp = ast_channel_alloc(1, state, 0, 0, "", p->exten, p->context, linkedid, 0, "ALSA/%s", indevname)))
+ if (!(tmp = ast_channel_alloc(1, state, 0, 0, "", p->exten, p->context, assignedids, requestor, 0, "ALSA/%s", indevname)))
return NULL;
ast_channel_stage_snapshot(tmp);
return tmp;
}
-static struct ast_channel *alsa_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+static struct ast_channel *alsa_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
struct ast_format tmpfmt;
char buf[256];
if (alsa.owner) {
ast_log(LOG_NOTICE, "Already have a call on the ALSA channel\n");
*cause = AST_CAUSE_BUSY;
- } else if (!(tmp = alsa_new(&alsa, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL))) {
+ } else if (!(tmp = alsa_new(&alsa, AST_STATE_DOWN, assignedids, requestor))) {
ast_log(LOG_WARNING, "Unable to create new ALSA channel\n");
}
ast_copy_string(alsa.exten, mye, sizeof(alsa.exten));
ast_copy_string(alsa.context, myc, sizeof(alsa.context));
hookstate = 1;
- alsa_new(&alsa, AST_STATE_RINGING, NULL);
+ alsa_new(&alsa, AST_STATE_RINGING, NULL, NULL);
} else
ast_cli(a->fd, "No such extension '%s' in context '%s'\n", mye, myc);
}
}
static struct ast_channel *announce_request(const char *type, struct ast_format_cap *cap,
- const struct ast_channel *requestor, const char *data, int *cause);
+ const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
static struct ast_channel *record_request(const char *type, struct ast_format_cap *cap,
- const struct ast_channel *requestor, const char *data, int *cause);
+ const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
static struct ast_channel_tech announce_tech = {
.type = "Announcer",
.properties = AST_CHAN_TP_INTERNAL,
};
-static struct ast_channel *media_request_helper(struct ast_format_cap *cap,
+static struct ast_channel *media_request_helper(struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids,
const struct ast_channel *requestor, const char *data, struct ast_channel_tech *tech, const char *role)
{
struct ast_channel *chan;
callid = ast_read_threadstorage_callid();
chan = ast_unreal_new_channels(pvt, tech,
- AST_STATE_UP, AST_STATE_UP, NULL, NULL, requestor, callid);
+ AST_STATE_UP, AST_STATE_UP, NULL, NULL, assignedids, requestor, callid);
if (!chan) {
return NULL;
}
}
static struct ast_channel *announce_request(const char *type, struct ast_format_cap *cap,
- const struct ast_channel *requestor, const char *data, int *cause)
+ const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
- return media_request_helper(cap, requestor, data, &announce_tech, "announcer");
+ return media_request_helper(cap, assignedids, requestor, data, &announce_tech, "announcer");
}
static struct ast_channel *record_request(const char *type, struct ast_format_cap *cap,
- const struct ast_channel *requestor, const char *data, int *cause)
+ const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
- return media_request_helper(cap, requestor, data, &record_tech, "recorder");
+ return media_request_helper(cap, assignedids, requestor, data, &record_tech, "recorder");
}
static void cleanup_capabilities(void)
/*! Channel Technology Callbacks @{ */
static struct ast_channel *console_request(const char *type, struct ast_format_cap *cap,
- const struct ast_channel *requestor, const char *data, int *cause);
+ const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
static int console_digit_begin(struct ast_channel *c, char digit);
static int console_digit_end(struct ast_channel *c, char digit, unsigned int duration);
static int console_text(struct ast_channel *c, const char *text);
/*!
* \note Called with the pvt struct locked
*/
-static struct ast_channel *console_new(struct console_pvt *pvt, const char *ext, const char *ctx, int state, const char *linkedid)
+static struct ast_channel *console_new(struct console_pvt *pvt, const char *ext, const char *ctx, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
struct ast_channel *chan;
if (!(chan = ast_channel_alloc(1, state, pvt->cid_num, pvt->cid_name, NULL,
- ext, ctx, linkedid, 0, "Console/%s", pvt->name))) {
+ ext, ctx, assignedids, requestor, 0, "Console/%s", pvt->name))) {
return NULL;
}
return chan;
}
-static struct ast_channel *console_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+static struct ast_channel *console_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
struct ast_channel *chan = NULL;
struct console_pvt *pvt;
}
console_pvt_lock(pvt);
- chan = console_new(pvt, NULL, NULL, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL);
+ chan = console_new(pvt, NULL, NULL, AST_STATE_DOWN, assignedids, requestor);
console_pvt_unlock(pvt);
if (!chan)
if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
console_pvt_lock(pvt);
pvt->hookstate = 1;
- console_new(pvt, mye, myc, AST_STATE_RINGING, NULL);
+ console_new(pvt, mye, myc, AST_STATE_RINGING, NULL, NULL);
console_pvt_unlock(pvt);
} else
ast_cli(a->fd, "No such extension '%s' in context '%s'\n", mye, myc);
}
-static struct ast_channel *dahdi_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
+static struct ast_channel *dahdi_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
static int dahdi_digit_begin(struct ast_channel *ast, char digit);
static int dahdi_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int dahdi_sendtext(struct ast_channel *c, const char *text);
*
* \param callid_created value returned from ast_callid_threadstorage_auto()
*/
-static struct ast_channel *dahdi_new_callid_clean(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const char *linked, struct ast_callid *callid, int callid_created);
+static struct ast_channel *dahdi_new_callid_clean(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, struct ast_callid *callid, int callid_created);
-static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const char *linkedid, struct ast_callid *callid);
+static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, struct ast_callid *callid);
static struct ast_channel *my_new_analog_ast_channel(void *pvt, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor)
{
struct dahdi_pvt *p = pvt;
int dsub = analogsub_to_dahdisub(sub);
- return dahdi_new_callid_clean(p, state, startpbx, dsub, 0, requestor ? ast_channel_linkedid(requestor) : "", callid, callid_created);
+ return dahdi_new_callid_clean(p, state, startpbx, dsub, 0, NULL, requestor, callid, callid_created);
}
#if defined(HAVE_PRI) || defined(HAVE_SS7)
#endif /* defined(HAVE_PRI) || defined(HAVE_SS7) */
#if defined(HAVE_PRI)
-static struct ast_channel *my_new_pri_ast_channel(void *pvt, int state, enum sig_pri_law law, char *exten, const struct ast_channel *requestor)
+static struct ast_channel *my_new_pri_ast_channel(void *pvt, int state, enum sig_pri_law law, char *exten, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
struct dahdi_pvt *p = pvt;
int audio;
break;
}
- return dahdi_new_callid_clean(p, state, 0, SUB_REAL, newlaw, requestor ? ast_channel_linkedid(requestor) : "", callid, callid_created);
+ return dahdi_new_callid_clean(p, state, 0, SUB_REAL, newlaw, assignedids, requestor, callid, callid_created);
}
#endif /* defined(HAVE_PRI) */
* \retval ast_channel on success.
* \retval NULL on error.
*/
-static struct ast_channel *my_new_ss7_ast_channel(void *pvt, int state, enum sig_ss7_law law, char *exten, const struct ast_channel *requestor)
+static struct ast_channel *my_new_ss7_ast_channel(void *pvt, int state, enum sig_ss7_law law, char *exten, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
struct dahdi_pvt *p = pvt;
int audio;
newlaw = DAHDI_LAW_MULAW;
break;
}
- return dahdi_new_callid_clean(p, state, 0, SUB_REAL, newlaw, requestor ? ast_channel_linkedid(requestor) : "", callid, callid_created);
+ return dahdi_new_callid_clean(p, state, 0, SUB_REAL, newlaw, assignedids, requestor, callid, callid_created);
}
#endif /* defined(HAVE_SS7) */
}
if (!p->mfcr2_accept_on_offer) {
/* The user wants us to start the PBX thread right away without accepting the call first */
- c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL, callid);
+ c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL, NULL, callid);
if (c) {
/* Done here, don't disable reading now since we still need to generate MF tones to accept
the call or reject it and detect the tone off condition of the other end, all of this
}
goto dahdi_r2_on_call_accepted_cleanup;
}
- c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL, callid);
+ c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL, NULL, callid);
if (c) {
/* chan_dahdi will take care of reading from now on in the PBX thread, tell the
library to forget about it */
*/
ast_mutex_unlock(&p->lock);
ast_channel_unlock(ast);
- chan = dahdi_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, NULL, callid);
+ chan = dahdi_new(p, AST_STATE_RESERVED, 0, SUB_THREEWAY, 0, NULL, NULL, callid);
ast_channel_lock(ast);
ast_mutex_lock(&p->lock);
if (p->dahditrcallerid) {
return chan_name;
}
-static struct ast_channel *dahdi_new_callid_clean(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const char *linkedid, struct ast_callid *callid, int callid_created)
+static struct ast_channel *dahdi_new_callid_clean(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, struct ast_callid *callid, int callid_created)
{
- struct ast_channel *new_channel = dahdi_new(i, state, startpbx, idx, law, linkedid, callid);
+ struct ast_channel *new_channel = dahdi_new(i, state, startpbx, idx, law, assignedids, requestor, callid);
ast_callid_threadstorage_auto_clean(callid, callid_created);
return new_channel;
}
-static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const char *linkedid, struct ast_callid *callid)
+static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, struct ast_callid *callid)
{
struct ast_channel *tmp;
struct ast_format deflaw;
return NULL;
}
- tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "DAHDI/%s", ast_str_buffer(chan_name));
+ tmp = ast_channel_alloc(0, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags, "DAHDI/%s", ast_str_buffer(chan_name));
ast_free(chan_name);
if (!tmp) {
return NULL;
restore_gains(mtd->pvt);
mtd->pvt->ringt = mtd->pvt->ringt_base;
- if ((chan = dahdi_new(mtd->pvt, AST_STATE_RING, 0, SUB_REAL, 0, NULL, callid))) {
+ if ((chan = dahdi_new(mtd->pvt, AST_STATE_RING, 0, SUB_REAL, 0, NULL, NULL, callid))) {
int result;
if (dahdi_analog_lib_handles(mtd->pvt->sig, mtd->pvt->radio, mtd->pvt->oprmode)) {
dahdi_ec_enable(i);
/* The channel is immediately up. Start right away */
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
- chan = dahdi_new(i, AST_STATE_RING, 1, SUB_REAL, 0, NULL, callid);
+ chan = dahdi_new(i, AST_STATE_RING, 1, SUB_REAL, 0, NULL, NULL, callid);
if (!chan) {
ast_log(LOG_WARNING, "Unable to start PBX on channel %d\n", i->channel);
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_CONGESTION);
}
} else {
/* Check for callerid, digits, etc */
- chan = dahdi_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, NULL, callid);
+ chan = dahdi_new(i, AST_STATE_RESERVED, 0, SUB_REAL, 0, NULL, NULL, callid);
if (chan) {
if (has_voicemail(i))
res = tone_zone_play_tone(i->subs[SUB_REAL].dfd, DAHDI_TONE_STUTTER);
/* Check for callerid, digits, etc */
callid_created = ast_callid_threadstorage_auto(&callid);
if (i->cid_start == CID_START_POLARITY_IN) {
- chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, callid);
+ chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, NULL, callid);
} else {
- chan = dahdi_new(i, AST_STATE_RING, 0, SUB_REAL, 0, NULL, callid);
+ chan = dahdi_new(i, AST_STATE_RING, 0, SUB_REAL, 0, NULL, NULL, callid);
}
if (!chan) {
ast_verb(2, "Starting post polarity "
"CID detection on channel %d\n",
i->channel);
- chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, callid);
+ chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, NULL, callid);
if (!chan) {
ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
} else if (ast_pthread_create_detached(&threadid, NULL, analog_ss_thread, chan)) {
} else {
struct ast_callid *callid = NULL;
int callid_created = ast_callid_threadstorage_auto(&callid);
- chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, callid);
+ chan = dahdi_new(i, AST_STATE_PRERING, 0, SUB_REAL, 0, NULL, NULL, callid);
if (!chan) {
ast_log(LOG_WARNING, "Cannot allocate new structure on channel %d\n", i->channel);
} else {
return p;
}
-static struct ast_channel *dahdi_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+static struct ast_channel *dahdi_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
int callwait = 0;
struct dahdi_pvt *p;
tmp = sig_ss7_request(p->sig_pvt, SIG_SS7_DEFLAW, requestor, transcapdigital);
#endif /* defined(HAVE_SS7) */
} else {
- tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, requestor ? ast_channel_linkedid(requestor) : "", callid);
+ tmp = dahdi_new(p, AST_STATE_RESERVED, 0, p->owner ? SUB_CALLWAIT : SUB_REAL, 0, assignedids, requestor, callid);
}
if (!tmp) {
p->outgoing = 0;
AST_MUTEX_DEFINE_STATIC(gtalklock); /*!< Protect the interface list (of gtalk_pvt's) */
/* Forward declarations */
-static struct ast_channel *gtalk_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
+static struct ast_channel *gtalk_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
/*static int gtalk_digit(struct ast_channel *ast, char digit, unsigned int duration);*/
static int gtalk_sendtext(struct ast_channel *ast, const char *text);
static int gtalk_digit_begin(struct ast_channel *ast, char digit);
}
/*! \brief Start new gtalk channel */
-static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i, int state, const char *title, const char *linkedid)
+static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i, int state, const char *title, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
struct ast_channel *tmp;
const char *n2;
n2 = title;
else
n2 = i->us;
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, linkedid, client->accountcode, i->exten, client->context, client->amaflags, "Gtalk/%s-%04lx", n2, ast_random() & 0xffff);
+ tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, client->accountcode, i->exten, client->context, assignedids, requestor, client->amaflags, "Gtalk/%s-%04lx", n2, ast_random() & 0xffff);
if (!tmp) {
ast_log(LOG_WARNING, "Unable to allocate Gtalk channel structure!\n");
return NULL;
return -1;
}
- chan = gtalk_new(client, p, AST_STATE_DOWN, pak->from->user, NULL);
+ chan = gtalk_new(client, p, AST_STATE_DOWN, pak->from->user, NULL, NULL);
if (!chan) {
gtalk_free_pvt(client, p);
return -1;
}
/*!\brief Part of PBX interface */
-static struct ast_channel *gtalk_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+static struct ast_channel *gtalk_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
struct gtalk_pvt *p = NULL;
struct gtalk *client = NULL;
ASTOBJ_WRLOCK(client);
p = gtalk_alloc(client, strchr(sender, '@') ? sender : client->connection->jid->full, strchr(to, '@') ? to : client->user, NULL);
if (p) {
- chan = gtalk_new(client, p, AST_STATE_DOWN, to, requestor ? ast_channel_linkedid(requestor) : NULL);
+ chan = gtalk_new(client, p, AST_STATE_DOWN, to, assignedids, requestor);
}
ASTOBJ_UNLOCK(client);
return chan;
static void oh323_set_owner(struct oh323_pvt *pvt, struct ast_channel *c);
-static struct ast_channel *oh323_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest, int *cause);
+static struct ast_channel *oh323_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *dest, int *cause);
static int oh323_digit_begin(struct ast_channel *c, char digit);
static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration);
static int oh323_call(struct ast_channel *c, const char *dest, int timeout);
}
/*! \brief Private structure should be locked on a call */
-static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const char *host, const char *linkedid)
+static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const char *host, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
struct ast_channel *ch;
char *cid_num, *cid_name;
/* Don't hold a oh323_pvt lock while we allocate a chanel */
ast_mutex_unlock(&pvt->lock);
- ch = ast_channel_alloc(1, state, cid_num, cid_name, pvt->accountcode, pvt->exten, pvt->context, linkedid, pvt->amaflags, "H323/%s", host);
+ ch = ast_channel_alloc(1, state, cid_num, cid_name, pvt->accountcode, pvt->exten, pvt->context, assignedids, requestor, pvt->amaflags, "H323/%s", host);
/* Update usage counter */
ast_module_ref(ast_module_info->self);
ast_mutex_lock(&pvt->lock);
return 0;
}
}
-static struct ast_channel *oh323_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest, int *cause)
+static struct ast_channel *oh323_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *dest, int *cause)
{
struct oh323_pvt *pvt;
struct ast_channel *tmpc = NULL;
ast_mutex_unlock(&caplock);
ast_mutex_lock(&pvt->lock);
- tmpc = __oh323_new(pvt, AST_STATE_DOWN, tmp1, requestor ? ast_channel_linkedid(requestor) : NULL);
+ tmpc = __oh323_new(pvt, AST_STATE_DOWN, tmp1, assignedids, requestor);
ast_mutex_unlock(&pvt->lock);
if (!tmpc) {
oh323_destroy(pvt);
}
/* allocate a channel and tell asterisk about it */
- c = __oh323_new(pvt, AST_STATE_RINGING, pvt->cd.call_token, NULL);
+ c = __oh323_new(pvt, AST_STATE_RINGING, pvt->cd.call_token, NULL, NULL);
/* And release when done */
ast_mutex_unlock(&pvt->lock);
static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
-static struct ast_channel *iax2_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
+static struct ast_channel *iax2_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
static struct ast_frame *iax2_read(struct ast_channel *c);
static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
}
/*! \brief Create new call, interface with the PBX core */
-static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capability, const char *linkedid, unsigned int cachable)
+static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capability, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, unsigned int cachable)
{
struct ast_channel *tmp;
struct chan_iax2_pvt *i;
/* Don't hold call lock */
ast_mutex_unlock(&iaxsl[callno]);
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
+ tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags, "IAX2/%s-%d", i->host, i->callno);
ast_mutex_lock(&iaxsl[callno]);
if (i != iaxs[callno]) {
if (tmp) {
(f.frametype == AST_FRAME_IAX)) {
if (ast_test_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART)) {
ast_clear_flag64(iaxs[fr->callno], IAX_DELAYPBXSTART);
- if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL,
+ if (!ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->chosenformat, NULL, NULL,
ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_AUTHENTICATED))) {
ast_variables_destroy(ies.vars);
ast_mutex_unlock(&iaxsl[fr->callno]);
using_prefs);
ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
- if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL, 1)))
+ if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, format, NULL, NULL, 1)))
iax2_destroy(fr->callno);
else if (ies.vars) {
struct ast_datastore *variablestore;
iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
- if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL, 1)))
+ if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL, NULL, 1)))
iax2_destroy(fr->callno);
else if (ies.vars) {
struct ast_datastore *variablestore;
}
}
-static struct ast_channel *iax2_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+static struct ast_channel *iax2_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
int callno;
int res;
ast_string_field_set(iaxs[callno], host, pds.peer);
}
- c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, requestor ? ast_channel_linkedid(requestor) : NULL, cai.found);
+ c = ast_iax2_new(callno, AST_STATE_DOWN, cai.capability, assignedids, requestor, cai.found);
ast_mutex_unlock(&iaxsl[callno]);
AST_MUTEX_DEFINE_STATIC(jinglelock); /*!< Protect the interface list (of jingle_pvt's) */
/* Forward declarations */
-static struct ast_channel *jingle_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
+static struct ast_channel *jingle_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
static int jingle_sendtext(struct ast_channel *ast, const char *text);
static int jingle_digit_begin(struct ast_channel *ast, char digit);
static int jingle_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
}
/*! \brief Start new jingle channel */
-static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *i, int state, const char *title, const char *linkedid)
+static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *i, int state, const char *title, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
struct ast_channel *tmp;
struct ast_format_cap *what; /* SHALLOW COPY DO NOT DESTROY */
str = title;
else
str = i->them;
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", "", "", linkedid, 0, "Jingle/%s-%04lx", str, ast_random() & 0xffff);
+ tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", "", "", assignedids, requestor, 0, "Jingle/%s-%04lx", str, ast_random() & 0xffff);
if (!tmp) {
ast_log(LOG_WARNING, "Unable to allocate Jingle channel structure!\n");
return NULL;
ast_log(LOG_WARNING, "Unable to allocate jingle structure!\n");
return -1;
}
- chan = jingle_new(client, p, AST_STATE_DOWN, pak->from->user, NULL);
+ chan = jingle_new(client, p, AST_STATE_DOWN, pak->from->user, NULL, NULL);
if (!chan) {
jingle_free_pvt(client, p);
return -1;
}
/*! \brief Part of PBX interface */
-static struct ast_channel *jingle_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+static struct ast_channel *jingle_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
struct jingle_pvt *p = NULL;
struct jingle *client = NULL;
ASTOBJ_WRLOCK(client);
p = jingle_alloc(client, to, NULL);
if (p)
- chan = jingle_new(client, p, AST_STATE_DOWN, to, requestor ? ast_channel_linkedid(requestor) : NULL);
+ chan = jingle_new(client, p, AST_STATE_DOWN, to, assignedids, requestor);
ASTOBJ_UNLOCK(client);
return chan;
static char *mgcp_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
static int reload_config(int reload);
-static struct ast_channel *mgcp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest, int *cause);
+static struct ast_channel *mgcp_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *dest, int *cause);
static int mgcp_call(struct ast_channel *ast, const char *dest, int timeout);
static int mgcp_hangup(struct ast_channel *ast);
static int mgcp_answer(struct ast_channel *ast);
return res;
}
-static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state, const char *linkedid)
+static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
struct ast_channel *tmp;
struct ast_variable *v = NULL;
struct mgcp_endpoint *i = sub->parent;
struct ast_format tmpfmt;
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, linkedid, i->accountcode, i->exten, i->context, i->amaflags, "MGCP/%s@%s-%d", i->name, i->parent->name, sub->id);
+ tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags, "MGCP/%s@%s-%d", i->name, i->parent->name, sub->id);
if (tmp) {
ast_channel_stage_snapshot(tmp);
ast_channel_tech_set(tmp, &mgcp_tech);
#else
transmit_notify_request(sub, p->ncs ? "L/rt" : "G/rt");
#endif
- c = mgcp_new(sub, AST_STATE_RING, NULL);
+ c = mgcp_new(sub, AST_STATE_RING, NULL, NULL);
if (!c) {
ast_log(LOG_WARNING, "Unable to start PBX on channel %s@%s\n", p->name, p->parent->name);
transmit_notify_request(sub, p->ncs ? "L/cg" : "G/cg");
} else {
transmit_notify_request(sub, "L/dl");
}
- c = mgcp_new(sub, AST_STATE_DOWN, NULL);
+ c = mgcp_new(sub, AST_STATE_DOWN, NULL, NULL);
if (c) {
if (ast_pthread_create_detached(&t, NULL, mgcp_ss, c)) {
ast_log(LOG_WARNING, "Unable to create switch thread: %s\n", strerror(errno));
return 0;
}
-static struct ast_channel *mgcp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest, int *cause)
+static struct ast_channel *mgcp_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *dest, int *cause)
{
struct mgcp_subchannel *sub;
struct ast_channel *tmpc = NULL;
ast_mutex_unlock(&sub->lock);
return NULL;
}
- tmpc = mgcp_new(sub->owner ? sub->next : sub, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL);
+ tmpc = mgcp_new(sub->owner ? sub->next : sub, AST_STATE_DOWN, assignedids, requestor);
ast_mutex_unlock(&sub->lock);
if (!tmpc)
ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
static void chan_misdn_log(int level, int port, char *tmpl, ...)
__attribute__((format(printf, 3, 4)));
-static struct ast_channel *misdn_new(struct chan_list *cl, int state, char *exten, char *callerid, struct ast_format_cap *cap, const char *linkedid, int port, int c);
+static struct ast_channel *misdn_new(struct chan_list *cl, int state, char *exten, char *callerid, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, int port, int c);
static void send_digit_to_chan(struct chan_list *cl, char digit);
static int pbx_start_chan(struct chan_list *ch);
return cl;
}
-static struct ast_channel *misdn_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+static struct ast_channel *misdn_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
struct ast_channel *ast;
char group[BUFFERSIZE + 1] = "";
}
cl->bc = newbc;
- ast = misdn_new(cl, AST_STATE_RESERVED, args.ext, NULL, cap, requestor ? ast_channel_linkedid(requestor) : NULL, port, channel);
+ ast = misdn_new(cl, AST_STATE_RESERVED, args.ext, NULL, cap, assignedids, requestor, port, channel);
if (!ast) {
chan_list_unref(cl, "Failed to create a new channel");
misdn_lib_release(newbc);
}
}
-static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char *exten, char *callerid, struct ast_format_cap *cap, const char *linkedid, int port, int c)
+static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char *exten, char *callerid, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, int port, int c)
{
struct ast_channel *tmp;
char *cid_name = NULL;
ast_callerid_parse(callerid, &cid_name, &cid_num);
}
- tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", linkedid, 0, "%s/%s%d-u%d", misdn_type, c ? "" : "tmp", chan_offset + c, glob_channel++);
+ tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", assignedids, requestor, 0, "%s/%s%d-u%d", misdn_type, c ? "" : "tmp", chan_offset + c, glob_channel++);
if (tmp) {
chan_misdn_log(2, port, " --> * NEW CHANNEL dialed:%s caller:%s\n", exten, callerid);
return RESPONSE_ERR;
}
ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
- chan = misdn_new(ch, AST_STATE_RESERVED, bc->dialed.number, bc->caller.number, cap, NULL, bc->port, bc->channel);
+ chan = misdn_new(ch, AST_STATE_RESERVED, bc->dialed.number, bc->caller.number, cap, NULL, NULL, bc->port, bc->channel);
cap = ast_format_cap_destroy(cap);
}
if (!chan) {
static struct ast_sched_context *sched; /*!< Scheduling context for RTCP */
/* \brief Asterisk core interaction functions */
-static struct ast_channel *jingle_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
+static struct ast_channel *jingle_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
static int jingle_sendtext(struct ast_channel *ast, const char *text);
static int jingle_digit_begin(struct ast_channel *ast, char digit);
static int jingle_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
}
/*! \brief Function called to create a new Jingle Asterisk channel */
-static struct ast_channel *jingle_new(struct jingle_endpoint *endpoint, struct jingle_session *session, int state, const char *title, const char *linkedid, const char *cid_name)
+static struct ast_channel *jingle_new(struct jingle_endpoint *endpoint, struct jingle_session *session, int state, const char *title, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *cid_name)
{
struct ast_channel *chan;
const char *str = S_OR(title, session->remote);
return NULL;
}
- if (!(chan = ast_channel_alloc(1, state, S_OR(title, ""), S_OR(cid_name, ""), "", "", "", linkedid, 0, "Motif/%s-%04lx", str, ast_random() & 0xffff))) {
+ if (!(chan = ast_channel_alloc(1, state, S_OR(title, ""), S_OR(cid_name, ""), "", "", "", assignedids, requestor, 0, "Motif/%s-%04lx", str, ast_random() & 0xffff))) {
return NULL;
}
}
/*! \brief Function called by core to create a new outgoing Jingle session */
-static struct ast_channel *jingle_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+static struct ast_channel *jingle_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
RAII_VAR(struct jingle_config *, cfg, ao2_global_obj_ref(globals), ao2_cleanup);
RAII_VAR(struct jingle_endpoint *, endpoint, NULL, ao2_cleanup);
/* Note that for Google-V1 and Google-V2 we don't stop built-in ICE support, this will happen in jingle_new */
}
- if (!(chan = jingle_new(endpoint, session, AST_STATE_DOWN, target, requestor ? ast_channel_linkedid(requestor) : NULL, NULL))) {
+ if (!(chan = jingle_new(endpoint, session, AST_STATE_DOWN, target, assignedids, requestor, NULL))) {
ast_log(LOG_ERROR, "Unable to create Jingle channel on endpoint '%s'\n", args.name);
*cause = AST_CAUSE_SWITCH_CONGESTION;
ao2_ref(session, -1);
}
/* Create a new Asterisk channel using the above local session */
- if (!(chan = jingle_new(endpoint, session, AST_STATE_DOWN, pak->from->user, NULL, pak->from->full))) {
+ if (!(chan = jingle_new(endpoint, session, AST_STATE_DOWN, pak->from->user, NULL, NULL, pak->from->full))) {
ao2_ref(session, -1);
jingle_send_error_response(endpoint->connection, pak, "cancel", "service-unavailable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'", NULL);
return;
static const char tdesc[] = "Multicast RTP Paging Channel Driver";
/* Forward declarations */
-static struct ast_channel *multicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
+static struct ast_channel *multicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
static int multicast_rtp_call(struct ast_channel *ast, const char *dest, int timeout);
static int multicast_rtp_hangup(struct ast_channel *ast);
static struct ast_frame *multicast_rtp_read(struct ast_channel *ast);
}
/*! \brief Function called when we should prepare to call the destination */
-static struct ast_channel *multicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+static struct ast_channel *multicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
char *tmp = ast_strdupa(data), *multicast_type = tmp, *destination, *control;
struct ast_rtp_instance *instance;
goto failure;
}
- if (!(chan = ast_channel_alloc(1, AST_STATE_DOWN, "", "", "", "", "", requestor ? ast_channel_linkedid(requestor) : "", 0, "MulticastRTP/%p", instance))) {
+ if (!(chan = ast_channel_alloc(1, AST_STATE_DOWN, "", "", "", "", "", assignedids, requestor, 0, "MulticastRTP/%p", instance))) {
ast_rtp_instance_destroy(instance);
goto failure;
}
struct ast_module_user *u; /*! for holding a reference to this module */
};
-static struct ast_channel *nbs_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
+static struct ast_channel *nbs_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
static int nbs_call(struct ast_channel *ast, const char *dest, int timeout);
static int nbs_hangup(struct ast_channel *ast);
static struct ast_frame *nbs_xread(struct ast_channel *ast);
return 0;
}
-static struct ast_channel *nbs_new(struct nbs_pvt *i, int state, const char *linkedid)
+static struct ast_channel *nbs_new(struct nbs_pvt *i, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
struct ast_channel *tmp;
- tmp = ast_channel_alloc(1, state, 0, 0, "", "s", context, linkedid, 0, "NBS/%s", i->stream);
+ tmp = ast_channel_alloc(1, state, 0, 0, "", "s", context, assignedids, requestor, 0, "NBS/%s", i->stream);
if (tmp) {
ast_channel_tech_set(tmp, &nbs_tech);
ast_channel_set_fd(tmp, 0, nbs_fd(i->nbs));
}
-static struct ast_channel *nbs_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+static struct ast_channel *nbs_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
struct nbs_pvt *p;
struct ast_channel *tmp = NULL;
}
p = nbs_alloc(data);
if (p) {
- tmp = nbs_new(p, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL);
+ tmp = nbs_new(p, AST_STATE_DOWN, assignedids, requestor);
if (!tmp)
nbs_destroy(p);
}
static int setformat(struct chan_oss_pvt *o, int mode);
-static struct ast_channel *oss_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor,
+static struct ast_channel *oss_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor,
const char *data, int *cause);
static int oss_digit_begin(struct ast_channel *c, char digit);
static int oss_digit_end(struct ast_channel *c, char digit, unsigned int duration);
/*!
* \brief allocate a new channel.
*/
-static struct ast_channel *oss_new(struct chan_oss_pvt *o, char *ext, char *ctx, int state, const char *linkedid)
+static struct ast_channel *oss_new(struct chan_oss_pvt *o, char *ext, char *ctx, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
struct ast_channel *c;
- c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, linkedid, 0, "Console/%s", o->device + 5);
+ c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", ext, ctx, assignedids, requestor, 0, "Console/%s", o->device + 5);
if (c == NULL)
return NULL;
ast_channel_tech_set(c, &oss_tech);
return c;
}
-static struct ast_channel *oss_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+static struct ast_channel *oss_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
struct ast_channel *c;
struct chan_oss_pvt *o;
*cause = AST_CAUSE_BUSY;
return NULL;
}
- c = oss_new(o, NULL, NULL, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL);
+ c = oss_new(o, NULL, NULL, AST_STATE_DOWN, assignedids, requestor);
if (c == NULL) {
ast_log(LOG_WARNING, "Unable to create new OSS channel\n");
return NULL;
myc = o->ctx;
if (ast_exists_extension(NULL, myc, mye, 1, NULL)) {
o->hookstate = 1;
- oss_new(o, mye, myc, AST_STATE_RINGING, NULL);
+ oss_new(o, mye, myc, AST_STATE_RINGING, NULL, NULL);
} else
ast_cli(a->fd, "No such extension '%s' in context '%s'\n", mye, myc);
if (s)
static char cid_num[AST_MAX_EXTENSION];
static char cid_name[AST_MAX_EXTENSION];
-static struct ast_channel *phone_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
+static struct ast_channel *phone_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
static int phone_digit_begin(struct ast_channel *ast, char digit);
static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int phone_call(struct ast_channel *ast, const char *dest, int timeout);
return 0;
}
-static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *cntx, const char *linkedid)
+static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *cntx, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
struct ast_channel *tmp;
struct phone_codec_data queried_codec;
struct ast_format tmpfmt;
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", i->ext, i->context, linkedid, 0, "Phone/%s", i->dev + 5);
+ tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", i->ext, i->context, assignedids, requestor, 0, "Phone/%s", i->dev + 5);
if (tmp) {
ast_channel_lock(tmp);
ast_channel_tech_set(tmp, cur_tech);
!phonee.bits.dtmf_ready) &&
ast_exists_extension(NULL, i->context, i->ext, 1, i->cid_num)) {
/* It's a valid extension in its context, get moving! */
- phone_new(i, AST_STATE_RING, i->context, NULL);
+ phone_new(i, AST_STATE_RING, i->context, NULL, NULL);
/* No need to restart monitor, we are the monitor */
} else if (!ast_canmatch_extension(NULL, i->context, i->ext, 1, i->cid_num)) {
/* There is nothing in the specified extension that can match anymore.
Try the default */
if (ast_exists_extension(NULL, "default", i->ext, 1, i->cid_num)) {
/* Check the default, too... */
- phone_new(i, AST_STATE_RING, "default", NULL);
+ phone_new(i, AST_STATE_RING, "default", NULL, NULL);
/* XXX This should probably be justified better XXX */
} else if (!ast_canmatch_extension(NULL, "default", i->ext, 1, i->cid_num)) {
/* It's not a valid extension, give a busy signal */
offhook = ioctl(i->fd, PHONE_HOOKSTATE);
if (offhook) {
if (i->mode == MODE_IMMEDIATE) {
- phone_new(i, AST_STATE_RING, i->context, NULL);
+ phone_new(i, AST_STATE_RING, i->context, NULL, NULL);
} else if (i->mode == MODE_DIALTONE) {
ast_module_ref(ast_module_info->self);
/* Reset the extension */
}
if (phonee.bits.pstn_ring) {
ast_verbose("Unit is ringing\n");
- phone_new(i, AST_STATE_RING, i->context, NULL);
+ phone_new(i, AST_STATE_RING, i->context, NULL, NULL);
}
if (phonee.bits.caller_id)
ast_verbose("We have caller ID\n");
return tmp;
}
-static struct ast_channel *phone_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+static struct ast_channel *phone_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
struct phone_pvt *p;
struct ast_channel *tmp = NULL;
if (strncmp(name, p->dev + 5, length) == 0 &&
!isalnum(name[length])) {
if (!p->owner) {
- tmp = phone_new(p, AST_STATE_DOWN, p->context, requestor ? ast_channel_linkedid(requestor) : NULL);
+ tmp = phone_new(p, AST_STATE_DOWN, p->context, assignedids, requestor);
break;
} else
*cause = AST_CAUSE_BUSY;
}
/* \brief Asterisk core interaction functions */
-static struct ast_channel *chan_pjsip_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
+static struct ast_channel *chan_pjsip_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
static int chan_pjsip_sendtext(struct ast_channel *ast, const char *text);
static int chan_pjsip_digit_begin(struct ast_channel *ast, char digit);
static int chan_pjsip_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
};
/*! \brief Function called to create a new PJSIP Asterisk channel */
-static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int state, const char *exten, const char *title, const char *linkedid, const char *cid_name)
+static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int state, const char *exten, const char *title, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *cid_name)
{
struct ast_channel *chan;
struct ast_format fmt;
return NULL;
}
- if (!(chan = ast_channel_alloc(1, state, S_OR(session->id.number.str, ""), S_OR(session->id.name.str, ""), "", "", "", linkedid, 0, "PJSIP/%s-%08x", ast_sorcery_object_get_id(session->endpoint),
+ if (!(chan = ast_channel_alloc(1, state, S_OR(session->id.number.str, ""), S_OR(session->id.name.str, ""), "", "", "", assignedids, requestor, 0, "PJSIP/%s-%08x", ast_sorcery_object_get_id(session->endpoint),
ast_atomic_fetchadd_int((int *)&chan_idx, +1)))) {
return NULL;
}
}
/*! \brief Function called by core to create a new outgoing PJSIP session */
-static struct ast_channel *chan_pjsip_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+static struct ast_channel *chan_pjsip_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
struct request_data req_data;
RAII_VAR(struct ast_sip_session *, session, NULL, ao2_cleanup);
session = req_data.session;
- if (!(session->channel = chan_pjsip_new(session, AST_STATE_DOWN, NULL, NULL, requestor ? ast_channel_linkedid(requestor) : NULL, NULL))) {
+ if (!(session->channel = chan_pjsip_new(session, AST_STATE_DOWN, NULL, NULL, assignedids, requestor, NULL))) {
/* Session needs to be terminated prematurely */
return NULL;
}
datastore->data = transport_data;
ast_sip_session_add_datastore(session, datastore);
- if (!(session->channel = chan_pjsip_new(session, AST_STATE_RING, session->exten, NULL, NULL, NULL))) {
+ if (!(session->channel = chan_pjsip_new(session, AST_STATE_RING, session->exten, NULL, NULL, NULL, NULL))) {
if (pjsip_inv_end_session(session->inv_session, 503, NULL, &packet) == PJ_SUCCESS) {
ast_sip_session_send_response(session, packet);
}
in coming releases. */
/*--- PBX interface functions */
-static struct ast_channel *sip_request_call(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest, int *cause);
+static struct ast_channel *sip_request_call(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *dest, int *cause);
static int sip_devicestate(const char *data);
static int sip_sendtext(struct ast_channel *ast, const char *text);
static int sip_call(struct ast_channel *ast, const char *dest, int timeout);
*
* \return New ast_channel locked.
*/
-static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *title, const char *linkedid, struct ast_callid *callid)
+static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *title, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, struct ast_callid *callid)
{
struct ast_channel *tmp;
struct ast_variable *v = NULL;
sip_pvt_unlock(i);
/* Don't hold a sip pvt lock while we allocate a channel */
- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, linkedid, i->amaflags, "SIP/%s-%08x", my_name, ast_atomic_fetchadd_int((int *)&chan_idx, +1));
+ tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, assignedids, requestor, i->amaflags, "SIP/%s-%08x", my_name, ast_atomic_fetchadd_int((int *)&chan_idx, +1));
}
if (!tmp) {
ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n");
/* First invitation - create the channel. Allocation
* failures are handled below. */
- c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL), NULL, p->logger_callid);
+ c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL), NULL, NULL, p->logger_callid);
if (cc_recall_core_id != -1) {
ast_setup_cc_recall_datastore(c, cc_recall_core_id);
* To: header.
* \endverbatim
*/
-static struct ast_channel *sip_request_call(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest, int *cause)
+static struct ast_channel *sip_request_call(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *dest, int *cause)
{
struct sip_pvt *p;
struct ast_channel *tmpc = NULL;
sip_pvt_lock(p);
- tmpc = sip_new(p, AST_STATE_DOWN, host, requestor ? ast_channel_linkedid(requestor) : NULL, callid); /* Place the call */
+ tmpc = sip_new(p, AST_STATE_DOWN, host, assignedids, requestor, callid); /* Place the call */
if (callid) {
callid = ast_callid_unref(callid);
}
int keepalive_count;
};
-static struct ast_channel *skinny_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest, int *cause);
+static struct ast_channel *skinny_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *dest, int *cause);
static AST_LIST_HEAD_STATIC(sessions, skinnysession);
static int skinny_devicestate(const char *data);
}
}
-static struct ast_channel *skinny_new(struct skinny_line *l, struct skinny_subline *subline, int state, const char *linkedid, int direction)
+static struct ast_channel *skinny_new(struct skinny_line *l, struct skinny_subline *subline, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, int direction)
{
struct ast_channel *tmp;
struct skinny_subchannel *sub;
return NULL;
}
- tmp = ast_channel_alloc(1, state, l->cid_num, l->cid_name, l->accountcode, l->exten, l->context, linkedid, l->amaflags, "Skinny/%s@%s-%d", l->name, d->name, callnums);
+ tmp = ast_channel_alloc(1, state, l->cid_num, l->cid_name, l->accountcode, l->exten, l->context, assignedids, requestor, l->amaflags, "Skinny/%s@%s-%d", l->name, d->name, callnums);
if (!tmp) {
ast_log(LOG_WARNING, "Unable to allocate channel structure\n");
return NULL;
if (!(sub->substate == SUBSTATE_HOLD)) {
setsubstate(sub, SUBSTATE_HOLD);
}
- c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
+ c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, NULL, SKINNY_OUTGOING);
if (c) {
newsub = ast_channel_tech_pvt(c);
/* point the sub and newsub at each other so we know they are related */
transmit_displaynotify(d, "CFwd disabled", 10);
} else {
if (!sub || !sub->owner) {
- if (!(c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING))) {
+ if (!(c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, NULL, SKINNY_OUTGOING))) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
return;
}
break;
}
- c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
+ c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, NULL, SKINNY_OUTGOING);
if (!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
} else {
}
if (!sub || !sub->owner)
- c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
+ c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, NULL, SKINNY_OUTGOING);
else
c = sub->owner;
d->name, instance, callreference);
if (!sub || !sub->owner) {
- c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
+ c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, NULL, SKINNY_OUTGOING);
} else {
c = sub->owner;
}
if (sub && sub->owner) {
ast_debug(1, "Current subchannel [%s] already has owner\n", ast_channel_name(sub->owner));
} else {
- c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
+ c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, NULL, SKINNY_OUTGOING);
if (c) {
setsubstate(ast_channel_tech_pvt(c), SUBSTATE_OFFHOOK);
} else {
if (sub && sub->owner) {
ast_debug(1, "Current sub [%s] already has owner\n", ast_channel_name(sub->owner));
} else {
- c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
+ c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, NULL, SKINNY_OUTGOING);
if (c) {
setsubstate(ast_channel_tech_pvt(c), SUBSTATE_OFFHOOK);
} else {
l = sub->line;
}
- c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
+ c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, NULL, SKINNY_OUTGOING);
if(!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
}
if (!sub || !sub->owner) {
- c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
+ c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, NULL, SKINNY_OUTGOING);
} else {
c = sub->owner;
}
d->name, instance, callreference);
/* New Call ALWAYS gets a new sub-channel */
- c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
+ c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, NULL, SKINNY_OUTGOING);
sub = ast_channel_tech_pvt(c);
if (!c) {
} else { /* No sub, maybe an inactive SLA call */
struct skinny_subline *subline;
subline = find_subline_by_callid(d, callreference);
- c = skinny_new(l, subline, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
+ c = skinny_new(l, subline, AST_STATE_DOWN, NULL, NULL, SKINNY_OUTGOING);
if (!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
} else {
{
struct skinny_subline *subline;
subline = find_subline_by_callid(d, callreference);
- c = skinny_new(l, subline, AST_STATE_DOWN, NULL, SKINNY_OUTGOING);
+ c = skinny_new(l, subline, AST_STATE_DOWN, NULL, NULL, SKINNY_OUTGOING);
if (!c) {
ast_log(LOG_WARNING, "Unable to create channel for %s@%s\n", l->name, d->name);
} else {
SKINNY_DEBUG(DEBUG_PACKET, 3, "Received SOFTKEY_GPICKUP from %s, inst %d, callref %d\n",
d->name, instance, callreference);
if (!sub || !sub->owner) {
- c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, SKINNY_INCOMING);
+ c = skinny_new(l, NULL, AST_STATE_DOWN, NULL, NULL, SKINNY_INCOMING);
} else {
c = sub->owner;
}
return get_devicestate(l);
}
-static struct ast_channel *skinny_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest, int *cause)
+static struct ast_channel *skinny_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *dest, int *cause)
{
struct skinny_line *l;
struct skinny_subline *subline = NULL;
l = subline->line;
}
ast_verb(3, "skinny_request(%s)\n", tmp);
- tmpc = skinny_new(l, subline, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL, SKINNY_INCOMING);
+ tmpc = skinny_new(l, subline, AST_STATE_DOWN, assignedids, requestor, SKINNY_INCOMING);
if (!tmpc) {
ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
} else if (subline) {
static const char channel_type[] = "USTM";
/*! Protos */
-static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state, const char *linkedid);
+static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor);
static int load_module(void);
static int reload(void);
static int unload_module(void);
static int reload_config(void);
static void unistim_set_owner(struct unistim_subchannel *sub, struct ast_channel *chan);
static void show_main_page(struct unistimsession *pte);
-static struct ast_channel *unistim_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor,
+static struct ast_channel *unistim_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor,
const char *dest, int *cause);
static int unistim_call(struct ast_channel *ast, const char *dest, int timeout);
static int unistim_hangup(struct ast_channel *ast);
sub_stop_silence(s, sub);
send_tone(s, 0, 0);
/* Make new channel */
- c = unistim_new(sub_trans, AST_STATE_DOWN, NULL);
+ c = unistim_new(sub_trans, AST_STATE_DOWN, NULL, NULL);
if (!c) {
ast_log(LOG_WARNING, "Cannot allocate new structure on channel %p\n", sub->parent);
return;
RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
const char *pickupexten;
- c = unistim_new(sub, AST_STATE_DOWN, NULL); /* No, starting a new one */
+ c = unistim_new(sub, AST_STATE_DOWN, NULL, NULL); /* No, starting a new one */
if (!sub->rtp) { /* Need to start RTP before calling ast_pbx_run */
start_rtp(sub);
}
/*--- unistim_new: Initiate a call in the UNISTIM channel */
/* called from unistim_request (calls from the pbx ) */
-static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state, const char *linkedid)
+static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
struct ast_channel *tmp;
struct unistim_line *l;
}
l = sub->parent;
tmp = ast_channel_alloc(1, state, l->cid_num, NULL, l->accountcode, l->exten,
- l->parent->context, linkedid, l->amaflags, "USTM/%s@%s-%p", l->name, l->parent->name, sub);
+ l->parent->context, assignedids, requestor, l->amaflags, "USTM/%s@%s-%p", l->name, l->parent->name, sub);
if (unistimdebug) {
ast_verb(0, "unistim_new sub=%d (%p) chan=%p line=%s\n", sub->subtype, sub, tmp, l->name);
}
/*--- unistim_request: PBX interface function ---*/
/* UNISTIM calls initiated by the PBX arrive here */
-static struct ast_channel *unistim_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *dest,
+static struct ast_channel *unistim_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *dest,
int *cause)
{
struct unistim_subchannel *sub, *sub_ring, *sub_trans;
sub->subtype = SUB_RING;
sub->softkey = -1;
ast_format_cap_copy(sub->parent->cap, cap);
- tmpc = unistim_new(sub, AST_STATE_DOWN, requestor ? ast_channel_linkedid(requestor) : NULL);
+ tmpc = unistim_new(sub, AST_STATE_DOWN, assignedids, requestor);
if (!tmpc) {
ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
}
} *iflist = NULL;
-static struct ast_channel *vpb_new(struct vpb_pvt *i, enum ast_channel_state state, const char *context, const char *linkedid);
+static struct ast_channel *vpb_new(struct vpb_pvt *i, enum ast_channel_state state, const char *context, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor);
static void *do_chanreads(void *pvt);
-static struct ast_channel *vpb_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
+static struct ast_channel *vpb_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
static int vpb_digit_begin(struct ast_channel *ast, char digit);
static int vpb_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
static int vpb_call(struct ast_channel *ast, const char *dest, int timeout);
break;
case VPB_RING:
if (p->mode == MODE_FXO) /* FXO port ring, start * */ {
- vpb_new(p, AST_STATE_RING, p->context, NULL);
+ vpb_new(p, AST_STATE_RING, p->context, NULL, NULL);
if (UsePolarityCID != 1) {
if (p->callerid_type == 1) {
ast_verb(4, "Using VPB Caller ID\n");
case VPB_STATION_OFFHOOK:
if (p->mode == MODE_IMMEDIATE) {
- vpb_new(p,AST_STATE_RING, p->context, NULL);
+ vpb_new(p,AST_STATE_RING, p->context, NULL, NULL);
} else {
ast_verb(4, "%s: handle_notowned: playing dialtone\n", p->dev);
playtone(p->handle, &Dialtone);
if (ast_exists_extension(NULL, p->context, p->ext, 1, p->callerid)){
ast_verb(4, "%s: handle_notowned: DTMF IDD timer out, matching on [%s] in [%s]\n", p->dev, p->ext, p->context);
- vpb_new(p, AST_STATE_RING, p->context, NULL);
+ vpb_new(p, AST_STATE_RING, p->context, NULL, NULL);
}
} else if (e->data == p->ring_timer_id) {
/* We didnt get another ring in time! */
vpb_timer_start(p->dtmfidd_timer);
} else {
ast_verb(4, "%s: handle_notowned: Matched on [%s] in [%s]\n", p->dev, p->ext , p->context);
- vpb_new(p, AST_STATE_UP, p->context, NULL);
+ vpb_new(p, AST_STATE_UP, p->context, NULL, NULL);
}
} else if (!ast_canmatch_extension(NULL, p->context, p->ext, 1, p->callerid)) {
if (ast_exists_extension(NULL, "default", p->ext, 1, p->callerid)) {
- vpb_new(p, AST_STATE_UP, "default", NULL);
+ vpb_new(p, AST_STATE_UP, "default", NULL, NULL);
} else if (!ast_canmatch_extension(NULL, "default", p->ext, 1, p->callerid)) {
ast_verb(4, "%s: handle_notowned: can't match anything in %s or default\n", p->dev, p->context);
playtone(p->handle, &Busytone);
return NULL;
}
-static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state state, const char *context, const char *linkedid)
+static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state state, const char *context, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)
{
struct ast_channel *tmp;
char cid_num[256];
}
ast_verb(4, "%s: New call for context [%s]\n", me->dev, context);
- tmp = ast_channel_alloc(1, state, 0, 0, "", me->ext, me->context, linkedid, AST_AMA_NONE, "%s", me->dev);
+ tmp = ast_channel_alloc(1, state, 0, 0, "", me->ext, me->context, assignedids, requestor, AST_AMA_NONE, "%s", me->dev);
if (tmp) {
if (use_ast_ind == 1){
ast_channel_tech_set(tmp, &vpb_tech_indicate);
return tmp;
}
-static struct ast_channel *vpb_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+static struct ast_channel *vpb_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
struct vpb_pvt *p;
struct ast_channel *tmp = NULL;
if (group == -1) {
if (strncmp(s, p->dev + 4, sizeof p->dev) == 0) {
if (!p->owner) {
- tmp = vpb_new(p, AST_STATE_DOWN, p->context, requestor ? ast_channel_linkedid(requestor) : NULL);
+ tmp = vpb_new(p, AST_STATE_DOWN, p->context, assignedids, requestor);
break;
}
}
} else {
if ((p->group == group) && (!p->owner)) {
- tmp = vpb_new(p, AST_STATE_DOWN, p->context, requestor ? ast_channel_linkedid(requestor) : NULL);
+ tmp = vpb_new(p, AST_STATE_DOWN, p->context, assignedids, requestor);
break;
}
}
* \param flags Flags that will alter the behavior of the bridge
* \param creator Entity that created the bridge (optional)
* \param name Name given to the bridge by its creator (optional, requires named creator)
+ * \param name id Unique ID given to the bridge by its creator (optional)
*
* \retval a pointer to a new bridge on success
* \retval NULL on failure
* This creates a no frills two party bridge that will be
* destroyed once one of the channels hangs up.
*/
-struct ast_bridge *ast_bridge_base_new(uint32_t capabilities, unsigned int flags, const char *creator, const char *name);
+struct ast_bridge *ast_bridge_base_new(uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id);
/*!
* \brief Try locking the bridge.
* \param flags Flags that will alter the behavior of the bridge
* \param creator Entity that created the bridge (optional)
* \param name Name given to the bridge by its creator (optional, requires named creator)
+ * \param id Unique ID given to the bridge by its creator (optional)
*
* \retval self on success
* \retval NULL on failure, self is already destroyed
* \code
* struct ast_bridge *bridge;
* bridge = bridge_alloc(sizeof(*bridge), &ast_bridge_base_v_table);
- * bridge = bridge_base_init(bridge, AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_FLAG_DISSOLVE_HANGUP, NULL, NULL);
+ * bridge = bridge_base_init(bridge, AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_FLAG_DISSOLVE_HANGUP, NULL, NULL, NULL);
* \endcode
*
* This creates a no frills two party bridge that will be
* destroyed once one of the channels hangs up.
*/
-struct ast_bridge *bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags, const char *creator, const char *name);
+struct ast_bridge *bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id);
/*!
* \internal
const char *value;
} ast_chan_write_info_t;
+/*!
+ * \brief Structure to pass both assignedid values to channel drivers
+ * \note The second value is used only by core_unreal (LOCAL)
+ */
+struct ast_assigned_ids {
+ const char *uniqueid;
+ const char *uniqueid2;
+};
+
/*!
* \brief
* Structure to describe a channel "technology", ie a channel driver
*
* \param type type of channel to request
* \param cap Format capabilities for requested channel
+ * \param assignedid Unique ID string to assign to channel
* \param requestor channel asking for data
* \param addr destination of the call
* \param cause Cause of failure
* \retval NULL failure
* \retval non-NULL channel on success
*/
- struct ast_channel *(* const requester)(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *addr, int *cause);
+ struct ast_channel *(* const requester)(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int *cause);
int (* const devicestate)(const char *device_number); /*!< Devicestate call back */
* and "default" context.
* \note Since 12.0.0 this function returns with the newly created channel locked.
*/
-struct ast_channel * attribute_malloc __attribute__((format(printf, 13, 14)))
+struct ast_channel * attribute_malloc __attribute__((format(printf, 14, 15)))
__ast_channel_alloc(int needqueue, int state, const char *cid_num,
const char *cid_name, const char *acctcode,
- const char *exten, const char *context,
- const char *linkedid, enum ama_flags amaflag,
+ const char *exten, const char *context, const struct ast_assigned_ids *assignedids,
+ const struct ast_channel *requestor, enum ama_flags amaflag,
const char *file, int line, const char *function,
const char *name_fmt, ...);
* and "default" context.
* \note Since 12.0.0 this function returns with the newly created channel locked.
*/
-#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, linkedid, amaflag, ...) \
- __ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, linkedid, amaflag, \
+#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag, ...) \
+ __ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag, \
__FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)
#if defined(REF_DEBUG) || defined(__AST_DEBUG_MALLOC)
*
* \param type type of channel to request
* \param request_cap Format capabilities for requested channel
+ * \param assignedids Unique ID to create channel with
* \param requestor channel asking for data
* \param addr destination of the call
* \param cause Cause of failure
* \retval NULL failure
* \retval non-NULL channel on success
*/
-struct ast_channel *ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_channel *requestor, const char *addr, int *cause);
+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);
/*!
* \brief Request a channel of a given type, with data as optional information used
*
* \param type type of channel to request
* \param cap format capabilities for requested channel
+ * \param assignedids Unique Id to assign to channel
* \param requestor channel asking for data
* \param addr destination of the call
* \param timeout maximum amount of time to wait for an answer
* \return Returns an ast_channel on success or no answer, NULL on failure. Check the value of chan->_state
* to know if the call was answered or not.
*/
-struct ast_channel *ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *addr,
+struct ast_channel *ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr,
int timeout, int *reason, const char *cid_num, const char *cid_name);
/*!
* by the low level module and attempt to place a call on it
* \param type type of channel to request
* \param cap format capabilities for requested channel
+ * \param assignedids Unique Id to assign to channel
* \param requestor channel requesting data
* \param addr destination of the call
* \param timeout maximum amount of time to wait for an answer
* \return Returns an ast_channel on success or no answer, NULL on failure. Check the value of chan->_state
* to know if the call was answered or not.
*/
-struct ast_channel *__ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *addr,
+struct ast_channel *__ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr,
int timeout, int *reason, const char *cid_num, const char *cid_name, struct outgoing_helper *oh);
/*!
*/
int ast_internal_timing_enabled(struct ast_channel *chan);
+/*!
+ * \brief Determine which channel has an older linkedid
+ * \param a First channel
+ * \param b Second channel
+ * \return Returns an ast_channel structure that has oldest linkedid
+ */
+struct ast_channel *ast_channel_internal_oldest_linkedid(struct ast_channel *a, struct ast_channel *b);
+
+/*!
+ * \brief Copy the full linkedid channel id structure from one channel to another
+ * \param dest Destination to copy linkedid to
+ * \param source Source channel to copy linkedid from
+ * \return void
+ */
+void ast_channel_internal_copy_linkedid(struct ast_channel *dest, struct ast_channel *source);
+
+/*!
+ * \brief Swap uniqueid and linkedid beteween two channels
+ * \param a First channel
+ * \param b Second channel
+ * \return void
+ *
+ * \note
+ * This is used in masquerade to exchange identities
+ */
+void ast_channel_internal_swap_uniqueid_and_linkedid(struct ast_channel *a, struct ast_channel *b);
+
+/*!
+ * \brief Set uniqueid and linkedid string value only (not time)
+ * \param chan The channel to set the uniqueid to
+ * \param uniqueid The uniqueid to set
+ * \param linkedid The linkedid to set
+ * \return void
+ *
+ * \note
+ * This is used only by ast_cel_fabricate_channel_from_event()
+ * to create a temporary fake channel - time values are invalid
+ */
+void ast_channel_internal_set_fake_ids(struct ast_channel *chan, const char *uniqueid, const char *linkedid);
+
/* Misc. functions below */
/*!
* \brief Internal channel functions for channel.c to use
*/
-#define ast_channel_internal_alloc(destructor, linkedid) __ast_channel_internal_alloc(destructor, linkedid, __FILE__, __LINE__, __PRETTY_FUNCTION__)
-struct ast_channel *__ast_channel_internal_alloc(void (*destructor)(void *obj), const char *linkedid, const char *file, int line, const char *function);
+#define ast_channel_internal_alloc(destructor, assignedid, requestor) __ast_channel_internal_alloc(destructor, assignedid, requestor, __FILE__, __LINE__, __PRETTY_FUNCTION__)
+struct ast_channel *__ast_channel_internal_alloc(void (*destructor)(void *obj), const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *file, int line, const char *function);
void ast_channel_internal_finalize(struct ast_channel *chan);
int ast_channel_internal_is_finalized(struct ast_channel *chan);
void ast_channel_internal_cleanup(struct ast_channel *chan);
*/
struct ast_channel *ast_unreal_new_channels(struct ast_unreal_pvt *p,
const struct ast_channel_tech *tech, int semi1_state, int semi2_state,
- const char *exten, const char *context, const struct ast_channel *requestor,
- struct ast_callid *callid);
+ const char *exten, const char *context, const struct ast_assigned_ids *assignedids,
+ const struct ast_channel *requestor, struct ast_callid *callid);
/*!
* \brief Setup unreal owner and chan channels before initiating call.
* \note Appends a channel to a dialing structure
* \return Returns channel reference number on success, -1 on failure
*/
-int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device);
+int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids);
/*! \brief Request all appended channels, but do not dial
* \param dial Dialing structure
* \param locked_channel Optional. The outbound channel that was created. This is returned
* both locked and reference bumped. If a caller provides a channel parameter, it must
* unlock the channel and decrement the reference count.
+ * \param assignedid Optional. The uniqueid to assign the channel that was created.
+ * \param assignedid2 Optional. The uniqueid to assign the second local channel.
* \param early_media If non-zero, allow early-media on the originated channel
*/
int ast_pbx_outgoing_exten(const char *type, struct ast_format_cap *cap, const char *addr,
int timeout, const char *context, const char *exten, int priority, int *reason,
int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars,
- const char *account, struct ast_channel **locked_channel, int early_media);
+ const char *account, struct ast_channel **locked_channel, int early_media,
+ const struct ast_assigned_ids *assignedids);
/*! \brief Synchronously or asynchronously make an outbound call and execute an
* application on the channel.
* \param vars Variables to set on the outbound channel
* \param account The accountcode for the outbound channel
* \param locked_channel Optional. The outbound channel that was created. This is returned
+ * \param assignedid Optional. The uniqueid to assign the channel that was created.
+ * \param assignedid2 Optional. The uniqueid to assign the second local channel.
* both locked and reference bumped. If a caller provides a channel parameter, it must
* unlock the channel and decrement the reference count.
*/
int ast_pbx_outgoing_app(const char *type, struct ast_format_cap *cap, const char *addr,
int timeout, const char *app, const char *appdata, int *reason, int sync,
const char *cid_num, const char *cid_name, struct ast_variable *vars,
- const char *account, struct ast_channel **locked_channel);
+ const char *account, struct ast_channel **locked_channel,
+ const struct ast_assigned_ids *assignedids);
/*!
* \brief Evaluate a condition
*
* \param type The type of bridge to be created
* \param name Optional name to give to the bridge
+ * \param id Optional Unique ID to give to the bridge
*
* \return New bridge.
* \return \c NULL on error.
*/
-struct ast_bridge *stasis_app_bridge_create(const char *type, const char *name);
+struct ast_bridge *stasis_app_bridge_create(const char *type, const char *name, const char *id);
/*!
* \brief Returns the bridge with the given id.
* \param target_type What the target type is
* \param skipms Number of milliseconds to skip for forward/reverse operations.
* \param offsetms Number of milliseconds to skip before playing.
+ * \param id ID to assign the new playback or NULL for default.
* \return Playback control object.
* \return \c NULL on error.
*/
struct stasis_app_control *control, const char *file,
const char *language, const char *target_id,
enum stasis_app_playback_target_type target_type,
- int skipms, long offsetms);
+ int skipms, long offsetms, const char *id);
/*!
* \brief Gets the current state of a playback operation.
*/
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 *app, const char *app_args, const char *snoop_id);
#endif /* _ASTERISK_STASIS_APP_SNOOP_H */
return bridge;
}
-struct ast_bridge *bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags, const char *creator, const char *name)
+struct ast_bridge *bridge_base_init(struct ast_bridge *self, uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
{
char uuid_hold[AST_UUID_STR_LEN];
return NULL;
}
- ast_uuid_generate_str(uuid_hold, AST_UUID_STR_LEN);
- ast_string_field_set(self, uniqueid, uuid_hold);
+ if (!ast_strlen_zero(id)) {
+ ast_string_field_set(self, uniqueid, id);
+ } else {
+ ast_uuid_generate_str(uuid_hold, AST_UUID_STR_LEN);
+ ast_string_field_set(self, uniqueid, uuid_hold);
+ }
ast_string_field_set(self, creator, creator);
if (!ast_strlen_zero(creator)) {
ast_string_field_set(self, name, name);
.get_merge_priority = bridge_base_get_merge_priority,
};
-struct ast_bridge *ast_bridge_base_new(uint32_t capabilities, unsigned int flags, const char *creator, const char *name)
+struct ast_bridge *ast_bridge_base_new(uint32_t capabilities, unsigned int flags, const char *creator, const char *name, const char *id)
{
void *bridge;
bridge = bridge_alloc(sizeof(struct ast_bridge), &ast_bridge_base_v_table);
- bridge = bridge_base_init(bridge, capabilities, flags, creator, name);
+ bridge = bridge_base_init(bridge, capabilities, flags, creator, name, id);
bridge = bridge_register(bridge);
return bridge;
}
int cause;
snprintf(chan_name, sizeof(chan_name), "%s@%s", exten, context);
- local = ast_request("Local", ast_channel_nativeformats(transferer), transferer,
+ local = ast_request("Local", ast_channel_nativeformats(transferer), NULL, transferer,
chan_name, &cause);
if (!local) {
return AST_BRIDGE_TRANSFER_FAIL;
int res;
const char *app = NULL;
- local_chan = ast_request("Local", ast_channel_nativeformats(chan1), chan1,
+ local_chan = ast_request("Local", ast_channel_nativeformats(chan1), NULL, chan1,
dest, &cause);
if (!local_chan) {
return -1;
}
- if (ast_dial_append(props->dial, props->transferer_type, props->transferer_addr)) {
+ if (ast_dial_append(props->dial, props->transferer_type, props->transferer_addr, NULL)) {
return -1;
}
ast_format_cap_add(cap, ast_format_set(&fmt, AST_FORMAT_SLINEAR, 0));
/* Get a channel that is the destination we wish to call */
- props->recall_target = ast_request("Local", cap, NULL, destination, &cause);
+ props->recall_target = ast_request("Local", cap, NULL, NULL, destination, &cause);
if (!props->recall_target) {
ast_log(LOG_ERROR, "Unable to request outbound channel for recall target\n");
return -1;
int cause;
/* Now we request a local channel to prepare to call the destination */
- chan = ast_request("Local", ast_channel_nativeformats(caller), caller, destination,
+ chan = ast_request("Local", ast_channel_nativeformats(caller), NULL, caller, destination,
&cause);
if (!chan) {
return NULL;
bridge = bridge_alloc(sizeof(struct ast_bridge), &ast_bridge_basic_v_table);
bridge = bridge_base_init(bridge,
AST_BRIDGE_CAPABILITY_NATIVE | AST_BRIDGE_CAPABILITY_1TO1MIX
- | AST_BRIDGE_CAPABILITY_MULTIMIX, NORMAL_FLAGS, NULL, NULL);
+ | AST_BRIDGE_CAPABILITY_MULTIMIX, NORMAL_FLAGS, NULL, NULL, NULL);
bridge = bridge_basic_personality_alloc(bridge);
bridge = bridge_register(bridge);
return bridge;
{
struct ast_bridge_channel *other = NULL;
struct ast_bridge *bridge = bridge_channel->bridge;
- const char *oldest_linkedid = ast_channel_linkedid(bridge_channel->chan);
+ struct ast_channel *oldest_linkedid_chan = bridge_channel->chan;
AST_LIST_TRAVERSE(&bridge->channels, other, entry) {
if (other == swap) {
continue;
}
- oldest_linkedid = ast_channel_oldest_linkedid(oldest_linkedid, ast_channel_linkedid(other->chan));
- }
-
- if (ast_strlen_zero(oldest_linkedid)) {
- return;
+ oldest_linkedid_chan = ast_channel_internal_oldest_linkedid(
+ oldest_linkedid_chan, other->chan);
}
ast_channel_lock(bridge_channel->chan);
- ast_channel_linkedid_set(bridge_channel->chan, oldest_linkedid);
+ ast_channel_internal_copy_linkedid(bridge_channel->chan,
+ oldest_linkedid_chan);
ast_channel_unlock(bridge_channel->chan);
AST_LIST_TRAVERSE(&bridge->channels, other, entry) {
if (other == swap) {
continue;
}
ast_channel_lock(other->chan);
- ast_channel_linkedid_set(other->chan, oldest_linkedid);
+ ast_channel_internal_copy_linkedid(other->chan,
+ oldest_linkedid_chan);
ast_channel_unlock(other->chan);
}
}
}
ast_format_cap_add(tmp_cap, ast_format_set(&tmp_fmt, AST_FORMAT_SLINEAR, 0));
- if (!(chan = ast_request_and_dial(tech, tmp_cap, NULL, target, recall_timer, &reason, generic_pvt->cid_num, generic_pvt->cid_name))) {
+ if (!(chan = ast_request_and_dial(tech, tmp_cap, NULL, NULL, target, recall_timer, &reason, generic_pvt->cid_num, generic_pvt->cid_name))) {
/* Hmm, no channel. Sucks for you, bud.
*/
ast_log_dynamic_level(cc_logger_level, "Core %d: Failed to call back %s for reason %d\n",
ast_channel_exten_set(tchan, record.extension);
ast_channel_context_set(tchan, record.context);
ast_channel_name_set(tchan, record.channel_name);
- ast_channel_uniqueid_set(tchan, record.unique_id);
- ast_channel_linkedid_set(tchan, record.linked_id);
+ ast_channel_internal_set_fake_ids(tchan, record.unique_id, record.linked_id);
ast_channel_accountcode_set(tchan, record.account_code);
ast_channel_peeraccount_set(tchan, record.peer_account);
ast_channel_userfield_set(tchan, record.user_field);
/*! \brief Create a new channel structure */
static struct ast_channel * attribute_malloc __attribute__((format(printf, 13, 0)))
__ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char *cid_name,
- const char *acctcode, const char *exten, const char *context,
- const char *linkedid, enum ama_flags amaflag, const char *file, int line,
+ const char *acctcode, const char *exten, const char *context, const struct ast_assigned_ids *assignedids,
+ const struct ast_channel *requestor, enum ama_flags amaflag, const char *file, int line,
const char *function, const char *name_fmt, va_list ap)
{
struct ast_channel *tmp;
return NULL;
}
- if (!(tmp = ast_channel_internal_alloc(ast_channel_destructor, linkedid))) {
+ if (!(tmp = ast_channel_internal_alloc(ast_channel_destructor, assignedids, requestor))) {
/* Channel structure allocation failure. */
return NULL;
}
struct ast_channel *__ast_channel_alloc(int needqueue, int state, const char *cid_num,
const char *cid_name, const char *acctcode,
- const char *exten, const char *context,
- const char *linkedid, enum ama_flags amaflag,
+ const char *exten, const char *context, const struct ast_assigned_ids *assignedids,
+ const struct ast_channel *requestor, enum ama_flags amaflag,
const char *file, int line, const char *function,
const char *name_fmt, ...)
{
va_start(ap, name_fmt);
result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
- linkedid, amaflag, file, line, function, name_fmt, ap);
+ assignedids, requestor, amaflag, file, line, function, name_fmt, ap);
va_end(ap);
return result;
struct ast_channel *tmp;
struct varshead *headp;
- if (!(tmp = ast_channel_internal_alloc(ast_dummy_channel_destructor, NULL))) {
+ if (!(tmp = ast_channel_internal_alloc(ast_dummy_channel_destructor, NULL, NULL))) {
/* Dummy channel structure allocation failure. */
return NULL;
}
data = tmpchan;
type = "Local";
}
- if (!(new_chan = ast_request(type, cap, orig, data, &cause))) {
+ if (!(new_chan = ast_request(type, cap, NULL, orig, data, &cause))) {
ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause);
handle_cause(cause, outstate);
ast_hangup(orig);
return new_chan;
}
-struct ast_channel *__ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *addr, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
+struct ast_channel *__ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
{
int dummy_outstate;
int cause = 0;
else
outstate = &dummy_outstate; /* make outstate always a valid pointer */
- chan = ast_request(type, cap, requestor, addr, &cause);
+ chan = ast_request(type, cap, assignedids, requestor, addr, &cause);
if (!chan) {
ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, addr);
handle_cause(cause, outstate);
return chan;
}
-struct ast_channel *ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *addr, int timeout, int *outstate, const char *cidnum, const char *cidname)
+struct ast_channel *ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *addr, int timeout, int *outstate, const char *cidnum, const char *cidname)
{
- return __ast_request_and_dial(type, cap, requestor, addr, timeout, outstate, cidnum, cidname, NULL);
+ return __ast_request_and_dial(type, cap, assignedids, requestor, addr, timeout, outstate, cidnum, cidname, NULL);
}
static int set_security_requirements(const struct ast_channel *requestor, struct ast_channel *out)
return 0;
}
-struct ast_channel *ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_channel *requestor, const char *addr, int *cause)
+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)
{
struct chanlist *chan;
struct ast_channel *c;
ast_format_cap_remove_bytype(joint_cap, AST_FORMAT_TYPE_AUDIO);
ast_format_cap_add(joint_cap, &best_audio_fmt);
- if (!(c = chan->tech->requester(type, joint_cap, requestor, addr, cause))) {
+ if (!(c = chan->tech->requester(type, joint_cap, assignedids, requestor, addr, cause))) {
ast_format_cap_destroy(joint_cap);
return NULL;
}
}
}
-const char *ast_channel_oldest_linkedid(const char *a, const char *b)
-{
- const char *satime, *saseq;
- const char *sbtime, *sbseq;
- const char *dash;
- unsigned int atime, aseq, btime, bseq;
-
- if (ast_strlen_zero(a)) {
- return b;
- }
-
- if (ast_strlen_zero(b)) {
- return a;
- }
-
- satime = a;
- sbtime = b;
-
- /* jump over the system name */
- if ((dash = strrchr(satime, '-'))) {
- satime = dash+1;
- }
- if ((dash = strrchr(sbtime, '-'))) {
- sbtime = dash+1;
- }
-
- /* the sequence comes after the '.' */
- saseq = strchr(satime, '.');
- sbseq = strchr(sbtime, '.');
- if (!saseq || !sbseq) {
- return NULL;
- }
- saseq++;
- sbseq++;
-
- /* convert it all to integers */
- atime = atoi(satime); /* note that atoi is ignoring the '.' after the time string */
- btime = atoi(sbtime); /* note that atoi is ignoring the '.' after the time string */
- aseq = atoi(saseq);
- bseq = atoi(sbseq);
-
- /* and finally compare */
- if (atime == btime) {
- return (aseq < bseq) ? a : b;
- }
- else {
- return (atime < btime) ? a : b;
- }
-}
void ast_channel_name_to_dial_string(char *channel_name)
{
struct ast_format wformat;
struct ast_format tmp_format;
char tmp_name[AST_CHANNEL_NAME];
- const char *tmp_id;
char clone_sending_dtmf_digit;
struct timeval clone_sending_dtmf_tv;
/* Swap uniqueid's of the channels. This needs to happen before channel renames,
* so rename events get the proper id's.
*/
- tmp_id = ast_strdupa(ast_channel_uniqueid(clonechan));
- ast_channel_uniqueid_set(clonechan, ast_channel_uniqueid(original));
- ast_channel_uniqueid_set(original, tmp_id);
+ ast_channel_internal_swap_uniqueid_and_linkedid(clonechan, original);
/* Swap channel names. This uses ast_channel_name_set directly, so we
* don't get any spurious rename events.
char *accountcode;
char *exten;
char *context;
- char *linkedid;
char *name;
int amaflags;
struct ast_format readformat;
my_vars.accountcode = ast_strdupa(ast_channel_accountcode(yankee));
my_vars.exten = ast_strdupa(ast_channel_exten(yankee));
my_vars.context = ast_strdupa(ast_channel_context(yankee));
- my_vars.linkedid = ast_strdupa(ast_channel_linkedid(yankee));
my_vars.name = ast_strdupa(ast_channel_name(yankee));
my_vars.amaflags = ast_channel_amaflags(yankee);
ast_format_copy(&my_vars.writeformat, ast_channel_writeformat(yankee));
/* Do not hold any channel locks while calling channel_alloc() since the function
* locks the channel container when linking the new channel in. */
if (!(yanked_chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, my_vars.accountcode,
- my_vars.exten, my_vars.context, my_vars.linkedid, my_vars.amaflags,
+ my_vars.exten, my_vars.context, NULL, yankee, my_vars.amaflags,
"Surrogate/%s", my_vars.name))) {
return NULL;
}
#include "asterisk/stringfields.h"
#include "asterisk/test.h"
+/*!
+ * \brief Channel UniqueId structure
+ * \note channel creation time used for determining LinkedId Propagation
+ */
+struct ast_channel_id {
+ time_t creation_time; /*!< Creation time */
+ int creation_unique; /*!< sub-second unique value */
+ char unique_id[AST_MAX_UNIQUEID]; /*< Unique Identifier */
+};
+
/*!
* \brief Main Channel structure associated with a channel.
*
AST_STRING_FIELD(peeraccount); /*!< Peer account code for billing */
AST_STRING_FIELD(userfield); /*!< Userfield for CEL billing */
AST_STRING_FIELD(call_forward); /*!< Where to forward to if asked to dial on this interface */
- AST_STRING_FIELD(uniqueid); /*!< Unique Channel Identifier */
- AST_STRING_FIELD(linkedid); /*!< Linked Channel Identifier -- gets propagated by linkage */
AST_STRING_FIELD(parkinglot); /*! Default parking lot, if empty, default parking lot */
AST_STRING_FIELD(hangupsource); /*! Who is responsible for hanging up this channel */
AST_STRING_FIELD(dialcontext); /*!< Dial: Extension context that we were called from */
);
+ struct ast_channel_id uniqueid; /*!< Unique Channel Identifier - can be specified on creation */
+ struct ast_channel_id linkedid; /*!< Linked Channel Identifier - oldest propagated when bridged */
+
struct timeval whentohangup; /*!< Non-zero, set to actual time when channel is to be hung up */
pthread_t blocker; /*!< If anyone is blocking, this is them */
MEMBER(ast_channel, peeraccount, AST_DATA_STRING) \
MEMBER(ast_channel, userfield, AST_DATA_STRING) \
MEMBER(ast_channel, call_forward, AST_DATA_STRING) \
- MEMBER(ast_channel, uniqueid, AST_DATA_STRING) \
- MEMBER(ast_channel, linkedid, AST_DATA_STRING) \
MEMBER(ast_channel, parkinglot, AST_DATA_STRING) \
MEMBER(ast_channel, hangupsource, AST_DATA_STRING) \
MEMBER(ast_channel, dialcontext, AST_DATA_STRING) \
}
}
+ ast_data_add_str(tree, "uniqueid", ast_channel_uniqueid(chan));
+ ast_data_add_str(tree, "linkedid", ast_channel_linkedid(chan));
+
ast_data_add_codec(tree, "oldwriteformat", ast_channel_oldwriteformat(chan));
ast_data_add_codec(tree, "readformat", ast_channel_readformat(chan));
ast_data_add_codec(tree, "writeformat", ast_channel_writeformat(chan));
DEFINE_STRINGFIELD_SETTERS_FOR(peeraccount, 1, 0);
DEFINE_STRINGFIELD_SETTERS_FOR(userfield, 0, 0);
DEFINE_STRINGFIELD_SETTERS_FOR(call_forward, 0, 0);
-DEFINE_STRINGFIELD_SETTERS_FOR(uniqueid, 0, 1);
-DEFINE_STRINGFIELD_SETTERS_FOR(linkedid, 1, 1);
DEFINE_STRINGFIELD_SETTERS_FOR(parkinglot, 0, 0);
DEFINE_STRINGFIELD_SETTERS_FOR(hangupsource, 0, 0);
DEFINE_STRINGFIELD_SETTERS_FOR(dialcontext, 0, 0);
DEFINE_STRINGFIELD_GETTER_FOR(peeraccount);
DEFINE_STRINGFIELD_GETTER_FOR(userfield);
DEFINE_STRINGFIELD_GETTER_FOR(call_forward);
-DEFINE_STRINGFIELD_GETTER_FOR(uniqueid);
-DEFINE_STRINGFIELD_GETTER_FOR(linkedid);
DEFINE_STRINGFIELD_GETTER_FOR(parkinglot);
DEFINE_STRINGFIELD_GETTER_FOR(hangupsource);
DEFINE_STRINGFIELD_GETTER_FOR(dialcontext);
+const char *ast_channel_uniqueid(const struct ast_channel *chan)
+{
+ ast_assert(chan->uniqueid.unique_id[0] != '\0');
+ return chan->uniqueid.unique_id;
+}
+
+const char *ast_channel_linkedid(const struct ast_channel *chan)
+{
+ ast_assert(chan->linkedid.unique_id[0] != '\0');
+ return chan->linkedid.unique_id;
+}
+
const char *ast_channel_appl(const struct ast_channel *chan)
{
return chan->appl;
#define DIALED_CAUSES_BUCKETS 37
-struct ast_channel *__ast_channel_internal_alloc(void (*destructor)(void *obj), const char *linkedid, const char *file, int line, const char *function)
+struct ast_channel *__ast_channel_internal_alloc(void (*destructor)(void *obj), const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *file, int line, const char *function)
{
struct ast_channel *tmp;
#if defined(REF_DEBUG)
return ast_channel_unref(tmp);
}
- if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
- ast_channel_uniqueid_build(tmp, "%li.%d", (long)time(NULL),
- ast_atomic_fetchadd_int(&uniqueint, 1));
+ /* set the creation time in the uniqueid */
+ tmp->uniqueid.creation_time = time(NULL);
+ tmp->uniqueid.creation_unique = ast_atomic_fetchadd_int(&uniqueint, 1);
+
+ /* use provided id or default to historical {system-}time.# format */
+ if (assignedids && !ast_strlen_zero(assignedids->uniqueid)) {
+ ast_copy_string(tmp->uniqueid.unique_id, assignedids->uniqueid, sizeof(tmp->uniqueid.unique_id));
+ } else if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
+ snprintf(tmp->uniqueid.unique_id, sizeof(tmp->uniqueid.unique_id), "%li.%d",
+ (long)(tmp->uniqueid.creation_time),
+ tmp->uniqueid.creation_unique);
} else {
- ast_channel_uniqueid_build(tmp, "%s-%li.%d", ast_config_AST_SYSTEM_NAME,
- (long)time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1));
+ snprintf(tmp->uniqueid.unique_id, sizeof(tmp->uniqueid.unique_id), "%s-%li.%d",
+ ast_config_AST_SYSTEM_NAME,
+ (long)(tmp->uniqueid.creation_time),
+ tmp->uniqueid.creation_unique);
}
- if (!ast_strlen_zero(linkedid)) {
- ast_string_field_set(tmp, linkedid, linkedid);
+ /* copy linked id from parent channel if known */
+ if (requestor) {
+ tmp->linkedid = requestor->linkedid;
} else {
- ast_string_field_set(tmp, linkedid, tmp->uniqueid);
+ tmp->linkedid = tmp->uniqueid;
}
return tmp;
}
+struct ast_channel *ast_channel_internal_oldest_linkedid(struct ast_channel *a, struct ast_channel *b)
+{
+ ast_assert(a->linkedid.creation_time != 0);
+ ast_assert(b->linkedid.creation_time != 0);
+
+ if (a->linkedid.creation_time < b->linkedid.creation_time) {
+ return a;
+ }
+ if (b->linkedid.creation_time < a->linkedid.creation_time) {
+ return b;
+ }
+ if (a->linkedid.creation_unique < b->linkedid.creation_unique) {
+ return a;
+ }
+ return b;
+}
+
+void ast_channel_internal_copy_linkedid(struct ast_channel *dest, struct ast_channel *source)
+{
+ dest->linkedid = source->linkedid;
+}
+
+void ast_channel_internal_swap_uniqueid_and_linkedid(struct ast_channel *a, struct ast_channel *b)
+{
+ struct ast_channel_id temp;
+
+ temp = a->uniqueid;
+ a->uniqueid = b->uniqueid;
+ b->uniqueid = temp;
+
+ temp = a->linkedid;
+ a->linkedid = b->linkedid;
+ b->linkedid = temp;
+}
+
+void ast_channel_internal_set_fake_ids(struct ast_channel *chan, const char *uniqueid, const char *linkedid)
+{
+ strncpy(chan->uniqueid.unique_id, uniqueid, sizeof(chan->uniqueid.unique_id));
+ strncpy(chan->linkedid.unique_id, linkedid, sizeof(chan->linkedid.unique_id));
+}
+
void ast_channel_internal_cleanup(struct ast_channel *chan)
{
if (chan->dialed_causes) {
int ast_channel_internal_setup_topics(struct ast_channel *chan)
{
- const char *topic_name = chan->uniqueid;
+ const char *topic_name = chan->uniqueid.unique_id;
ast_assert(chan->topics == NULL);
if (ast_strlen_zero(topic_name)) {
static struct ao2_container *locals;
-static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause);
+static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);
static int local_call(struct ast_channel *ast, const char *dest, int timeout);
static int local_hangup(struct ast_channel *ast);
static int local_devicestate(const char *data);
}
/*! \brief Part of PBX interface */
-static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, const char *data, int *cause)
+static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)
{
struct local_pvt *p;
struct ast_channel *chan;
}
callid = ast_read_threadstorage_callid();
chan = ast_unreal_new_channels(&p->base, &local_tech, AST_STATE_DOWN, AST_STATE_RING,
- p->exten, p->context, requestor, callid);
+ p->exten, p->context, assignedids, requestor, callid);
if (chan) {
ao2_link(locals, p);
}
struct ast_channel *ast_unreal_new_channels(struct ast_unreal_pvt *p,
const struct ast_channel_tech *tech, int semi1_state, int semi2_state,
- const char *exten, const char *context, const struct ast_channel *requestor,
- struct ast_callid *callid)
+ const char *exten, const char *context, const struct ast_assigned_ids *assignedids,
+ const struct ast_channel *requestor, struct ast_callid *callid)
{
struct ast_channel *owner;
struct ast_channel *chan;
- const char *linkedid = requestor ? ast_channel_linkedid(requestor) : NULL;
struct ast_format fmt;
+ struct ast_assigned_ids id1 = {NULL, NULL};
+ struct ast_assigned_ids id2 = {NULL, NULL};
int generated_seqno = ast_atomic_fetchadd_int((int *) &name_sequence, +1);
+ /* set unique ids for the two channels */
+ if (assignedids && !ast_strlen_zero(assignedids->uniqueid)) {
+ id1.uniqueid = assignedids->uniqueid;
+ id2.uniqueid = assignedids->uniqueid2;
+ }
+
+ /* if id1 given but not id2, use default of id1;2 */
+ if (id1.uniqueid && ast_strlen_zero(id2.uniqueid)) {
+ char *uniqueid2;
+ ast_asprintf(&uniqueid2, "%s;2", id1.uniqueid);
+ id2.uniqueid = uniqueid2;
+ }
+
/*
* Allocate two new Asterisk channels
*
* isn't set, then each channel will generate its own linkedid.
*/
if (!(owner = ast_channel_alloc(1, semi1_state, NULL, NULL, NULL,
- exten, context, linkedid, 0,
+ exten, context, &id1, requestor, 0,
"%s/%s-%08x;1", tech->type, p->name, generated_seqno))) {
ast_log(LOG_WARNING, "Unable to allocate owner channel structure\n");
return NULL;
ast_channel_unlock(owner);
if (!(chan = ast_channel_alloc(1, semi2_state, NULL, NULL, NULL,
- exten, context, ast_channel_linkedid(owner), 0,
+ exten, context, &id2, owner, 0,
"%s/%s-%08x;2", tech->type, p->name, generated_seqno))) {
ast_log(LOG_WARNING, "Unable to allocate chan channel structure\n");
ao2_ref(p, -1);
void *options[AST_DIAL_OPTION_MAX]; /*!< Channel specific options */
int cause; /*!< Cause code in case of failure */
unsigned int is_running_app:1; /*!< Is this running an application? */
+ char *assignedid1; /*!< UniqueID to assign channel */
+ char *assignedid2; /*!< UniqueID to assign 2nd channel */
struct ast_channel *owner; /*!< Asterisk channel */
AST_LIST_ENTRY(ast_dial_channel) list; /*!< Linked list information */
};
* \note Appends a channel to a dialing structure
* \return Returns channel reference number on success, -1 on failure
*/
-int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device)
+int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device, const struct ast_assigned_ids *assignedids)
{
struct ast_dial_channel *channel = NULL;
channel->tech = ast_strdup(tech);
channel->device = ast_strdup(device);
+ /* Store the assigned id */
+ if (assignedids && !ast_strlen_zero(assignedids->uniqueid))
+ {
+ channel->assignedid1 = ast_strdup(assignedids->uniqueid);
+
+ if (!ast_strlen_zero(assignedids->uniqueid2)) {
+ channel->assignedid2 = ast_strdup(assignedids->uniqueid2);
+ }
+ }
+
/* Grab reference number from dial structure */
channel->num = ast_atomic_fetchadd_int(&dial->num, +1);
char numsubst[AST_MAX_EXTENSION];
struct ast_format_cap *cap_all_audio = NULL;
struct ast_format_cap *cap_request;
+ struct ast_assigned_ids assignedids = {channel->assignedid1, channel->assignedid2};
/* Copy device string over */
ast_copy_string(numsubst, channel->device, sizeof(numsubst));
}
/* If we fail to create our owner channel bail out */
- if (!(channel->owner = ast_request(channel->tech, cap_request, chan, numsubst, &channel->cause))) {
+ if (!(channel->owner = ast_request(channel->tech, cap_request, &assignedids, chan, numsubst, &channel->cause))) {
cap_all_audio = ast_format_cap_destroy(cap_all_audio);
return -1;
}
/* Drop old destination information */
ast_free(channel->tech);
ast_free(channel->device);
+ if (channel->assignedid1) {
+ ast_free(channel->assignedid1);
+ channel->assignedid1 = NULL;
+ }
+ if (channel->assignedid2) {
+ ast_free(channel->assignedid2);
+ channel->assignedid2 = NULL;
+ }
/* Update the dial channel with the new destination information */
channel->tech = ast_strdup(tech);
/* Free structure */
ast_free(channel->tech);
ast_free(channel->device);
+ if (channel->assignedid1) {
+ ast_free(channel->assignedid1);
+ }
+ if (channel->assignedid2) {
+ ast_free(channel->assignedid2);
+ }
+
AST_LIST_REMOVE_CURRENT(list);
ast_free(channel);
}
<parameter name="Codecs">
<para>Comma-separated list of codecs to use for this call.</para>
</parameter>
+ <parameter name="ChannelId">
+ <para>Channel UniqueId to be set on the channel.</para>
+ </parameter>
+ <parameter name="OtherChannelId">
+ <para>Channel UniqueId to be set on the second local channel.</para>
+ </parameter>
</syntax>
<description>
<para>Generates an outgoing call to a
AST_STRING_FIELD(exten);
AST_STRING_FIELD(idtext);
AST_STRING_FIELD(account);
+ AST_STRING_FIELD(channelid);
+ AST_STRING_FIELD(otherchannelid);
);
int priority;
struct ast_variable *vars;
int reason = 0;
struct ast_channel *chan = NULL, *chans[1];
char requested_channel[AST_CHANNEL_NAME];
+ struct ast_assigned_ids assignedids = {in->channelid, in->otherchannelid};
if (!ast_strlen_zero(in->app)) {
res = ast_pbx_outgoing_app(in->tech, in->cap, in->data,
in->timeout, in->app, in->appdata, &reason, 1,
S_OR(in->cid_num, NULL),
S_OR(in->cid_name, NULL),
- in->vars, in->account, &chan);
+ in->vars, in->account, &chan, &assignedids);
} else {
res = ast_pbx_outgoing_exten(in->tech, in->cap, in->data,
in->timeout, in->context, in->exten, in->priority, &reason, 1,
S_OR(in->cid_num, NULL),
S_OR(in->cid_name, NULL),
- in->vars, in->account, &chan, in->early_media);
+ in->vars, in->account, &chan, in->early_media, &assignedids);
}
/* Any vars memory was passed to the ast_pbx_outgoing_xxx() calls. */
in->vars = NULL;
const char *id = astman_get_header(m, "ActionID");
const char *codecs = astman_get_header(m, "Codecs");
const char *early_media = astman_get_header(m, "Earlymedia");
+ struct ast_assigned_ids assignedids = {
+ astman_get_header(m, "ChannelId"),
+ astman_get_header(m, "OtherChannelId")
+ };
struct ast_variable *vars = NULL;
char *tech, *data;
char *l = NULL, *n = NULL;
pthread_t th;
int bridge_early = 0;
+ if (strlen(assignedids.uniqueid) >= AST_MAX_UNIQUEID ||
+ strlen(assignedids.uniqueid2) >= AST_MAX_UNIQUEID) {
+ ast_log(LOG_WARNING, "Uniqueid length exceeds maximum of %d\n", AST_MAX_UNIQUEID);
+ }
+
if (!cap) {
astman_send_error(s, m, "Internal Error. Memory allocation failure.");
return 0;
ast_string_field_set(fast, context, context);
ast_string_field_set(fast, exten, exten);
ast_string_field_set(fast, account, account);
+ ast_string_field_set(fast, channelid, assignedids.uniqueid);
+ ast_string_field_set(fast, otherchannelid, assignedids.uniqueid2);
fast->vars = vars;
fast->cap = cap;
cap = NULL; /* transfered originate helper the capabilities structure. It is now responsible for freeing it. */
}
}
} else if (!ast_strlen_zero(app)) {
- res = ast_pbx_outgoing_app(tech, cap, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL);
+ res = ast_pbx_outgoing_app(tech, cap, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL, assignedids.uniqueid ? &assignedids : NULL);
/* Any vars memory was passed to ast_pbx_outgoing_app(). */
} else {
if (exten && context && pi) {
- res = ast_pbx_outgoing_exten(tech, cap, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL, bridge_early);
+ res = ast_pbx_outgoing_exten(tech, cap, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL, bridge_early, assignedids.uniqueid ? &assignedids : NULL);
/* Any vars memory was passed to ast_pbx_outgoing_exten(). */
} else {
astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
chan = ast_channel_alloc(1, AST_STATE_UP,
NULL, NULL, NULL,
- NULL, NULL, NULL, 0,
+ NULL, NULL, NULL, NULL, 0,
"%s", "Message/ast_msg_queue");
if (!chan) {
static int pbx_outgoing_attempt(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *context,
const char *exten, int priority, const char *app, const char *appdata, int *reason, int synchronous, const char *cid_num,
- const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **channel, int early_media)
+ const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **channel, int early_media, const struct ast_assigned_ids *assignedids)
{
RAII_VAR(struct pbx_outgoing *, outgoing, ao2_alloc(sizeof(*outgoing), pbx_outgoing_destroy), ao2_cleanup);
struct ast_channel *dialed;
return -1;
}
- if (ast_dial_append(outgoing->dial, type, addr)) {
+ if (ast_dial_append(outgoing->dial, type, addr, assignedids)) {
return -1;
}
if ((synchronous > 1) && ast_dial_state(outgoing->dial) != AST_DIAL_RESULT_ANSWERED &&
ast_strlen_zero(app) && ast_exists_extension(NULL, context, "failed", 1, NULL)) {
- struct ast_channel *failed = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", NULL, 0, "OutgoingSpoolFailed");
+ struct ast_channel *failed = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", NULL, NULL, 0, "OutgoingSpoolFailed");
if (failed) {
char failed_reason[4] = "";
return 0;
}
-int ast_pbx_outgoing_exten(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *context, const char *exten, int priority, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **channel, int early_media)
+int ast_pbx_outgoing_exten(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *context, const char *exten, int priority, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **channel, int early_media, const struct ast_assigned_ids *assignedids)
{
return pbx_outgoing_attempt(type, cap, addr, timeout, context, exten, priority, NULL, NULL, reason, synchronous, cid_num,
- cid_name, vars, account, channel, early_media);
+ cid_name, vars, account, channel, early_media, assignedids);
}
-int ast_pbx_outgoing_app(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *app, const char *appdata, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
+int ast_pbx_outgoing_app(const char *type, struct ast_format_cap *cap, const char *addr, int timeout, const char *app, const char *appdata, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel, const struct ast_assigned_ids *assignedids)
{
if (ast_strlen_zero(app)) {
return -1;
}
return pbx_outgoing_attempt(type, cap, addr, timeout, NULL, NULL, 0, app, appdata, reason, synchronous, cid_num,
- cid_name, vars, account, locked_channel, 0);
+ cid_name, vars, account, locked_channel, 0, assignedids);
}
/* this is the guts of destroying a context --
ast_verb(3, "Attempting call on %s/%s for application %s(%s) (Retry %d)\n", o->tech, o->dest, o->app, o->data, o->retries);
res = ast_pbx_outgoing_app(o->tech, o->capabilities, o->dest, o->waittime * 1000,
o->app, o->data, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name,
- o->vars, o->account, NULL);
+ o->vars, o->account, NULL, NULL);
o->vars = NULL;
} else {
ast_verb(3, "Attempting call on %s/%s for %s@%s:%d (Retry %d)\n", o->tech, o->dest, o->exten, o->context,o->priority, o->retries);
res = ast_pbx_outgoing_exten(o->tech, o->capabilities, o->dest,
o->waittime * 1000, o->context, o->exten, o->priority, &reason,
2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, o->account, NULL,
- ast_test_flag(&o->options, SPOOL_FLAG_EARLY_MEDIA));
+ ast_test_flag(&o->options, SPOOL_FLAG_EARLY_MEDIA), NULL);
o->vars = NULL;
}
if (res) {
return NULL;
}
- return ast_request(type, cap, NULL, "ARI", NULL);
+ return ast_request(type, cap, NULL, NULL, "ARI", NULL);
}
void ast_ari_bridges_play(struct ast_variable *headers,
playback = stasis_app_control_play_uri(control, args->media, language,
args->bridge_id, STASIS_PLAYBACK_TARGET_BRIDGE, args->skipms,
- args->offsetms);
+ args->offsetms, NULL);
if (!playback) {
ast_ari_response_alloc_failed(response);
struct ast_ari_bridges_create_args *args,
struct ast_ari_response *response)
{
- RAII_VAR(struct ast_bridge *, bridge, stasis_app_bridge_create(args->type, args->name), ao2_cleanup);
+ RAII_VAR(struct ast_bridge *, bridge, stasis_app_bridge_create(args->type, args->name, args->bridge_id), ao2_cleanup);
RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
if (!bridge) {
ast_ari_response_ok(response,
ast_bridge_snapshot_to_json(snapshot, stasis_app_get_sanitizer()));
}
+
+void ast_ari_bridges_create_or_update_with_id(struct ast_variable *headers,
+ struct ast_ari_bridges_create_or_update_with_id_args *args,
+ struct ast_ari_response *response)
+{
+ RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args->bridge_id), ao2_cleanup);
+ RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
+
+ if (bridge) {
+ /* update */
+ if (strcmp(args->name, bridge->name)) {
+ ast_ari_response_error(
+ response, 500, "Internal Error",
+ "Changing bridge name is not implemented");
+ return;
+ }
+ if (!ast_strlen_zero(args->type)) {
+ ast_ari_response_error(
+ response, 500, "Internal Error",
+ "Changing bridge type is not implemented");
+ return;
+ }
+ ast_ari_response_ok(response,
+ ast_bridge_snapshot_to_json(snapshot, stasis_app_get_sanitizer()));
+ return;
+ }
+
+ bridge = stasis_app_bridge_create(args->type, args->name, args->bridge_id);
+ if (!bridge) {
+ ast_ari_response_error(
+ response, 500, "Internal Error",
+ "Unable to create bridge");
+ return;
+ }
+
+ snapshot = ast_bridge_snapshot_create(bridge);
+ if (!snapshot) {
+ ast_ari_response_error(
+ response, 500, "Internal Error",
+ "Unable to create snapshot for new bridge");
+ return;
+ }
+
+ ast_ari_response_ok(response,
+ ast_bridge_snapshot_to_json(snapshot, stasis_app_get_sanitizer()));
+}
struct ast_ari_bridges_create_args {
/*! \brief Type of bridge to create. */
const char *type;
+ /*! \brief Unique ID to give to the bridge being created. */
+ const char *bridge_id;
/*! \brief Name to give to the bridge being created. */
const char *name;
};
* \param[out] response HTTP response
*/
void ast_ari_bridges_create(struct ast_variable *headers, struct ast_ari_bridges_create_args *args, struct ast_ari_response *response);
+/*! \brief Argument struct for ast_ari_bridges_create_or_update_with_id() */
+struct ast_ari_bridges_create_or_update_with_id_args {
+ /*! \brief Set the type of bridge. */
+ const char *type;
+ /*! \brief Unique ID to give to the bridge being created. */
+ const char *bridge_id;
+ /*! \brief Set the name of the bridge. */
+ const char *name;
+};
+/*!
+ * \brief Body parsing function for /bridges/{bridgeId}.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_bridges_create_or_update_with_id_parse_body(
+ struct ast_json *body,
+ struct ast_ari_bridges_create_or_update_with_id_args *args);
+
+/*!
+ * \brief Create a new bridge or updates an existing one.
+ *
+ * This bridge persists until it has been shut down, or Asterisk has been shut down.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+void ast_ari_bridges_create_or_update_with_id(struct ast_variable *headers, struct ast_ari_bridges_create_or_update_with_id_args *args, struct ast_ari_response *response);
/*! \brief Argument struct for ast_ari_bridges_get() */
struct ast_ari_bridges_get_args {
/*! \brief Bridge's id */
ast_ari_response_no_content(response);
}
-void ast_ari_channels_play(struct ast_variable *headers,
- struct ast_ari_channels_play_args *args,
+static void ari_channels_handle_play(
+ const char *args_channel_id,
+ const char *args_media,
+ const char *args_lang,
+ int args_offsetms,
+ int args_skipms,
+ const char *args_playback_id,
struct ast_ari_response *response)
{
RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
ast_assert(response != NULL);
- control = find_control(response, args->channel_id);
+ control = find_control(response, args_channel_id);
if (control == NULL) {
/* Response filled in by find_control */
return;
return;
}
- if (args->skipms < 0) {
+ if (args_skipms < 0) {
ast_ari_response_error(
response, 400, "Bad Request",
"skipms cannot be negative");
return;
}
- if (args->offsetms < 0) {
+ if (args_offsetms < 0) {
ast_ari_response_error(
response, 400, "Bad Request",
"offsetms cannot be negative");
return;
}
- language = S_OR(args->lang, snapshot->language);
+ language = S_OR(args_lang, snapshot->language);
- playback = stasis_app_control_play_uri(control, args->media, language,
- args->channel_id, STASIS_PLAYBACK_TARGET_CHANNEL, args->skipms, args->offsetms);
+ playback = stasis_app_control_play_uri(control, args_media, language,
+ args_channel_id, STASIS_PLAYBACK_TARGET_CHANNEL, args_skipms, args_offsetms, args_playback_id);
if (!playback) {
ast_ari_response_error(
response, 500, "Internal Server Error",
ast_ari_response_created(response, playback_url, json);
}
+void ast_ari_channels_play(struct ast_variable *headers,
+ struct ast_ari_channels_play_args *args,
+ struct ast_ari_response *response)
+{
+ ari_channels_handle_play(
+ args->channel_id,
+ args->media,
+ args->lang,
+ args->offsetms,
+ args->skipms,
+ args->playback_id,
+ response);
+}
+
+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)
+{
+ ari_channels_handle_play(
+ args->channel_id,
+ args->media,
+ args->lang,
+ args->offsetms,
+ args->skipms,
+ args->playback_id,
+ response);
+}
+
void ast_ari_channels_record(struct ast_variable *headers,
struct ast_ari_channels_record_args *args,
struct ast_ari_response *response)
}
msg = stasis_cache_get(cache, ast_channel_snapshot_type(),
- args->channel_id);
+ args->channel_id);
if (!msg) {
ast_ari_response_error(
response, 404, "Not Found",
struct ast_variable *new_var;
new_var = ast_variable_new(ast_json_object_iter_key(it_json_var),
- ast_json_string_get(ast_json_object_iter_value(it_json_var)),
- "");
+ ast_json_string_get(ast_json_object_iter_value(it_json_var)),
+ "");
if (!new_var) {
ast_variables_destroy(*variables);
*variables = NULL;
return 0;
}
-void ast_ari_channels_originate(struct ast_variable *headers,
- struct ast_ari_channels_originate_args *args,
+static void ari_channels_handle_originate_with_id(const char *args_endpoint,
+ const char *args_extension,
+ const char *args_context,
+ long args_priority,
+ 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,
struct ast_ari_response *response)
{
char *dialtech;
RAII_VAR(struct ast_format_cap *, cap,
ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK), ast_format_cap_destroy);
struct ast_format tmp_fmt;
- RAII_VAR(struct ast_variable *, variables, NULL, ast_variables_destroy);
char *stuff;
struct ast_channel *chan;
RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
+ struct ast_assigned_ids assignedids = {args_channel_id, args_other_channel_id};
+
+ if (strlen(assignedids.uniqueid) >= AST_MAX_UNIQUEID ||
+ strlen(assignedids.uniqueid2) >= AST_MAX_UNIQUEID) {
+ ast_log(LOG_WARNING, "Uniqueid length exceeds maximum of %d\n", AST_MAX_UNIQUEID);
+ }
if (!cap) {
ast_ari_response_alloc_failed(response);
}
ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_SLINEAR, 0));
- /* Parse any query parameters out of the body parameter */
- if (args->variables) {
- struct ast_json *json_variables;
-
- ast_ari_channels_originate_parse_body(args->variables, args);
- json_variables = ast_json_object_get(args->variables, "variables");
- if (json_variables) {
- if (json_to_ast_variables(json_variables, &variables)) {
- ast_log(AST_LOG_ERROR, "Unable to convert 'variables' in JSON body to channel variables\n");
- ast_ari_response_alloc_failed(response);
- return;
- }
- }
- }
-
- if (ast_strlen_zero(args->endpoint)) {
+ if (ast_strlen_zero(args_endpoint)) {
ast_ari_response_error(response, 400, "Bad Request",
"Endpoint must be specified");
return;
}
- dialtech = ast_strdupa(args->endpoint);
+ dialtech = ast_strdupa(args_endpoint);
if ((stuff = strchr(dialtech, '/'))) {
*stuff++ = '\0';
ast_copy_string(dialdevice, stuff, sizeof(dialdevice));
return;
}
- if (args->timeout > 0) {
- timeout = args->timeout * 1000;
- } else if (args->timeout == -1) {
+ if (args_timeout > 0) {
+ timeout = args_timeout * 1000;
+ } else if (args_timeout == -1) {
timeout = -1;
}
- if (!ast_strlen_zero(args->caller_id)) {
- caller_id = ast_strdupa(args->caller_id);
+ if (!ast_strlen_zero(args_caller_id)) {
+ caller_id = ast_strdupa(args_caller_id);
ast_callerid_parse(caller_id, &cid_name, &cid_num);
if (ast_is_shrinkable_phonenumber(cid_num)) {
}
}
- if (!ast_strlen_zero(args->app)) {
+ if (!ast_strlen_zero(args_app)) {
const char *app = "Stasis";
RAII_VAR(struct ast_str *, appdata, ast_str_create(64), ast_free);
return;
}
- ast_str_set(&appdata, 0, "%s", args->app);
- if (!ast_strlen_zero(args->app_args)) {
- ast_str_append(&appdata, 0, ",%s", args->app_args);
+ ast_str_set(&appdata, 0, "%s", args_app);
+ if (!ast_strlen_zero(args_app_args)) {
+ ast_str_append(&appdata, 0, ",%s", args_app_args);
}
/* originate a channel, putting it into an application */
- if (ast_pbx_outgoing_app(dialtech, cap, dialdevice, timeout, app, ast_str_buffer(appdata), NULL, 0, cid_num, cid_name, variables, NULL, &chan)) {
+ if (ast_pbx_outgoing_app(dialtech, cap, dialdevice, timeout, app, ast_str_buffer(appdata), NULL, 0, cid_num, cid_name, variables, NULL, &chan, &assignedids)) {
ast_ari_response_alloc_failed(response);
return;
}
- } else if (!ast_strlen_zero(args->extension)) {
+ } else if (!ast_strlen_zero(args_extension)) {
/* originate a channel, sending it to an extension */
- if (ast_pbx_outgoing_exten(dialtech, cap, dialdevice, timeout, S_OR(args->context, "default"), args->extension, args->priority ? args->priority : 1, NULL, 0, cid_num, cid_name, variables, NULL, &chan, 0)) {
+ if (ast_pbx_outgoing_exten(dialtech, cap, dialdevice, timeout, S_OR(args_context, "default"), args_extension, args_priority ? args_priority : 1, NULL, 0, cid_num, cid_name, variables, NULL, &chan, 0, &assignedids)) {
ast_ari_response_alloc_failed(response);
return;
}
snapshot = ast_channel_snapshot_create(chan);
ast_channel_unlock(chan);
- if (!ast_strlen_zero(args->app)) {
+ if (!ast_strlen_zero(args_app)) {
/* channel: + channel ID + null terminator */
char uri[9 + strlen(ast_channel_uniqueid(chan))];
const char *uris[1] = { uri, };
sprintf(uri, "channel:%s", ast_channel_uniqueid(chan));
- stasis_app_subscribe(args->app, uris, 1, NULL);
+ stasis_app_subscribe(args_app, uris, 1, NULL);
}
ast_ari_response_ok(response, ast_channel_snapshot_to_json(snapshot, NULL));
ast_channel_unref(chan);
}
+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)
+{
+ RAII_VAR(struct ast_variable *, variables, NULL, ast_variables_destroy);
+
+ /* Parse any query parameters out of the body parameter */
+ if (args->variables) {
+ struct ast_json *json_variables;
+
+ ast_ari_channels_originate_with_id_parse_body(args->variables, args);
+ json_variables = ast_json_object_get(args->variables, "variables");
+ if (json_variables) {
+ if (json_to_ast_variables(json_variables, &variables)) {
+ ast_log(AST_LOG_ERROR, "Unable to convert 'variables' in JSON body to channel variables\n");
+ ast_ari_response_alloc_failed(response);
+ return;
+ }
+ }
+ }
+
+ ari_channels_handle_originate_with_id(
+ args->endpoint,
+ args->extension,
+ args->context,
+ args->priority,
+ args->app,
+ args->app_args,
+ args->caller_id,
+ args->timeout,
+ variables,
+ args->channel_id,
+ args->other_channel_id,
+ response);
+}
+
+void ast_ari_channels_originate(struct ast_variable *headers,
+ struct ast_ari_channels_originate_args *args,
+ struct ast_ari_response *response)
+{
+ RAII_VAR(struct ast_variable *, variables, NULL, ast_variables_destroy);
+
+ /* Parse any query parameters out of the body parameter */
+ if (args->variables) {
+ struct ast_json *json_variables;
+
+ ast_ari_channels_originate_parse_body(args->variables, args);
+ json_variables = ast_json_object_get(args->variables, "variables");
+ if (json_variables) {
+ if (json_to_ast_variables(json_variables, &variables)) {
+ ast_log(AST_LOG_ERROR, "Unable to convert 'variables' in JSON body to channel variables\n");
+ ast_ari_response_alloc_failed(response);
+ return;
+ }
+ }
+ }
+
+ ari_channels_handle_originate_with_id(
+ args->endpoint,
+ args->extension,
+ args->context,
+ args->priority,
+ args->app,
+ args->app_args,
+ args->caller_id,
+ args->timeout,
+ variables,
+ args->channel_id,
+ args->other_channel_id,
+ response);
+}
+
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)
ast_ari_response_no_content(response);
}
-void ast_ari_channels_snoop_channel(struct ast_variable *headers, struct ast_ari_channels_snoop_channel_args *args, 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)
{
enum stasis_app_snoop_direction spy, whisper;
RAII_VAR(struct ast_channel *, chan, NULL, ast_channel_cleanup);
ast_assert(response != NULL);
- if (ast_strlen_zero(args->spy) || !strcmp(args->spy, "none")) {
+ if (ast_strlen_zero(args_spy) || !strcmp(args_spy, "none")) {
spy = STASIS_SNOOP_DIRECTION_NONE;
- } else if (!strcmp(args->spy, "both")) {
+ } else if (!strcmp(args_spy, "both")) {
spy = STASIS_SNOOP_DIRECTION_BOTH;
- } else if (!strcmp(args->spy, "out")) {
+ } else if (!strcmp(args_spy, "out")) {
spy = STASIS_SNOOP_DIRECTION_OUT;
- } else if (!strcmp(args->spy, "in")) {
+ } else if (!strcmp(args_spy, "in")) {
spy = STASIS_SNOOP_DIRECTION_IN;
} else {
ast_ari_response_error(
return;
}
- if (ast_strlen_zero(args->whisper) || !strcmp(args->whisper, "none")) {
+ if (ast_strlen_zero(args_whisper) || !strcmp(args_whisper, "none")) {
whisper = STASIS_SNOOP_DIRECTION_NONE;
- } else if (!strcmp(args->whisper, "both")) {
+ } else if (!strcmp(args_whisper, "both")) {
whisper = STASIS_SNOOP_DIRECTION_BOTH;
- } else if (!strcmp(args->whisper, "out")) {
+ } else if (!strcmp(args_whisper, "out")) {
whisper = STASIS_SNOOP_DIRECTION_OUT;
- } else if (!strcmp(args->whisper, "in")) {
+ } else if (!strcmp(args_whisper, "in")) {
whisper = STASIS_SNOOP_DIRECTION_IN;
} else {
ast_ari_response_error(
response, 400, "Bad Request",
"Direction must be specified for at least spy or whisper");
return;
- } else if (ast_strlen_zero(args->app)) {
+ } else if (ast_strlen_zero(args_app)) {
ast_ari_response_error(
response, 400, "Bad Request",
"Application name is required");
return;
}
- chan = ast_channel_get_by_name(args->channel_id);
+ chan = ast_channel_get_by_name(args_channel_id);
if (chan == NULL) {
ast_ari_response_error(
response, 404, "Channel Not Found",
return;
}
- snoop = stasis_app_control_snoop(chan, spy, whisper, args->app, args->app_args);
+ snoop = stasis_app_control_snoop(chan, spy, whisper, args_app, args_app_args,
+ args_snoop_id);
if (snoop == NULL) {
ast_ari_response_error(
response, 500, "Internal error",
snapshot = ast_channel_snapshot_create(snoop);
ast_ari_response_ok(response, ast_channel_snapshot_to_json(snapshot, NULL));
}
+
+void ast_ari_channels_snoop_channel(struct ast_variable *headers,
+ struct ast_ari_channels_snoop_channel_args *args,
+ struct ast_ari_response *response)
+{
+ ari_channels_handle_snoop_channel(
+ args->channel_id,
+ args->spy,
+ args->whisper,
+ args->app,
+ args->app_args,
+ args->snoop_id,
+ response);
+}
+
+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)
+{
+ ari_channels_handle_snoop_channel(
+ args->channel_id,
+ args->spy,
+ args->whisper,
+ args->app,
+ args->app_args,
+ args->snoop_id,
+ response);
+}
int timeout;
/*! \brief The 'variables' key in the body object holds variable key/value pairs to set on the channel on creation. Other keys in the body object are interpreted as query parameters. Ex. { 'endpoint': 'SIP/Alice', 'variables': { 'CALLERID(name)': 'Alice' } } */
struct ast_json *variables;
+ /*! \brief The unique id to assign the channel on creation. */
+ const char *channel_id;
+ /*! \brief The unique id to assign the second channel when using local channels. */
+ const char *other_channel_id;
};
/*!
* \brief Body parsing function for /channels.
* \param[out] response HTTP response
*/
void ast_ari_channels_get(struct ast_variable *headers, struct ast_ari_channels_get_args *args, struct ast_ari_response *response);
+/*! \brief Argument struct for ast_ari_channels_originate_with_id() */
+struct ast_ari_channels_originate_with_id_args {
+ /*! \brief The unique id to assign the channel on creation. */
+ const char *channel_id;
+ /*! \brief Endpoint to call. */
+ const char *endpoint;
+ /*! \brief The extension to dial after the endpoint answers */
+ const char *extension;
+ /*! \brief The context to dial after the endpoint answers. If omitted, uses 'default' */
+ const char *context;
+ /*! \brief The priority to dial after the endpoint answers. If omitted, uses 1 */
+ long priority;
+ /*! \brief The application that is subscribed to the originated channel, and passed to the Stasis application. */
+ const char *app;
+ /*! \brief The application arguments to pass to the Stasis application. */
+ const char *app_args;
+ /*! \brief CallerID to use when dialing the endpoint or extension. */
+ const char *caller_id;
+ /*! \brief Timeout (in seconds) before giving up dialing, or -1 for no timeout. */
+ int timeout;
+ /*! \brief The 'variables' key in the body object holds variable key/value pairs to set on the channel on creation. Other keys in the body object are interpreted as query parameters. Ex. { 'endpoint': 'SIP/Alice', 'variables': { 'CALLERID(name)': 'Alice' } } */
+ struct ast_json *variables;
+ /*! \brief The unique id to assign the second channel when using local channels. */
+ const char *other_channel_id;
+};
+/*!
+ * \brief Body parsing function for /channels/{channelId}.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_channels_originate_with_id_parse_body(
+ struct ast_json *body,
+ struct ast_ari_channels_originate_with_id_args *args);
+
+/*!
+ * \brief 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.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+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);
/*! \brief Argument struct for ast_ari_channels_hangup() */
struct ast_ari_channels_hangup_args {
/*! \brief Channel's id */
int offsetms;
/*! \brief Number of milliseconds to skip for forward/reverse operations. */
int skipms;
+ /*! \brief Playback ID. */
+ const char *playback_id;
};
/*!
* \brief Body parsing function for /channels/{channelId}/play.
* \param[out] response HTTP response
*/
void ast_ari_channels_play(struct ast_variable *headers, struct ast_ari_channels_play_args *args, struct ast_ari_response *response);
+/*! \brief Argument struct for ast_ari_channels_play_with_id() */
+struct ast_ari_channels_play_with_id_args {
+ /*! \brief Channel's id */
+ const char *channel_id;
+ /*! \brief Playback ID. */
+ const char *playback_id;
+ /*! \brief Media's URI to play. */
+ const char *media;
+ /*! \brief For sounds, selects language for sound. */
+ const char *lang;
+ /*! \brief Number of media to skip before playing. */
+ int offsetms;
+ /*! \brief Number of milliseconds to skip for forward/reverse operations. */
+ int skipms;
+};
+/*!
+ * \brief Body parsing function for /channels/{channelId}/play/{playbackId}.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_channels_play_with_id_parse_body(
+ struct ast_json *body,
+ struct ast_ari_channels_play_with_id_args *args);
+
+/*!
+ * \brief Start playback of media and specify the playbackId.
+ *
+ * The media URI may be any of a number of URI's. Currently sound: and recording: 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.)
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+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);
/*! \brief Argument struct for ast_ari_channels_record() */
struct ast_ari_channels_record_args {
/*! \brief Channel's id */
const char *app;
/*! \brief The application arguments to pass to the Stasis application */
const char *app_args;
+ /*! \brief Unique ID to assign to snooping channel */
+ const char *snoop_id;
};
/*!
* \brief Body parsing function for /channels/{channelId}/snoop.
* \param[out] response HTTP response
*/
void ast_ari_channels_snoop_channel(struct ast_variable *headers, struct ast_ari_channels_snoop_channel_args *args, struct ast_ari_response *response);
+/*! \brief Argument struct for ast_ari_channels_snoop_channel_with_id() */
+struct ast_ari_channels_snoop_channel_with_id_args {
+ /*! \brief Channel's id */
+ const char *channel_id;
+ /*! \brief Unique ID to assign to snooping channel */
+ const char *snoop_id;
+ /*! \brief Direction of audio to spy on */
+ const char *spy;
+ /*! \brief Direction of audio to whisper into */
+ const char *whisper;
+ /*! \brief Application the snooping channel is placed into */
+ const char *app;
+ /*! \brief The application arguments to pass to the Stasis application */
+ const char *app_args;
+};
+/*!
+ * \brief Body parsing function for /channels/{channelId}/snoop/{snoopId}.
+ * \param body The JSON body from which to parse parameters.
+ * \param[out] args The args structure to parse into.
+ * \retval zero on success
+ * \retval non-zero on failure
+ */
+int ast_ari_channels_snoop_channel_with_id_parse_body(
+ struct ast_json *body,
+ struct ast_ari_channels_snoop_channel_with_id_args *args);
+
+/*!
+ * \brief Start snooping.
+ *
+ * Snoop (spy/whisper) on a specific channel.
+ *
+ * \param headers HTTP headers
+ * \param args Swagger parameters
+ * \param[out] response HTTP response
+ */
+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);
#endif /* _ASTERISK_RESOURCE_CHANNELS_H */
snprintf(buf, sizeof(buf), "%d", parkingspace);
oh.vars = ast_variable_new("_PARKEDAT", buf, "");
- dchan = __ast_request_and_dial(dial_tech, cap_slin, NULL, dial_string, 30000,
+ dchan = __ast_request_and_dial(dial_tech, cap_slin, NULL, NULL, dial_string, 30000,
&outstate,
parkee_snapshot->caller_number,
parkee_snapshot->caller_name,
bridge = bridge_alloc(sizeof(struct ast_bridge_parking), &ast_bridge_parking_v_table);
bridge = bridge_base_init(bridge, AST_BRIDGE_CAPABILITY_HOLDING,
AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
- | AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM, "Parking", bridge_lot->name);
+ | AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM, "Parking", bridge_lot->name, NULL);
bridge = ast_bridge_parking_init(bridge, bridge_lot);
bridge = bridge_register(bridge);
return bridge;
snprintf(destination, sizeof(destination), "%s@%s", exten, context);
/* Now we request that chan_local prepare to call the destination */
- parkee = ast_request("Local", ast_channel_nativeformats(parker), parker, destination,
+ parkee = ast_request("Local", ast_channel_nativeformats(parker), NULL, parker, destination,
&cause);
if (!parkee) {
return NULL;
static struct ast_channel *create_alice_channel(void)
{
struct ast_channel *alice = ast_channel_alloc(0, AST_STATE_DOWN,
- "100", "Alice", "100", "100", "default", NULL, 0,
+ "100", "Alice", "100", "100", "default", NULL, NULL, 0,
CHANNEL_TECH_NAME "/Alice");
if (!alice) {
if (field) {
args->type = ast_json_string_get(field);
}
+ field = ast_json_object_get(body, "bridgeId");
+ if (field) {
+ args->bridge_id = ast_json_string_get(field);
+ }
field = ast_json_object_get(body, "name");
if (field) {
args->name = ast_json_string_get(field);
if (strcmp(i->name, "type") == 0) {
args.type = (i->value);
} else
+ if (strcmp(i->name, "bridgeId") == 0) {
+ args.bridge_id = (i->value);
+ } else
if (strcmp(i->name, "name") == 0) {
args.name = (i->value);
} else
}
#endif /* AST_DEVMODE */
+fin: __attribute__((unused))
+ return;
+}
+int ast_ari_bridges_create_or_update_with_id_parse_body(
+ struct ast_json *body,
+ struct ast_ari_bridges_create_or_update_with_id_args *args)
+{
+ struct ast_json *field;
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "type");
+ if (field) {
+ args->type = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "name");
+ if (field) {
+ args->name = ast_json_string_get(field);
+ }
+ return 0;
+}
+
+/*!
+ * \brief Parameter parsing callback for /bridges/{bridgeId}.
+ * \param get_params GET parameters in the HTTP request.
+ * \param path_vars Path variables extracted from the request.
+ * \param headers HTTP headers.
+ * \param[out] response Response to the HTTP request.
+ */
+static void ast_ari_bridges_create_or_update_with_id_cb(
+ struct ast_tcptls_session_instance *ser,
+ struct ast_variable *get_params, struct ast_variable *path_vars,
+ struct ast_variable *headers, struct ast_ari_response *response)
+{
+ struct ast_ari_bridges_create_or_update_with_id_args args = {};
+ struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
+#if defined(AST_DEVMODE)
+ int is_valid;
+ int code;
+#endif /* AST_DEVMODE */
+
+ for (i = get_params; i; i = i->next) {
+ if (strcmp(i->name, "type") == 0) {
+ args.type = (i->value);
+ } else
+ if (strcmp(i->name, "name") == 0) {
+ args.name = (i->value);
+ } else
+ {}
+ }
+ for (i = path_vars; i; i = i->next) {
+ if (strcmp(i->name, "bridgeId") == 0) {
+ args.bridge_id = (i->value);
+ } else
+ {}
+ }
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ if (ast_ari_bridges_create_or_update_with_id_parse_body(body, &args)) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+ ast_ari_bridges_create_or_update_with_id(headers, &args, response);
+#if defined(AST_DEVMODE)
+ code = response->response_code;
+
+ switch (code) {
+ case 0: /* Implementation is still a stub, or the code wasn't set */
+ is_valid = response->message == NULL;
+ break;
+ case 500: /* Internal Server Error */
+ case 501: /* Not Implemented */
+ is_valid = 1;
+ break;
+ default:
+ if (200 <= code && code <= 299) {
+ is_valid = ast_ari_validate_bridge(
+ response->message);
+ } else {
+ ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}\n", code);
+ is_valid = 0;
+ }
+ }
+
+ if (!is_valid) {
+ ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}\n");
+ ast_ari_response_error(response, 500,
+ "Internal Server Error", "Response validation failed");
+ }
+#endif /* AST_DEVMODE */
+
fin: __attribute__((unused))
return;
}
.path_segment = "bridgeId",
.is_wildcard = 1,
.callbacks = {
+ [AST_HTTP_POST] = ast_ari_bridges_create_or_update_with_id_cb,
[AST_HTTP_GET] = ast_ari_bridges_get_cb,
[AST_HTTP_DELETE] = ast_ari_bridges_destroy_cb,
},
if (field) {
args->timeout = ast_json_integer_get(field);
}
+ field = ast_json_object_get(body, "channelId");
+ if (field) {
+ args->channel_id = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "otherChannelId");
+ if (field) {
+ args->other_channel_id = ast_json_string_get(field);
+ }
return 0;
}
if (strcmp(i->name, "timeout") == 0) {
args.timeout = atoi(i->value);
} else
+ if (strcmp(i->name, "channelId") == 0) {
+ args.channel_id = (i->value);
+ } else
+ if (strcmp(i->name, "otherChannelId") == 0) {
+ args.other_channel_id = (i->value);
+ } else
{}
}
/* Look for a JSON request entity */
}
#endif /* AST_DEVMODE */
+fin: __attribute__((unused))
+ return;
+}
+int ast_ari_channels_originate_with_id_parse_body(
+ struct ast_json *body,
+ struct ast_ari_channels_originate_with_id_args *args)
+{
+ struct ast_json *field;
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "endpoint");
+ if (field) {
+ args->endpoint = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "extension");
+ if (field) {
+ args->extension = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "context");
+ if (field) {
+ args->context = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "priority");
+ if (field) {
+ args->priority = ast_json_integer_get(field);
+ }
+ field = ast_json_object_get(body, "app");
+ if (field) {
+ args->app = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "appArgs");
+ if (field) {
+ args->app_args = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "callerId");
+ if (field) {
+ args->caller_id = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "timeout");
+ if (field) {
+ args->timeout = ast_json_integer_get(field);
+ }
+ field = ast_json_object_get(body, "otherChannelId");
+ if (field) {
+ args->other_channel_id = ast_json_string_get(field);
+ }
+ return 0;
+}
+
+/*!
+ * \brief Parameter parsing callback for /channels/{channelId}.
+ * \param get_params GET parameters in the HTTP request.
+ * \param path_vars Path variables extracted from the request.
+ * \param headers HTTP headers.
+ * \param[out] response Response to the HTTP request.
+ */
+static void ast_ari_channels_originate_with_id_cb(
+ struct ast_tcptls_session_instance *ser,
+ struct ast_variable *get_params, struct ast_variable *path_vars,
+ struct ast_variable *headers, struct ast_ari_response *response)
+{
+ struct ast_ari_channels_originate_with_id_args args = {};
+ struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
+#if defined(AST_DEVMODE)
+ int is_valid;
+ int code;
+#endif /* AST_DEVMODE */
+
+ for (i = get_params; i; i = i->next) {
+ if (strcmp(i->name, "endpoint") == 0) {
+ args.endpoint = (i->value);
+ } else
+ if (strcmp(i->name, "extension") == 0) {
+ args.extension = (i->value);
+ } else
+ if (strcmp(i->name, "context") == 0) {
+ args.context = (i->value);
+ } else
+ if (strcmp(i->name, "priority") == 0) {
+ args.priority = atol(i->value);
+ } else
+ if (strcmp(i->name, "app") == 0) {
+ args.app = (i->value);
+ } else
+ if (strcmp(i->name, "appArgs") == 0) {
+ args.app_args = (i->value);
+ } else
+ if (strcmp(i->name, "callerId") == 0) {
+ args.caller_id = (i->value);
+ } else
+ if (strcmp(i->name, "timeout") == 0) {
+ args.timeout = atoi(i->value);
+ } else
+ if (strcmp(i->name, "otherChannelId") == 0) {
+ args.other_channel_id = (i->value);
+ } else
+ {}
+ }
+ for (i = path_vars; i; i = i->next) {
+ if (strcmp(i->name, "channelId") == 0) {
+ args.channel_id = (i->value);
+ } else
+ {}
+ }
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ args.variables = ast_json_ref(body);
+ ast_ari_channels_originate_with_id(headers, &args, response);
+#if defined(AST_DEVMODE)
+ code = response->response_code;
+
+ switch (code) {
+ case 0: /* Implementation is still a stub, or the code wasn't set */
+ is_valid = response->message == NULL;
+ break;
+ case 500: /* Internal Server Error */
+ case 501: /* Not Implemented */
+ case 400: /* Invalid parameters for originating a channel. */
+ is_valid = 1;
+ break;
+ default:
+ if (200 <= code && code <= 299) {
+ is_valid = ast_ari_validate_channel(
+ response->message);
+ } else {
+ ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}\n", code);
+ is_valid = 0;
+ }
+ }
+
+ if (!is_valid) {
+ ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}\n");
+ ast_ari_response_error(response, 500,
+ "Internal Server Error", "Response validation failed");
+ }
+#endif /* AST_DEVMODE */
+
fin: __attribute__((unused))
return;
}
if (field) {
args->skipms = ast_json_integer_get(field);
}
+ field = ast_json_object_get(body, "playbackId");
+ if (field) {
+ args->playback_id = ast_json_string_get(field);
+ }
return 0;
}
if (strcmp(i->name, "skipms") == 0) {
args.skipms = atoi(i->value);
} else
+ if (strcmp(i->name, "playbackId") == 0) {
+ args.playback_id = (i->value);
+ } else
{}
}
for (i = path_vars; i; i = i->next) {
}
#endif /* AST_DEVMODE */
+fin: __attribute__((unused))
+ return;
+}
+int ast_ari_channels_play_with_id_parse_body(
+ struct ast_json *body,
+ struct ast_ari_channels_play_with_id_args *args)
+{
+ struct ast_json *field;
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "media");
+ if (field) {
+ args->media = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "lang");
+ if (field) {
+ args->lang = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "offsetms");
+ if (field) {
+ args->offsetms = ast_json_integer_get(field);
+ }
+ field = ast_json_object_get(body, "skipms");
+ if (field) {
+ args->skipms = ast_json_integer_get(field);
+ }
+ return 0;
+}
+
+/*!
+ * \brief Parameter parsing callback for /channels/{channelId}/play/{playbackId}.
+ * \param get_params GET parameters in the HTTP request.
+ * \param path_vars Path variables extracted from the request.
+ * \param headers HTTP headers.
+ * \param[out] response Response to the HTTP request.
+ */
+static void ast_ari_channels_play_with_id_cb(
+ struct ast_tcptls_session_instance *ser,
+ struct ast_variable *get_params, struct ast_variable *path_vars,
+ struct ast_variable *headers, struct ast_ari_response *response)
+{
+ struct ast_ari_channels_play_with_id_args args = {};
+ struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
+#if defined(AST_DEVMODE)
+ int is_valid;
+ int code;
+#endif /* AST_DEVMODE */
+
+ for (i = get_params; i; i = i->next) {
+ if (strcmp(i->name, "media") == 0) {
+ args.media = (i->value);
+ } else
+ if (strcmp(i->name, "lang") == 0) {
+ args.lang = (i->value);
+ } else
+ if (strcmp(i->name, "offsetms") == 0) {
+ args.offsetms = atoi(i->value);
+ } else
+ if (strcmp(i->name, "skipms") == 0) {
+ args.skipms = atoi(i->value);
+ } else
+ {}
+ }
+ for (i = path_vars; i; i = i->next) {
+ if (strcmp(i->name, "channelId") == 0) {
+ args.channel_id = (i->value);
+ } else
+ if (strcmp(i->name, "playbackId") == 0) {
+ args.playback_id = (i->value);
+ } else
+ {}
+ }
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ if (ast_ari_channels_play_with_id_parse_body(body, &args)) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+ ast_ari_channels_play_with_id(headers, &args, response);
+#if defined(AST_DEVMODE)
+ code = response->response_code;
+
+ switch (code) {
+ case 0: /* Implementation is still a stub, or the code wasn't set */
+ is_valid = response->message == NULL;
+ break;
+ case 500: /* Internal Server Error */
+ case 501: /* Not Implemented */
+ case 404: /* Channel not found */
+ case 409: /* Channel not in a Stasis application */
+ is_valid = 1;
+ break;
+ default:
+ if (200 <= code && code <= 299) {
+ is_valid = ast_ari_validate_playback(
+ response->message);
+ } else {
+ ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/play/{playbackId}\n", code);
+ is_valid = 0;
+ }
+ }
+
+ if (!is_valid) {
+ ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/play/{playbackId}\n");
+ ast_ari_response_error(response, 500,
+ "Internal Server Error", "Response validation failed");
+ }
+#endif /* AST_DEVMODE */
+
fin: __attribute__((unused))
return;
}
if (field) {
args->app_args = ast_json_string_get(field);
}
+ field = ast_json_object_get(body, "snoopId");
+ if (field) {
+ args->snoop_id = ast_json_string_get(field);
+ }
return 0;
}
if (strcmp(i->name, "appArgs") == 0) {
args.app_args = (i->value);
} else
+ if (strcmp(i->name, "snoopId") == 0) {
+ args.snoop_id = (i->value);
+ } else
{}
}
for (i = path_vars; i; i = i->next) {
}
#endif /* AST_DEVMODE */
+fin: __attribute__((unused))
+ return;
+}
+int ast_ari_channels_snoop_channel_with_id_parse_body(
+ struct ast_json *body,
+ struct ast_ari_channels_snoop_channel_with_id_args *args)
+{
+ struct ast_json *field;
+ /* Parse query parameters out of it */
+ field = ast_json_object_get(body, "spy");
+ if (field) {
+ args->spy = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "whisper");
+ if (field) {
+ args->whisper = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "app");
+ if (field) {
+ args->app = ast_json_string_get(field);
+ }
+ field = ast_json_object_get(body, "appArgs");
+ if (field) {
+ args->app_args = ast_json_string_get(field);
+ }
+ return 0;
+}
+
+/*!
+ * \brief Parameter parsing callback for /channels/{channelId}/snoop/{snoopId}.
+ * \param get_params GET parameters in the HTTP request.
+ * \param path_vars Path variables extracted from the request.
+ * \param headers HTTP headers.
+ * \param[out] response Response to the HTTP request.
+ */
+static void ast_ari_channels_snoop_channel_with_id_cb(
+ struct ast_tcptls_session_instance *ser,
+ struct ast_variable *get_params, struct ast_variable *path_vars,
+ struct ast_variable *headers, struct ast_ari_response *response)
+{
+ struct ast_ari_channels_snoop_channel_with_id_args args = {};
+ struct ast_variable *i;
+ RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
+#if defined(AST_DEVMODE)
+ int is_valid;
+ int code;
+#endif /* AST_DEVMODE */
+
+ for (i = get_params; i; i = i->next) {
+ if (strcmp(i->name, "spy") == 0) {
+ args.spy = (i->value);
+ } else
+ if (strcmp(i->name, "whisper") == 0) {
+ args.whisper = (i->value);
+ } else
+ if (strcmp(i->name, "app") == 0) {
+ args.app = (i->value);
+ } else
+ if (strcmp(i->name, "appArgs") == 0) {
+ args.app_args = (i->value);
+ } else
+ {}
+ }
+ for (i = path_vars; i; i = i->next) {
+ if (strcmp(i->name, "channelId") == 0) {
+ args.channel_id = (i->value);
+ } else
+ if (strcmp(i->name, "snoopId") == 0) {
+ args.snoop_id = (i->value);
+ } else
+ {}
+ }
+ /* Look for a JSON request entity */
+ body = ast_http_get_json(ser, headers);
+ if (!body) {
+ switch (errno) {
+ case EFBIG:
+ ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
+ goto fin;
+ case ENOMEM:
+ ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
+ goto fin;
+ case EIO:
+ ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
+ goto fin;
+ }
+ }
+ if (ast_ari_channels_snoop_channel_with_id_parse_body(body, &args)) {
+ ast_ari_response_alloc_failed(response);
+ goto fin;
+ }
+ ast_ari_channels_snoop_channel_with_id(headers, &args, response);
+#if defined(AST_DEVMODE)
+ code = response->response_code;
+
+ switch (code) {
+ case 0: /* Implementation is still a stub, or the code wasn't set */
+ is_valid = response->message == NULL;
+ break;
+ case 500: /* Internal Server Error */
+ case 501: /* Not Implemented */
+ case 400: /* Invalid parameters */
+ case 404: /* Channel not found */
+ is_valid = 1;
+ break;
+ default:
+ if (200 <= code && code <= 299) {
+ is_valid = ast_ari_validate_channel(
+ response->message);
+ } else {
+ ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/snoop/{snoopId}\n", code);
+ is_valid = 0;
+ }
+ }
+
+ if (!is_valid) {
+ ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/snoop/{snoopId}\n");
+ ast_ari_response_error(response, 500,
+ "Internal Server Error", "Response validation failed");
+ }
+#endif /* AST_DEVMODE */
+
fin: __attribute__((unused))
return;
}
.children = { }
};
/*! \brief REST handler for /api-docs/channels.{format} */
+static struct stasis_rest_handlers channels_channelId_play_playbackId = {
+ .path_segment = "playbackId",
+ .is_wildcard = 1,
+ .callbacks = {
+ [AST_HTTP_POST] = ast_ari_channels_play_with_id_cb,
+ },
+ .num_children = 0,
+ .children = { }
+};
+/*! \brief REST handler for /api-docs/channels.{format} */
static struct stasis_rest_handlers channels_channelId_play = {
.path_segment = "play",
.callbacks = {
[AST_HTTP_POST] = ast_ari_channels_play_cb,
},
- .num_children = 0,
- .children = { }
+ .num_children = 1,
+ .children = { &channels_channelId_play_playbackId, }
};
/*! \brief REST handler for /api-docs/channels.{format} */
static struct stasis_rest_handlers channels_channelId_record = {
.children = { }
};
/*! \brief REST handler for /api-docs/channels.{format} */
+static struct stasis_rest_handlers channels_channelId_snoop_snoopId = {
+ .path_segment = "snoopId",
+ .is_wildcard = 1,
+ .callbacks = {
+ [AST_HTTP_POST] = ast_ari_channels_snoop_channel_with_id_cb,
+ },
+ .num_children = 0,
+ .children = { }
+};
+/*! \brief REST handler for /api-docs/channels.{format} */
static struct stasis_rest_handlers channels_channelId_snoop = {
.path_segment = "snoop",
.callbacks = {
[AST_HTTP_POST] = ast_ari_channels_snoop_channel_cb,
},
- .num_children = 0,
- .children = { }
+ .num_children = 1,
+ .children = { &channels_channelId_snoop_snoopId, }
};
/*! \brief REST handler for /api-docs/channels.{format} */
static struct stasis_rest_handlers channels_channelId = {
.is_wildcard = 1,
.callbacks = {
[AST_HTTP_GET] = ast_ari_channels_get_cb,
+ [AST_HTTP_POST] = ast_ari_channels_originate_with_id_cb,
[AST_HTTP_DELETE] = ast_ari_channels_hangup_cb,
},
.num_children = 12,
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/_private.h"
+#include "asterisk/channel.h"
#include "asterisk/calendar.h"
#include "asterisk/utils.h"
#include "asterisk/astobj2.h"
goto notify_cleanup;
}
- if (ast_dial_append(dial, tech, dest) < 0) {
+ if (ast_dial_append(dial, tech, dest, NULL) < 0) {
ast_log(LOG_ERROR, "Could not append channel\n");
goto notify_cleanup;
}
ast_dial_set_global_timeout(dial, event->owner->notify_waittime);
generate_random_string(buf, sizeof(buf));
- if (!(chan = ast_channel_alloc(1, AST_STATE_DOWN, 0, 0, 0, 0, 0, 0, 0, "Calendar/%s-%s", event->owner->name, buf))) {
+ if (!(chan = ast_channel_alloc(1, AST_STATE_DOWN, 0, 0, 0, 0, 0, NULL, NULL, 0, "Calendar/%s-%s", event->owner->name, buf))) {
ast_log(LOG_ERROR, "Could not allocate notification channel\n");
goto notify_cleanup;
}
#include <libxml/parser.h>
#include "asterisk/module.h"
+#include "asterisk/channel.h"
#include "asterisk/calendar.h"
#include "asterisk/lock.h"
#include "asterisk/config.h"
#include <ne_redirect.h>
#include "asterisk/module.h"
+#include "asterisk/channel.h"
#include "asterisk/calendar.h"
#include "asterisk/lock.h"
#include "asterisk/config.h"
#include <iksemel.h>
#include "asterisk/module.h"
+#include "asterisk/channel.h"
#include "asterisk/calendar.h"
#include "asterisk/lock.h"
#include "asterisk/config.h"
#include <ne_redirect.h>
#include "asterisk/module.h"
+#include "asterisk/channel.h"
#include "asterisk/calendar.h"
#include "asterisk/lock.h"
#include "asterisk/config.h"
return CLI_FAILURE;
}
ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
- ast_pbx_outgoing_app(chantech, cap, chandata, TIMEOUT * 1000, app, appdata, &reason, 0, NULL, NULL, NULL, NULL, NULL);
+ ast_pbx_outgoing_app(chantech, cap, chandata, TIMEOUT * 1000, app, appdata, &reason, 0, NULL, NULL, NULL, NULL, NULL, NULL);
cap = ast_format_cap_destroy(cap);
return CLI_SUCCESS;
return CLI_FAILURE;
}
ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
- ast_pbx_outgoing_exten(chantech, cap, chandata, TIMEOUT * 1000, context, exten, 1, &reason, 0, NULL, NULL, NULL, NULL, NULL, 0);
+ ast_pbx_outgoing_exten(chantech, cap, chandata, TIMEOUT * 1000, context, exten, 1, &reason, 0, NULL, NULL, NULL, NULL, NULL, 0, NULL);
cap = ast_format_cap_destroy(cap);
return CLI_SUCCESS;
ast_format_cap_add(cap, ast_format_set(&format, AST_FORMAT_SLINEAR, 0));
- return ast_request("Announcer", cap, NULL, "ARI_MOH", NULL);
+ return ast_request("Announcer", cap, NULL, NULL, "ARI_MOH", NULL);
}
/*! Provides the moh channel with a thread so it can actually play its music */
ao2_cleanup(control);
}
-struct ast_bridge *stasis_app_bridge_create(const char *type, const char *name)
+struct ast_bridge *stasis_app_bridge_create(const char *type, const char *name, const char *id)
{
struct ast_bridge *bridge;
int capabilities;
return NULL;
}
- bridge = ast_bridge_base_new(capabilities, flags, "Stasis", name);
+ bridge = ast_bridge_base_new(capabilities, flags, "Stasis", name, id);
if (bridge) {
if (!ao2_link(app_bridges, bridge)) {
ast_bridge_destroy(bridge, 0);
}
static struct stasis_app_playback *playback_create(
- struct stasis_app_control *control)
+ struct stasis_app_control *control, const char *id)
{
RAII_VAR(struct stasis_app_playback *, playback, NULL, ao2_cleanup);
- char id[AST_UUID_STR_LEN];
+ char uuid[AST_UUID_STR_LEN];
int res;
if (!control) {
return NULL;
}
- ast_uuid_generate_str(id, sizeof(id));
- ast_string_field_set(playback, id, id);
+ if (!ast_strlen_zero(id)) {
+ ast_string_field_set(playback, id, id);
+ } else {
+ ast_uuid_generate_str(uuid, sizeof(uuid));
+ ast_string_field_set(playback, id, uuid);
+ }
playback->control = control;
struct stasis_app_control *control, const char *uri,
const char *language, const char *target_id,
enum stasis_app_playback_target_type target_type,
- int skipms, long offsetms)
+ int skipms, long offsetms, const char *id)
{
RAII_VAR(struct stasis_app_playback *, playback, NULL, ao2_cleanup);
ast_debug(3, "%s: Sending play(%s) command\n",
stasis_app_control_get_channel_id(control), uri);
- playback = playback_create(control);
+ playback = playback_create(control, id);
if (skipms == 0) {
skipms = PLAYBACK_DEFAULT_SKIPMS;
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 *app, const char *app_args, const char *snoop_id)
{
RAII_VAR(struct stasis_app_snoop *, snoop, NULL, ao2_cleanup);
pthread_t thread;
+ struct ast_assigned_ids assignedids = {snoop_id, NULL};
if (spy == STASIS_SNOOP_DIRECTION_NONE &&
whisper == STASIS_SNOOP_DIRECTION_NONE) {
snoop_determine_format(chan, snoop);
/* Allocate a Snoop channel and set up various parameters */
- snoop->chan = ast_channel_alloc(1, AST_STATE_UP, "", "", "", "", "", "", 0, "Snoop/%s-%08x", ast_channel_uniqueid(chan),
+ snoop->chan = ast_channel_alloc(1, AST_STATE_UP, "", "", "", "", "", &assignedids, NULL, 0, "Snoop/%s-%08x", ast_channel_uniqueid(chan),
ast_atomic_fetchadd_int((int *)&chan_idx, +1));
if (!snoop->chan) {
return NULL;
return -1;
}
- if (ast_dial_append(dial, tech, resource) < 0) {
+ if (ast_dial_append(dial, tech, resource, NULL) < 0) {
ast_log(LOG_ERROR, "Failed to add %s/%s to dialing structure.\n", tech, resource);
return -1;
}
]
}
},
+ {
+ "name": "bridgeId",
+ "description": "Unique ID to give to the bridge being created.",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
{
"name": "name",
"description": "Name to give to the bridge being created.",
"path": "/bridges/{bridgeId}",
"description": "Individual bridge",
"operations": [
+ {
+ "httpMethod": "POST",
+ "summary": "Create a new bridge or updates an existing one.",
+ "notes": "This bridge persists until it has been shut down, or Asterisk has been shut down.",
+ "nickname": "create_or_update_with_id",
+ "responseClass": "Bridge",
+ "parameters": [
+ {
+ "name": "type",
+ "description": "Set the type of bridge.",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "string",
+ "allowableValues": {
+ "valueType": "LIST",
+ "values": [
+ "mixing",
+ "holding"
+ ]
+ }
+ },
+ {
+ "name": "bridgeId",
+ "description": "Unique ID to give to the bridge being created.",
+ "paramType": "path",
+ "required": true,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
+ {
+ "name": "name",
+ "description": "Set the name of the bridge.",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "string"
+ }
+ ]
+ },
{
"httpMethod": "GET",
"summary": "Get bridge details.",
"required": false,
"dataType": "containers",
"allowMultiple": false
+ },
+ {
+ "name": "channelId",
+ "description": "The unique id to assign the channel on creation.",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
+ {
+ "name": "otherChannelId",
+ "description": "The unique id to assign the second channel when using local channels.",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "string"
}
],
"errorResponses": [
}
]
},
+ {
+ "httpMethod": "POST",
+ "summary": "Create a new channel (originate with id).",
+ "notes": "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.",
+ "nickname": "originateWithId",
+ "responseClass": "Channel",
+ "parameters": [
+ {
+ "name": "channelId",
+ "description": "The unique id to assign the channel on creation.",
+ "paramType": "path",
+ "required": true,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
+ {
+ "name": "endpoint",
+ "description": "Endpoint to call.",
+ "paramType": "query",
+ "required": true,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
+ {
+ "name": "extension",
+ "description": "The extension to dial after the endpoint answers",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
+ {
+ "name": "context",
+ "description": "The context to dial after the endpoint answers. If omitted, uses 'default'",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
+ {
+ "name": "priority",
+ "description": "The priority to dial after the endpoint answers. If omitted, uses 1",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "long"
+ },
+ {
+ "name": "app",
+ "description": "The application that is subscribed to the originated channel, and passed to the Stasis application.",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
+ {
+ "name": "appArgs",
+ "description": "The application arguments to pass to the Stasis application.",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
+ {
+ "name": "callerId",
+ "description": "CallerID to use when dialing the endpoint or extension.",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
+ {
+ "name": "timeout",
+ "description": "Timeout (in seconds) before giving up dialing, or -1 for no timeout.",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "int",
+ "defaultValue": 30
+ },
+ {
+ "name": "variables",
+ "description": "The 'variables' key in the body object holds variable key/value pairs to set on the channel on creation. Other keys in the body object are interpreted as query parameters. Ex. { 'endpoint': 'SIP/Alice', 'variables': { 'CALLERID(name)': 'Alice' } }",
+ "paramType": "body",
+ "required": false,
+ "dataType": "containers",
+ "allowMultiple": false
+ },
+ {
+ "name": "otherChannelId",
+ "description": "The unique id to assign the second channel when using local channels.",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "string"
+ }
+ ],
+ "errorResponses": [
+ {
+ "code": 400,
+ "reason": "Invalid parameters for originating a channel."
+ }
+ ]
+
+ },
{
"httpMethod": "DELETE",
"summary": "Delete (i.e. hangup) a channel.",
"allowMultiple": false,
"dataType": "int"
},
+ {
+ "name": "skipms",
+ "description": "Number of milliseconds to skip for forward/reverse operations.",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "int",
+ "defaultValue": 3000
+ },
+ {
+ "name": "playbackId",
+ "description": "Playback ID.",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "string"
+ }
+ ],
+ "errorResponses": [
+ {
+ "code": 404,
+ "reason": "Channel not found"
+ },
+ {
+ "code": 409,
+ "reason": "Channel not in a Stasis application"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "path": "/channels/{channelId}/play/{playbackId}",
+ "description": "Play media to a channel",
+ "operations": [
+ {
+ "httpMethod": "POST",
+ "summary": "Start playback of media and specify the playbackId.",
+ "notes": "The media URI may be any of a number of URI's. Currently sound: and recording: 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.)",
+ "nickname": "playWithId",
+ "responseClass": "Playback",
+ "parameters": [
+ {
+ "name": "channelId",
+ "description": "Channel's id",
+ "paramType": "path",
+ "required": true,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
+ {
+ "name": "playbackId",
+ "description": "Playback ID.",
+ "paramType": "path",
+ "required": true,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
+ {
+ "name": "media",
+ "description": "Media's URI to play.",
+ "paramType": "query",
+ "required": true,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
+ {
+ "name": "lang",
+ "description": "For sounds, selects language for sound.",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
+ {
+ "name": "offsetms",
+ "description": "Number of media to skip before playing.",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "int"
+ },
{
"name": "skipms",
"description": "Number of milliseconds to skip for forward/reverse operations.",
"allowMultiple": false,
"dataType": "string"
},
+ {
+ "name": "appArgs",
+ "description": "The application arguments to pass to the Stasis application",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
+ {
+ "name": "snoopId",
+ "description": "Unique ID to assign to snooping channel",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "string"
+ }
+ ],
+ "errorResponses": [
+ {
+ "code": 400,
+ "reason": "Invalid parameters"
+ },
+ {
+ "code": 404,
+ "reason": "Channel not found"
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "path": "/channels/{channelId}/snoop/{snoopId}",
+ "description": "Snoop (spy/whisper) on a channel",
+ "operations": [
+ {
+ "httpMethod": "POST",
+ "summary": "Start snooping.",
+ "notes": "Snoop (spy/whisper) on a specific channel.",
+ "nickname": "snoopChannelWithId",
+ "responseClass": "Channel",
+ "parameters": [
+ {
+ "name": "channelId",
+ "description": "Channel's id",
+ "paramType": "path",
+ "required": true,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
+ {
+ "name": "snoopId",
+ "description": "Unique ID to assign to snooping channel",
+ "paramType": "path",
+ "required": true,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
+ {
+ "name": "spy",
+ "description": "Direction of audio to spy on",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "string",
+ "defaultValue": "none",
+ "allowableValues": {
+ "valueType": "LIST",
+ "values": [
+ "none",
+ "both",
+ "out",
+ "in"
+ ]
+ }
+ },
+ {
+ "name": "whisper",
+ "description": "Direction of audio to whisper into",
+ "paramType": "query",
+ "required": false,
+ "allowMultiple": false,
+ "dataType": "string",
+ "defaultValue": "none",
+ "allowableValues": {
+ "valueType": "LIST",
+ "values": [
+ "none",
+ "both",
+ "out",
+ "in"
+ ]
+ }
+ },
+ {
+ "name": "app",
+ "description": "Application the snooping channel is placed into",
+ "paramType": "query",
+ "required": true,
+ "allowMultiple": false,
+ "dataType": "string"
+ },
{
"name": "appArgs",
"description": "The application arguments to pass to the Stasis application",
"'%s', '%s', '%s', '%s'\n", group1_full, group2_full, category1_full, category2_full);
if (!(test_channel1 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
- NULL, NULL, 0, 0, "TestChannel1"))) {
+ NULL, NULL, NULL, NULL, 0, "TestChannel1"))) {
goto exit_group_test;
}
ast_channel_unlock(test_channel1);
if (!(test_channel2 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
- NULL, NULL, 0, 0, "TestChannel2"))) {
+ NULL, NULL, NULL, NULL, 0, "TestChannel2"))) {
goto exit_group_test;
}
ast_channel_unlock(test_channel2);
if (!(test_channel3 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
- NULL, NULL, 0, 0, "TestChannel3"))) {
+ NULL, NULL, NULL, NULL, 0, "TestChannel3"))) {
goto exit_group_test;
}
ast_channel_unlock(test_channel3);
if (!(test_channel4 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
- NULL, NULL, 0, 0, "TestChannel4"))) {
+ NULL, NULL, NULL, NULL, 0, "TestChannel4"))) {
goto exit_group_test;
}
ast_channel_unlock(test_channel4);
/*! \brief Create a \ref test_cdr_chan_tech for Alice, and set the expected
* CDR records' linkedid and uniqueid. */
#define CREATE_ALICE_CHANNEL(channel_var, caller_id, expected_record) do { \
- (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, 0, CHANNEL_TECH_NAME "/Alice"); \
+ (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Alice"); \
ast_channel_set_caller((channel_var), (caller_id), NULL); \
ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
/*! \brief Create a \ref test_cdr_chan_tech for Bob, and set the expected
* CDR records' linkedid and uniqueid. */
#define CREATE_BOB_CHANNEL(channel_var, caller_id, expected_record) do { \
- (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "200", "Bob", "200", "200", "default", NULL, 0, CHANNEL_TECH_NAME "/Bob"); \
+ (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "200", "Bob", "200", "200", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Bob"); \
ast_channel_set_caller((channel_var), (caller_id), NULL); \
ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
/*! \brief Create a \ref test_cdr_chan_tech for Charlie, and set the expected
* CDR records' linkedid and uniqueid. */
#define CREATE_CHARLIE_CHANNEL(channel_var, caller_id, expected_record) do { \
- (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "300", "Charlie", "300", "300", "default", NULL, 0, CHANNEL_TECH_NAME "/Charlie"); \
+ (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "300", "Charlie", "300", "300", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Charlie"); \
ast_channel_set_caller((channel_var), (caller_id), NULL); \
ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
/*! \brief Create a \ref test_cdr_chan_tech for Charlie, and set the expected
* CDR records' linkedid and uniqueid. */
#define CREATE_DAVID_CHANNEL(channel_var, caller_id, expected_record) do { \
- (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "400", "David", "400", "400", "default", NULL, 0, CHANNEL_TECH_NAME "/David"); \
+ (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, "400", "David", "400", "400", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/David"); \
ast_channel_set_caller((channel_var), (caller_id), NULL); \
ast_copy_string((expected_record)->uniqueid, ast_channel_uniqueid((channel_var)), sizeof((expected_record)->uniqueid)); \
ast_copy_string((expected_record)->linkedid, ast_channel_linkedid((channel_var)), sizeof((expected_record)->linkedid)); \
ast_test_validate(test, !ast_bridge_impart(bridge, chan_alice, NULL, NULL, AST_BRIDGE_IMPART_CHAN_DEPARTABLE));
- chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_alice), 0, CHANNEL_TECH_NAME "/Bob");
+ chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_alice, 0, CHANNEL_TECH_NAME "/Bob");
ast_channel_unlock(chan_bob);
ast_copy_string(bob_expected.linkedid, ast_channel_linkedid(chan_bob), sizeof(bob_expected.linkedid));
ast_copy_string(bob_expected.uniqueid, ast_channel_uniqueid(chan_bob), sizeof(bob_expected.uniqueid));
EMULATE_APP_DATA(chan_caller, 1, "Dial", "CDRTestChannel/Bob");
- chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
+ chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
ast_channel_unlock(chan_callee);
ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
- chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
+ chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
ast_channel_unlock(chan_callee);
ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
- chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
+ chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
ast_channel_unlock(chan_callee);
ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
- chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
+ chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
ast_channel_unlock(chan_callee);
ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
- chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
+ chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
ast_channel_unlock(chan_callee);
ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob&" CHANNEL_TECH_NAME "/Charlie&" CHANNEL_TECH_NAME "/David");
/* Outbound channels are created */
- chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
+ chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
ast_channel_unlock(chan_bob);
ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_OUTGOING);
EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
- chan_charlie = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "300", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Charlie");
+ chan_charlie = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "300", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Charlie");
ast_channel_unlock(chan_charlie);
ast_set_flag(ast_channel_flags(chan_charlie), AST_FLAG_OUTGOING);
EMULATE_APP_DATA(chan_charlie, 0, "AppDial", "(Outgoing Line)");
- chan_david = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "400", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/David");
+ chan_david = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "400", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/David");
ast_channel_unlock(chan_david);
ast_set_flag(ast_channel_flags(chan_david), AST_FLAG_OUTGOING);
EMULATE_APP_DATA(chan_david, 0, "AppDial", "(Outgoing Line)");
EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
- chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
+ chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
ast_channel_unlock(chan_callee);
ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
COPY_IDS(chan_callee, &bob_expected_one);
EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
- chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
+ chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
ast_channel_unlock(chan_callee);
ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
EMULATE_APP_DATA(chan_caller, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
- chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, ast_channel_linkedid(chan_caller), 0, CHANNEL_TECH_NAME "/Bob");
+ chan_callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, "200", NULL, NULL, NULL, chan_caller, 0, CHANNEL_TECH_NAME "/Bob");
ast_channel_unlock(chan_callee);
ast_set_flag(ast_channel_flags(chan_callee), AST_FLAG_OUTGOING);
EMULATE_APP_DATA(chan_callee, 0, "AppDial", "(Outgoing Line)");
EMULATE_APP_DATA(chan_alice, 1, "Dial", CHANNEL_TECH_NAME "/Bob");
- chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, "200", "Bob", "200", "200", "default", NULL, 0, CHANNEL_TECH_NAME "/Bob");
+ chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, "200", "Bob", "200", "200", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Bob");
ast_channel_unlock(chan_bob);
ast_set_flag(ast_channel_flags(chan_bob), AST_FLAG_OUTGOING);
EMULATE_APP_DATA(chan_bob, 0, "AppDial", "(Outgoing Line)");
ast_copy_string(charlie_expected_two.uniqueid, ast_channel_uniqueid(chan_charlie), sizeof(charlie_expected_two.uniqueid));
ast_copy_string(charlie_expected_two.linkedid, ast_channel_linkedid(chan_alice), sizeof(charlie_expected_two.linkedid));
- chan_david = ast_channel_alloc(0, AST_STATE_DOWN, "400", "David", "400", "400", "default", NULL, 0, CHANNEL_TECH_NAME "/David");
+ chan_david = ast_channel_alloc(0, AST_STATE_DOWN, "400", "David", "400", "400", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/David");
ast_channel_unlock(chan_david);
ast_set_flag(ast_channel_flags(chan_david), AST_FLAG_OUTGOING);
EMULATE_APP_DATA(chan_david, 0, "AppDial", "(Outgoing Line)");
/*! \brief Create a \ref test_cel_chan_tech for Alice. */
#define CREATE_ALICE_CHANNEL(channel_var, caller_id) do { \
- (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "100", "100", "default", NULL, 0, CHANNEL_TECH_NAME "/Alice"); \
+ (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "100", "100", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Alice"); \
APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL); \
ast_channel_unlock((channel_var)); \
} while (0)
/*! \brief Create a \ref test_cel_chan_tech for Bob. */
#define CREATE_BOB_CHANNEL(channel_var, caller_id) do { \
- (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "200", "200", "default", NULL, 0, CHANNEL_TECH_NAME "/Bob"); \
+ (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "200", "200", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Bob"); \
APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL); \
ast_channel_unlock((channel_var)); \
} while (0)
/*! \brief Create a \ref test_cel_chan_tech for Charlie. */
#define CREATE_CHARLIE_CHANNEL(channel_var, caller_id) do { \
- (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "300", "300", "default", NULL, 0, CHANNEL_TECH_NAME "/Charlie"); \
+ (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "300", "300", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/Charlie"); \
APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL); \
ast_channel_unlock((channel_var)); \
} while (0)
/*! \brief Create a \ref test_cel_chan_tech for David. */
#define CREATE_DAVID_CHANNEL(channel_var, caller_id) do { \
- (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "400", "400", "default", NULL, 0, CHANNEL_TECH_NAME "/David"); \
+ (channel_var) = ast_channel_alloc(0, AST_STATE_DOWN, (caller_id)->id.number.str, (caller_id)->id.name.str, "400", "400", "default", NULL, NULL, 0, CHANNEL_TECH_NAME "/David"); \
APPEND_EVENT(channel_var, AST_CEL_CHANNEL_START, NULL, NULL); \
ast_channel_unlock((channel_var)); \
} while (0)
START_DIALED_FULL(caller, callee, "200", "Bob")
#define START_DIALED_FULL(caller, callee, number, name) do { \
- callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, number, NULL, NULL, ast_channel_linkedid(caller), 0, CHANNEL_TECH_NAME "/" name); \
+ callee = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, number, NULL, NULL, NULL, caller, 0, CHANNEL_TECH_NAME "/" name); \
ast_channel_unlock(callee); \
if (append_expected_event(callee, AST_CEL_CHANNEL_START, NULL, NULL, NULL)) { \
return AST_TEST_FAIL; \
}
type = stasis_message_type_create("test-type", NULL);
- chan = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, 0, "TEST/Alice");
+ chan = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, NULL, 0, "TEST/Alice");
ast_channel_unlock(chan);
json = ast_json_pack("{s: s}",
"foo", "bar");
}
type = stasis_message_type_create("test-type", NULL);
- chan = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, 0, "TEST/Alice");
+ chan = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, NULL, 0, "TEST/Alice");
ast_channel_unlock(chan);
json = ast_json_pack("{s: s}",
"foo", "bar");
json = ast_json_pack("{s: s}",
"type", "test");
- chan_alice = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, 0, "TEST/Alice");
+ chan_alice = ast_channel_alloc(0, AST_STATE_DOWN, "100", "Alice", "100", "100", "default", NULL, NULL, 0, "TEST/Alice");
ast_channel_unlock(chan_alice);
- chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, "200", "Bob", "200", "200", "default", NULL, 0, "TEST/Bob");
+ chan_bob = ast_channel_alloc(0, AST_STATE_DOWN, "200", "Bob", "200", "200", "default", NULL, NULL, 0, "TEST/Bob");
ast_channel_unlock(chan_bob);
- chan_charlie = ast_channel_alloc(0, AST_STATE_DOWN, "300", "Bob", "300", "300", "default", NULL, 0, "TEST/Charlie");
+ chan_charlie = ast_channel_alloc(0, AST_STATE_DOWN, "300", "Bob", "300", "300", "default", NULL, NULL, 0, "TEST/Charlie");
ast_channel_unlock(chan_charlie);
blob = ast_multi_channel_blob_create(json);
ast_test_validate(test, NULL == ast_channel_snapshot_to_json(NULL, NULL));
- chan = ast_channel_alloc(0, AST_STATE_DOWN, "cid_num", "cid_name", "acctcode", "exten", "context", NULL, 0, "TEST/name");
+ chan = ast_channel_alloc(0, AST_STATE_DOWN, "cid_num", "cid_name", "acctcode", "exten", "context", NULL, NULL, 0, "TEST/name");
ast_channel_unlock(chan);
ast_test_validate(test, NULL != chan);
ast_channel_lock(chan);
ast_test_validate(test, NULL != sub);
chan = ast_channel_alloc(0, AST_STATE_DOWN, "100", __func__, "100",
- "100", "default", NULL, 0, "TEST/test_res");
+ "100", "default", NULL, NULL, 0, "TEST/test_res");
ast_test_validate(test, NULL != chan);
ast_endpoint_add_channel(uut, chan);
ast_test_status_update(test, "Testing variable substitution ...\n");
- c = ast_channel_alloc(0, 0, "", "", "", "", "", "", 0, "Test/substitution");
+ c = ast_channel_alloc(0, 0, "", "", "", "", "", NULL, NULL, 0, "Test/substitution");
ast_channel_unlock(c);
#define TEST(t) if (t == AST_TEST_FAIL) { res = AST_TEST_FAIL; }
struct ast_channel *mock_channel;
struct ast_format_cap *native_formats;
- if (!(mock_channel = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, NULL, NULL, 0, 0, "TestChannel"))) {
+ if (!(mock_channel = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, "TestChannel"))) {
return NULL;
}