[Freeswitch-svn] [commit] r4430 - freeswitch/trunk/src/mod/endpoints/mod_wanpipe

Freeswitch SVN anthm at freeswitch.org
Fri Mar 2 14:12:26 EST 2007


Author: anthm
Date: Fri Mar  2 14:12:26 2007
New Revision: 4430

Added:
   freeswitch/trunk/src/mod/endpoints/mod_wanpipe/sigboost.h
   freeswitch/trunk/src/mod/endpoints/mod_wanpipe/ss7boost_client.c
   freeswitch/trunk/src/mod/endpoints/mod_wanpipe/ss7boost_client.h
Modified:
   freeswitch/trunk/src/mod/endpoints/mod_wanpipe/Makefile
   freeswitch/trunk/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c

Log:
Add ss7boost signalling to mod_wanpipe

Modified: freeswitch/trunk/src/mod/endpoints/mod_wanpipe/Makefile
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_wanpipe/Makefile	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_wanpipe/Makefile	Fri Mar  2 14:12:26 2007
@@ -1,7 +1,7 @@
 CFLAGS +=-I/usr/local/include -I/usr/src/libpri -I/usr/src/linux/include -I. -I/usr/include
 CFLAGS +=-D__LINUX__ -D_REENTRANT -D_GNU_SOURCE -DAFT_A104 -DWANPIPE_TDM_API
 LDFLAGS += -lsangoma
-
+OBJS = ss7boost_client.o mod_wanpipe.o
 
 ifeq ($(OSARCH),Darwin)
 	LINKER=g++
@@ -14,9 +14,12 @@
 depends:
 	MAKE=$(MAKE) $(BASE)/build/buildlib.sh $(BASE) install libsangoma --prefix=$(PREFIX) --with-libpri=/usr/src/libpri
 
-$(MODNAME).$(DYNAMIC_LIB_EXTEN): $(MODNAME).c
+%.o:  %.c
+	$(CC) $(CFLAGS) $(MOD_CFLAGS) -g -ggdb -Werror -fPIC -c $< -o $@ 
+
+$(MODNAME).$(DYNAMIC_LIB_EXTEN): $(OBJS) $(MODNAME).c
 	$(CC) $(CFLAGS) -fPIC -c $(MODNAME).c -o $(MODNAME).o 
-	$(LINKER) $(SOLINK) -o $(MODNAME).$(DYNAMIC_LIB_EXTEN)  $(MODNAME).o $(LDFLAGS)
+	$(LINKER) $(SOLINK) -o $(MODNAME).$(DYNAMIC_LIB_EXTEN)  $(OBJS) $(LDFLAGS)
 
 clean:
 	rm -fr *.$(DYNAMIC_LIB_EXTEN) *.o *~

Modified: freeswitch/trunk/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_wanpipe/mod_wanpipe.c	Fri Mar  2 14:12:26 2007
@@ -34,6 +34,7 @@
 #include <libsangoma.h>
 #include <sangoma_pri.h>
 #include <libteletone.h>
+#include <ss7boost_client.h>
 
 #ifndef INVALID_HANDLE_VALUE
 #define INVALID_HANDLE_VALUE -1
@@ -67,11 +68,39 @@
 	TFLAG_ABORT = (1 << 8),
 	TFLAG_SWITCH = (1 << 9),
 	TFLAG_NOSIG = (1 << 10),
-	TFLAG_BYE = (1 << 11)
+	TFLAG_BYE = (1 << 11),
+	TFLAG_CODEC = (1 << 12)
 } TFLAGS;
 
 
 #define DEFAULT_SAMPLES_PER_FRAME 160
+#define MAX_SPANS 128
+
+struct channel_map {
+	char map[SANGOMA_MAX_CHAN_PER_SPAN][SWITCH_UUID_FORMATTED_LENGTH + 1];
+};
+
+
+unsigned int txseq=0;
+unsigned int rxseq=0;
+
+#define SETUP_LEN CORE_MAX_CHAN_PER_SPAN*CORE_MAX_SPANS+1
+
+struct ss7boost_handle {
+	char *local_ip;
+	char *remote_ip;
+	int local_port;
+	int remote_port;
+	ss7boost_client_connection_t mcon;
+	switch_mutex_t *mutex;
+	struct channel_map span_chanmap[MAX_SPANS];
+	char setup_array[SETUP_LEN][SWITCH_UUID_FORMATTED_LENGTH + 1];
+	uint32_t setup_index;
+};
+
+typedef struct ss7boost_handle ss7boost_handle_t;
+
+static int isup_exec_command(ss7boost_handle_t *ss7boost_handle, int span, int chan, int id, int cmd, int cause);
 
 static struct {
 	int debug;
@@ -81,10 +110,12 @@
 	int dtmf_off;
 	int supress_dtmf_tone;
 	int configured_spans;
+	int configured_boost_spans;
 	char *dialplan;
 	switch_hash_t *call_hash;
 	switch_mutex_t *hash_mutex;
 	switch_mutex_t *channel_mutex;
+	ss7boost_handle_t *ss7boost_handle;
 } globals;
 
 struct wanpipe_pri_span {
@@ -107,11 +138,8 @@
 
 typedef struct wpsock wpsock_t;
 
-
-#define MAX_SPANS 128
 static struct wanpipe_pri_span *SPANS[MAX_SPANS];
 
-
 struct private_object {
 	unsigned int flags;			/* FLAGS */
 	switch_frame_t read_frame;	/* Frame for Writing */
@@ -135,6 +163,12 @@
 	unsigned int skip_write_frames;
 	switch_mutex_t *flag_mutex;
 	int frame_size;
+	ss7boost_handle_t *ss7boost_handle;
+	int boost_chan_number;
+	int boost_span_number;
+	int boost_trunk_group;
+	uint32_t setup_index;
+	uint32_t boost_pres;
 #ifdef DOTRACE
 	int fd;
 	int fd2;
@@ -142,10 +176,6 @@
 };
 typedef struct private_object private_object_t;
 
-struct channel_map {
-	char map[SANGOMA_MAX_CHAN_PER_SPAN][SWITCH_UUID_FORMATTED_LENGTH + 1];
-};
-
 static int wp_close(private_object_t *tech_pvt)
 {
 	int ret = 0;
@@ -315,27 +345,20 @@
 static switch_status_t config_wanpipe(int reload);
 
 
-/* 
-   State methods they get called when the state changes to the specific state 
-   returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
-   so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it.
-*/
-static switch_status_t wanpipe_on_init(switch_core_session_t *session)
+static switch_status_t wanpipe_codec_init(private_object_t *tech_pvt)
 {
-	private_object_t *tech_pvt;
-	switch_channel_t *channel = NULL;
-	wanpipe_tdm_api_t tdm_api = {{0}};
 	int err = 0;
+	wanpipe_tdm_api_t tdm_api = {{0}};
 	unsigned int rate = 8000;
+	switch_channel_t *channel = NULL;
 
+	if (switch_test_flag(tech_pvt, TFLAG_CODEC)) {
+		return SWITCH_STATUS_SUCCESS;
+	}
 
-	channel = switch_core_session_get_channel(session);
-	assert(channel != NULL);
-
-	tech_pvt = switch_core_session_get_private(session);
-	assert(tech_pvt != NULL);
 
-	tech_pvt->read_frame.data = tech_pvt->databuf;
+	channel = switch_core_session_get_channel(tech_pvt->session);
+	assert(channel != NULL);
 
 	err = sangoma_tdm_set_codec(tech_pvt->wpsock->fd, &tdm_api, WP_SLINEAR);
 	
@@ -344,7 +367,7 @@
 
 	if (switch_core_codec_init
 		(&tech_pvt->read_codec, "L16", NULL, rate, globals.samples_per_frame / 8, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
-		 switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
+		 switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s Cannot set read codec\n", switch_channel_get_name(channel));
 		switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
 		return SWITCH_STATUS_FALSE;
@@ -352,15 +375,15 @@
 
 	if (switch_core_codec_init
 		(&tech_pvt->write_codec, "L16", NULL, rate, globals.samples_per_frame / 8, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
-		 switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
+		 switch_core_session_get_pool(tech_pvt->session)) != SWITCH_STATUS_SUCCESS) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%s Cannot set read codec\n", switch_channel_get_name(channel));
 		switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
 		return SWITCH_STATUS_FALSE;
 	}
 	tech_pvt->read_frame.rate = rate;
 	tech_pvt->read_frame.codec = &tech_pvt->read_codec;
-	switch_core_session_set_read_codec(session, &tech_pvt->read_codec);
-	switch_core_session_set_write_codec(session, &tech_pvt->write_codec);
+	switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec);
+	switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec);
 
 #ifdef DOTRACE	
 						tech_pvt->fd = open("/tmp/wp-in.raw", O_WRONLY | O_TRUNC | O_CREAT);
@@ -381,11 +404,74 @@
 	tech_pvt->tone_session.wait = globals.dtmf_off * (tech_pvt->tone_session.rate / 1000);
 	
 	teletone_dtmf_detect_init (&tech_pvt->dtmf_detect, rate);
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Audio init %s\n", switch_channel_get_name(channel));
+
+	switch_set_flag(tech_pvt, TFLAG_CODEC);
+
+	return SWITCH_STATUS_SUCCESS;
+
+}
+
+
+/* 
+   State methods they get called when the state changes to the specific state 
+   returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
+   so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it.
+*/
+static switch_status_t wanpipe_on_init(switch_core_session_t *session)
+{
+	private_object_t *tech_pvt;
+	switch_channel_t *channel = NULL;
+	switch_status_t status;
+
+	channel = switch_core_session_get_channel(session);
+	assert(channel != NULL);
+
+	tech_pvt = switch_core_session_get_private(session);
+	assert(tech_pvt != NULL);
+
+	tech_pvt->read_frame.data = tech_pvt->databuf;
+
+	if (tech_pvt->ss7boost_handle)  {
+		if (switch_channel_test_flag(channel, CF_OUTBOUND)) {
+			ss7boost_client_event_t event;
 
+			event.calling_number_presentation = tech_pvt->boost_pres;
+			event.trunk_group = tech_pvt->boost_trunk_group;
+		
+			switch_mutex_lock(tech_pvt->ss7boost_handle->mutex);
+			tech_pvt->setup_index = ++tech_pvt->ss7boost_handle->setup_index;
+			if (tech_pvt->ss7boost_handle->setup_index == SETUP_LEN - 1) {
+				tech_pvt->ss7boost_handle->setup_index = 0;
+			}
+			switch_mutex_unlock(tech_pvt->ss7boost_handle->mutex);
+		
+			switch_copy_string(tech_pvt->ss7boost_handle->setup_array[tech_pvt->setup_index],
+							   switch_core_session_get_uuid(session), 
+							   sizeof(tech_pvt->ss7boost_handle->setup_array[tech_pvt->setup_index]));
+		
+			
+			ss7boost_client_call_init(&event, tech_pvt->caller_profile->caller_id_number, tech_pvt->caller_profile->destination_number, tech_pvt->setup_index);
+			
+			if (ss7boost_client_connection_write(&tech_pvt->ss7boost_handle->mcon, &event) <= 0) {
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Critical System Error: Failed to tx on ISUP socket [%s]: %s\n", strerror(errno));
+			}
+			
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Called Event TG=%d\n", tech_pvt->boost_trunk_group);
+			goto done;
+		}
+	} 
+
+	if ((status = wanpipe_codec_init(tech_pvt)) != SWITCH_STATUS_SUCCESS) {
+		switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+		return status;
+	}
+	
 	if (switch_test_flag(tech_pvt, TFLAG_NOSIG)) {
 		switch_channel_mark_answered(channel);
 	}
 
+ done:
 
 	/* Move Channel's State Machine to RING */
 	switch_channel_set_state(channel, CS_RING);
@@ -423,13 +509,8 @@
 	tech_pvt = switch_core_session_get_private(session);
 	assert(tech_pvt != NULL);
 
-	switch_set_flag_locked(tech_pvt, TFLAG_BYE);
 
-	if (!switch_test_flag(tech_pvt, TFLAG_NOSIG)) {
-		chanmap = tech_pvt->spri->private_info;
-	}
 
-	//sangoma_socket_close(&tech_pvt->wpsock->fd);
 	wp_close(tech_pvt);
 
 	switch_core_codec_destroy(&tech_pvt->read_codec);
@@ -438,16 +519,34 @@
 
 	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "WANPIPE HANGUP\n");
 
-	if (!switch_test_flag(tech_pvt, TFLAG_NOSIG)) {
-		pri_hangup(tech_pvt->spri->pri, tech_pvt->call, switch_channel_get_cause(channel));
-		pri_destroycall(tech_pvt->spri->pri, tech_pvt->call);
+	if (tech_pvt->ss7boost_handle) {
+		switch_mutex_lock(tech_pvt->ss7boost_handle->mutex);
+		*tech_pvt->ss7boost_handle->span_chanmap[tech_pvt->boost_span_number].map[tech_pvt->boost_chan_number] = '\0';
+		switch_mutex_unlock(tech_pvt->ss7boost_handle->mutex);
+		if (!switch_test_flag(tech_pvt, TFLAG_BYE)) {
+			isup_exec_command(tech_pvt->ss7boost_handle,
+							  tech_pvt->boost_span_number,
+							  tech_pvt->boost_chan_number,
+							  -1,
+							  SIGBOOST_EVENT_CALL_STOPPED,
+							  SIGBOOST_RELEASE_CAUSE_NORMAL);
+		}
+	} else if (tech_pvt->spri) {
+		chanmap = tech_pvt->spri->private_info;
+
+		if (!switch_test_flag(tech_pvt, TFLAG_BYE)) {
+			pri_hangup(tech_pvt->spri->pri, tech_pvt->call, switch_channel_get_cause(channel));
+			pri_destroycall(tech_pvt->spri->pri, tech_pvt->call);
+		}
 
 		switch_mutex_lock(globals.channel_mutex);
 		*chanmap->map[tech_pvt->callno] = '\0';
-
 		switch_mutex_unlock(globals.channel_mutex);
+		
 	}
 
+	switch_set_flag_locked(tech_pvt, TFLAG_BYE);
+
 	teletone_destroy_session(&tech_pvt->tone_session);
 
 	switch_buffer_destroy(&tech_pvt->dtmf_buffer);
@@ -490,9 +589,19 @@
 	tech_pvt = switch_core_session_get_private(session);
 	assert(tech_pvt != NULL);
 
-	if (switch_test_flag(tech_pvt, TFLAG_INBOUND) && !switch_test_flag(tech_pvt, TFLAG_NOSIG)) {
-		pri_answer(tech_pvt->spri->pri, tech_pvt->call, 0, 1);
+	if (tech_pvt->spri) {
+		if (switch_test_flag(tech_pvt, TFLAG_INBOUND)) {
+			pri_answer(tech_pvt->spri->pri, tech_pvt->call, 0, 1);
+		}
+	} else if (tech_pvt->ss7boost_handle) {
+		isup_exec_command(tech_pvt->ss7boost_handle,
+						  tech_pvt->boost_span_number,
+						  tech_pvt->boost_chan_number,
+						  -1,
+						  SIGBOOST_EVENT_CALL_ANSWERED,
+						  0);
 	}
+
 	return SWITCH_STATUS_SUCCESS;
 }
 
@@ -705,10 +814,7 @@
 
 	switch(sig) {
 	case SWITCH_SIG_KILL:
-		switch_mutex_lock(tech_pvt->flag_mutex);
-		switch_set_flag(tech_pvt, TFLAG_BYE);
-		switch_clear_flag(tech_pvt, TFLAG_MEDIA);
-		switch_mutex_unlock(tech_pvt->flag_mutex);
+		switch_clear_flag_locked(tech_pvt, TFLAG_MEDIA);
 		break;
 	default:
 		break;
@@ -765,29 +871,59 @@
 {
 	char *bchan = NULL;
 	char name[128] = "";
-		
+	char *protocol;
+	char *dest;
+	int ready = 0, is_pri = 0, is_boost = 0, is_raw = 0;
 
-	if (outbound_profile && outbound_profile->destination_number) {
-		bchan = strchr(outbound_profile->destination_number, '=');
-	} else {
-		return SWITCH_STATUS_FALSE;
+
+	if (!outbound_profile) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Doh! no caller profile\n");
+		return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+	}
+
+	protocol = switch_core_session_strdup(session, outbound_profile->destination_number);
+
+	if (!(dest = strchr(protocol, '/'))) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error No protocol specified!\n");
+		return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
 	}
+	
+	*dest++ = '\0';
 
-	if (bchan) {
-		bchan++;
-		if (!bchan) {
-			return SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL;
-		}
-		outbound_profile->destination_number++;
-	} else if (!globals.configured_spans) {
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error No Spans Configured.\n");
-		SWITCH_CAUSE_NETWORK_OUT_OF_ORDER;
+	if (!strcasecmp(protocol, "raw")) {
+		bchan = dest;
+		is_raw = ready = 1;
+	} else if (!strcasecmp(protocol, "pri")) {
+		if ((is_pri = globals.configured_spans)) {
+			ready = is_pri;
+		} else {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error No PRI Spans Configured.\n");
+		}
+	} else if (!strcasecmp(protocol, "ss7boost")) {
+		if ((is_boost = globals.configured_boost_spans)) {
+			ready = is_boost;
+		} else {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error No SS7BOOST Spans Configured.\n");
+		}
+	}
+	
+	if (!ready) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Continue!\n");
+		return SWITCH_CAUSE_NETWORK_OUT_OF_ORDER;
 	}
 
+	outbound_profile->destination_number = dest;
 
 	if ((*new_session = switch_core_session_request(&wanpipe_endpoint_interface, pool))) {
 		private_object_t *tech_pvt;
 		switch_channel_t *channel;
+		switch_caller_profile_t *caller_profile = NULL;
+		int callno = 0;
+		struct sangoma_pri *spri;
+		int span = 0, autospan = 0, autochan = 0;
+		char *num, *p;
+		struct channel_map *chanmap = NULL;
+
 
 		switch_core_session_add_stream(*new_session, NULL);
 		if ((tech_pvt = (private_object_t *) switch_core_session_alloc(*new_session, sizeof(private_object_t)))) {
@@ -797,181 +933,193 @@
 			switch_core_session_set_private(*new_session, tech_pvt);
 			tech_pvt->session = *new_session;
 		} else {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
 			switch_core_session_destroy(new_session);
-			SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+			return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
 		}
 
 		
-		if (outbound_profile) {
-			switch_caller_profile_t *caller_profile;
-			struct sangoma_pri *spri;
-			int span = 0, autospan = 0, autochan = 0;
-			char *num, *p;
-			int callno = 0;
-			struct channel_map *chanmap = NULL;
-
-			caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
-			if (!bchan) {
-				num = caller_profile->destination_number;
-				if ((p = strchr(num, '/'))) {
-					*p++ = '\0';
+		caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
 
-					if (*num == 'a') {
-						span = 1;
-						autospan = 1;
-					} else if (*num = 'A') {
-						span = MAX_SPANS - 1;
-						autospan = -1;
+		if (is_pri) {
+			num = caller_profile->destination_number;
+			if ((p = strchr(num, '/'))) {
+				*p++ = '\0';
+
+				if (*num == 'a') {
+					span = 1;
+					autospan = 1;
+				} else if (*num = 'A') {
+					span = MAX_SPANS - 1;
+					autospan = -1;
+				} else {
+					if (num && *num > 47 && *num < 58) {
+						span = atoi(num);
 					} else {
-						if (num && *num > 47 && *num < 58) {
-							span = atoi(num);
-						} else {
-							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invlid Syntax\n");
-							switch_core_session_destroy(new_session);
-							return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
-						}
+						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invlid Syntax\n");
+						switch_core_session_destroy(new_session);
+						return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
 					}
-					num = p;
-					if ((p = strchr(num, '/'))) {
-						*p++ = '\0';
-						if (*num == 'a') {
-							autochan = 1;
-						} else if (*num == 'A') {
-							autochan = -1;
-						} else if (num && *num > 47 && *num < 58) {
-							callno = atoi(num);
-						} else {
-							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invlid Syntax\n");
-                            switch_core_session_destroy(new_session);
-                            return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
-						}
-						caller_profile->destination_number = p;
+				}
+				num = p;
+				if ((p = strchr(num, '/'))) {
+					*p++ = '\0';
+					if (*num == 'a') {
+						autochan = 1;
+					} else if (*num == 'A') {
+						autochan = -1;
+					} else if (num && *num > 47 && *num < 58) {
+						callno = atoi(num);
 					} else {
 						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invlid Syntax\n");
 						switch_core_session_destroy(new_session);
 						return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
 					}
+					caller_profile->destination_number = p;
+				} else {
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invlid Syntax\n");
+					switch_core_session_destroy(new_session);
+					return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
 				}
 			}
+		}
 
-			tech_pvt->caller_profile = caller_profile;
+		tech_pvt->caller_profile = caller_profile;
 
-			if (bchan) {
-				int chan, span;
+		if (is_raw) {
+			int chan, span;
 
-				if (sangoma_span_chan_fromif(bchan, &span, &chan)) {
-					if (!wp_open(tech_pvt, span, chan)) {
-						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open fd for s%dc%d! [%s]\n", span, chan, strerror(errno));
-						switch_core_session_destroy(new_session);
-						return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
-					}
-					switch_set_flag_locked(tech_pvt, TFLAG_NOSIG);
-					snprintf(name, sizeof(name), "WanPipe/%s/nosig", bchan);
-					switch_channel_set_name(channel, name);			
-					switch_channel_set_caller_profile(channel, caller_profile);
-				} else {
-					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid address\n");
+			if (sangoma_span_chan_fromif(bchan, &span, &chan)) {
+				if (!wp_open(tech_pvt, span, chan)) {
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open fd for s%dc%d! [%s]\n", span, chan, strerror(errno));
 					switch_core_session_destroy(new_session);
-					return SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL;
+					return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
 				}
+				switch_set_flag_locked(tech_pvt, TFLAG_NOSIG);
+				snprintf(name, sizeof(name), "wanpipe/%s/nosig", bchan);
+				switch_channel_set_name(channel, name);			
+				switch_channel_set_caller_profile(channel, caller_profile);
 			} else {
-				switch_mutex_lock(globals.channel_mutex);
-				callno = 0;
-				while (!callno) {
-					if (autospan > 0 && span == MAX_SPANS - 1) {
-						break;
-					}
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid address\n");
+				switch_core_session_destroy(new_session);
+				return SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL;
+			}
+		} else if (is_pri) {
+			switch_mutex_lock(globals.channel_mutex);
+			callno = 0;
+			while (!callno) {
+				if (autospan > 0 && span == MAX_SPANS - 1) {
+					break;
+				}
 
-					if (autospan < 0 && span == 0) {
-						break;
-					}
+				if (autospan < 0 && span == 0) {
+					break;
+				}
 
-					if (SPANS[span] && (spri = &SPANS[span]->spri) && switch_test_flag(spri, SANGOMA_PRI_READY)) {
-						chanmap = spri->private_info;
+				if (SPANS[span] && (spri = &SPANS[span]->spri) && switch_test_flag(spri, SANGOMA_PRI_READY)) {
+					chanmap = spri->private_info;
 						
-						if (autochan > 0) {
-							for(callno = 1; callno < SANGOMA_MAX_CHAN_PER_SPAN; callno++) {
-								if ((SPANS[span]->bchans & (1 << callno)) && ! *chanmap->map[callno]) {
-									switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Choosing channel s%dc%d\n", span, callno);
-									goto done;
-								}
+					if (autochan > 0) {
+						for(callno = 1; callno < SANGOMA_MAX_CHAN_PER_SPAN; callno++) {
+							if ((SPANS[span]->bchans & (1 << callno)) && ! *chanmap->map[callno]) {
+								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Choosing channel s%dc%d\n", span, callno);
+								goto done;
 							}
-							callno = 0;
-						} else if (autochan < 0) {
-							for(callno = SANGOMA_MAX_CHAN_PER_SPAN; callno > 0; callno--) {
-								if ((SPANS[span]->bchans & (1 << callno)) && ! *chanmap->map[callno]) {
-									switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Choosing channel s%dc%d\n", span, callno);
-									goto done;
-								}
+						}
+						callno = 0;
+					} else if (autochan < 0) {
+						for(callno = SANGOMA_MAX_CHAN_PER_SPAN; callno > 0; callno--) {
+							if ((SPANS[span]->bchans & (1 << callno)) && ! *chanmap->map[callno]) {
+								switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Choosing channel s%dc%d\n", span, callno);
+								goto done;
 							}
-							callno = 0;
 						}
-					}
-
-					if (autospan > 0) {
-						span++;
-					} else if (autospan < 0) {
-						span--;
+						callno = 0;
 					}
 				}
-			done:
-				switch_mutex_unlock(globals.channel_mutex);
 
-				if (!spri || callno == 0 || callno == (SANGOMA_MAX_CHAN_PER_SPAN)) {
-					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No Free Channels!\n");
-					switch_core_session_destroy(new_session);
-					return SWITCH_CAUSE_SWITCH_CONGESTION;
+				if (autospan > 0) {
+					span++;
+				} else if (autospan < 0) {
+					span--;
 				}
+			}
+		done:
+			switch_mutex_unlock(globals.channel_mutex);
+
+			if (!spri || callno == 0 || callno == (SANGOMA_MAX_CHAN_PER_SPAN)) {
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No Free Channels!\n");
+				switch_core_session_destroy(new_session);
+				return SWITCH_CAUSE_SWITCH_CONGESTION;
+			}
 				
-				tech_pvt->callno = callno;
+			tech_pvt->callno = callno;
 				
-				if (spri && (tech_pvt->call = pri_new_call(spri->pri))) {
-					struct pri_sr *sr;
+			if (spri && (tech_pvt->call = pri_new_call(spri->pri))) {
+				struct pri_sr *sr;
 					
-					snprintf(name, sizeof(name), "WanPipe/s%dc%d/%s", spri->span, callno, caller_profile->destination_number);
-					switch_channel_set_name(channel, name);			
-					switch_channel_set_caller_profile(channel, caller_profile);
-					sr = pri_sr_new();
-					pri_sr_set_channel(sr, callno, 0, 0);
-					pri_sr_set_bearer(sr, 0, SPANS[span]->l1);
-					pri_sr_set_called(sr, caller_profile->destination_number, SPANS[span]->dp, 1);
-					pri_sr_set_caller(sr,
-									  caller_profile->caller_id_number,
-									  caller_profile->caller_id_name,
-									  SPANS[span]->dp,
-									  PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN);
-					pri_sr_set_redirecting(sr,
-										   caller_profile->caller_id_number,
-										   SPANS[span]->dp,
-										   PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN,
-										   PRI_REDIR_UNCONDITIONAL);
+				snprintf(name, sizeof(name), "wanpipe/pri/s%dc%d/%s", spri->span, callno, caller_profile->destination_number);
+				switch_channel_set_name(channel, name);			
+				switch_channel_set_caller_profile(channel, caller_profile);
+				sr = pri_sr_new();
+				pri_sr_set_channel(sr, callno, 0, 0);
+				pri_sr_set_bearer(sr, 0, SPANS[span]->l1);
+				pri_sr_set_called(sr, caller_profile->destination_number, SPANS[span]->dp, 1);
+				pri_sr_set_caller(sr,
+								  caller_profile->caller_id_number,
+								  caller_profile->caller_id_name,
+								  SPANS[span]->dp,
+								  PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN);
+				pri_sr_set_redirecting(sr,
+									   caller_profile->caller_id_number,
+									   SPANS[span]->dp,
+									   PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN,
+									   PRI_REDIR_UNCONDITIONAL);
 				
-					if (pri_setup(spri->pri, tech_pvt->call , sr)) {
-						switch_core_session_destroy(new_session);
-						pri_sr_free(sr);
-						return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
-					}
+				if (pri_setup(spri->pri, tech_pvt->call , sr)) {
+					switch_core_session_destroy(new_session);
+					pri_sr_free(sr);
+					return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+				}
 
-					if (!wp_open(tech_pvt, spri->span, callno)) {
-						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open fd!\n");
-						switch_core_session_destroy(new_session);
-						pri_sr_free(sr);
-						return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
-					}
+				if (!wp_open(tech_pvt, spri->span, callno)) {
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open fd!\n");
+					switch_core_session_destroy(new_session);
 					pri_sr_free(sr);
-					switch_copy_string(chanmap->map[callno],
-									   switch_core_session_get_uuid(*new_session),
-									   sizeof(chanmap->map[callno]));
-					tech_pvt->spri = spri;
+					return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
 				}
+				pri_sr_free(sr);
+				switch_copy_string(chanmap->map[callno],
+								   switch_core_session_get_uuid(*new_session),
+								   sizeof(chanmap->map[callno]));
+				tech_pvt->spri = spri;
 			}
-		} else {
-			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Doh! no caller profile\n");
-			switch_core_session_destroy(new_session);
-			return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+		} else if (is_boost) {
+			char *p;
+
+			if ((p = strchr(caller_profile->destination_number, '/'))) {
+				char *grp = caller_profile->destination_number;
+				*p = '\0';
+				caller_profile->destination_number = p+1;
+				tech_pvt->boost_trunk_group = atoi(grp+1) - 1;
+				if (tech_pvt->boost_trunk_group < 0) {
+					tech_pvt->boost_trunk_group = 0;
+				}
+			}
+			sprintf(name, "wanpipe/ss7boost/%s", caller_profile->destination_number);
+			switch_channel_set_name(channel, name);
+			tech_pvt->ss7boost_handle = globals.ss7boost_handle;
+
+			if (session && switch_core_session_compare(session, *new_session)) {
+				private_object_t *otech_pvt = switch_core_session_get_private(session);
+				tech_pvt->boost_pres = otech_pvt->boost_pres;
+			}
+
 		}
 
+
+
+		tech_pvt->caller_profile = caller_profile;
 		switch_channel_set_flag(channel, CF_OUTBOUND);
 		switch_set_flag_locked(tech_pvt, TFLAG_OUTBOUND);
 		switch_channel_set_state(channel, CS_INIT);
@@ -1069,9 +1217,9 @@
 		}
 
 		tech_pvt->cause = pevent->hangup.cause;
-
+		switch_set_flag_locked(tech_pvt, TFLAG_BYE);
 		switch_channel_hangup(channel, tech_pvt->cause);
-
+		
 		switch_mutex_lock(globals.channel_mutex);
 		*chanmap->map[pevent->hangup.channel] = '\0';
 		switch_mutex_unlock(globals.channel_mutex);
@@ -1207,9 +1355,9 @@
 			switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
 			channel = switch_core_session_get_channel(session);
 			switch_core_session_set_private(session, tech_pvt);
-			sprintf(name, "s%dc%d", spri->span, pevent->ring.channel);
+			sprintf(name, "wanpipe/pri/s%dc%d", spri->span, pevent->ring.channel);
 			switch_channel_set_name(channel, name);
-
+			tech_pvt->session = session;
 		} else {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
 			switch_core_session_destroy(&session);
@@ -1379,11 +1527,502 @@
 
 }
 
+
+static int isup_exec_command(ss7boost_handle_t *ss7boost_handle, int span, int chan, int id, int cmd, int cause)
+{
+	ss7boost_client_event_t oevent;
+	int r = 0;
+
+	switch_mutex_lock(ss7boost_handle->mutex);
+	ss7boost_client_event_init(&oevent, cmd, chan, span);
+	oevent.release_cause = cause;
+	
+	if (id >= 0) {
+		oevent.call_setup_id = id;
+	}
+	
+	if (ss7boost_client_connection_write(&ss7boost_handle->mcon, &oevent) <= 0){
+		r = -1;
+	}
+
+	switch_mutex_unlock(ss7boost_handle->mutex);
+
+	return r;
+}
+
+static int waitfor_socket(int fd, int timeout, int flags)
+{
+    struct pollfd pfds[1];
+    int res;
+ 
+    memset(&pfds[0], 0, sizeof(pfds[0]));
+    pfds[0].fd = fd;
+    pfds[0].events = flags;
+    res = poll(pfds, 1, timeout);
+
+    if (res > 0) {
+	if(pfds[0].revents & POLLIN) {
+		res = 1;
+	} else if ((pfds[0].revents & POLLERR)) {
+		res = -1;
+    	} else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"System Error: Poll Event Error no event!\n");
+		res = -1;
+	}
+    }
+
+    return res;
+}
+
+
+static void validate_number(unsigned char *s)
+{
+	unsigned char *p;
+	for (p = s; *p; p++) {
+		if (*p < 48 || *p > 57) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Encountered a non-numeric character [%c]!\n", *p);
+			*p = '\0';
+			break;
+		}
+	}
+}
+
+
+static void handle_call_stop(ss7boost_handle_t *ss7boost_handle, ss7boost_client_event_t *event)
+{
+	char *uuid = ss7boost_handle->span_chanmap[event->span].map[event->chan];
+
+	if (*uuid) {
+		switch_core_session_t *session;
+
+		if ((session = switch_core_session_locate(uuid))) {
+			private_object_t *tech_pvt;
+			switch_channel_t *channel;
+	
+			channel = switch_core_session_get_channel(session);
+			assert(channel != NULL);
+
+			tech_pvt = switch_core_session_get_private(session);
+			assert(tech_pvt != NULL);
+			switch_set_flag_locked(tech_pvt, TFLAG_BYE);
+			switch_channel_hangup(channel, event->release_cause);
+			switch_core_session_rwunlock(session);
+		}
+		*uuid = '\0';
+
+	} 
+
+	isup_exec_command(ss7boost_handle,
+					  event->span, 
+					  event->chan, 
+					  -1,
+					  SIGBOOST_EVENT_CALL_STOPPED_ACK,
+					  0);
+
+
+}
+
+static void handle_call_start(ss7boost_handle_t *ss7boost_handle, ss7boost_client_event_t *event)
+{
+	switch_core_session_t *session = NULL;
+	switch_channel_t *channel = NULL;
+	char name[128];
+
+	if (*ss7boost_handle->span_chanmap[event->span].map[event->chan]) {
+		isup_exec_command(ss7boost_handle,
+						  event->span, 
+						  event->chan, 
+						  -1,
+						  SIGBOOST_EVENT_CALL_START_NACK,
+						  SIGBOOST_RELEASE_CAUSE_BUSY);		
+		return;
+	}
+
+	
+	if ((session = switch_core_session_request(&wanpipe_endpoint_interface, NULL))) {
+		private_object_t *tech_pvt;
+
+		switch_core_session_add_stream(session, NULL);
+		if ((tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t)))) {
+			memset(tech_pvt, 0, sizeof(*tech_pvt));
+			switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
+			channel = switch_core_session_get_channel(session);
+			switch_core_session_set_private(session, tech_pvt);
+			sprintf(name, "wanpipe/ss7boost/s%dc%d", event->span+1, event->chan+1);
+			switch_channel_set_name(channel, name);
+			tech_pvt->session = session;
+		} else {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
+			goto fail;
+		}
+
+
+		if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
+																  NULL,
+																  globals.dialplan,
+																  "FreeSWITCH(boost)",
+																  event->calling_number_digits,
+#ifdef WIN32
+																  NULL,
+#else
+																  event->calling_number_digits,
+#endif
+																  NULL,
+																  NULL,
+																  NULL,
+																  (char *)modname,
+																  NULL,
+																  event->called_number_digits))) {
+			switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
+		}
+
+		switch_set_flag_locked(tech_pvt, TFLAG_INBOUND);
+
+		tech_pvt->cause = -1;
+
+		tech_pvt->ss7boost_handle = ss7boost_handle;
+		tech_pvt->boost_span_number = event->span;
+		tech_pvt->boost_chan_number = event->chan;
+		tech_pvt->boost_pres = event->calling_number_presentation;
+		
+		if (!wp_open(tech_pvt, event->span+1, event->chan+1)) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open channel %d:%s\n", event->span+1, event->chan+1);
+			goto fail;
+		}
+
+		switch_copy_string(ss7boost_handle->span_chanmap[event->span].map[event->chan], switch_core_session_get_uuid(session), 
+						   sizeof(ss7boost_handle->span_chanmap[event->span].map[event->chan]));
+		
+		switch_channel_set_state(channel, CS_INIT);
+		isup_exec_command(ss7boost_handle,
+						  event->span, 
+						  event->chan, 
+						  -1,
+						  SIGBOOST_EVENT_CALL_START_ACK,
+						  0);
+		switch_core_session_thread_launch(session);
+		return;
+	} else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create new Inbound Channel!\n");
+	}
+
+	
+ fail:
+	if (session) {
+		switch_core_session_destroy(&session);
+	}
+
+	isup_exec_command(ss7boost_handle,
+					  event->span, 
+					  event->chan, 
+					  -1,
+					  SIGBOOST_EVENT_CALL_STOPPED,
+					  SIGBOOST_RELEASE_CAUSE_BUSY);
+
+}
+
+
+static void handle_heartbeat(ss7boost_handle_t *ss7boost_handle, ss7boost_client_event_t *event)
+{
+
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Heartbeat!\n");
+
+	isup_exec_command(ss7boost_handle,
+					  event->span, 
+					  event->chan, 
+					  -1,
+					  SIGBOOST_EVENT_HEARTBEAT,
+					  0);
+}
+
+
+static void handle_call_start_ack(ss7boost_handle_t *ss7boost_handle, ss7boost_client_event_t *event)
+{
+	char *uuid = ss7boost_handle->setup_array[event->call_setup_id];
+	
+	if (*uuid) {
+		switch_core_session_t *session;
+
+		if ((session = switch_core_session_locate(uuid))) {
+			private_object_t *tech_pvt;
+			switch_channel_t *channel;
+	
+			channel = switch_core_session_get_channel(session);
+			assert(channel != NULL);
+			
+			tech_pvt = switch_core_session_get_private(session);
+			assert(tech_pvt != NULL);
+			
+			tech_pvt->ss7boost_handle = ss7boost_handle;
+			tech_pvt->boost_span_number = event->span;
+			tech_pvt->boost_chan_number = event->chan;
+			
+			switch_copy_string(ss7boost_handle->span_chanmap[event->span].map[event->chan], switch_core_session_get_uuid(session), 
+							   sizeof(ss7boost_handle->span_chanmap[event->span].map[event->chan]));
+
+
+
+			if (!tech_pvt->wpsock) {
+				if (!wp_open(tech_pvt, tech_pvt->boost_span_number+1, tech_pvt->boost_chan_number+1)) {
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open fd for s%dc%d! [%s]\n", 
+									  tech_pvt->boost_span_number+1, tech_pvt->boost_chan_number+1, strerror(errno));
+					switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+					return;
+				}
+				if (wanpipe_codec_init(tech_pvt) != SWITCH_STATUS_SUCCESS) {
+					switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+					return;
+				}
+			}
+
+			switch_channel_mark_pre_answered(channel);
+			
+			switch_core_session_rwunlock(session);
+		}
+		*uuid = '\0';
+	}
+}
+
+static void handle_call_start_nack_ack(ss7boost_handle_t *ss7boost_handle, ss7boost_client_event_t *event)
+{
+	// WTF IS THIS! ?
+}
+
+static void handle_call_answer(ss7boost_handle_t *ss7boost_handle, ss7boost_client_event_t *event)
+{
+	char *uuid = ss7boost_handle->span_chanmap[event->span].map[event->chan];
+
+	if (*uuid) {
+		switch_core_session_t *session;
+		
+		if ((session = switch_core_session_locate(uuid))) {
+			private_object_t *tech_pvt;
+			switch_channel_t *channel;
+	
+			channel = switch_core_session_get_channel(session);
+			assert(channel != NULL);
+
+			tech_pvt = switch_core_session_get_private(session);
+			assert(tech_pvt != NULL);
+
+			if (!tech_pvt->wpsock) {
+				if (!wp_open(tech_pvt, tech_pvt->boost_span_number+1, tech_pvt->boost_chan_number+1)) {
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't open fd for s%dc%d! [%s]\n", 
+									  tech_pvt->boost_span_number+1, tech_pvt->boost_chan_number+1, strerror(errno));
+					switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+					return;
+				}
+				if (wanpipe_codec_init(tech_pvt) != SWITCH_STATUS_SUCCESS) {
+					switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
+					return;
+				}
+			}
+			
+			switch_channel_mark_answered(channel);
+			switch_core_session_rwunlock(session);
+		} else {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Session %s missing!\n", uuid);
+			*uuid = '\0';
+		}
+
+	} else {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "No UUID?\n");
+	}
+}
+
+static void handle_call_stop_ack(ss7boost_handle_t *ss7boost_handle, ss7boost_client_event_t *event)
+{
+	// TODO anything here?
+}
+
+
+static void handle_call_start_nack(ss7boost_handle_t *ss7boost_handle, ss7boost_client_event_t *event)
+{
+	char *uuid = ss7boost_handle->setup_array[event->call_setup_id];
+	
+	if (*uuid) {
+		switch_core_session_t *session;
+
+		if ((session = switch_core_session_locate(uuid))) {
+			private_object_t *tech_pvt;
+			switch_channel_t *channel;
+	
+			channel = switch_core_session_get_channel(session);
+			assert(channel != NULL);
+			
+			tech_pvt = switch_core_session_get_private(session);
+			assert(tech_pvt != NULL);
+			
+			tech_pvt->ss7boost_handle = ss7boost_handle;
+			tech_pvt->boost_span_number = event->span;
+			tech_pvt->boost_chan_number = event->chan;
+			
+			switch_channel_hangup(channel, event->release_cause);
+			
+			isup_exec_command(ss7boost_handle,
+							  event->span,
+							  event->chan, 
+							  event->call_setup_id,
+							  SIGBOOST_EVENT_CALL_START_NACK_ACK,
+							  0);
+
+			switch_core_session_rwunlock(session);
+		} else {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Session %s missing!\n", uuid);
+		}
+		*uuid = '\0';
+	}
+}
+
+static int parse_ss7_event(ss7boost_handle_t *ss7boost_handle, ss7boost_client_event_t *event)
+{
+	int ret = 0;
+
+	switch_mutex_lock(ss7boost_handle->mutex);
+		
+	validate_number((unsigned char*)event->called_number_digits);
+	validate_number((unsigned char*)event->calling_number_digits);
+
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
+					  "\nRX EVENT\n"
+					  "===================================\n"
+					  "           rType: %s (%0x HEX)\n"
+					  "           rSpan: [%d]\n"
+					  "           rChan: [%d]\n"
+					  "  rCalledNum: %s\n"
+					  " rCallingNum: %s\n"
+					  "      rCause: %s\n"
+					  " rInterface : [w%dg%d]\n"
+					  "  rEvent ID : [%d]\n"
+					  "   rSetup ID: [%d]\n"
+					  "        rSeq: [%d]\n"
+					  "===================================\n"
+					  "\n",
+					  ss7boost_client_event_id_name(event->event_id),
+					  event->event_id,
+					  event->span+1,
+					  event->chan+1,
+					  (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"),
+					  (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A"),
+					  switch_channel_cause2str(event->release_cause),
+					  event->span+1,
+					  event->chan+1,
+					  event->event_id,
+					  event->call_setup_id,
+					  event->seqno
+					  );
+	
+
+	switch(event->event_id) {
+	
+	case SIGBOOST_EVENT_CALL_START:
+		handle_call_start(ss7boost_handle, event);
+		break;
+	case SIGBOOST_EVENT_CALL_STOPPED:
+		handle_call_stop(ss7boost_handle, event);
+		break;
+	case SIGBOOST_EVENT_CALL_START_ACK:
+		handle_call_start_ack(ss7boost_handle, event);
+		break;
+	case SIGBOOST_EVENT_CALL_START_NACK:
+		handle_call_start_nack(ss7boost_handle, event);
+		break;
+	case SIGBOOST_EVENT_CALL_ANSWERED:
+		handle_call_answer(ss7boost_handle, event);
+		break;
+	case SIGBOOST_EVENT_HEARTBEAT:
+		handle_heartbeat(ss7boost_handle, event);
+		break;
+	case SIGBOOST_EVENT_CALL_START_NACK_ACK:
+		handle_call_start_nack_ack(ss7boost_handle, event);
+		break;
+	case SIGBOOST_EVENT_CALL_STOPPED_ACK:
+		handle_call_stop_ack(ss7boost_handle, event);
+		break;
+	default:
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Warning no handler implemented for [%s]\n", 
+						  ss7boost_client_event_id_name(event->event_id));
+		break;
+	}
+	switch_mutex_unlock(ss7boost_handle->mutex);
+	return ret;
+}
+
+static void *SWITCH_THREAD_FUNC boost_thread_run(switch_thread_t *thread, void *obj)
+{
+	ss7boost_handle_t *ss7boost_handle = (ss7boost_handle_t *) obj;
+	ss7boost_client_event_t *event;
+	int ss = 0;
+
+	if (ss7boost_client_connection_open(&ss7boost_handle->mcon,
+									ss7boost_handle->local_ip, 
+									ss7boost_handle->local_port,
+									ss7boost_handle->remote_ip,
+									ss7boost_handle->remote_port,
+									module_pool) != SWITCH_STATUS_SUCCESS) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "FATAL ERROR CREATING CLIENT CONNECTION\n");
+		return NULL;
+	}
+			
+	isup_exec_command(ss7boost_handle,
+					  0,
+					  0, 
+					  -1,
+					  SIGBOOST_EVENT_SYSTEM_RESTART,
+					  0);
+	
+	
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Monitor Thread Started\n");
+	
+	switch_mutex_lock(globals.hash_mutex);
+	globals.configured_boost_spans++;
+	switch_mutex_unlock(globals.hash_mutex);
+
+	globals.ss7boost_handle = ss7boost_handle;
+	
+	for(;;) {
+		if (ss7boost_client_connection_read(&ss7boost_handle->mcon, &event) == SWITCH_STATUS_SUCCESS) {
+				struct timeval current;
+				struct timeval difftime;
+				gettimeofday(&current,NULL);
+				timersub (&current, &event->tv, &difftime);
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Socket Event [%s] T=%d:%d\n",
+								  ss7boost_client_event_id_name(event->event_id),
+								  difftime.tv_sec, difftime.tv_usec);
+				
+				parse_ss7_event(ss7boost_handle, event);
+		} else {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error: Reading from Boost Socket! %s\n", strerror(errno));
+			break;
+		}
+	}
+
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Close udp socket [%d]\n", ss7boost_handle->mcon.socket);
+	ss7boost_client_connection_close(&ss7boost_handle->mcon);
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Monitor Thread Ended\n");	
+	
+
+	return NULL;
+}
+
+static void launch_ss7boost_handle(ss7boost_handle_t *ss7boost_handle)
+{
+	switch_thread_t *thread;
+	switch_threadattr_t *thd_attr = NULL;
+	
+	switch_threadattr_create(&thd_attr, module_pool);
+	switch_threadattr_detach_set(thd_attr, 1);
+	switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
+	switch_thread_create(&thread, thd_attr, boost_thread_run, ss7boost_handle, module_pool);
+}
+
+
+
 static switch_status_t config_wanpipe(int reload)
 {
 	char *cf = "wanpipe.conf";
 	int current_span = 0, min_span = 0, max_span = 0;
-	switch_xml_t cfg, xml, settings, param, span;
+	switch_xml_t cfg, xml, settings, param, pri_spans, ss7boost_handles, span;
 
 	globals.samples_per_frame = DEFAULT_SAMPLES_PER_FRAME;
 	globals.dtmf_on = 150;
@@ -1410,14 +2049,55 @@
 				globals.dtmf_on = atoi(val);
 			} else if (!strcmp(var, "dtmf-off")) {
 				globals.dtmf_off = atoi(val);
+			} else if (!strcmp(var, "dialplan")) {
+				set_global_dialplan(val);
 			} else if (!strcmp(var, "supress-dtmf-tone")) {
 				globals.supress_dtmf_tone = switch_true(val);
 			}
 		}
 	}
 
-	
-	for (span = switch_xml_child(cfg, "span"); span; span = span->next) {
+	ss7boost_handles = switch_xml_child(cfg, "ss7boost_handles");
+	for (span = switch_xml_child(ss7boost_handles, "handle"); span; span = span->next) {
+		char *local_ip = NULL, *remote_ip = NULL;
+		int local_port = 0, remote_port = 0;
+		ss7boost_handle_t *ss7boost_handle;
+
+		for (param = switch_xml_child(span, "param"); param; param = param->next) {
+			char *var = (char *) switch_xml_attr_soft(param, "name");
+			char *val = (char *) switch_xml_attr_soft(param, "value");
+			
+			if (!strcasecmp(var, "local-ip")) {
+				local_ip = val;
+			} else if (!strcasecmp(var, "local-port")) {
+				local_port = atoi(val);
+			} else if (!strcasecmp(var, "remote-ip")) {
+				remote_ip = val;
+			} else if (!strcasecmp(var, "remote-port")) {
+				remote_port = atoi(val);
+			}
+		}
+
+
+		if (!(local_ip && local_port && remote_ip && remote_port)) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Config, skipping...\n");
+			continue;
+		}
+
+		assert(ss7boost_handle = malloc(sizeof(*ss7boost_handle)));
+		memset(ss7boost_handle, 0, sizeof(*ss7boost_handle));
+		ss7boost_handle->local_ip = switch_core_strdup(module_pool, local_ip);
+		ss7boost_handle->local_port = local_port;
+		ss7boost_handle->remote_ip = switch_core_strdup(module_pool, remote_ip);
+		ss7boost_handle->remote_port = remote_port;
+
+		switch_mutex_init(&ss7boost_handle->mutex, SWITCH_MUTEX_NESTED, module_pool);
+		launch_ss7boost_handle(ss7boost_handle);
+		break;
+	}
+
+	pri_spans = switch_xml_child(cfg, "pri_spans");
+	for (span = switch_xml_child(pri_spans, "span"); span; span = span->next) {
 		char *id = (char *) switch_xml_attr(span, "id");
 		int32_t i = 0;
 
@@ -1498,8 +2178,6 @@
 					SPANS[current_span]->dp = str2dp(val);
 				} else if (!strcmp(var, "l1")) {
 					SPANS[current_span]->l1 = str2l1(val);
-				} else if (!strcmp(var, "dialplan")) {
-					set_global_dialplan(val);
 				}
 			}
 		}
@@ -1507,7 +2185,7 @@
 	switch_xml_free(xml);
 
 	if (!globals.dialplan) {
-		set_global_dialplan("default");
+		set_global_dialplan("XML");
 	}
 
 
@@ -1529,7 +2207,9 @@
 			}
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Launch span %d\n", current_span);
 			pri_thread_launch(&SPANS[current_span]->spri);
+			switch_mutex_lock(globals.hash_mutex);
 			globals.configured_spans++;
+			switch_mutex_unlock(globals.hash_mutex);
 		}
 	}
 

Added: freeswitch/trunk/src/mod/endpoints/mod_wanpipe/sigboost.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/endpoints/mod_wanpipe/sigboost.h	Fri Mar  2 14:12:26 2007
@@ -0,0 +1,82 @@
+/****************************************************************************
+ * sigboost.h     $Revision: 1.1 $
+ *
+ * Definitions for the sigboost interface.
+ *
+ * WARNING WARNING WARNING
+ *
+ * This file is used by sangoma_mgd and perhaps other programs. Any changes 
+ * to this file must be coordinated with other user programs,
+ *
+ * Copyright (C) 2005  Xygnada Technology, Inc.
+ * 
+****************************************************************************/
+#ifndef _SIGBOOST_H_
+#define _SIGBOOST_H_
+
+#include <stdint.h>
+
+enum	e_sigboost_event_id_values
+{
+	SIGBOOST_EVENT_CALL_START			= 0x80, /*128*/
+	SIGBOOST_EVENT_CALL_START_ACK			= 0x81, /*129*/
+	SIGBOOST_EVENT_CALL_START_NACK			= 0x82, /*130*/
+	SIGBOOST_EVENT_CALL_START_NACK_ACK		= 0x83, /*131*/
+	SIGBOOST_EVENT_CALL_ANSWERED			= 0x84, /*132*/
+	SIGBOOST_EVENT_CALL_STOPPED			= 0x85, /*133*/
+	SIGBOOST_EVENT_CALL_STOPPED_ACK			= 0x86, /*134*/
+	SIGBOOST_EVENT_SYSTEM_RESTART			= 0x87, /*135*/
+	SIGBOOST_EVENT_HEARTBEAT			= 0x88, /*136*/
+};
+
+enum	e_sigboost_release_cause_values
+{
+	SIGBOOST_RELEASE_CAUSE_UNDEFINED		= 0x00,
+	SIGBOOST_RELEASE_CAUSE_NORMAL			= 0x90,
+	SIGBOOST_RELEASE_CAUSE_BUSY			= 0x91,
+	SIGBOOST_RELEASE_CAUSE_CALLED_NOT_EXIST		= 0x92,
+	SIGBOOST_RELEASE_CAUSE_CIRCUIT_RESET		= 0x93,
+	SIGBOOST_RELEASE_CAUSE_NOANSWER			= 0x94
+};
+
+enum	e_sigboost_call_setup_ack_nack_cause_values
+{
+	SIGBOOST_CALL_SETUP_CIRCUIT_RESET		= 0x10,
+	SIGBOOST_CALL_SETUP_NACK_CKT_START_TIMEOUT	= 0x11,
+	SIGBOOST_CALL_SETUP_NACK_ALL_CKTS_BUSY		= 0x12,
+	SIGBOOST_CALL_SETUP_NACK_CALLED_NUM_TOO_BIG	= 0x13,
+	SIGBOOST_CALL_SETUP_NACK_CALLING_NUM_TOO_BIG	= 0x14,
+	SIGBOOST_CALL_SETUP_NACK_CALLED_NUM_TOO_SMALL	= 0x15,
+	SIGBOOST_CALL_SETUP_NACK_CALLING_NUM_TOO_SMALL	= 0x16,
+};
+
+#define MAX_DIALED_DIGITS	31
+
+/* Next two defines are used to create the range of values for call_setup_id
+ * in the t_sigboost structure.
+ * 0..((CORE_MAX_SPANS * CORE_MAX_CHAN_PER_SPAN) - 1) */
+#define CORE_MAX_SPANS 		200
+#define CORE_MAX_CHAN_PER_SPAN 	30
+#define MAX_PENDING_CALLS 	CORE_MAX_SPANS * CORE_MAX_CHAN_PER_SPAN
+/* 0..(MAX_PENDING_CALLS-1) is range of call_setup_id below */
+
+#pragma pack(1)
+typedef struct
+{
+	uint32_t	event_id;
+	uint32_t	seqno;
+	uint32_t	call_setup_id;
+	uint32_t	trunk_group;
+	uint32_t	span;
+	uint32_t	chan;
+	uint32_t	called_number_digits_count;
+	int8_t		called_number_digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */
+	uint32_t	calling_number_digits_count; /* it's an array */
+	int8_t		calling_number_digits [MAX_DIALED_DIGITS + 1]; /* it's a null terminated string */
+	uint32_t	release_cause;
+	struct timeval  tv;
+	uint32_t	calling_number_presentation;
+} t_sigboost;
+#pragma pack()
+
+#endif

Added: freeswitch/trunk/src/mod/endpoints/mod_wanpipe/ss7boost_client.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/endpoints/mod_wanpipe/ss7boost_client.c	Fri Mar  2 14:12:26 2007
@@ -0,0 +1,263 @@
+/* 
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005/2006, Anthony Minessale II <anthmct at yahoo.com>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II <anthmct at yahoo.com>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Anthony Minessale II <anthmct at yahoo.com>
+ * Nenad Corbic <ncorbic at sangoma.com>
+ *
+ *
+ * ss7boost_client.c Client for the SS7Boost Protocol
+ *
+ */
+#include <ss7boost_client.h>
+#include <switch.h>
+
+
+extern unsigned int txseq;
+extern unsigned int rxseq;
+
+struct ss7boost_client_map {
+	uint32_t event_id;
+	char *name;
+};
+
+static struct ss7boost_client_map ss7boost_client_table[] = {
+	{SIGBOOST_EVENT_CALL_START, "CALL_START"},
+	{SIGBOOST_EVENT_CALL_START_ACK, "CALL_START_ACK"},
+	{SIGBOOST_EVENT_CALL_START_NACK, "CALL_START_NACK"},
+	{SIGBOOST_EVENT_CALL_START_NACK_ACK, "CALL_START_NACK_ACK"},
+	{SIGBOOST_EVENT_CALL_ANSWERED, "CALL_ANSWERED"},
+	{SIGBOOST_EVENT_CALL_STOPPED, "CALL_STOPPED"},
+	{SIGBOOST_EVENT_CALL_STOPPED_ACK, "CALL_STOPPED_ACK"},
+	{SIGBOOST_EVENT_SYSTEM_RESTART, "SYSTEM_RESTART"},
+	{SIGBOOST_EVENT_HEARTBEAT, "HEARTBEAT"},
+}; 
+
+
+
+static switch_status_t create_udp_socket(ss7boost_client_connection_t *mcon, char *local_ip, int local_port, char *ip, int port)
+{
+
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "connect %s:%d->%s:%d\n", local_ip, local_port, ip, port);
+
+	if (switch_sockaddr_info_get(&mcon->local_addr, local_ip, SWITCH_UNSPEC, local_port, 0, mcon->pool) != SWITCH_STATUS_SUCCESS) {
+		goto fail;
+	}
+
+	if (switch_sockaddr_info_get(&mcon->remote_addr, ip, SWITCH_UNSPEC, port, 0, mcon->pool) != SWITCH_STATUS_SUCCESS) {
+		goto fail;
+	}
+	
+	if (switch_socket_create(&mcon->socket, AF_INET, SOCK_DGRAM, 0, mcon->pool) == SWITCH_STATUS_SUCCESS) {
+		if (switch_socket_bind(mcon->socket, mcon->local_addr) != SWITCH_STATUS_SUCCESS) {
+			goto fail;
+		}
+	} else {
+		goto fail;
+	}
+
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Created boost connection %s:%d->%s:%d\n", local_ip, local_port, ip, port);
+	return SWITCH_STATUS_SUCCESS;
+
+ fail:
+
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failure creating boost connection %s:%d->%s:%d\n", local_ip, local_port, ip, port);
+	return SWITCH_STATUS_FALSE;
+}
+
+
+
+SWITCH_DECLARE(switch_status_t) ss7boost_client_connection_close(ss7boost_client_connection_t *mcon)
+{
+	switch_socket_close(mcon->socket);
+	mcon->socket = NULL;
+	memset(mcon, 0, sizeof(*mcon));
+
+	return SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_DECLARE(switch_status_t) ss7boost_client_connection_open(ss7boost_client_connection_t *mcon,
+															char *local_ip,
+															int local_port,
+															char *ip,
+															int port,
+															switch_memory_pool_t *pool)
+{
+	memset(mcon, 0, sizeof(*mcon));
+	mcon->pool = pool;
+
+	if (create_udp_socket(mcon, local_ip, local_port, ip, port) == SWITCH_STATUS_SUCCESS) {
+		switch_mutex_init(&mcon->mutex, SWITCH_MUTEX_NESTED, mcon->pool);
+		return SWITCH_STATUS_SUCCESS;
+	}
+	
+	memset(mcon, 0, sizeof(*mcon));
+	return SWITCH_STATUS_FALSE;
+}
+
+SWITCH_DECLARE(switch_status_t) ss7boost_client_connection_read(ss7boost_client_connection_t *mcon, ss7boost_client_event_t **event)
+{
+	unsigned int fromlen = sizeof(struct sockaddr_in);
+	switch_size_t bytes = 0;
+
+	bytes = sizeof(mcon->event);
+
+	if (switch_socket_recvfrom(mcon->local_addr, mcon->socket, 0, (void *)&mcon->event, &bytes) != SWITCH_STATUS_SUCCESS) {
+		bytes = 0;
+	}
+
+	if (bytes == sizeof(mcon->event) || 
+            bytes == (sizeof(mcon->event)-sizeof(uint32_t))) {
+		if (rxseq != mcon->event.seqno) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, 
+			"------------------------------------------\n");
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, 
+			"Critical Error: Invalid Sequence Number Expect=%i Rx=%i\n",
+			rxseq,mcon->event.seqno);
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, 
+			"------------------------------------------\n");
+		}
+		rxseq++;
+
+		*event = &mcon->event;
+		return SWITCH_STATUS_SUCCESS;
+	}
+
+	return SWITCH_STATUS_FALSE;
+}
+
+SWITCH_DECLARE(switch_status_t) ss7boost_client_connection_write(ss7boost_client_connection_t *mcon, ss7boost_client_event_t *event)
+{
+	int err;
+	switch_size_t len;
+
+	if (!event) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Critical Error: No Event Device\n");
+		return -EINVAL;
+	}
+
+	if (event->span < 0 || event->chan < 0 || event->span > 7 || event->chan > 30) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, 
+			"------------------------------------------\n");
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, 
+			"Critical Error: Invalid Span=%i Chan=%i\n",
+			event->span,event->chan);
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, 
+			"------------------------------------------\n");
+	}
+
+#ifdef WIN32
+	//TODO set the tv with win func
+#else 
+	gettimeofday(&event->tv,NULL);
+#endif
+
+	switch_mutex_lock(mcon->mutex);
+	event->seqno=txseq++;
+	len = sizeof(*event);
+	if (switch_socket_sendto(mcon->socket, mcon->remote_addr, 0, (void *) event, &len) != SWITCH_STATUS_SUCCESS) {
+		err = -1;
+	}
+	switch_mutex_unlock(mcon->mutex);
+
+	if (len != sizeof(ss7boost_client_event_t)) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write Error: [%d][%d][%s]\n", mcon->socket, errno, strerror(errno));
+		err = -1;
+	}
+
+
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
+					  "\nTX EVENT\n"
+					  "===================================\n"
+					  "       tType: %s (%0x HEX)\n"
+					  "       tSpan: [%d]\n"
+					  "       tChan: [%d]\n"
+					  "  tCalledNum: %s\n"
+					  " tCallingNum: %s\n"
+					  "      tCause: %d\n"
+					  "  tInterface: [w%dg%d]\n"
+					  "   tEvent ID: [%d]\n"
+					  "   tSetup ID: [%d]\n"
+					  "        tSeq: [%d]\n"
+					  "===================================\n"
+					  "\n",
+					  ss7boost_client_event_id_name(event->event_id),
+					  event->event_id,
+					  event->span+1,
+					  event->chan+1,
+					  (event->called_number_digits_count ? (char *) event->called_number_digits : "N/A"),
+					  (event->calling_number_digits_count ? (char *) event->calling_number_digits : "N/A"),
+					  event->release_cause,
+					  event->span+1,
+					  event->chan+1,
+					  event->event_id,
+					  event->call_setup_id,
+					  event->seqno
+					  );
+
+
+	return err ? SWITCH_STATUS_FALSE : SWITCH_STATUS_SUCCESS;
+}
+
+SWITCH_DECLARE(void) ss7boost_client_call_init(ss7boost_client_event_t *event, char *calling, char *called, int setup_id)
+{
+	memset(event, 0, sizeof(ss7boost_client_event_t));
+	event->event_id = SIGBOOST_EVENT_CALL_START;
+
+	if (calling) {
+		strncpy((char*)event->calling_number_digits, calling, sizeof(event->calling_number_digits)-1);
+		event->calling_number_digits_count = strlen(calling);
+	}
+
+	if (called) {
+		strncpy((char*)event->called_number_digits, called, sizeof(event->called_number_digits)-1);
+		event->called_number_digits_count = strlen(called);
+	}
+		
+	event->call_setup_id = setup_id;
+	
+}
+
+SWITCH_DECLARE(void) ss7boost_client_event_init(ss7boost_client_event_t *event, ss7boost_client_event_id_t event_id, int chan, int span) 
+{
+	memset(event, 0, sizeof(ss7boost_client_event_t));
+	event->event_id = event_id;
+	event->chan = chan;
+	event->span = span;
+}
+
+SWITCH_DECLARE(char *) ss7boost_client_event_id_name(uint32_t event_id)
+{
+	int x;
+	char *ret = NULL;
+
+	for (x = 0 ; x < sizeof(ss7boost_client_table)/sizeof(struct ss7boost_client_map); x++) {
+		if (ss7boost_client_table[x].event_id == event_id) {
+			ret = ss7boost_client_table[x].name;
+			break;
+		}
+	}
+
+	return ret;
+}

Added: freeswitch/trunk/src/mod/endpoints/mod_wanpipe/ss7boost_client.h
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/endpoints/mod_wanpipe/ss7boost_client.h	Fri Mar  2 14:12:26 2007
@@ -0,0 +1,107 @@
+/* 
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005/2006, Anthony Minessale II <anthmct at yahoo.com>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ *
+ * The Initial Developer of the Original Code is
+ * Anthony Minessale II <anthmct at yahoo.com>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Anthony Minessale II <anthmct at yahoo.com>
+ * Nenad Corbic <ncorbic at sangoma.com>
+ *
+ *
+ * ss7boost_client.h Client for the SS7Boost Protocol
+ *
+ */
+#ifndef _SS7BOOST_CLIENT_H
+#define _SS7BOOST_CLIENT_H
+
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdarg.h>
+#include <netdb.h>
+#include <sigboost.h>
+#include <pthread.h>
+#include <sys/time.h>
+#include <switch.h>
+
+
+
+#define ss7boost_client_test_flag(p,flag) 		({ \
+					((p)->flags & (flag)); \
+					})
+
+#define ss7boost_client_set_flag(p,flag) 		do { \
+					((p)->flags |= (flag)); \
+					} while (0)
+
+#define ss7boost_client_clear_flag(p,flag) 		do { \
+					((p)->flags &= ~(flag)); \
+					} while (0)
+
+#define ss7boost_client_copy_flags(dest,src,flagz)	do { \
+					(dest)->flags &= ~(flagz); \
+					(dest)->flags |= ((src)->flags & (flagz)); \
+					} while (0)
+
+typedef  t_sigboost ss7boost_client_event_t;
+typedef uint32_t ss7boost_client_event_id_t;
+
+struct ss7boost_client_connection {
+	switch_socket_t *socket;
+	switch_sockaddr_t *local_addr;
+	switch_sockaddr_t *remote_addr;
+	ss7boost_client_event_t event;
+	unsigned int flags;
+	switch_mutex_t *mutex;
+	switch_memory_pool_t * pool;
+};
+
+typedef enum {
+	MSU_FLAG_EVENT = (1 << 0)
+} ss7boost_client_flag_t;
+
+typedef struct ss7boost_client_connection ss7boost_client_connection_t;
+
+SWITCH_DECLARE(switch_status_t) ss7boost_client_connection_close(ss7boost_client_connection_t *mcon);
+SWITCH_DECLARE(switch_status_t) ss7boost_client_connection_open(ss7boost_client_connection_t *mcon,
+															char *local_ip,
+															int local_port,
+															char *ip,
+															int port,
+															switch_memory_pool_t *pool);
+SWITCH_DECLARE(switch_status_t) ss7boost_client_connection_read(ss7boost_client_connection_t *mcon, ss7boost_client_event_t **event);
+SWITCH_DECLARE(switch_status_t) ss7boost_client_connection_write(ss7boost_client_connection_t *mcon, ss7boost_client_event_t *event);
+SWITCH_DECLARE(void) ss7boost_client_event_init(ss7boost_client_event_t *event, ss7boost_client_event_id_t event_id, int chan, int span);
+SWITCH_DECLARE(void) ss7boost_client_call_init(ss7boost_client_event_t *event, char *calling, char *called, int setup_id);
+SWITCH_DECLARE(char *) ss7boost_client_event_id_name(uint32_t event_id);
+
+#endif
+
+



More information about the Freeswitch-svn mailing list