Revision
14391
Author
cseket
Date
2009-07-27 15:26:00 -0500 (Mon, 27 Jul 2009)

Log Message

hunt dialplan before channel init, not general enough to submit on jira, but it would be nice to avoid duplicate routing logic, that already is in dialplan

Modified Paths

Diff

Modified: freeswitch/branches/cseket/src/mod/endpoints/mod_sofia/mod_sofia.c (14390 => 14391)


--- freeswitch/branches/cseket/src/mod/endpoints/mod_sofia/mod_sofia.c	2009-07-27 20:18:20 UTC (rev 14390)
+++ freeswitch/branches/cseket/src/mod/endpoints/mod_sofia/mod_sofia.c	2009-07-27 20:26:00 UTC (rev 14391)
@@ -35,6 +35,7 @@
 
 /* Best viewed in a 160 x 60 VT100 Terminal or so the line below at least fits across your screen*/
 /*************************************************************************************************************************************************************/
+
 #include "mod_sofia.h"
 #include "sofia-sip/sip_extra.h"
 SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load);
@@ -142,6 +143,8 @@
 		sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
 	}
 
+	//	switch_channel_set_state(switch_core_session_get_channel(session), CS_INIT);
+
 	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s SOFIA RESET\n", switch_channel_get_name(switch_core_session_get_channel(session)));
 
 	return SWITCH_STATUS_SUCCESS;
@@ -153,10 +156,14 @@
 	private_object_t *tech_pvt = switch_core_session_get_private(session);
 	switch_assert(tech_pvt != NULL);
 
+	//	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "HIBERNATE???\n");
+
 	if (!sofia_test_flag(tech_pvt, TFLAG_HOLD_LOCK)) {
 		sofia_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
 	}
 
+	//	switch_channel_set_state(switch_core_session_get_channel(session), CS_INIT);
+
 	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s SOFIA HIBERNATE\n", switch_channel_get_name(switch_core_session_get_channel(session)));
 
 	return SWITCH_STATUS_SUCCESS;
@@ -2532,6 +2539,94 @@
 	return SWITCH_STATUS_SUCCESS;
 }
 
+
+
+switch_status_t prehunt_dialplan(switch_core_session_t *session, switch_event_t *var_event, switch_caller_profile_t *outbound_profile, switch_caller_profile_t *hunt_profile, char **endpoint_name)
+{
+	switch_dialplan_interface_t *dialplan_interface = NULL;
+	switch_caller_extension_t *extension = NULL;
+	switch_caller_profile_t *new_profile = NULL;
+	char *dparg = NULL;
+	char *expanded_data = NULL;
+	switch_channel_t *channel = switch_core_session_get_channel(session);
+	char *data, *ext, *dp, *context;
+	char *app;
+
+
+	if (!(dialplan_interface = switch_loadable_module_get_dialplan_interface(hunt_profile->dialplan))) {
+		return SWITCH_STATUS_FALSE;
+	}
+					
+	extension = dialplan_interface->hunt_function(session, dparg, hunt_profile);
+					
+	if (extension) {
+		while (extension->current_application) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "application: %s data: %s\n", extension->current_application->application_name, extension->current_application->application_data);
+
+			app = extension->current_application->application_name;
+
+			expanded_data = switch_channel_expand_variables(channel, extension->current_application->application_data);
+			data = switch_core_strdup(switch_core_session_get_pool(session), expanded_data);
+			if (expanded_data != extension->current_application->application_data) {
+				switch_safe_free(expanded_data);
+			}
+
+			if (!strcasecmp(app, "execute_extension")) {
+				new_profile = switch_caller_profile_clone(session, hunt_profile);
+
+				ext = data;
+				dp = NULL;
+				context = NULL;
+
+				if ((dp = strchr(ext, ' '))) {
+					*dp++ = '\0';
+					if ((context = strchr(dp, ' '))) {
+						*context++ = '\0';
+					}
+				}
+				new_profile->destination_number = ext;
+				new_profile->dialplan = dp;
+				new_profile->context = context;
+
+				prehunt_dialplan(session, var_event, outbound_profile, new_profile, endpoint_name);
+				
+			} else if (!strcasecmp(app, "set") || !strcasecmp(app, "export")) {
+				char *var = data;
+				char *value = NULL;
+				if ((value = strchr(var, '='))) {
+					*value++ = '\0';
+				}
+
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Set var: '%s' value: '%s'\n", var, value);
+				switch_channel_set_variable(channel, var, value);
+			} else if (!strcasecmp(app, "bridge")) {
+				char *dest_to;
+				char *p = data;
+				
+				if ((dest_to = strchr(data, '/'))) {
+					*dest_to++ = '\0';
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Rewrite destination_number: %s\n", dest_to);
+					outbound_profile->destination_number = switch_core_strdup(outbound_profile->pool, dest_to);
+				}
+
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "data: %s\n", data);
+				if ((p = strchr(data, '}'))) {
+					*p++ = '\0';
+					*endpoint_name = switch_core_strdup(switch_core_session_get_pool(session), p);
+				} else {
+					*endpoint_name = switch_core_strdup(switch_core_session_get_pool(session), data);
+				}
+				return SWITCH_STATUS_SUCCESS;
+			}
+			extension->current_application = extension->current_application->next;
+
+		}
+	}
+
+	return SWITCH_STATUS_SUCCESS;
+
+}
+
 static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session, switch_event_t *var_event,
 												  switch_caller_profile_t *outbound_profile, switch_core_session_t **new_session,
 												  switch_memory_pool_t **pool, switch_originate_flag_t flags)
@@ -2545,6 +2640,7 @@
 	switch_channel_t *nchannel;
 	char *host = NULL, *dest_to = NULL;
 	const char *hval = NULL;
+	char *prehunt_dp = NULL;
 
 	*new_session = NULL;
 
@@ -2553,21 +2649,60 @@
 		goto error;
 	}
 
+	
+	nchannel = switch_core_session_get_channel(nsession);
+	caller_profile = switch_caller_profile_clone(nsession, outbound_profile);
+	switch_channel_set_caller_profile(nchannel, caller_profile);
+
+	// DEBUG
+	if (var_event->headers) {
+		switch_event_header_t *event_header = NULL;
+        for (event_header = var_event->headers; event_header; event_header = event_header->next) {
+            switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Header info: %s => %s\n", event_header->name, event_header->value);
+        }
+	}
+
+	if ((prehunt_dp = switch_event_get_header(var_event, "sofia_prehunt_dialplan"))) {
+		switch_caller_profile_t *hunt_profile = NULL;
+		char *context = switch_event_get_header(var_event, "sofia_prehunt_context");
+		const char *caller_id_name, *caller_id_number;
+		char *endpoint_name;
+
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Pre-Hunt Diaplan\n");
+		
+		hunt_profile = switch_caller_profile_clone(nsession, caller_profile);
+
+		hunt_profile->dialplan = switch_core_sprintf(hunt_profile->pool, prehunt_dp);
+		if (context) {
+			hunt_profile->context = switch_core_sprintf(hunt_profile->pool, context);
+		}
+		
+		prehunt_dialplan(nsession, var_event, outbound_profile, hunt_profile, &endpoint_name);
+
+		if ((caller_id_name = switch_channel_get_variable(nchannel, "effective_caller_id_name"))) {
+			caller_profile->caller_id_name = switch_core_sprintf(caller_profile->pool, caller_id_name);
+			outbound_profile->caller_id_name = switch_core_sprintf(outbound_profile->pool, caller_id_name);
+		}
+		if ((caller_id_number = switch_channel_get_variable(nchannel, "effective_caller_id_number"))) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "caller id number: %s\n", caller_id_number);
+			caller_profile->caller_id_number = switch_core_sprintf(caller_profile->pool, caller_id_number);
+			outbound_profile->caller_id_number = switch_core_sprintf(outbound_profile->pool, caller_id_number);
+		}
+	}
+
 	if (!(tech_pvt = (struct private_object *) switch_core_session_alloc(nsession, sizeof(*tech_pvt)))) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Error Creating Session\n");
 		goto error;
 	}
 	switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(nsession));
 	switch_mutex_init(&tech_pvt->sofia_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(nsession));
-
+	
 	data = switch_core_session_strdup(nsession, outbound_profile->destination_number);
 	if ((dest_to = strchr(data, '^'))) {
 		*dest_to++ = '\0';
 	}
 	profile_name = data;
 
-	nchannel = switch_core_session_get_channel(nsession);
-
 	if ((hval = switch_event_get_header(var_event, "sip_invite_to_uri"))) {
 		dest_to = switch_core_session_strdup(nsession, hval);
 	}
@@ -2752,15 +2887,13 @@
 	}
 	switch_channel_set_variable(nchannel, "sip_destination_url", tech_pvt->dest);
 
-	caller_profile = switch_caller_profile_clone(nsession, outbound_profile);
 	caller_profile->destination_number = switch_core_strdup(caller_profile->pool, dest);
-	switch_channel_set_caller_profile(nchannel, caller_profile);
 	switch_channel_set_flag(nchannel, CF_OUTBOUND);
 	sofia_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);
 	sofia_clear_flag_locked(tech_pvt, TFLAG_LATE_NEGOTIATION);
 	if (switch_channel_get_state(nchannel) == CS_NEW) {
 		switch_channel_set_state(nchannel, CS_INIT);
-	}
+	} 
 	tech_pvt->caller_profile = caller_profile;
 	*new_session = nsession;
 	cause = SWITCH_CAUSE_SUCCESS;