uniqueid: channel linkedid, ami, ari object creation with id's
authorScott Griepentrog <sgriepentrog@digium.com>
Fri, 7 Mar 2014 15:47:55 +0000 (15:47 +0000)
committerScott Griepentrog <sgriepentrog@digium.com>
Fri, 7 Mar 2014 15:47:55 +0000 (15:47 +0000)
Much needed was a way to assign id to objects on creation, and
much change was necessary to accomplish it.  Channel uniqueids
and linkedids are split into separate string and creation time
components without breaking linkedid propgation.  This allowed
the uniqueid to be specified by the user interface - and those
values are now carried through to channel creation, adding the
assignedids value to every function in the chain including the
channel drivers. For local channels, the second channel can be
specified or left to default to a ;2 suffix of first.  In ARI,
bridge, playback, and snoop objects can also be created with a
specified uniqueid.

Along the way, the args order to allocating channels was fixed
in chan_mgcp and chan_gtalk, and linkedid is no longer lost as
masquerade occurs.

(closes issue ASTERISK-23120)
Review: https://reviewboard.asterisk.org/r/3191/
........

Merged revisions 410157 from http://svn.asterisk.org/svn/asterisk/branches/12

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@410158 65c4cc65-6c06-0410-ace0-fbb531ad65f3

88 files changed:
addons/chan_mobile.c
addons/chan_ooh323.c
apps/app_agent_pool.c
apps/app_bridgewait.c
apps/app_chanisavail.c
apps/app_confbridge.c
apps/app_dial.c
apps/app_followme.c
apps/app_meetme.c
apps/app_originate.c
apps/app_page.c
apps/app_queue.c
apps/app_voicemail.c
apps/confbridge/conf_chan_announce.c
apps/confbridge/conf_chan_record.c
channels/chan_alsa.c
channels/chan_bridge_media.c
channels/chan_console.c
channels/chan_dahdi.c
channels/chan_gtalk.c
channels/chan_h323.c
channels/chan_iax2.c
channels/chan_jingle.c
channels/chan_mgcp.c
channels/chan_misdn.c
channels/chan_motif.c
channels/chan_multicast_rtp.c
channels/chan_nbs.c
channels/chan_oss.c
channels/chan_phone.c
channels/chan_pjsip.c
channels/chan_sip.c
channels/chan_skinny.c
channels/chan_unistim.c
channels/chan_vpb.cc
include/asterisk/bridge.h
include/asterisk/bridge_internal.h
include/asterisk/channel.h
include/asterisk/channel_internal.h
include/asterisk/core_unreal.h
include/asterisk/dial.h
include/asterisk/pbx.h
include/asterisk/stasis_app.h
include/asterisk/stasis_app_playback.h
include/asterisk/stasis_app_snoop.h
main/bridge.c
main/bridge_basic.c
main/bridge_channel.c
main/ccss.c
main/cel.c
main/channel.c
main/channel_internal_api.c
main/core_local.c
main/core_unreal.c
main/dial.c
main/manager.c
main/message.c
main/pbx.c
pbx/pbx_spool.c
res/ari/resource_bridges.c
res/ari/resource_bridges.h
res/ari/resource_channels.c
res/ari/resource_channels.h
res/parking/parking_applications.c
res/parking/parking_bridge.c
res/parking/parking_bridge_features.c
res/parking/parking_tests.c
res/res_ari_bridges.c
res/res_ari_channels.c
res/res_calendar.c
res/res_calendar_caldav.c
res/res_calendar_ews.c
res/res_calendar_exchange.c
res/res_calendar_icalendar.c
res/res_clioriginate.c
res/res_stasis.c
res/res_stasis_playback.c
res/res_stasis_snoop.c
res/stasis/control.c
rest-api/api-docs/bridges.json
rest-api/api-docs/channels.json
tests/test_app.c
tests/test_cdr.c
tests/test_cel.c
tests/test_stasis_channels.c
tests/test_stasis_endpoints.c
tests/test_substitution.c
tests/test_voicemail_api.c

index 197974a..a7cbc00 100644 (file)
@@ -209,9 +209,9 @@ static char *mblsendsms_desc =
 "  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);
@@ -838,7 +838,7 @@ e_return:
 */
 
 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;
@@ -855,7 +855,7 @@ static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, char *cid_num
        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;
@@ -887,7 +887,7 @@ 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;
@@ -946,7 +946,7 @@ static struct ast_channel *mbl_request(const char *type, struct ast_format_cap *
        }
 
        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");
@@ -3591,7 +3591,7 @@ static int handle_response_clip(struct mbl_pvt *pvt, char *buf)
                        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);
@@ -3681,7 +3681,7 @@ static int handle_response_cmgr(struct mbl_pvt *pvt, char *buf)
                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;
                }
@@ -4140,7 +4140,7 @@ static void *do_monitor_headset(void *data)
 
                                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;
index 4982165..bf465e2 100644 (file)
@@ -71,7 +71,7 @@ static struct ast_jb_conf global_jbconf;
 
 /* 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);
@@ -363,7 +363,8 @@ static pthread_t monitor_thread = AST_PTHREADT_NULL;
 
 
 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;
@@ -378,7 +379,7 @@ static struct ast_channel *ooh323_new(struct ooh323_pvt *i, int state,
        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);
@@ -569,7 +570,7 @@ static struct ooh323_pvt *ooh323_alloc(int callref, char *callToken)
        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;
@@ -718,7 +719,7 @@ static struct ast_channel *ooh323_request(const char *type, struct ast_format_ca
 
 
        chan = ooh323_new(p, AST_STATE_DOWN, p->username, cap,
-                                requestor ? ast_channel_linkedid(requestor) : NULL);
+                                assignedids, requestor);
        
        ast_mutex_unlock(&p->lock);
 
@@ -1918,7 +1919,7 @@ int ooh323_onReceivedSetup(ooCallData *call, Q931Message *pmsg)
        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");
index a44c75d..699be58 100644 (file)
@@ -1367,7 +1367,7 @@ static struct ast_bridge *bridge_agent_hold_new(void)
        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;
 }
index aa83e0b..222c9d9 100644 (file)
@@ -361,7 +361,7 @@ static struct wait_bridge_wrapper *get_wait_bridge_wrapper(const char *bridge_na
                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;
index 8eef4ca..afc763b 100644 (file)
@@ -171,7 +171,7 @@ static int chanavail_exec(struct ast_channel *chan, const char *data)
                        }
                        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);
index 10cfb09..d2e38bd 100644 (file)
@@ -691,7 +691,7 @@ static int conf_start_record(struct confbridge_conference *conference)
 
        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) {
@@ -1219,7 +1219,7 @@ static struct confbridge_conference *join_conference_bridge(const char *conferen
                /* 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;
@@ -1371,7 +1371,7 @@ static int alloc_playback_chan(struct confbridge_conference *conference)
                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) {
index ce73e9a..3b74346 100644 (file)
@@ -873,7 +873,7 @@ static void do_forward(struct chanlist *o, struct cause_args *num,
                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);
@@ -2429,7 +2429,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
                        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",
index 3171001..1fb22b1 100644 (file)
@@ -1056,7 +1056,7 @@ static struct ast_channel *findmeexec(struct fm_args *tpargs, struct ast_channel
                                                ? "/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",
index 37053b3..9198ea6 100644 (file)
@@ -1667,7 +1667,7 @@ static struct ast_conference *build_conf(const char *confno, const char *pin,
        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);
@@ -3087,7 +3087,7 @@ static void meetme_menu_admin_extended(enum menu_modes *menu_mode, int *dtmf, st
                        }
 
                        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;
@@ -3341,7 +3341,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
 
        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;
@@ -6344,7 +6344,7 @@ static int sla_ring_station(struct sla_ringing_trunk *ringing_trunk, struct sla_
        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;
        }
@@ -6850,7 +6850,7 @@ static void *dial_trunk(void *data)
 
        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);
@@ -8132,7 +8132,7 @@ AST_TEST_DEFINE(test_meetme_data_provider)
                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;
index f924921..b196194 100644 (file)
@@ -178,14 +178,14 @@ static int originate_exec(struct ast_channel *chan, const char *data)
 
                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);
index 31e75e4..f5e1460 100644 (file)
@@ -351,7 +351,7 @@ static int page_exec(struct ast_channel *chan, const char *data)
                }
 
                /* 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;
index cfd81b1..425ed89 100644 (file)
@@ -4058,7 +4058,7 @@ static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies
        }
 
        /* 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++;
@@ -4586,7 +4586,7 @@ static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callatte
 
                                        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",
index 44e88cb..f86e4c1 100644 (file)
@@ -13779,7 +13779,7 @@ AST_TEST_DEFINE(test_voicemail_vmsayname)
                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;
        }
index 952ef98..189a632 100644 (file)
@@ -77,7 +77,7 @@ static void announce_pvt_destructor(void *vdoomed)
        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;
@@ -102,7 +102,7 @@ static struct ast_channel *announce_request(const char *type, struct ast_format_
        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);
index 78d1f27..34de5af 100644 (file)
@@ -53,13 +53,13 @@ static int rec_write(struct ast_channel *ast, struct ast_frame *f)
        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) {
index a68a0b2..98adfdd 100644 (file)
@@ -141,7 +141,7 @@ static int autoanswer = 1;
 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);
@@ -574,11 +574,11 @@ static int alsa_indicate(struct ast_channel *chan, int cond, const void *data, s
        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);
@@ -614,7 +614,7 @@ static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state, const ch
        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];
@@ -632,7 +632,7 @@ static struct ast_channel *alsa_request(const char *type, struct ast_format_cap
        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");
        }
 
@@ -881,7 +881,7 @@ static char *console_dial(struct ast_cli_entry *e, int cmd, struct ast_cli_args
                        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);
        }
index 7aaca66..ac15e7d 100644 (file)
@@ -65,10 +65,10 @@ static int media_hangup(struct ast_channel *ast)
 }
 
 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",
@@ -114,7 +114,7 @@ static struct ast_channel_tech record_tech = {
        .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;
@@ -133,7 +133,7 @@ static struct ast_channel *media_request_helper(struct ast_format_cap *cap,
        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;
        }
@@ -150,15 +150,15 @@ static struct ast_channel *media_request_helper(struct ast_format_cap *cap,
 }
 
 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)
index 083af7c..b1f5cdf 100644 (file)
@@ -195,7 +195,7 @@ static struct ast_jb_conf global_jbconf;
 
 /*! 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);
@@ -419,12 +419,12 @@ static int stop_stream(struct console_pvt *pvt)
 /*!
  * \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;
        }
 
@@ -458,7 +458,7 @@ static struct ast_channel *console_new(struct console_pvt *pvt, const char *ext,
        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;
@@ -481,7 +481,7 @@ static struct ast_channel *console_request(const char *type, struct ast_format_c
        }
 
        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)
@@ -844,7 +844,7 @@ static char *cli_console_dial(struct ast_cli_entry *e, int cmd, struct ast_cli_a
        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);
index d89fffd..fb5877f 100644 (file)
@@ -969,7 +969,7 @@ static struct dahdi_chan_conf dahdi_chan_conf_default(void)
 }
 
 
-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);
@@ -2103,9 +2103,9 @@ static void my_swap_subchannels(void *pvt, enum analog_sub a, struct ast_channel
  *
  * \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)
 {
@@ -2114,7 +2114,7 @@ static struct ast_channel *my_new_analog_ast_channel(void *pvt, int state, int s
        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)
@@ -2129,7 +2129,7 @@ static int dahdi_setlaw(int dfd, int law)
 #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;
@@ -2172,7 +2172,7 @@ static struct ast_channel *my_new_pri_ast_channel(void *pvt, int state, enum sig
                        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) */
 
@@ -3030,7 +3030,7 @@ static void my_ss7_set_loopback(void *pvt, int enable)
  * \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;
@@ -3063,7 +3063,7 @@ static struct ast_channel *my_new_ss7_ast_channel(void *pvt, int state, enum sig
                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) */
 
@@ -3553,7 +3553,7 @@ static void dahdi_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, con
        }
        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
@@ -3607,7 +3607,7 @@ static void dahdi_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t
                        }
                        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 */
@@ -7784,7 +7784,7 @@ static struct ast_frame *dahdi_handle_event(struct ast_channel *ast)
                                         */
                                        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) {
@@ -8860,16 +8860,16 @@ static struct ast_str *create_channel_name(struct dahdi_pvt *i)
        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;
@@ -8899,7 +8899,7 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
                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;
@@ -10502,7 +10502,7 @@ static void *mwi_thread(void *data)
                                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)) {
@@ -10929,7 +10929,7 @@ static struct dahdi_pvt *handle_init_event(struct dahdi_pvt *i, int event)
                                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);
@@ -10938,7 +10938,7 @@ static struct dahdi_pvt *handle_init_event(struct dahdi_pvt *i, int event)
                                }
                        } 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);
@@ -10982,9 +10982,9 @@ static struct dahdi_pvt *handle_init_event(struct dahdi_pvt *i, int event)
                        /* 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) {
@@ -11112,7 +11112,7 @@ static struct dahdi_pvt *handle_init_event(struct dahdi_pvt *i, int event)
                                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)) {
@@ -11383,7 +11383,7 @@ static void *do_monitor(void *data)
                                                                        } 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 {
@@ -13161,7 +13161,7 @@ static struct dahdi_pvt *determine_starting_point(const char *data, struct dahdi
        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;
@@ -13262,7 +13262,7 @@ static struct ast_channel *dahdi_request(const char *type, struct ast_format_cap
                                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;
index 60213d3..032cb21 100644 (file)
@@ -186,7 +186,7 @@ static struct ast_format_cap *global_capability;
 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);
@@ -1133,7 +1133,7 @@ static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const
 }
 
 /*! \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;
@@ -1144,7 +1144,7 @@ static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i,
                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;
@@ -1367,7 +1367,7 @@ static int gtalk_newcall(struct gtalk *client, ikspak *pak)
                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;
@@ -1925,7 +1925,7 @@ static int gtalk_hangup(struct ast_channel *ast)
 }
 
 /*!\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;
@@ -1970,7 +1970,7 @@ static struct ast_channel *gtalk_request(const char *type, struct ast_format_cap
        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;
index 013e49e..2101d23 100644 (file)
@@ -252,7 +252,7 @@ static void prune_peers(void);
 
 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);
@@ -1039,7 +1039,7 @@ static int __oh323_rtp_create(struct oh323_pvt *pvt)
 }
 
 /*! \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;
@@ -1058,7 +1058,7 @@ static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const c
        
        /* 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);
@@ -1819,7 +1819,7 @@ static int create_addr(struct oh323_pvt *pvt, char *opeer)
                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;
@@ -1891,7 +1891,7 @@ static struct ast_channel *oh323_request(const char *type, struct ast_format_cap
        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);
@@ -2394,7 +2394,7 @@ static int answer_call(unsigned call_reference, const char *token)
        }
 
        /* 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);
index c0232f3..185abfc 100644 (file)
@@ -1253,7 +1253,7 @@ static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, c
 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);
@@ -5775,7 +5775,7 @@ static int iax2_getpeertrunk(struct ast_sockaddr addr)
 }
 
 /*! \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;
@@ -5790,7 +5790,7 @@ static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capab
 
        /* 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) {
@@ -10405,7 +10405,7 @@ static int socket_process_helper(struct iax2_thread *thread)
                    (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]);
@@ -11259,7 +11259,7 @@ static int socket_process_helper(struct iax2_thread *thread)
                                                                                        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;
@@ -11333,7 +11333,7 @@ immediatedial:
                                                                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;
@@ -12297,7 +12297,7 @@ static void free_context(struct iax2_context *con)
        }
 }
 
-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;
@@ -12358,7 +12358,7 @@ static struct ast_channel *iax2_request(const char *type, struct ast_format_cap
                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]);
 
index 410cb32..6855753 100644 (file)
@@ -181,7 +181,7 @@ static struct ast_format_cap *global_capability;
 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);
@@ -847,7 +847,7 @@ static void jingle_set_owner(struct jingle_pvt *pvt, struct ast_channel *chan)
 }
 
 /*! \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 */
@@ -858,7 +858,7 @@ static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *
                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;
@@ -1068,7 +1068,7 @@ static int jingle_newcall(struct jingle *client, ikspak *pak)
                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;
@@ -1575,7 +1575,7 @@ static int jingle_hangup(struct ast_channel *ast)
 }
 
 /*! \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;
@@ -1618,7 +1618,7 @@ static struct ast_channel *jingle_request(const char *type, struct ast_format_ca
        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;
index 3044882..ad2b8bc 100644 (file)
@@ -451,7 +451,7 @@ static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub
 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);
@@ -1488,14 +1488,14 @@ static int mgcp_indicate(struct ast_channel *ast, int ind, const void *data, siz
        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);
@@ -3336,7 +3336,7 @@ static void handle_hd_hf(struct mgcp_subchannel *sub, char *ev)
 #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");
@@ -3348,7 +3348,7 @@ static void handle_hd_hf(struct mgcp_subchannel *sub, char *ev)
                                } 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));
@@ -3942,7 +3942,7 @@ static int restart_monitor(void)
        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;
@@ -3981,7 +3981,7 @@ static struct ast_channel *mgcp_request(const char *type, struct ast_format_cap
                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);
index 02b5250..47d5947 100644 (file)
@@ -675,7 +675,7 @@ static int *misdn_ports;
 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);
@@ -7853,7 +7853,7 @@ static struct chan_list *chan_list_init(int orig)
        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] = "";
@@ -8087,7 +8087,7 @@ static struct ast_channel *misdn_request(const char *type, struct ast_format_cap
        }
        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);
@@ -8172,7 +8172,7 @@ static void update_name(struct ast_channel *tmp, 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 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;
@@ -8195,7 +8195,7 @@ static struct ast_channel *misdn_new(struct chan_list *chlist, int state,  char
                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);
 
@@ -10213,7 +10213,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
                                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) {
index 248f811..80b7f0d 100644 (file)
@@ -333,7 +333,7 @@ static AO2_GLOBAL_OBJ_STATIC(globals);
 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);
@@ -772,7 +772,7 @@ static struct jingle_session *jingle_alloc(struct jingle_endpoint *endpoint, con
 }
 
 /*! \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);
@@ -782,7 +782,7 @@ static struct ast_channel *jingle_new(struct jingle_endpoint *endpoint, struct j
                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;
        }
 
@@ -1892,7 +1892,7 @@ static int jingle_hangup(struct ast_channel *ast)
 }
 
 /*! \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);
@@ -1993,7 +1993,7 @@ static struct ast_channel *jingle_request(const char *type, struct ast_format_ca
                /* 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);
@@ -2405,7 +2405,7 @@ static void jingle_action_session_initiate(struct jingle_endpoint *endpoint, str
        }
 
        /* 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;
index e3d8f9b..730b2f4 100644 (file)
@@ -56,7 +56,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 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);
@@ -110,7 +110,7 @@ static int multicast_rtp_hangup(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;
@@ -149,7 +149,7 @@ static struct ast_channel *multicast_rtp_request(const char *type, struct ast_fo
                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;
        }
index 7cce241..cbfb6b3 100644 (file)
@@ -67,7 +67,7 @@ struct nbs_pvt {
        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);
@@ -218,10 +218,10 @@ static int nbs_xwrite(struct ast_channel *ast, struct ast_frame *frame)
        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));
@@ -252,7 +252,7 @@ static struct ast_channel *nbs_new(struct nbs_pvt *i, int state, const char *lin
 }
 
 
-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;
@@ -264,7 +264,7 @@ static struct ast_channel *nbs_request(const char *type, struct ast_format_cap *
        }
        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);
        }
index 3a52ac9..e5300ef 100644 (file)
@@ -334,7 +334,7 @@ static struct chan_oss_pvt oss_default = {
 
 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);
@@ -792,11 +792,11 @@ static int oss_indicate(struct ast_channel *c, int cond, const void *data, size_
 /*!
  * \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);
@@ -842,7 +842,7 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *o, char *ext, char *ctx,
        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;
@@ -872,7 +872,7 @@ static struct ast_channel *oss_request(const char *type, struct ast_format_cap *
                *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;
@@ -1131,7 +1131,7 @@ static char *console_dial(struct ast_cli_entry *e, int cmd, struct ast_cli_args
                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)
index 94a40ca..2adef52 100644 (file)
@@ -159,7 +159,7 @@ static struct phone_pvt {
 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);
@@ -855,12 +855,12 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
        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);
@@ -954,14 +954,14 @@ static void phone_check_exception(struct phone_pvt *i)
                             !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 */
@@ -979,7 +979,7 @@ static void phone_check_exception(struct phone_pvt *i)
                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 */
@@ -1015,7 +1015,7 @@ static void phone_check_exception(struct phone_pvt *i)
        }
        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");
@@ -1243,7 +1243,7 @@ static struct phone_pvt *mkif(const char *iface, int mode, int txgain, int rxgai
        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;
@@ -1261,7 +1261,7 @@ static struct ast_channel *phone_request(const char *type, struct ast_format_cap
                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;
index e324b33..fbd3e07 100644 (file)
@@ -81,7 +81,7 @@ static void chan_pjsip_pvt_dtor(void *obj)
 }
 
 /* \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);
@@ -340,7 +340,7 @@ static struct ast_rtp_glue chan_pjsip_rtp_glue = {
 };
 
 /*! \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;
@@ -352,7 +352,7 @@ static struct ast_channel *chan_pjsip_new(struct ast_sip_session *session, int s
                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;
        }
@@ -1677,7 +1677,7 @@ static int request(void *obj)
 }
 
 /*! \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);
@@ -1692,7 +1692,7 @@ static struct ast_channel *chan_pjsip_request(const char *type, struct ast_forma
 
        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;
        }
@@ -1918,7 +1918,7 @@ static int chan_pjsip_incoming_request(struct ast_sip_session *session, struct p
        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);
                }
index 6b7a3e4..36680d9 100644 (file)
@@ -1167,7 +1167,7 @@ struct show_peers_context;
        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);
@@ -8057,7 +8057,7 @@ static int sip_indicate(struct ast_channel *ast, int condition, const void *data
  *
  * \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;
@@ -8079,7 +8079,7 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
 
                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");
@@ -25484,7 +25484,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str
                        /* 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);
@@ -29496,7 +29496,7 @@ static int sip_devicestate(const char *data)
  *     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;
@@ -29707,7 +29707,7 @@ static struct ast_channel *sip_request_call(const char *type, struct ast_format_
 
        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);
        }
index 57b6574..cf0b072 100644 (file)
@@ -1627,7 +1627,7 @@ struct skinnysession {
        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);
@@ -5397,7 +5397,7 @@ static void skinny_set_owner(struct skinny_subchannel* sub, struct ast_channel*
        }
 }
 
-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;
@@ -5410,7 +5410,7 @@ static struct ast_channel *skinny_new(struct skinny_line *l, struct skinny_subli
                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;
@@ -6145,7 +6145,7 @@ static int handle_transfer_button(struct skinny_subchannel *sub)
                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 */
@@ -6190,7 +6190,7 @@ static void handle_callforward_button(struct skinny_line *l, struct skinny_subch
                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;
                        }
@@ -6370,7 +6370,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
                        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 {
@@ -6391,7 +6391,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
                }
 
                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;
 
@@ -6426,7 +6426,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
                        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;
                }
@@ -6538,7 +6538,7 @@ static int handle_stimulus_message(struct skinny_req *req, struct skinnysession
                        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 {
@@ -6609,7 +6609,7 @@ static int handle_offhook_message(struct skinny_req *req, struct skinnysession *
                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 {
@@ -6965,7 +6965,7 @@ static int handle_enbloc_call_message(struct skinny_req *req, struct skinnysessi
                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);
@@ -7026,7 +7026,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
                }
 
                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;
                }
@@ -7043,7 +7043,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
                        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) {
@@ -7155,7 +7155,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
                } 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 {
@@ -7232,7 +7232,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
                {
                        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 {
@@ -7254,7 +7254,7 @@ static int handle_soft_key_event_message(struct skinny_req *req, struct skinnyse
                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;
                }
@@ -7707,7 +7707,7 @@ static int skinny_devicestate(const char *data)
        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;
@@ -7734,7 +7734,7 @@ static struct ast_channel *skinny_request(const char *type, struct ast_format_ca
                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) {
index 5e06366..c625dc5 100644 (file)
@@ -681,14 +681,14 @@ static const char tdesc[] = "UNISTIM Channel Driver";
 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);
@@ -3071,7 +3071,7 @@ static void handle_call_outgoing(struct unistimsession *s)
                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;
@@ -3127,7 +3127,7 @@ static void handle_call_outgoing(struct unistimsession *s)
                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);
                }
@@ -5607,7 +5607,7 @@ static int unistim_send_mwi_to_peer(struct unistim_line *peer, unsigned int tick
 
 /*--- 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;
@@ -5623,7 +5623,7 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state
        }
        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);
        }
@@ -5841,7 +5841,7 @@ static int restart_monitor(void)
 
 /*--- 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;
@@ -5905,7 +5905,7 @@ static struct ast_channel *unistim_request(const char *type, struct ast_format_c
        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);
        }
index 5ea24cc..f1a45ab 100644 (file)
@@ -347,9 +347,9 @@ static struct vpb_pvt {
 
 } *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);
@@ -1118,7 +1118,7 @@ static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e)
                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");
@@ -1142,7 +1142,7 @@ static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e)
 
        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);
@@ -1187,7 +1187,7 @@ static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e)
                        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! */
@@ -1263,11 +1263,11 @@ static inline int monitor_handle_notowned(struct vpb_pvt *p, VPB_EVENT *e)
                                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);
@@ -2424,7 +2424,7 @@ static void *do_chanreads(void *pvt)
        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];
@@ -2437,7 +2437,7 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state st
        }
        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);
@@ -2501,7 +2501,7 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state st
        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;
@@ -2534,13 +2534,13 @@ static struct ast_channel *vpb_request(const char *type, struct ast_format_cap *
                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;
                        }
                }
index 0706b3a..d8c27f4 100644 (file)
@@ -333,6 +333,7 @@ extern struct ast_bridge_methods ast_bridge_base_v_table;
  * \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
@@ -347,7 +348,7 @@ extern struct ast_bridge_methods ast_bridge_base_v_table;
  * 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.
index e9726a1..e50e7f9 100644 (file)
@@ -89,6 +89,7 @@ struct ast_bridge *bridge_alloc(size_t size, const struct ast_bridge_methods *v_
  * \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
@@ -98,13 +99,13 @@ struct ast_bridge *bridge_alloc(size_t size, const struct ast_bridge_methods *v_
  * \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
index 106117d..aa2f863 100644 (file)
@@ -562,6 +562,15 @@ typedef struct {
 } 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
  * See for examples:
@@ -588,6 +597,7 @@ struct ast_channel_tech {
         *
         * \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
@@ -599,7 +609,7 @@ struct ast_channel_tech {
         * \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 */
 
@@ -1129,11 +1139,11 @@ struct ast_datastore *ast_channel_datastore_find(struct ast_channel *chan, const
  *       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, ...);
 
@@ -1148,8 +1158,8 @@ struct ast_channel * attribute_malloc __attribute__((format(printf, 13, 14)))
  *       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)
@@ -1338,6 +1348,7 @@ struct ast_channel *ast_channel_release(struct ast_channel *chan);
  *
  * \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
@@ -1349,7 +1360,7 @@ struct ast_channel *ast_channel_release(struct ast_channel *chan);
  * \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
@@ -1357,6 +1368,7 @@ struct ast_channel *ast_request(const char *type, struct ast_format_cap *request
  *
  * \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
@@ -1367,7 +1379,7 @@ struct ast_channel *ast_request(const char *type, struct ast_format_cap *request
  * \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);
 
 /*!
@@ -1375,6 +1387,7 @@ struct ast_channel *ast_request_and_dial(const char *type, struct ast_format_cap
  * 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
@@ -1385,7 +1398,7 @@ struct ast_channel *ast_request_and_dial(const char *type, struct ast_format_cap
  * \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);
 
 /*!
@@ -2365,6 +2378,46 @@ void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_sil
  */
 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 */
 
 /*!
index c94cc46..d1231b4 100644 (file)
@@ -18,8 +18,8 @@
  * \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);
index cd8a2cd..e118c74 100644 (file)
@@ -206,8 +206,8 @@ struct ast_unreal_pvt *ast_unreal_alloc(size_t size, ao2_destructor_fn destructo
  */
 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.
index 19b1c87..b61116f 100644 (file)
@@ -72,7 +72,7 @@ struct ast_dial *ast_dial_create(void);
  * \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
index 77694a5..784b976 100644 (file)
@@ -1122,12 +1122,15 @@ int ast_async_goto_by_name(const char *chan, const char *context, const char *ex
  * \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.
@@ -1148,13 +1151,16 @@ int ast_pbx_outgoing_exten(const char *type, struct ast_format_cap *cap, const c
  * \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
index ac5c648..40ec208 100644 (file)
@@ -598,11 +598,12 @@ int stasis_app_control_queue_control(struct stasis_app_control *control,
  *
  * \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.
index 3587871..b352995 100644 (file)
@@ -90,6 +90,7 @@ enum stasis_app_playback_target_type {
  * \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.
  */
@@ -97,7 +98,7 @@ struct stasis_app_playback *stasis_app_control_play_uri(
        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.
index a9c998f..c261a88 100644 (file)
@@ -55,6 +55,6 @@ enum stasis_app_snoop_direction {
  */
 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 */
index 8acf260..1baf01c 100644 (file)
@@ -732,7 +732,7 @@ struct ast_bridge *bridge_alloc(size_t size, const struct ast_bridge_methods *v_
        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];
 
@@ -740,8 +740,12 @@ struct ast_bridge *bridge_base_init(struct ast_bridge *self, uint32_t capabiliti
                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);
@@ -901,12 +905,12 @@ struct ast_bridge_methods ast_bridge_base_v_table = {
        .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;
 }
@@ -3716,7 +3720,7 @@ static enum ast_transfer_result blind_transfer_bridge(struct ast_channel *transf
        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;
@@ -3879,7 +3883,7 @@ static enum ast_transfer_result attended_transfer_bridge(struct ast_channel *cha
        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) {
index 317c574..4a68f49 100644 (file)
@@ -2237,7 +2237,7 @@ static int recalling_enter(struct attended_transfer_properties *props)
                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;
        }
 
@@ -2360,7 +2360,7 @@ static int retransfer_enter(struct attended_transfer_properties *props)
        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;
@@ -2920,7 +2920,7 @@ static struct ast_channel *dial_transfer(struct ast_channel *caller, const char
        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;
@@ -3239,7 +3239,7 @@ struct ast_bridge *ast_bridge_basic_new(void)
        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;
index ae33cd0..06da4ee 100644 (file)
@@ -222,28 +222,27 @@ void ast_bridge_channel_update_linkedids(struct ast_bridge_channel *bridge_chann
 {
        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);
        }
 }
index fadc6e3..6251473 100644 (file)
@@ -2827,7 +2827,7 @@ static void *generic_recall(void *data)
        }
 
        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",
index 1cd5099..d1602f8 100644 (file)
@@ -829,8 +829,7 @@ struct ast_channel *ast_cel_fabricate_channel_from_event(const struct ast_event
        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);
index da4f794..0252bd8 100644 (file)
@@ -857,8 +857,8 @@ static void ast_dummy_channel_destructor(void *obj);
 /*! \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;
@@ -876,7 +876,7 @@ __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char
                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;
        }
@@ -1039,8 +1039,8 @@ __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char
 
 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, ...)
 {
@@ -1049,7 +1049,7 @@ struct ast_channel *__ast_channel_alloc(int needqueue, int state, const char *ci
 
        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;
@@ -1066,7 +1066,7 @@ struct ast_channel *ast_dummy_channel_alloc(void)
        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;
        }
@@ -5595,7 +5595,7 @@ struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_chan
                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);
@@ -5645,7 +5645,7 @@ struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_chan
        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;
@@ -5659,7 +5659,7 @@ struct ast_channel *__ast_request_and_dial(const char *type, struct ast_format_c
        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);
@@ -5831,9 +5831,9 @@ struct ast_channel *__ast_request_and_dial(const char *type, struct ast_format_c
        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)
@@ -5876,7 +5876,7 @@ static int set_security_requirements(const struct ast_channel *requestor, struct
        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;
@@ -5933,7 +5933,7 @@ struct ast_channel *ast_request(const char *type, struct ast_format_cap *request
                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;
                }
@@ -6330,55 +6330,6 @@ static void clone_variables(struct ast_channel *original, struct ast_channel *cl
        }
 }
 
-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)
 {
@@ -6422,7 +6373,6 @@ static void channel_do_masquerade(struct ast_channel *original, struct ast_chann
        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;
 
@@ -6488,9 +6438,7 @@ static void channel_do_masquerade(struct ast_channel *original, struct ast_chann
        /* 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.
@@ -10203,7 +10151,6 @@ struct ast_channel *ast_channel_yank(struct ast_channel *yankee)
                char *accountcode;
                char *exten;
                char *context;
-               char *linkedid;
                char *name;
                int amaflags;
                struct ast_format readformat;
@@ -10214,7 +10161,6 @@ struct ast_channel *ast_channel_yank(struct ast_channel *yankee)
        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));
@@ -10224,7 +10170,7 @@ struct ast_channel *ast_channel_yank(struct ast_channel *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;
        }
index 51d83e1..d444d7f 100644 (file)
@@ -51,6 +51,16 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #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.
  *
  * \note When adding fields to this structure, it is important to add the field
@@ -101,13 +111,14 @@ struct ast_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 */
 
@@ -239,8 +250,6 @@ AST_DATA_STRUCTURE(ast_callerid, DATA_EXPORT_CALLERID);
        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)                       \
@@ -314,6 +323,9 @@ int ast_channel_data_add_structure(struct ast_data *tree,
                }
        }
 
+       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));
@@ -450,8 +462,6 @@ DEFINE_STRINGFIELD_SETTERS_FOR(accountcode, 1, 0);
 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);
@@ -469,12 +479,22 @@ DEFINE_STRINGFIELD_GETTER_FOR(accountcode);
 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;
@@ -1379,7 +1399,7 @@ static int pvt_cause_cmp_fn(void *obj, void *vstr, int flags)
 
 #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)
@@ -1400,23 +1420,75 @@ struct ast_channel *__ast_channel_internal_alloc(void (*destructor)(void *obj),
                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) {
@@ -1480,7 +1552,7 @@ int ast_channel_forward_endpoint(struct ast_channel *chan,
 
 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)) {
index edf2839..98db5e5 100644 (file)
@@ -137,7 +137,7 @@ static const char tdesc[] = "Local Proxy Channel Driver";
 
 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);
@@ -869,7 +869,7 @@ static struct local_pvt *local_alloc(const char *data, struct ast_format_cap *ca
 }
 
 /*! \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;
@@ -882,7 +882,7 @@ static struct ast_channel *local_request(const char *type, struct ast_format_cap
        }
        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);
        }
index 7ab7da7..bc081f5 100644 (file)
@@ -888,15 +888,29 @@ struct ast_unreal_pvt *ast_unreal_alloc(size_t size, ao2_destructor_fn destructo
 
 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
         *
@@ -905,7 +919,7 @@ struct ast_channel *ast_unreal_new_channels(struct ast_unreal_pvt *p,
         * 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;
@@ -944,7 +958,7 @@ struct ast_channel *ast_unreal_new_channels(struct ast_unreal_pvt *p,
        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);
index 6ff0e7f..246d4f4 100644 (file)
@@ -69,6 +69,8 @@ struct ast_dial_channel {
        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 */
 };
@@ -247,7 +249,7 @@ struct ast_dial *ast_dial_create(void)
  * \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;
 
@@ -263,6 +265,16 @@ int ast_dial_append(struct ast_dial *dial, const char *tech, const char *device)
        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);
 
@@ -281,6 +293,7 @@ static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channe
        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));
@@ -296,7 +309,7 @@ static int begin_dial_prerun(struct ast_dial_channel *channel, struct ast_channe
        }
 
        /* 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;
        }
@@ -461,6 +474,14 @@ static int handle_call_forward(struct ast_dial *dial, struct ast_dial_channel *c
        /* 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);
@@ -1045,6 +1066,13 @@ int ast_dial_destroy(struct ast_dial *dial)
                /* 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);
        }
index 0952939..18755b5 100644 (file)
@@ -542,6 +542,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
                        <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
@@ -4381,6 +4387,8 @@ struct fast_originate_helper {
                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;
@@ -4408,19 +4416,20 @@ static void *fast_originate(void *data)
        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;
@@ -4701,6 +4710,10 @@ static int action_originate(struct mansession *s, const struct message *m)
        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;
@@ -4715,6 +4728,11 @@ static int action_originate(struct mansession *s, const struct message *m)
        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;
@@ -4842,6 +4860,8 @@ static int action_originate(struct mansession *s, const struct message *m)
                        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. */
@@ -4856,11 +4876,11 @@ static int action_originate(struct mansession *s, const struct message *m)
                        }
                }
        } 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'");
index 7690e4a..70bda41 100644 (file)
@@ -671,7 +671,7 @@ static struct ast_channel *create_msg_q_chan(void)
 
        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) {
index 3662e85..b24bcd8 100644 (file)
@@ -10213,7 +10213,7 @@ static void pbx_outgoing_state_callback(struct ast_dial *dial)
 
 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;
@@ -10240,7 +10240,7 @@ static int pbx_outgoing_attempt(const char *type, struct ast_format_cap *cap, co
                return -1;
        }
 
-       if (ast_dial_append(outgoing->dial, type, addr)) {
+       if (ast_dial_append(outgoing->dial, type, addr, assignedids)) {
                return -1;
        }
 
@@ -10355,7 +10355,7 @@ static int pbx_outgoing_attempt(const char *type, struct ast_format_cap *cap, co
 
        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] = "";
@@ -10384,20 +10384,20 @@ static int pbx_outgoing_attempt(const char *type, struct ast_format_cap *cap, co
        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 --
index 31d883c..4461d7f 100644 (file)
@@ -375,14 +375,14 @@ static void *attempt_thread(void *data)
                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) {
index a8f2c3c..418b7c8 100644 (file)
@@ -314,7 +314,7 @@ static struct ast_channel *prepare_bridge_media_channel(const char *type)
                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,
@@ -370,7 +370,7 @@ 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);
@@ -697,7 +697,7 @@ void ast_ari_bridges_create(struct ast_variable *headers,
        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) {
@@ -718,3 +718,49 @@ void ast_ari_bridges_create(struct ast_variable *headers,
        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()));
+}
index 38ccb29..1b87823 100644 (file)
@@ -54,6 +54,8 @@ void ast_ari_bridges_list(struct ast_variable *headers, struct ast_ari_bridges_l
 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;
 };
@@ -78,6 +80,36 @@ int ast_ari_bridges_create_parse_body(
  * \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 */
index 3552070..2d074a1 100644 (file)
@@ -354,8 +354,13 @@ void ast_ari_channels_stop_silence(struct ast_variable *headers,
        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);
@@ -367,7 +372,7 @@ void ast_ari_channels_play(struct ast_variable *headers,
 
        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;
@@ -381,24 +386,24 @@ void ast_ari_channels_play(struct ast_variable *headers,
                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",
@@ -426,6 +431,34 @@ void ast_ari_channels_play(struct ast_variable *headers,
        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)
@@ -583,7 +616,7 @@ void ast_ari_channels_get(struct ast_variable *headers,
        }
 
        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",
@@ -698,8 +731,8 @@ static int json_to_ast_variables(struct ast_json *json_variables, struct ast_var
                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;
@@ -718,8 +751,17 @@ static int json_to_ast_variables(struct ast_json *json_variables, struct ast_var
        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;
@@ -731,10 +773,15 @@ void ast_ari_channels_originate(struct ast_variable *headers,
        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);
@@ -742,28 +789,13 @@ void ast_ari_channels_originate(struct ast_variable *headers,
        }
        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));
@@ -775,14 +807,14 @@ void ast_ari_channels_originate(struct ast_variable *headers,
                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)) {
@@ -790,7 +822,7 @@ void ast_ari_channels_originate(struct ast_variable *headers,
                }
        }
 
-       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);
@@ -800,19 +832,19 @@ void ast_ari_channels_originate(struct ast_variable *headers,
                        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;
                }
@@ -825,19 +857,91 @@ void ast_ari_channels_originate(struct ast_variable *headers,
        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)
@@ -902,7 +1006,14 @@ void ast_ari_channels_set_channel_var(struct ast_variable *headers,
        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);
@@ -911,13 +1022,13 @@ void ast_ari_channels_snoop_channel(struct ast_variable *headers, struct ast_ari
 
        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(
@@ -926,13 +1037,13 @@ void ast_ari_channels_snoop_channel(struct ast_variable *headers, struct ast_ari
                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(
@@ -946,14 +1057,14 @@ void ast_ari_channels_snoop_channel(struct ast_variable *headers, struct ast_ari
                        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",
@@ -961,7 +1072,8 @@ void ast_ari_channels_snoop_channel(struct ast_variable *headers, struct ast_ari
                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",
@@ -972,3 +1084,31 @@ void ast_ari_channels_snoop_channel(struct ast_variable *headers, struct ast_ari
        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);
+}
index 7f740a6..cf48cee 100644 (file)
@@ -70,6 +70,10 @@ struct ast_ari_channels_originate_args {
        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.
@@ -105,6 +109,52 @@ struct ast_ari_channels_get_args {
  * \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 */
@@ -393,6 +443,8 @@ struct ast_ari_channels_play_args {
        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.
@@ -415,6 +467,42 @@ int ast_ari_channels_play_parse_body(
  * \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 */
@@ -521,6 +609,8 @@ struct ast_ari_channels_snoop_channel_args {
        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.
@@ -543,5 +633,41 @@ int ast_ari_channels_snoop_channel_parse_body(
  * \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 */
index 2d481e4..85075bc 100644 (file)
@@ -704,7 +704,7 @@ static void announce_to_dial(char *dial_string, char *announce_string, int parki
 
        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,
index bb9dbf3..448d4ed 100644 (file)
@@ -456,7 +456,7 @@ struct ast_bridge *bridge_parking_new(struct parking_lot *bridge_lot)
        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;
index bf211a2..e9f8141 100644 (file)
@@ -200,7 +200,7 @@ static struct ast_channel *park_local_transfer(struct ast_channel *parker, const
        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;
index f676776..ea7fd31 100644 (file)
@@ -54,7 +54,7 @@ static const struct ast_party_caller alice_callerid = {
 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) {
index e1c9fe6..890a2ac 100644 (file)
@@ -112,6 +112,10 @@ int ast_ari_bridges_create_parse_body(
        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);
@@ -143,6 +147,9 @@ static void ast_ari_bridges_create_cb(
                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
@@ -199,6 +206,109 @@ static void ast_ari_bridges_create_cb(
 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;
+}
 /*!
  * \brief Parameter parsing callback for /bridges/{bridgeId}.
  * \param get_params GET parameters in the HTTP request.
@@ -1129,6 +1239,7 @@ static struct stasis_rest_handlers bridges_bridgeId = {
        .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,
        },
index 12ef168..ac159bf 100644 (file)
@@ -140,6 +140,14 @@ int ast_ari_channels_originate_parse_body(
        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;
 }
 
@@ -188,6 +196,12 @@ static void ast_ari_channels_originate_cb(
                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 */
@@ -298,6 +312,156 @@ static void ast_ari_channels_get_cb(
 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;
+}
 int ast_ari_channels_hangup_parse_body(
        struct ast_json *body,
        struct ast_ari_channels_hangup_args *args)
@@ -1431,6 +1595,10 @@ int ast_ari_channels_play_parse_body(
        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;
 }
 
@@ -1467,6 +1635,9 @@ static void ast_ari_channels_play_cb(
                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) {
@@ -1528,6 +1699,128 @@ static void ast_ari_channels_play_cb(
 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;
+}
 int ast_ari_channels_record_parse_body(
        struct ast_json *body,
        struct ast_ari_channels_record_args *args)
@@ -1897,6 +2190,10 @@ int ast_ari_channels_snoop_channel_parse_body(
        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;
 }
 
@@ -1933,6 +2230,9 @@ static void ast_ari_channels_snoop_channel_cb(
                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) {
@@ -1994,6 +2294,128 @@ static void ast_ari_channels_snoop_channel_cb(
 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;
+}
 
 /*! \brief REST handler for /api-docs/channels.{format} */
 static struct stasis_rest_handlers channels_channelId_continue = {
@@ -2073,13 +2495,23 @@ static struct stasis_rest_handlers channels_channelId_silence = {
        .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 = {
@@ -2101,13 +2533,23 @@ static struct stasis_rest_handlers channels_channelId_variable = {
        .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 = {
@@ -2115,6 +2557,7 @@ 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,
index c36e5cf..f279e73 100644 (file)
@@ -41,6 +41,7 @@
 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"
@@ -745,7 +746,7 @@ static void *do_notify(void *data)
                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;
        }
@@ -753,7 +754,7 @@ static void *do_notify(void *data)
        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;
        }
index b1dd628..0bf3e63 100644 (file)
@@ -41,6 +41,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include <libxml/parser.h>
 
 #include "asterisk/module.h"
+#include "asterisk/channel.h"
 #include "asterisk/calendar.h"
 #include "asterisk/lock.h"
 #include "asterisk/config.h"
index 3cf0d74..c6d827f 100644 (file)
@@ -40,6 +40,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include <ne_redirect.h>
 
 #include "asterisk/module.h"
+#include "asterisk/channel.h"
 #include "asterisk/calendar.h"
 #include "asterisk/lock.h"
 #include "asterisk/config.h"
index acfdcee..3f902a3 100644 (file)
@@ -40,6 +40,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include <iksemel.h>
 
 #include "asterisk/module.h"
+#include "asterisk/channel.h"
 #include "asterisk/calendar.h"
 #include "asterisk/lock.h"
 #include "asterisk/config.h"
index 3aea7a4..84b4e68 100644 (file)
@@ -38,6 +38,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include <ne_redirect.h>
 
 #include "asterisk/module.h"
+#include "asterisk/channel.h"
 #include "asterisk/calendar.h"
 #include "asterisk/lock.h"
 #include "asterisk/config.h"
index 0d639c7..cd8b5dd 100644 (file)
@@ -74,7 +74,7 @@ static char *orig_app(int fd, const char *chan, const char *app, const char *app
                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;
@@ -119,7 +119,7 @@ static char *orig_exten(int fd, const char *chan, const char *data)
                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;
index f6fc0ac..3a92971 100644 (file)
@@ -441,7 +441,7 @@ static struct ast_channel *prepare_bridge_moh_channel(void)
 
        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 */
@@ -585,7 +585,7 @@ static void control_unlink(struct stasis_app_control *control)
        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;
@@ -604,7 +604,7 @@ struct ast_bridge *stasis_app_bridge_create(const char *type, const char *name)
                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);
index c08c2fa..ee4a20b 100644 (file)
@@ -125,10 +125,10 @@ static void playback_dtor(void *obj)
 }
 
 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) {
@@ -147,8 +147,12 @@ static struct stasis_app_playback *playback_create(
                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;
 
@@ -462,7 +466,7 @@ struct stasis_app_playback *stasis_app_control_play_uri(
        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);
 
@@ -473,7 +477,7 @@ struct stasis_app_playback *stasis_app_control_play_uri(
        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;
index 65186d1..eaa2160 100644 (file)
@@ -286,10 +286,11 @@ static void snoop_determine_format(struct ast_channel *chan, struct stasis_app_s
 
 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) {
@@ -323,7 +324,7 @@ struct ast_channel *stasis_app_control_snoop(struct ast_channel *chan,
        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;
index 6b09291..d813a24 100644 (file)
@@ -293,7 +293,7 @@ static int app_control_dial(struct stasis_app_control *control,
                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;
        }
index b259ca8..3e89978 100644 (file)
                                                        }
                                                },
                                                {
+                                                       "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.",
                                                        "paramType": "query",
                        "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.",
                                        "nickname": "get",
index 0cfe90e..df90a4f 100644 (file)
                                                        "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
+                                               },
+