From: Alexei Gradinari Date: Tue, 22 May 2018 21:21:10 +0000 (-0400) Subject: pjsip_options: handle modification of qualify options in realtime X-Git-Tag: 13.22.0-rc1~38^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9ad3918acd47e16ce2b34db220a4d551415c9940;p=thirdparty%2Fasterisk.git pjsip_options: handle modification of qualify options in realtime Currentrly pjsip_options code does not handle the situation when the qualify options were changed in realtime database. Only 'module reload res_pjsip' helps. This patch add a check on contact add/update observers if the contact qualify options are different than local aor qualify options. If the qualify options were modified then synchronize the pjsip_options AOR local state. ASTERISK-27872 Change-Id: Id55210a18e62ed5d35a88e408d5fe84a3c513c62 --- diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c index d05d7bdaa8..055cb4fcd2 100644 --- a/res/res_pjsip/pjsip_options.c +++ b/res/res_pjsip/pjsip_options.c @@ -2059,6 +2059,29 @@ struct sip_options_contact_observer_task_data { struct ast_sip_contact *contact; }; + +/*! + * \brief Check if the contact qualify options are different than local aor qualify options + */ +static int has_qualify_changed (struct ast_sip_contact *contact, struct sip_options_aor *aor_options) +{ + if (!contact) { + return 0; + } + + if (!aor_options) { + if (contact->qualify_frequency) { + return 1; + } + } else if (contact->qualify_frequency != aor_options->qualify_frequency + || contact->authenticate_qualify != aor_options->authenticate_qualify + || ((int)(contact->qualify_timeout * 1000)) != ((int)(aor_options->qualify_timeout * 1000))) { + return 1; + } + + return 0; +} + /*! * \brief Task which adds a dynamic contact to an AOR * \note Run by aor_options->serializer @@ -2135,23 +2158,21 @@ static int sip_options_contact_add_management_task(void *obj) task_data.contact = obj; task_data.aor_options = ao2_find(sip_options_aors, task_data.contact->aor, OBJ_SEARCH_KEY); - if (!task_data.aor_options) { + + if (has_qualify_changed(task_data.contact, task_data.aor_options)) { struct ast_sip_aor *aor; - /* - * The only reason this would occur is if the AOR was sourced - * after the last reload happened. To handle this we fetch the - * AOR and treat it as if we received notification that it had - * been created. This will create the needed AOR feeder - * compositor and will cause any associated contact statuses and - * endpoint state compositors to also get created if needed. - */ aor = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "aor", task_data.contact->aor); if (aor) { + ast_debug(3, "AOR '%s' qualify options have been modified. Synchronize an AOR local state\n", + task_data.contact->aor); sip_options_aor_observer_modified_task(aor); ao2_ref(aor, -1); } + } + + if (!task_data.aor_options) { return 0; } @@ -2215,6 +2236,21 @@ static void contact_observer_updated(const void *obj) task_data->contact = (struct ast_sip_contact *) obj; task_data->aor_options = ao2_find(sip_options_aors, task_data->contact->aor, OBJ_SEARCH_KEY); + + if (has_qualify_changed(task_data->contact, task_data->aor_options)) { + struct ast_sip_aor *aor; + + aor = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "aor", + task_data->contact->aor); + if (aor) { + ast_debug(3, "AOR '%s' qualify options have been modified. Synchronize an AOR local state\n", + task_data->contact->aor); + ast_sip_push_task_wait_serializer(management_serializer, + sip_options_aor_observer_modified_task, aor); + ao2_ref(aor, -1); + } + } + if (!task_data->aor_options) { ast_free(task_data); return;