[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