]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Merged revisions 372841 via svnmerge from
authorAutomerge script <automerge@asterisk.org>
Tue, 11 Sep 2012 16:22:33 +0000 (16:22 +0000)
committerAutomerge script <automerge@asterisk.org>
Tue, 11 Sep 2012 16:22:33 +0000 (16:22 +0000)
file:///srv/subversion/repos/asterisk/branches/10

................
  r372841 | mmichelson | 2012-09-11 10:30:37 -0500 (Tue, 11 Sep 2012) | 15 lines

  Fix bad channel application data reference.

  When channels get bridged due to an AMI bridge action
  or a DTMF attended transfer, the two channels that
  get bridged have their application data pointing to
  the other channel's name. This means that if one channel
  is hung up but the other moves on, it means that the
  channel that moves on will have its application data
  pointing at freed memory.

  (issue ASTERISK-20335)
  ........

  Merged revisions 372840 from http://svn.asterisk.org/svn/asterisk/branches/1.8
................

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/10-digiumphones@372861 65c4cc65-6c06-0410-ace0-fbb531ad65f3

main/features.c

index f01d5d5cb26b102740dfc30bc70d340ba2598d94..a12d0527c335f5e1dc99d285a9cab69b39d8db06 100644 (file)
@@ -957,6 +957,33 @@ static struct ast_channel *feature_request_and_dial(struct ast_channel *caller,
        struct ast_channel *transferee, const char *type, struct ast_format_cap *cap, void *data,
        int timeout, int *outstate, const char *language);
 
+static const struct ast_datastore_info channel_app_data_datastore = {
+       .type = "Channel appdata datastore",
+       .destroy = ast_free_ptr,
+};
+
+static int set_chan_app_data(struct ast_channel *chan, const char *src_app_data)
+{
+       struct ast_datastore *datastore;
+       char *dst_app_data;
+
+       datastore = ast_datastore_alloc(&channel_app_data_datastore, NULL);
+       if (!datastore) {
+               return -1;
+       }
+
+       dst_app_data = ast_malloc(strlen(src_app_data) + 1);
+       if (!dst_app_data) {
+               ast_datastore_free(datastore);
+               return -1;
+       }
+
+       chan->data = strcpy(dst_app_data, src_app_data);
+       datastore->data = dst_app_data;
+       ast_channel_datastore_add(chan, datastore);
+       return 0;
+}
+
 /*!
  * \brief bridge the call 
  * \param data thread bridge.
@@ -970,9 +997,13 @@ static void *bridge_call_thread(void *data)
        struct ast_bridge_thread_obj *tobj = data;
 
        tobj->chan->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
-       tobj->chan->data = tobj->peer->name;
+       if (set_chan_app_data(tobj->chan, tobj->peer->name)) {
+               tobj->chan->data = "(Empty)";
+       }
        tobj->peer->appl = !tobj->return_to_pbx ? "Transferred Call" : "ManagerBridge";
-       tobj->peer->data = tobj->chan->name;
+       if (set_chan_app_data(tobj->peer, tobj->chan->name)) {
+               tobj->peer->data = "(Empty)";
+       }
 
        ast_bridge_call(tobj->peer, tobj->chan, &tobj->bconfig);