summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cdr/cdr_adaptive_odbc.c12
-rw-r--r--res/res_pjsip_mwi.c121
2 files changed, 116 insertions, 17 deletions
diff --git a/cdr/cdr_adaptive_odbc.c b/cdr/cdr_adaptive_odbc.c
index 22f7d7916..83877cbf1 100644
--- a/cdr/cdr_adaptive_odbc.c
+++ b/cdr/cdr_adaptive_odbc.c
@@ -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')
diff --git a/res/res_pjsip_mwi.c b/res/res_pjsip_mwi.c
index 9c275af46..2ab7dfee0 100644
--- a/res/res_pjsip_mwi.c
+++ b/res/res_pjsip_mwi.c
@@ -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;