diff options
-rw-r--r-- | cdr/cdr_adaptive_odbc.c | 12 | ||||
-rw-r--r-- | res/res_pjsip_mwi.c | 121 |
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; |