Merge "Fix/Update clang-RAII macro implementation"
authorMatt Jordan <mjordan@digium.com>
Wed, 22 Apr 2015 19:25:47 +0000 (14:25 -0500)
committerGerrit Code Review <gerrit2@gerrit.digium.api>
Wed, 22 Apr 2015 19:25:47 +0000 (14:25 -0500)
cdr/cdr_adaptive_odbc.c
res/res_pjsip_mwi.c

index 22f7d79..83877cb 100644 (file)
@@ -484,7 +484,6 @@ static int odbc_log(struct ast_cdr *cdr)
                                                }
                                        }
 
-                                       ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
                                        LENGTHEN_BUF2(strlen(colptr));
 
                                        /* Encode value, with escaping */
@@ -520,7 +519,6 @@ static int odbc_log(struct ast_cdr *cdr)
                                                        year += 2000;
                                                }
 
-                                               ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
                                                LENGTHEN_BUF2(17);
                                                ast_str_append(&sql2, 0, "%s{ d '%04d-%02d-%02d' }", first ? "" : ",", year, month, day);
                                        }
@@ -537,7 +535,6 @@ static int odbc_log(struct ast_cdr *cdr)
                                                        continue;
                                                }
 
-                                               ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
                                                LENGTHEN_BUF2(15);
                                                ast_str_append(&sql2, 0, "%s{ t '%02d:%02d:%02d' }", first ? "" : ",", hour, minute, second);
                                        }
@@ -566,7 +563,6 @@ static int odbc_log(struct ast_cdr *cdr)
                                                        year += 2000;
                                                }
 
-                                               ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
                                                LENGTHEN_BUF2(26);
                                                ast_str_append(&sql2, 0, "%s{ ts '%04d-%02d-%02d %02d:%02d:%02d' }", first ? "" : ",", year, month, day, hour, minute, second);
                                        }
@@ -581,7 +577,6 @@ static int odbc_log(struct ast_cdr *cdr)
                                                        continue;
                                                }
 
-                                               ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
                                                LENGTHEN_BUF2(12);
                                                ast_str_append(&sql2, 0, "%s%d", first ? "" : ",", integer);
                                        }
@@ -596,7 +591,6 @@ static int odbc_log(struct ast_cdr *cdr)
                                                        continue;
                                                }
 
-                                               ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
                                                LENGTHEN_BUF2(24);
                                                ast_str_append(&sql2, 0, "%s%lld", first ? "" : ",", integer);
                                        }
@@ -611,7 +605,6 @@ static int odbc_log(struct ast_cdr *cdr)
                                                        continue;
                                                }
 
-                                               ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
                                                LENGTHEN_BUF2(6);
                                                ast_str_append(&sql2, 0, "%s%d", first ? "" : ",", integer);
                                        }
@@ -626,7 +619,6 @@ static int odbc_log(struct ast_cdr *cdr)
                                                        continue;
                                                }
 
-                                               ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
                                                LENGTHEN_BUF2(4);
                                                ast_str_append(&sql2, 0, "%s%d", first ? "" : ",", integer);
                                        }
@@ -643,7 +635,6 @@ static int odbc_log(struct ast_cdr *cdr)
                                                if (integer != 0)
                                                        integer = 1;
 
-                                               ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
                                                LENGTHEN_BUF2(2);
                                                ast_str_append(&sql2, 0, "%s%d", first ? "" : ",", integer);
                                        }
@@ -676,7 +667,6 @@ static int odbc_log(struct ast_cdr *cdr)
                                                        continue;
                                                }
 
-                                               ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
                                                LENGTHEN_BUF2(entry->decimals);
                                                ast_str_append(&sql2, 0, "%s%*.*lf", first ? "" : ",", entry->decimals, entry->radix, number);
                                        }
@@ -710,7 +700,6 @@ static int odbc_log(struct ast_cdr *cdr)
                                                        continue;
                                                }
 
-                                               ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
                                                LENGTHEN_BUF2(entry->decimals);
                                                ast_str_append(&sql2, 0, "%s%lf", first ? "" : ",", number);
                                        }
@@ -719,6 +708,7 @@ static int odbc_log(struct ast_cdr *cdr)
                                        ast_log(LOG_WARNING, "Column type %d (field '%s:%s:%s') is unsupported at this time.\n", entry->type, tableptr->connection, tableptr->table, entry->name);
                                        continue;
                                }
+                               ast_str_append(&sql, 0, "%s%s", first ? "" : ",", entry->name);
                                first = 0;
                        } else if (entry->filtervalue
                                && ((!entry->negatefiltervalue && entry->filtervalue[0] != '\0')
index 9c275af..2ab7dfe 100644 (file)
@@ -100,12 +100,14 @@ struct mwi_stasis_subscription {
  */
 struct mwi_subscription {
        /*! Container of \ref mwi_stasis_subscription structures.
-        * A single MWI subscription may be fore multiple mailboxes, thus
+        * A single MWI subscription may be for multiple mailboxes, thus
         * requiring multiple stasis subscriptions
         */
        struct ao2_container *stasis_subs;
        /*! The SIP subscription. Unsolicited MWI does not use this */
        struct ast_sip_subscription *sip_sub;
+       /*! AORs we should react to for unsolicited MWI NOTIFY */
+       char *aors;
        /*! Is the MWI solicited (i.e. Initiated with an external SUBSCRIBE) ? */
        unsigned int is_solicited;
        /*! Identifier for the subscription.
@@ -196,6 +198,7 @@ static void mwi_subscription_destructor(void *obj)
        ast_debug(3, "Destroying MWI subscription for endpoint %s\n", sub->id);
        ao2_cleanup(sub->sip_sub);
        ao2_cleanup(sub->stasis_subs);
+       ast_free(sub->aors);
 }
 
 static struct mwi_subscription *mwi_subscription_alloc(struct ast_sip_endpoint *endpoint,
@@ -232,6 +235,14 @@ static struct mwi_subscription *mwi_subscription_alloc(struct ast_sip_endpoint *
        }
        sub->is_solicited = is_solicited;
 
+       if (!is_solicited && !ast_strlen_zero(endpoint->aors)) {
+               sub->aors = ast_strdup(endpoint->aors);
+               if (!sub->aors) {
+                       ao2_ref(sub, -1);
+                       return NULL;
+               }
+       }
+
        ast_debug(3, "Created %s MWI subscription for endpoint %s\n", is_solicited ? "solicited" : "unsolicited", sub->id);
 
        return sub;
@@ -796,21 +807,32 @@ static int serialized_cleanup(void *userdata)
        return 0;
 }
 
+static int send_notify(void *obj, void *arg, int flags)
+{
+       struct mwi_subscription *mwi_sub = obj;
+       struct ast_taskprocessor *serializer = mwi_sub->is_solicited ? ast_sip_subscription_get_serializer(mwi_sub->sip_sub) : NULL;
+
+       if (ast_sip_push_task(serializer, serialized_notify, ao2_bump(mwi_sub))) {
+               ao2_ref(mwi_sub, -1);
+       }
+
+       return 0;
+}
+
 static void mwi_stasis_cb(void *userdata, struct stasis_subscription *sub,
                struct stasis_message *msg)
 {
        struct mwi_subscription *mwi_sub = userdata;
 
        if (stasis_subscription_final_message(sub, msg)) {
-               ao2_ref(mwi_sub, +1);
-               ast_sip_push_task(NULL, serialized_cleanup, mwi_sub);
+               if (ast_sip_push_task(NULL, serialized_cleanup, ao2_bump(mwi_sub))) {
+                       ao2_ref(mwi_sub, -1);
+               }
                return;
        }
 
        if (ast_mwi_state_type() == stasis_message_type(msg)) {
-               struct ast_taskprocessor *serializer = mwi_sub->is_solicited ? ast_sip_subscription_get_serializer(mwi_sub->sip_sub) : NULL;
-               ao2_ref(mwi_sub, +1);
-               ast_sip_push_task(serializer, serialized_notify, mwi_sub);
+               send_notify(mwi_sub, NULL, 0);
        }
 }
 
@@ -858,6 +880,7 @@ static int unsubscribe(void *obj, void *arg, int flags)
        struct mwi_subscription *mwi_sub = obj;
 
        ao2_callback(mwi_sub->stasis_subs, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe_stasis, NULL);
+
        return CMP_MATCH;
 }
 
@@ -887,6 +910,83 @@ static void create_mwi_subscriptions(void)
        ao2_ref(mwi_subscriptions, -1);
 }
 
+/*! \brief Function called to send MWI NOTIFY on any unsolicited mailboxes relating to this AOR */
+static int send_contact_notify(void *obj, void *arg, int flags)
+{
+       struct mwi_subscription *mwi_sub = obj;
+       const char *aor = arg;
+
+       if (!mwi_sub->aors || !strstr(mwi_sub->aors, aor)) {
+               return 0;
+       }
+
+       if (ast_sip_push_task(NULL, serialized_notify, ao2_bump(mwi_sub))) {
+               ao2_ref(mwi_sub, -1);
+       }
+
+       return 0;
+}
+
+
+/*! \brief Function called when a contact is created or updated */
+static void mwi_contact_changed_observer(const void *object)
+{
+       char *id = ast_strdupa(ast_sorcery_object_get_id(object)), *aor = NULL;
+       struct ao2_container *mwi_subscriptions = ao2_global_obj_ref(unsolicited_mwi);
+
+       if (!mwi_subscriptions) {
+               return;
+       }
+
+       aor = strsep(&id, ";@");
+
+       ao2_callback(mwi_subscriptions, OBJ_NODATA, send_contact_notify, aor);
+       ao2_ref(mwi_subscriptions, -1);
+}
+
+/*! \brief Observer for contacts so unsolicited MWI is sent when a contact changes */
+static const struct ast_sorcery_observer mwi_contact_observer = {
+       .created = mwi_contact_changed_observer,
+       .updated = mwi_contact_changed_observer,
+};
+
+/*! \brief Task invoked to send initial MWI NOTIFY for unsolicited */
+static int send_initial_notify_all(void *obj)
+{
+       struct ao2_container *mwi_subscriptions = ao2_global_obj_ref(unsolicited_mwi);
+
+       if (!mwi_subscriptions) {
+               return 0;
+       }
+
+       ao2_callback(mwi_subscriptions, OBJ_NODATA, send_notify, NULL);
+       ao2_ref(mwi_subscriptions, -1);
+
+       return 0;
+}
+
+/*! \brief Event callback which fires initial unsolicited MWI NOTIFY messages when we're fully booted */
+static void mwi_startup_event_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
+{
+       struct ast_json_payload *payload;
+       const char *type;
+
+       if (stasis_message_type(message) != ast_manager_get_generic_type()) {
+               return;
+       }
+
+       payload = stasis_message_data(message);
+       type = ast_json_string_get(ast_json_object_get(payload->json, "type"));
+
+       if (strcmp(type, "FullyBooted")) {
+               return;
+       }
+
+       ast_sip_push_task(NULL, send_initial_notify_all, NULL);
+
+       stasis_unsubscribe(sub);
+}
+
 static int reload(void)
 {
        create_mwi_subscriptions();
@@ -901,6 +1001,14 @@ static int load_module(void)
                return AST_MODULE_LOAD_DECLINE;
        }
        create_mwi_subscriptions();
+       ast_sorcery_observer_add(ast_sip_get_sorcery(), "contact", &mwi_contact_observer);
+
+       if (ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)) {
+               ast_sip_push_task(NULL, send_initial_notify_all, NULL);
+       } else {
+               stasis_subscribe_pool(ast_manager_get_topic(), mwi_startup_event_cb, NULL);
+       }
+
        return AST_MODULE_LOAD_SUCCESS;
 }
 
@@ -910,6 +1018,7 @@ static int unload_module(void)
        if (mwi_subscriptions) {
                ao2_callback(mwi_subscriptions, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, unsubscribe, NULL);
                ao2_global_obj_release(unsolicited_mwi);
+               ast_sorcery_observer_remove(ast_sip_get_sorcery(), "contact", &mwi_contact_observer);
        }
        ast_sip_unregister_subscription_handler(&mwi_handler);
        return 0;