git migration: Refactor the ASTERISK_FILE_VERSION macro
[asterisk/asterisk.git] / main / channel_internal_api.c
index d444d7f..a2fafbf 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "asterisk.h"
 
-ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+ASTERISK_REGISTER_FILE()
 
 #include <unistd.h>
 #include <fcntl.h>
@@ -57,7 +57,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 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 */
+       char unique_id[AST_MAX_UNIQUEID];       /*!< Unique Identifier */
 };
 
 /*!
@@ -96,7 +96,7 @@ struct ast_channel {
        struct ast_tone_zone *zone;                     /*!< Tone zone as set in indications.conf or
                                                         *   in the CHANNEL dialplan function */
        struct ast_channel_monitor *monitor;            /*!< Channel monitoring */
-       struct ast_callid *callid;                      /*!< Bound call identifier pointer */
+       ast_callid callid;                      /*!< Bound call identifier pointer */
 #ifdef HAVE_EPOLL
        struct ast_epoll_data *epfd_data[AST_MAX_FDS];
 #endif
@@ -173,10 +173,12 @@ struct ast_channel {
                                                         *   See \arg \ref AstFileDesc */
        int softhangup;                         /*!< Whether or not we have been hung up...  Do not set this value
                                                         *   directly, use ast_softhangup() */
+       int unbridged;              /*!< If non-zero, the bridge core needs to re-evaluate the current
+                                        bridging technology which is in use by this channel's bridge. */
        int fdno;                                       /*!< Which fd had an event detected on */
        int streamid;                                   /*!< For streaming playback, the schedule ID */
        int vstreamid;                                  /*!< For streaming video playback, the schedule ID */
-       struct ast_format oldwriteformat;  /*!< Original writer format */
+       struct ast_format *oldwriteformat;  /*!< Original writer format */
        int timingfd;                                   /*!< Timing fd */
        enum ast_channel_state state;                   /*!< State of line -- Don't write directly, use ast_setstate() */
        int rings;                                      /*!< Number of rings so far */
@@ -193,10 +195,10 @@ struct ast_channel {
        struct ast_flags flags;                         /*!< channel flags of AST_FLAG_ type */
        int alertpipe[2];
        struct ast_format_cap *nativeformats;         /*!< Kinds of data this channel can natively handle */
-       struct ast_format readformat;            /*!< Requested read format (after translation) */
-       struct ast_format writeformat;           /*!< Requested write format (after translation) */
-       struct ast_format rawreadformat;         /*!< Raw read format (before translation) */
-       struct ast_format rawwriteformat;        /*!< Raw write format (before translation) */
+       struct ast_format *readformat;            /*!< Requested read format (after translation) */
+       struct ast_format *writeformat;           /*!< Requested write format (before translation) */
+       struct ast_format *rawreadformat;         /*!< Raw read format (before translation) */
+       struct ast_format *rawwriteformat;        /*!< Raw write format (after translation) */
        unsigned int emulate_dtmf_duration;             /*!< Number of ms left to emulate DTMF for */
 #ifdef HAVE_EPOLL
        int epfd;
@@ -219,6 +221,7 @@ struct ast_channel {
        struct timeval sending_dtmf_tv;         /*!< The time this channel started sending the current digit. (Invalid if sending_dtmf_digit is zero.) */
        struct stasis_cp_single *topics;                /*!< Topic for all channel's events */
        struct stasis_forward *endpoint_forward;        /*!< Subscription for event forwarding to endpoint's topic */
+       struct stasis_forward *endpoint_cache_forward; /*!< Subscription for cache updates to endpoint's topic */
 };
 
 /*! \brief The monotonically increasing integer counter for channel uniqueids */
@@ -376,7 +379,6 @@ int ast_channel_data_add_structure(struct ast_data *tree,
        ast_data_add_bool(data_softhangup, "timeout", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_TIMEOUT);
        ast_data_add_bool(data_softhangup, "appunload", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_APPUNLOAD);
        ast_data_add_bool(data_softhangup, "explicit", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_EXPLICIT);
-       ast_data_add_bool(data_softhangup, "unbridge", ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_UNBRIDGE);
 
        /* channel flags */
        data_flags = ast_data_add_node(tree, "flags");
@@ -826,7 +828,7 @@ struct ast_format_cap *ast_channel_nativeformats(const struct ast_channel *chan)
 }
 void ast_channel_nativeformats_set(struct ast_channel *chan, struct ast_format_cap *value)
 {
-       chan->nativeformats = value;
+       ao2_replace(chan->nativeformats, value);
 }
 struct ast_framehook_list *ast_channel_framehooks(const struct ast_channel *chan)
 {
@@ -912,15 +914,11 @@ enum ast_channel_state ast_channel_state(const struct ast_channel *chan)
 {
        return chan->state;
 }
-struct ast_callid *ast_channel_callid(const struct ast_channel *chan)
+ast_callid ast_channel_callid(const struct ast_channel *chan)
 {
-       if (chan->callid) {
-               ast_callid_ref(chan->callid);
-               return chan->callid;
-       }
-       return NULL;
+       return chan->callid;
 }
-void ast_channel_callid_set(struct ast_channel *chan, struct ast_callid *callid)
+void ast_channel_callid_set(struct ast_channel *chan, ast_callid callid)
 {
        char call_identifier_from[AST_CALLID_BUFFER_LENGTH];
        char call_identifier_to[AST_CALLID_BUFFER_LENGTH];
@@ -929,11 +927,9 @@ void ast_channel_callid_set(struct ast_channel *chan, struct ast_callid *callid)
        if (chan->callid) {
                ast_callid_strnprint(call_identifier_from, sizeof(call_identifier_from), chan->callid);
                ast_debug(3, "Channel Call ID changing from %s to %s\n", call_identifier_from, call_identifier_to);
-               /* unbind if already set */
-               ast_callid_unref(chan->callid);
        }
 
-       chan->callid = ast_callid_ref(callid);
+       chan->callid = callid;
 
        ast_test_suite_event_notify("CallIDChange",
                "State: CallIDChange\r\n"
@@ -943,32 +939,51 @@ void ast_channel_callid_set(struct ast_channel *chan, struct ast_callid *callid)
                ast_channel_name(chan),
                call_identifier_to,
                call_identifier_from);
-
-       ast_channel_publish_snapshot(chan);
 }
+
 void ast_channel_state_set(struct ast_channel *chan, enum ast_channel_state value)
 {
        chan->state = value;
 }
+void ast_channel_set_oldwriteformat(struct ast_channel *chan, struct ast_format *format)
+{
+       ao2_replace(chan->oldwriteformat, format);
+}
+void ast_channel_set_rawreadformat(struct ast_channel *chan, struct ast_format *format)
+{
+       ao2_replace(chan->rawreadformat, format);
+}
+void ast_channel_set_rawwriteformat(struct ast_channel *chan, struct ast_format *format)
+{
+       ao2_replace(chan->rawwriteformat, format);
+}
+void ast_channel_set_readformat(struct ast_channel *chan, struct ast_format *format)
+{
+       ao2_replace(chan->readformat, format);
+}
+void ast_channel_set_writeformat(struct ast_channel *chan, struct ast_format *format)
+{
+       ao2_replace(chan->writeformat, format);
+}
 struct ast_format *ast_channel_oldwriteformat(struct ast_channel *chan)
 {
-       return &chan->oldwriteformat;
+       return chan->oldwriteformat;
 }
 struct ast_format *ast_channel_rawreadformat(struct ast_channel *chan)
 {
-       return &chan->rawreadformat;
+       return chan->rawreadformat;
 }
 struct ast_format *ast_channel_rawwriteformat(struct ast_channel *chan)
 {
-       return &chan->rawwriteformat;
+       return chan->rawwriteformat;
 }
 struct ast_format *ast_channel_readformat(struct ast_channel *chan)
 {
-       return &chan->readformat;
+       return chan->readformat;
 }
 struct ast_format *ast_channel_writeformat(struct ast_channel *chan)
 {
-       return &chan->writeformat;
+       return chan->writeformat;
 }
 struct ast_hangup_handler_list *ast_channel_hangup_handlers(struct ast_channel *chan)
 {
@@ -1073,7 +1088,6 @@ void ast_channel_dtmf_tv_set(struct ast_channel *chan, struct timeval *value)
 void ast_channel_whentohangup_set(struct ast_channel *chan, struct timeval *value)
 {
        chan->whentohangup = *value;
-       ast_channel_publish_snapshot(chan);
 }
 void ast_channel_varshead_set(struct ast_channel *chan, struct varshead *value)
 {
@@ -1116,11 +1130,36 @@ void ast_channel_softhangup_internal_flag_clear(struct ast_channel *chan, int va
        chan ->softhangup &= ~value;
 }
 
+int ast_channel_unbridged_nolock(struct ast_channel *chan)
+{
+       return chan->unbridged;
+}
+
+int ast_channel_unbridged(struct ast_channel *chan)
+{
+       int res;
+       ast_channel_lock(chan);
+       res = ast_channel_unbridged_nolock(chan);
+       ast_channel_unlock(chan);
+       return res;
+}
+
+void ast_channel_set_unbridged_nolock(struct ast_channel *chan, int value)
+{
+       chan->unbridged = value;
+       ast_queue_frame(chan, &ast_null_frame);
+}
+
+void ast_channel_set_unbridged(struct ast_channel *chan, int value)
+{
+       ast_channel_lock(chan);
+       ast_channel_set_unbridged_nolock(chan, value);
+       ast_channel_unlock(chan);
+}
+
 void ast_channel_callid_cleanup(struct ast_channel *chan)
 {
-       if (chan->callid) {
-               chan->callid = ast_callid_unref(chan->callid);
-       }
+       chan->callid = 0;
 }
 
 /* Typedef accessors */
@@ -1131,7 +1170,6 @@ ast_group_t ast_channel_callgroup(const struct ast_channel *chan)
 void ast_channel_callgroup_set(struct ast_channel *chan, ast_group_t value)
 {
        chan->callgroup = value;
-       ast_channel_publish_snapshot(chan);
 }
 ast_group_t ast_channel_pickupgroup(const struct ast_channel *chan)
 {
@@ -1140,7 +1178,6 @@ ast_group_t ast_channel_pickupgroup(const struct ast_channel *chan)
 void ast_channel_pickupgroup_set(struct ast_channel *chan, ast_group_t value)
 {
        chan->pickupgroup = value;
-       ast_channel_publish_snapshot(chan);
 }
 struct ast_namedgroups *ast_channel_named_callgroups(const struct ast_channel *chan)
 {
@@ -1467,7 +1504,13 @@ struct ast_channel *ast_channel_internal_oldest_linkedid(struct ast_channel *a,
 
 void ast_channel_internal_copy_linkedid(struct ast_channel *dest, struct ast_channel *source)
 {
+       if (dest->linkedid.creation_time == source->linkedid.creation_time
+               && dest->linkedid.creation_unique == source->linkedid.creation_unique
+               && !strcmp(dest->linkedid.unique_id, source->linkedid.unique_id)) {
+               return;
+       }
        dest->linkedid = source->linkedid;
+       ast_channel_publish_snapshot(dest);
 }
 
 void ast_channel_internal_swap_uniqueid_and_linkedid(struct ast_channel *a, struct ast_channel *b)
@@ -1483,10 +1526,19 @@ void ast_channel_internal_swap_uniqueid_and_linkedid(struct ast_channel *a, stru
        b->linkedid = temp;
 }
 
+void ast_channel_internal_swap_topics(struct ast_channel *a, struct ast_channel *b)
+{
+       struct stasis_cp_single *temp;
+
+       temp = a->topics;
+       a->topics = b->topics;
+       b->topics = 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));
+       ast_copy_string(chan->uniqueid.unique_id, uniqueid, sizeof(chan->uniqueid.unique_id));
+       ast_copy_string(chan->linkedid.unique_id, linkedid, sizeof(chan->linkedid.unique_id));
 }
 
 void ast_channel_internal_cleanup(struct ast_channel *chan)
@@ -1500,6 +1552,7 @@ void ast_channel_internal_cleanup(struct ast_channel *chan)
        ast_string_field_free_memory(chan);
 
        chan->endpoint_forward = stasis_forward_cancel(chan->endpoint_forward);
+       chan->endpoint_cache_forward = stasis_forward_cancel(chan->endpoint_cache_forward);
 
        stasis_cp_single_unsubscribe(chan->topics);
        chan->topics = NULL;
@@ -1542,8 +1595,14 @@ int ast_channel_forward_endpoint(struct ast_channel *chan,
        chan->endpoint_forward =
                stasis_forward_all(ast_channel_topic(chan),
                        ast_endpoint_topic(endpoint));
+       if (!chan->endpoint_forward) {
+               return -1;
+       }
 
-       if (chan->endpoint_forward == NULL) {
+       chan->endpoint_cache_forward = stasis_forward_all(ast_channel_topic_cached(chan),
+               ast_endpoint_topic(endpoint));
+       if (!chan->endpoint_cache_forward) {
+               chan->endpoint_forward = stasis_forward_cancel(chan->endpoint_forward);
                return -1;
        }