Merge "cdr/cdr_adaptive_odbc.c: Refactor concatenate columns name."
authorMatt Jordan <mjordan@digium.com>
Wed, 22 Apr 2015 11:27:38 +0000 (06:27 -0500)
committerGerrit Code Review <gerrit2@gerrit.digium.api>
Wed, 22 Apr 2015 11:27:38 +0000 (06:27 -0500)
channels/sig_pri.c
funcs/func_pjsip_contact.c
include/asterisk/res_pjsip.h
main/channel_internal_api.c
res/res_pjsip/location.c
res/res_pjsip/pjsip_configuration.c
res/res_pjsip/pjsip_options.c
res/res_pjsip_pubsub.c

index a7cc3d7..e4ad589 100644 (file)
@@ -1376,10 +1376,9 @@ static void sig_pri_queue_unhold(struct sig_pri_span *pri, int chanpos)
 static void pri_queue_control(struct sig_pri_span *pri, int chanpos, int subclass)
 {
        struct ast_frame f = {AST_FRAME_CONTROL, };
-       struct sig_pri_chan *p = pri->pvts[chanpos];
 
        if (sig_pri_callbacks.queue_control) {
-               sig_pri_callbacks.queue_control(p->chan_pvt, subclass);
+               sig_pri_callbacks.queue_control(pri->pvts[chanpos]->chan_pvt, subclass);
        }
 
        f.subclass.integer = subclass;
@@ -1388,6 +1387,31 @@ static void pri_queue_control(struct sig_pri_span *pri, int chanpos, int subclas
 
 /*!
  * \internal
+ * \brief Queue a request to hangup control frame onto the owner channel.
+ *
+ * \param pri PRI span control structure.
+ * \param chanpos Channel position in the span.
+ *
+ * \note Assumes the pri->lock is already obtained.
+ * \note Assumes the sig_pri_lock_private(pri->pvts[chanpos]) is already obtained.
+ *
+ * \return Nothing
+ */
+static void sig_pri_queue_hangup(struct sig_pri_span *pri, int chanpos)
+{
+       if (sig_pri_callbacks.queue_control) {
+               sig_pri_callbacks.queue_control(pri->pvts[chanpos]->chan_pvt, AST_CONTROL_HANGUP);
+       }
+
+       sig_pri_lock_owner(pri, chanpos);
+       if (pri->pvts[chanpos]->owner) {
+               ast_queue_hangup(pri->pvts[chanpos]->owner);
+               ast_channel_unlock(pri->pvts[chanpos]->owner);
+       }
+}
+
+/*!
+ * \internal
  * \brief Queue a PVT_CAUSE_CODE frame onto the owner channel.
  * \since 11
  *
@@ -4035,14 +4059,14 @@ static void sig_pri_send_aoce_termination_request(struct sig_pri_span *pri, int
        }
 
        if (!(decoded = ast_aoc_create(AST_AOC_REQUEST, 0, AST_AOC_REQUEST_E))) {
-               ast_softhangup_nolock(pvt->owner, AST_SOFTHANGUP_DEV);
+               ast_queue_hangup(pvt->owner);
                goto cleanup_termination_request;
        }
 
        ast_aoc_set_termination_request(decoded);
 
        if (!(encoded = ast_aoc_encode(decoded, &encoded_size, pvt->owner))) {
-               ast_softhangup_nolock(pvt->owner, AST_SOFTHANGUP_DEV);
+               ast_queue_hangup(pvt->owner);
                goto cleanup_termination_request;
        }
 
@@ -4051,7 +4075,7 @@ static void sig_pri_send_aoce_termination_request(struct sig_pri_span *pri, int
        whentohangup.tv_sec = ms / 1000;
 
        if (ast_queue_control_data(pvt->owner, AST_CONTROL_AOC, encoded, encoded_size)) {
-               ast_softhangup_nolock(pvt->owner, AST_SOFTHANGUP_DEV);
+               ast_queue_hangup(pvt->owner);
                goto cleanup_termination_request;
        }
 
@@ -4295,43 +4319,6 @@ static void sig_pri_handle_cis_subcmds(struct sig_pri_span *pri, int event_id,
        }
 }
 
-#if defined(HAVE_PRI_AOC_EVENTS)
-/*!
- * \internal
- * \brief detect if AOC-S subcmd is present.
- * \since 1.8
- *
- * \param subcmds Subcommands to process if any. (Could be NULL).
- *
- * \note Knowing whether or not an AOC-E subcmd is present on certain
- * PRI hangup events is necessary to determine what method to use to hangup
- * the ast_channel.  If an AOC-E subcmd just came in, then a new AOC-E was queued
- * on the ast_channel.  If a soft hangup is used, the AOC-E msg will never make it
- * across the bridge, but if a AST_CONTROL_HANGUP frame is queued behind it
- * we can ensure the AOC-E frame makes it to it's destination before the hangup
- * frame is read.
- *
- *
- * \retval 0 AOC-E is not present in subcmd list
- * \retval 1 AOC-E is present in subcmd list
- */
-static int detect_aoc_e_subcmd(const struct pri_subcommands *subcmds)
-{
-       int i;
-
-       if (!subcmds) {
-               return 0;
-       }
-       for (i = 0; i < subcmds->counter_subcmd; ++i) {
-               const struct pri_subcommand *subcmd = &subcmds->subcmd[i];
-               if (subcmd->cmd == PRI_SUBCMD_AOC_E) {
-                       return 1;
-               }
-       }
-       return 0;
-}
-#endif /* defined(HAVE_PRI_AOC_EVENTS) */
-
 /*!
  * \internal
  * \brief Handle the call associated PRI subcommand events.
@@ -6567,9 +6554,8 @@ static void *pri_dchannel(void *vpri)
                                                                pri->pvts[chanpos]->call = NULL;
                                                        }
                                                }
-                                               /* Force soft hangup if appropriate */
-                                               if (pri->pvts[chanpos]->owner)
-                                                       ast_channel_softhangup_internal_flag_add(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
+                                               /* Force hangup if appropriate */
+                                               sig_pri_queue_hangup(pri, chanpos);
                                                sig_pri_unlock_private(pri->pvts[chanpos]);
                                        }
                                } else {
@@ -6581,8 +6567,8 @@ static void *pri_dchannel(void *vpri)
                                                                pri_destroycall(pri->pri, pri->pvts[x]->call);
                                                                pri->pvts[x]->call = NULL;
                                                        }
-                                                       if (pri->pvts[x]->owner)
-                                                               ast_channel_softhangup_internal_flag_add(pri->pvts[x]->owner, AST_SOFTHANGUP_DEV);
+                                                       /* Force hangup if appropriate */
+                                                       sig_pri_queue_hangup(pri, x);
                                                        sig_pri_unlock_private(pri->pvts[x]);
                                                }
                                }
@@ -7154,17 +7140,7 @@ static void *pri_dchannel(void *vpri)
                                                }
 
                                                if (do_hangup) {
-#if defined(HAVE_PRI_AOC_EVENTS)
-                                                       if (detect_aoc_e_subcmd(e->hangup.subcmds)) {
-                                                               /* If a AOC-E msg was sent during the release, we must use a
-                                                                * AST_CONTROL_HANGUP frame to guarantee that frame gets read before hangup */
-                                                               pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP);
-                                                       } else {
-                                                               ast_channel_softhangup_internal_flag_add(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
-                                                       }
-#else
-                                                       ast_channel_softhangup_internal_flag_add(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
-#endif /* defined(HAVE_PRI_AOC_EVENTS) */
+                                                       sig_pri_queue_hangup(pri, chanpos);
                                                }
                                        } else {
                                                /*
@@ -7314,16 +7290,11 @@ static void *pri_dchannel(void *vpri)
                                                        && ast_channel_is_bridged(pri->pvts[chanpos]->owner)) {
                                                        sig_pri_send_aoce_termination_request(pri, chanpos,
                                                                pri_get_timer(pri->pri, PRI_TIMER_T305) / 2);
-                                               } else if (detect_aoc_e_subcmd(e->hangup.subcmds)) {
-                                                       /* If a AOC-E msg was sent during the Disconnect, we must use a AST_CONTROL_HANGUP frame
-                                                        * to guarantee that frame gets read before hangup */
-                                                       pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP);
-                                               } else {
-                                                       ast_channel_softhangup_internal_flag_add(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
-                                               }
-#else
-                                               ast_channel_softhangup_internal_flag_add(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
+                                               } else
 #endif /* defined(HAVE_PRI_AOC_EVENTS) */
+                                               {
+                                                       sig_pri_queue_hangup(pri, chanpos);
+                                               }
                                        }
                                        ast_verb(3, "Span %d: Channel %d/%d got hangup request, cause %d\n",
                                                pri->span, pri->pvts[chanpos]->logicalspan,
@@ -8619,16 +8590,18 @@ int sig_pri_indicate(struct sig_pri_chan *p, struct ast_channel *chan, int condi
                                        if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E) {
                                                sig_pri_aoc_e_from_ast(p, decoded);
                                        }
-                                       /* if hangup was delayed for this AOC-E msg, waiting_for_aoc
+                                       /*
+                                        * If hangup was delayed for this AOC-E msg, waiting_for_aoc
                                         * will be set.  A hangup is already occuring via a timeout during
                                         * this delay.  Instead of waiting for that timeout to occur, go ahead
-                                        * and initiate the softhangup since the delay is no longer necessary */
+                                        * and initiate the hangup since the delay is no longer necessary.
+                                        */
                                        if (p->waiting_for_aoce) {
                                                p->waiting_for_aoce = 0;
                                                ast_debug(1,
                                                        "Received final AOC-E msg, continue with hangup on %s\n",
                                                        ast_channel_name(chan));
-                                               ast_softhangup_nolock(chan, AST_SOFTHANGUP_DEV);
+                                               ast_queue_hangup(chan);
                                        }
                                        break;
                                case AST_AOC_REQUEST:
index fc65ae9..e973704 100644 (file)
@@ -147,15 +147,9 @@ static int pjsip_contact_function_read(struct ast_channel *chan,
        contact_status = ast_sorcery_retrieve_by_id(pjsip_sorcery, CONTACT_STATUS, ast_sorcery_object_get_id(contact_obj));
 
        if (!strcmp(args.field_name, "status")) {
-               if (!contact_status) {
-                       ast_str_set(buf, len, "%s", "Unknown");
-               } else if (contact_status->status == UNAVAILABLE) {
-                       ast_str_set(buf, len, "%s", "Unreachable");
-               } else if (contact_status->status == AVAILABLE) {
-                       ast_str_set(buf, len, "%s", "Reachable");
-               }
+               ast_str_set(buf, len, "%s", ast_sip_get_contact_status_label(contact_status->status));
        } else if (!strcmp(args.field_name, "rtt")) {
-               if (!contact_status) {
+               if (contact_status->status == UNKNOWN) {
                        ast_str_set(buf, len, "%s", "N/A");
                } else {
                        ast_str_set(buf, len, "%" PRId64, contact_status->rtt);
index 99b65ab..12fc400 100644 (file)
@@ -177,7 +177,8 @@ struct ast_sip_contact {
  */
 enum ast_sip_contact_status_type {
        UNAVAILABLE,
-       AVAILABLE
+       AVAILABLE,
+       UNKNOWN
 };
 
 /*!
@@ -2002,5 +2003,13 @@ unsigned int ast_sip_get_keep_alive_interval(void);
  */
 unsigned int ast_sip_get_max_initial_qualify_time(void);
 
+/*!
+ * \brief translate ast_sip_contact_status_type to character string.
+ *
+ * \retval the character string equivalent.
+ */
+
+const char *ast_sip_get_contact_status_label(const enum ast_sip_contact_status_type status);
+const char *ast_sip_get_contact_short_status_label(const enum ast_sip_contact_status_type status);
 
 #endif /* _RES_PJSIP_H */
index a2fafbf..4e85398 100644 (file)
@@ -1449,6 +1449,10 @@ struct ast_channel *__ast_channel_internal_alloc(void (*destructor)(void *obj),
        tmp = ao2_alloc(sizeof(*tmp), destructor);
 #endif
 
+       if (!tmp) {
+               return NULL;
+       }
+
        if ((ast_string_field_init(tmp, 128))) {
                return ast_channel_unref(tmp);
        }
index f784cb4..2165041 100644 (file)
@@ -747,8 +747,8 @@ static int cli_contact_print_body(void *obj, void *arg, int flags)
                "Contact",
                flexwidth, flexwidth,
                wrapper->contact_id,
-               (status ? (status->status == AVAILABLE ? "Avail" : "Unavail") : "Unknown"),
-               (status ? ((long long) status->rtt) / 1000.0 : NAN));
+               ast_sip_get_contact_short_status_label(status->status),
+               (status->status != UNKNOWN ? ((long long) status->rtt) / 1000.0 : NAN));
 
        return 0;
 }
index ab0d084..54fdb65 100644 (file)
@@ -86,7 +86,7 @@ static int persistent_endpoint_update_state(void *obj, void *arg, int flags)
                        contact_status = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(),
                                CONTACT_STATUS, contact_id);
 
-                       if (contact_status && contact_status->status == AVAILABLE) {
+                       if (contact_status && contact_status->status != UNAVAILABLE) {
                                state = AST_ENDPOINT_ONLINE;
                        }
                        ao2_cleanup(contact_status);
@@ -184,10 +184,10 @@ static void persistent_endpoint_contact_status_observer(const void *object)
                "Contact: %s\r\n"
                        "Status: %s",
                ast_sorcery_object_get_id(contact_status),
-               (contact_status->status == AVAILABLE ? "Available" : "Unavailable"));
+               ast_sip_get_contact_status_label(contact_status->status));
 
        ast_verb(1, "Contact %s/%s is now %s\n", aor, contact,
-               contact_status->status == AVAILABLE ? "Available" : "Unavailable");
+               ast_sip_get_contact_status_label(contact_status->status));
 
        ao2_callback(persistent_endpoints, OBJ_NODATA, persistent_endpoint_update_state, aor);
 }
index 2653b33..40b6f7b 100644 (file)
 #define DEFAULT_ENCODING "text/plain"
 #define QUALIFIED_BUCKETS 211
 
+static const char *status_map [] = {
+       [UNAVAILABLE] = "Unreachable",
+       [AVAILABLE] = "Reachable",
+       [UNKNOWN] = "Unknown",
+};
+
+static const char *short_status_map [] = {
+       [UNAVAILABLE] = "Unavail",
+       [AVAILABLE] = "Avail",
+       [UNKNOWN] = "Unknown",
+};
+
+const char *ast_sip_get_contact_status_label(const enum ast_sip_contact_status_type status)
+{
+       return status_map[status];
+}
+
+const char *ast_sip_get_contact_short_status_label(const enum ast_sip_contact_status_type status)
+{
+       return short_status_map[status];
+}
+
 /*!
  * \internal
  * \brief Create a ast_sip_contact_status object.
@@ -48,7 +70,7 @@ static void *contact_status_alloc(const char *name)
                return NULL;
        }
 
-       status->status = UNAVAILABLE;
+       status->status = UNKNOWN;
 
        return status;
 }
@@ -86,19 +108,6 @@ static struct ast_sip_contact_status *find_or_create_contact_status(const struct
        return status;
 }
 
-static void delete_contact_status(const struct ast_sip_contact *contact)
-{
-       struct ast_sip_contact_status *status = ast_sorcery_retrieve_by_id(
-               ast_sip_get_sorcery(), CONTACT_STATUS, ast_sorcery_object_get_id(contact));
-
-       if (!status) {
-               return;
-       }
-
-       ast_sorcery_delete(ast_sip_get_sorcery(), status);
-       ao2_ref(status, -1);
-}
-
 /*!
  * \internal
  * \brief Update an ast_sip_contact_status's elements.
@@ -129,17 +138,19 @@ static void update_contact_status(const struct ast_sip_contact *contact,
 
        /* if the contact is available calculate the rtt as
           the diff between the last start time and "now" */
-       update->rtt = update->status == AVAILABLE ?
+       update->rtt = update->status == AVAILABLE && status->rtt_start.tv_sec > 0 ?
                ast_tvdiff_us(ast_tvnow(), status->rtt_start) : 0;
 
        update->rtt_start = ast_tv(0, 0);
 
+
+
        ast_test_suite_event_notify("AOR_CONTACT_QUALIFY_RESULT",
                "Contact: %s\r\n"
                        "Status: %s\r\n"
                        "RTT: %" PRId64,
                ast_sorcery_object_get_id(update),
-               (update->status == AVAILABLE ? "Available" : "Unavailable"),
+               ast_sip_get_contact_status_label(update->status),
                update->rtt);
 
        if (ast_sorcery_update(ast_sip_get_sorcery(), update)) {
@@ -499,7 +510,7 @@ static void qualify_and_schedule(struct ast_sip_contact *contact)
 
                schedule_qualify(contact, contact->qualify_frequency * 1000);
        } else {
-               delete_contact_status(contact);
+               update_contact_status(contact, UNKNOWN);
        }
 }
 
@@ -1011,6 +1022,8 @@ static int qualify_and_schedule_cb(void *obj, void *arg, int flags)
 
        if (contact->qualify_frequency) {
                schedule_qualify(contact, initial_interval);
+       } else {
+               update_contact_status(contact, UNKNOWN);
        }
 
        return 0;
@@ -1082,11 +1095,6 @@ static void qualify_and_schedule_all(void)
        ao2_ref(endpoints, -1);
 }
 
-static const char *status_map [] = {
-       [UNAVAILABLE] = "Unreachable",
-       [AVAILABLE] = "Reachable",
-};
-
 static int format_contact_status(void *obj, void *arg, int flags)
 {
        struct ast_sip_contact_wrapper *wrapper = obj;
@@ -1107,12 +1115,11 @@ static int format_contact_status(void *obj, void *arg, int flags)
 
        ast_str_append(&buf, 0, "AOR: %s\r\n", wrapper->aor_id);
        ast_str_append(&buf, 0, "URI: %s\r\n", contact->uri);
-       if (status) {
-               ast_str_append(&buf, 0, "Status: %s\r\n", status_map[status->status]);
-               ast_str_append(&buf, 0, "RoundtripUsec: %" PRId64 "\r\n", status->rtt);
-       } else {
-               ast_str_append(&buf, 0, "Status: Unknown\r\n");
+       ast_str_append(&buf, 0, "Status: %s\r\n", ast_sip_get_contact_status_label(status->status));
+       if (status->status == UNKNOWN) {
                ast_str_append(&buf, 0, "RoundtripUsec: N/A\r\n");
+       } else {
+               ast_str_append(&buf, 0, "RoundtripUsec: %" PRId64 "\r\n", status->rtt);
        }
        ast_str_append(&buf, 0, "EndpointName: %s\r\n",
                        ast_sorcery_object_get_id(endpoint));
index cf649b4..ebc43d1 100644 (file)
@@ -1019,6 +1019,7 @@ static int subscription_remove_serializer(void *obj)
         * remove the serializer will be successful.
         */
        ast_sip_dialog_set_serializer(sub_tree->dlg, NULL);
+       ast_sip_dialog_set_endpoint(sub_tree->dlg, NULL);
        pjsip_dlg_dec_session(sub_tree->dlg, &pubsub_module);
 
        return 0;
@@ -1188,6 +1189,7 @@ static void subscription_setup_dialog(struct sip_subscription_tree *sub_tree, pj
        pjsip_dlg_inc_session(dlg, &pubsub_module);
        sub_tree->dlg = dlg;
        ast_sip_dialog_set_serializer(dlg, sub_tree->serializer);
+       ast_sip_dialog_set_endpoint(dlg, sub_tree->endpoint);
        pjsip_evsub_set_mod_data(sub_tree->evsub, pubsub_module.id, sub_tree);
 }