[asterisk-commits] kharwell: branch kharwell/pimp_sip_qualify r390316 - in /team/kharwell/pimp_s...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri May 31 13:59:05 CDT 2013
Author: kharwell
Date: Fri May 31 13:59:04 2013
New Revision: 390316
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=390316
Log:
fixed scheduling issue, added permanent contacts
Modified:
team/kharwell/pimp_sip_qualify/res/res_sip/location.c
team/kharwell/pimp_sip_qualify/res/res_sip/sip_options.c
team/kharwell/pimp_sip_qualify/res/res_sip_registrar.c
Modified: team/kharwell/pimp_sip_qualify/res/res_sip/location.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_qualify/res/res_sip/location.c?view=diff&rev=390316&r1=390315&r2=390316
==============================================================================
--- team/kharwell/pimp_sip_qualify/res/res_sip/location.c (original)
+++ team/kharwell/pimp_sip_qualify/res/res_sip/location.c Fri May 31 13:59:04 2013
@@ -295,6 +295,8 @@
ast_sorcery_object_field_register(sorcery, "contact", "type", "", OPT_NOOP_T, 0, 0);
ast_sorcery_object_field_register(sorcery, "contact", "uri", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, uri));
ast_sorcery_object_field_register_custom(sorcery, "contact", "expiration_time", "", expiration_str2struct, expiration_struct2str, 0, 0);
+ ast_sorcery_object_field_register(sorcery, "contact", "qualify_frequency", 0, OPT_UINT_T,
+ PARSE_IN_RANGE, FLDSET(struct ast_sip_aor, qualify_frequency), 0, 86400);
ast_sorcery_object_field_register(sorcery, "aor", "type", "", OPT_NOOP_T, 0, 0);
ast_sorcery_object_field_register(sorcery, "aor", "minimum_expiration", "60", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, minimum_expiration));
Modified: team/kharwell/pimp_sip_qualify/res/res_sip/sip_options.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_qualify/res/res_sip/sip_options.c?view=diff&rev=390316&r1=390315&r2=390316
==============================================================================
--- team/kharwell/pimp_sip_qualify/res/res_sip/sip_options.c (original)
+++ team/kharwell/pimp_sip_qualify/res/res_sip/sip_options.c Fri May 31 13:59:04 2013
@@ -179,7 +179,7 @@
if (!aor || !(contacts = ast_sip_location_retrieve_aor_contacts(aor))) {
continue;
}
-
+
if (arg && ao2_find(contacts, arg, OBJ_NODATA | OBJ_POINTER)) {
return CMP_MATCH;
} else {
@@ -216,9 +216,7 @@
pjsip_rx_data *challenge = e->body.tsx_state.src.rdata;
pjsip_tx_data *tdata;
- ast_log(LOG_VERBOSE, "received qualify contact callback %s\n", contact->uri);
if (tsx->status_code != 401 && tsx->status_code != 407) {
- ast_log(LOG_VERBOSE, "update contact callback %s\n", contact->uri);
update_contact_status(contact, 1);
return;
}
@@ -252,10 +250,8 @@
static int qualify_contact(struct ast_sip_contact *contact)
{
pjsip_tx_data *tdata;
- ast_log(LOG_VERBOSE, "QUALIFY CONTACT %s\n", contact->uri);
/* assume we can't connect so if no reply comes back */
update_contact_status(contact, 0);
- ast_log(LOG_VERBOSE, "updated status sending OPTIONS %s\n", contact->uri);
if (ast_sip_create_request("OPTIONS", NULL, NULL, contact->uri, &tdata)) {
ast_log(LOG_ERROR, "Unable to create request to qualify contact %s\n",
@@ -263,15 +259,16 @@
return -1;
}
+ ao2_ref(contact, +1);
if (pjsip_endpt_send_request(ast_sip_get_pjsip_endpoint(),
tdata, -1, contact, qualify_contact_cb) != PJ_SUCCESS) {
pjsip_tx_data_dec_ref(tdata);
ast_log(LOG_ERROR, "Unable to send request to qualify contact %s\n",
contact->uri);
- return -1;
- }
-
- ao2_ref(contact, +1);
+ ao2_ref(contact, -1);
+ return -1;
+ }
+
return 0;
}
@@ -306,9 +303,13 @@
{
struct sched_data *data = obj;
- ast_log(LOG_VERBOSE, "removing from scheduler %s\n", data->contact->uri);
- AST_SCHED_DEL(sched, data->id);
- ao2_cleanup(data->contact);
+ if (!AST_SCHED_DEL(sched, data->id)) {
+ /* If we successfully deleted the qualify, we got it before it
+ * fired. We can safely unref the data that was passed to it.
+ * Otherwise, we're getting deleted while this is firing, so
+ * don't unref! */
+ ao2_cleanup(data->contact);
+ }
}
/*!
@@ -318,7 +319,6 @@
static int qualify_contact_task(void *obj)
{
RAII_VAR(struct ast_sip_contact *, contact, obj, ao2_cleanup);
- ast_log(LOG_VERBOSE, "qualify contact task\n");
return qualify_contact(contact);
}
@@ -329,10 +329,19 @@
static int qualify_contact_sched(const void *obj)
{
struct sched_data *data = (struct sched_data *)obj;
+
+ if (!data->contact) {
+ /* contact is gone - so remove from scheduler */
+ return 0;
+ }
+
ao2_ref(data->contact, +1);
- ast_log(LOG_VERBOSE, "qualify contact sched %s\n", data->contact->uri);
- return !ast_sip_push_task(
- NULL, qualify_contact_task, data->contact);
+ if (ast_sip_push_task(NULL, qualify_contact_task, data->contact)) {
+ ao2_ref(data->contact, -1);
+ return 0;
+ }
+
+ return data->contact->qualify_frequency * 1000;
}
/*!
@@ -345,72 +354,73 @@
sizeof(*data), sched_data_destructor), ao2_cleanup);
if (!data) {
- ast_log(LOG_ERROR,
- "Unable to create schedule qualify data\n");
-
+ ast_log(LOG_ERROR, "Unable to create schedule qualify data\n");
return;
}
- ast_log(LOG_VERBOSE, "schedule a qualify %s\n", contact->uri);
data->contact = contact;
- if ((data->id = ast_sched_add(
+ ao2_ref(data->contact, +1);
+ if ((data->id = ast_sched_add_variable(
sched, contact->qualify_frequency * 1000,
- qualify_contact_sched, data) <= 0)) {
+ qualify_contact_sched, data, 1) <= 0)) {
ast_log(LOG_ERROR, "Unable to schedule qualify for contact %s\n",
contact->uri);
+ ao2_ref(data->contact, -1);
return;
}
- ast_log(LOG_VERBOSE, "add to container %s\n", contact->uri);
- ao2_ref(data->contact, +1);
ao2_link(sched_qualifies, data);
}
/*!
* \internal
- * \brief A new contact has been created make sure it is available.
- */
-static void contact_created(const void *obj)
-{
- struct ast_sip_contact *contact = (struct ast_sip_contact *)obj;
-
- ast_log(LOG_VERBOSE, "creating contact %s, freq = %d\n", contact->uri, contact->qualify_frequency);
+ * \brief Remove the contact from the scheduler.
+ */
+static void unschedule_qualify(struct ast_sip_contact *contact)
+{
+ /* make sure the contact isn't already in the scheduler */
+ struct sched_data *data =
+ ao2_find(sched_qualifies, contact, OBJ_UNLINK);
+
+ if (data) {
+ /* if it does exist remove */
+ ao2_ref(data, -1);
+ }
+}
+
+/*!
+ * \internal
+ * \brief Qualify the given contact and sets up scheduling if configured.
+ */
+static void qualify_and_schedule(struct ast_sip_contact *contact)
+{
+ unschedule_qualify(contact);
+
ao2_ref(contact, +1);
ast_sip_push_task(NULL, qualify_contact_task, contact);
if (contact->qualify_frequency) {
- ast_log(LOG_VERBOSE, "schedule contact %s\n", contact->uri);
schedule_qualify(contact);
}
}
/*!
* \internal
+ * \brief A new contact has been created make sure it is available.
+ */
+static void contact_created(const void *obj)
+{
+ qualify_and_schedule((struct ast_sip_contact *)obj);
+}
+
+/*!
+ * \internal
* \brief A contact has been updated make sure it is still available.
*/
static void contact_updated(const void *obj)
{
- struct ast_sip_contact *contact = (struct ast_sip_contact *)obj;
-
- /* see if there was a scheduled check for the contact */
- struct sched_data *data =
- ao2_find(sched_qualifies, contact, OBJ_UNLINK);
-
- ast_log(LOG_VERBOSE, "Updating contact %s\n", contact->uri);
- if (data) {
- /* if it exists prepare for a re-schedule */
- ast_log(LOG_VERBOSE, "found in sched about to REMOVE!!! %s\n", contact->uri);
- ao2_ref(data, -1);
- }
-
- ao2_ref(contact, +1);
- ast_sip_push_task(NULL, qualify_contact_task, contact);
-
- if (contact->qualify_frequency) {
- ast_log(LOG_VERBOSE, "REgister in sched!!! %s\n", contact->uri);
- schedule_qualify(contact);
- }
+ qualify_and_schedule((struct ast_sip_contact *)obj);
}
/*!
@@ -424,16 +434,10 @@
RAII_VAR(struct contact_status *, status,
get_contact_status(contact), ao2_cleanup);
- struct sched_data *data =
- ao2_find(sched_qualifies, contact, OBJ_UNLINK);
-
- if (data) {
- /* if scheduled remove from scheduler */
- ao2_ref(data, -1);
- }
+ unschedule_qualify(contact);
if (ast_sorcery_delete(ast_sip_get_sorcery(), status)) {
- ast_log(LOG_ERROR, "Unable to delete contact_stats for contact %s\n",
+ ast_log(LOG_ERROR, "Unable to delete contact_status for contact %s\n",
contact->uri);
}
}
@@ -548,7 +552,7 @@
send_options_response(rdata, 416);
return -1;
}
-
+
sip_ruri = pjsip_uri_get_uri(ruri);
ast_copy_pj_str(exten, &sip_ruri->user, sizeof(exten));
@@ -621,7 +625,6 @@
struct sched_data *data = obj;
const char *id = flags & OBJ_KEY ? arg : ast_sorcery_object_get_id(arg);
- ast_log(LOG_VERBOSE, "COMPARING!!! stored = %s, incoming = %s\n", ast_sorcery_object_get_id(data->contact), id);
return !strcmp(ast_sorcery_object_get_id(data->contact), id);
}
@@ -643,8 +646,61 @@
ast_log(LOG_WARNING, "Unable to add contact observer\n");
return -1;
}
- ast_log(LOG_VERBOSE, "YAY added qualify stuff\n");
+
return 0;
+}
+
+static int qualify_and_schedule_cb(void *obj, void *arg, int flags)
+{
+ struct ast_sip_contact *contact = obj;
+ struct ast_sip_aor *aor = arg;
+
+ contact->qualify_frequency = aor->qualify_frequency;
+
+ qualify_and_schedule(contact);
+ return 0;
+}
+
+/*!
+ * \internal
+ * \brief Qualify and schedule an endpoint's permanent contacts
+ *
+ * \detail For the given endpoint retrieve its list of aors, qualify all
+ * permanent contacts, and schedule for checks if configured.
+ */
+static int qualify_and_schedule_permanent_cb(void *obj, void *arg, int flags)
+{
+ struct ast_sip_endpoint *endpoint = obj;
+ char *aor_name, *aors;
+
+ if (ast_strlen_zero(endpoint->aors)) {
+ return 0;
+ }
+
+ aors = ast_strdupa(endpoint->aors);
+
+ while ((aor_name = strsep(&aors, ","))) {
+ RAII_VAR(struct ast_sip_aor *, aor,
+ ast_sip_location_retrieve_aor(aor_name), ao2_cleanup);
+ RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
+
+ if (!aor) {
+ continue;
+ }
+
+ ao2_callback(aor->permanent_contacts, OBJ_NODATA, qualify_and_schedule_cb, aor);
+ }
+
+ return 0;
+}
+
+static void qualify_and_schedule_permanent(void)
+{
+ RAII_VAR(struct ao2_container *, endpoints,
+ ast_res_sip_get_endpoints(), ao2_cleanup);
+
+ ao2_callback(endpoints, OBJ_NODATA,
+ qualify_and_schedule_permanent_cb, NULL);
}
int ast_res_sip_init_options_handling(int reload)
@@ -663,6 +719,7 @@
}
if (reload) {
+ qualify_and_schedule_permanent();
return 0;
}
@@ -677,6 +734,7 @@
}
ast_cli_register_multiple(cli_options, ARRAY_LEN(cli_options));
+ qualify_and_schedule_permanent();
return 0;
}
Modified: team/kharwell/pimp_sip_qualify/res/res_sip_registrar.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_qualify/res/res_sip_registrar.c?view=diff&rev=390316&r1=390315&r2=390316
==============================================================================
--- team/kharwell/pimp_sip_qualify/res/res_sip_registrar.c (original)
+++ team/kharwell/pimp_sip_qualify/res/res_sip_registrar.c Fri May 31 13:59:04 2013
@@ -303,8 +303,8 @@
contact_uri, aor_name, expiration);
} else if (expiration) {
RAII_VAR(struct ast_sip_contact *, updated, ast_sorcery_copy(ast_sip_get_sorcery(), contact), ao2_cleanup);
-
updated->expiration_time = ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1));
+ updated->qualify_frequency = aor->qualify_frequency;
ast_sip_location_update_contact(updated);
ast_debug(3, "Refreshed contact '%s' on AOR '%s' with new expiration of %d seconds\n",
More information about the asterisk-commits
mailing list