[asterisk-commits] nadi: trunk r39378 - in /trunk/channels: ./ misdn/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue Aug 8 11:13:40 MST 2006


Author: nadi
Date: Tue Aug  8 13:13:40 2006
New Revision: 39378

URL: http://svn.digium.com/view/asterisk?rev=39378&view=rev
Log:
* first bits of decoding facility information elements
* fail on misdn_cfg_init() if elements in the config enum don't match with the config structs in misdn_config.c
* implemented first bits for encoding ISDN facility information elements via ASN.1 descriptions
* using unnamed semaphore for syncing in misdn_thread
* advanced fax detection: configurable detect timeout and context to jump into


Added:
    trunk/channels/misdn/asn1.c   (with props)
    trunk/channels/misdn/asn1.h   (with props)
Modified:
    trunk/channels/chan_misdn.c
    trunk/channels/misdn/Makefile
    trunk/channels/misdn/chan_misdn_config.h
    trunk/channels/misdn/fac.c
    trunk/channels/misdn/fac.h
    trunk/channels/misdn/isdn_lib.c
    trunk/channels/misdn/isdn_lib.h
    trunk/channels/misdn/isdn_msg_parser.c
    trunk/channels/misdn_config.c

Modified: trunk/channels/chan_misdn.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_misdn.c?rev=39378&r1=39377&r2=39378&view=diff
==============================================================================
--- trunk/channels/chan_misdn.c (original)
+++ trunk/channels/chan_misdn.c Tue Aug  8 13:13:40 2006
@@ -43,8 +43,7 @@
 #include <sys/ioctl.h>
 #include <signal.h>
 #include <sys/file.h>
-#include <sys/ipc.h>
-#include <sys/sem.h>
+#include <semaphore.h>
 
 #include "asterisk/channel.h"
 #include "asterisk/config.h"
@@ -157,7 +156,9 @@
 	char ast_rd_buf[4096];
 	struct ast_frame frame;
 
-	int faxdetect;
+	int faxdetect; /* 0:no 1:yes 2:yes+nojump */
+	int faxdetect_timeout;
+	struct timeval faxdetect_tv;
 	int faxhandled;
 
 	int ast_dsp;
@@ -258,7 +259,6 @@
 /* the main schedule context for stuff like l1 watcher, overlap dial, ... */
 static struct sched_context *misdn_tasks = NULL;
 static pthread_t misdn_tasks_thread;
-static int misdn_tasks_semid;
 
 static void chan_misdn_log(int level, int port, char *tmpl, ...);
 
@@ -417,15 +417,15 @@
 {
 	switch (bc->fac_type) {
 	case FACILITY_CALLDEFLECT:
-		chan_misdn_log(2,bc->port," --> calldeflect: %s\n",
+		chan_misdn_log(0,bc->port," --> calldeflect: %s\n",
 			       bc->fac.calldeflect_nr);
 		break;
 	case FACILITY_CENTREX:
-		chan_misdn_log(2,bc->port," --> centrex: %s\n",
+		chan_misdn_log(0,bc->port," --> centrex: %s\n",
 			       bc->fac.cnip);
 		break;
 	default:
-		chan_misdn_log(2,bc->port," --> unknown\n");
+		chan_misdn_log(0,bc->port," --> unknown\n");
 		
 	}
 }
@@ -453,11 +453,6 @@
 {
 	int wait;
 	struct sigaction sa;
-	struct sembuf semb = {
-		.sem_num = 0,
-		.sem_op = 1,
-		.sem_flg = 0
-	};
 
 	sa.sa_handler = sighandler;
 	sa.sa_flags = SA_NODEFER;
@@ -465,7 +460,7 @@
 	sigaddset(&sa.sa_mask, SIGUSR1);
 	sigaction(SIGUSR1, &sa, NULL);
 	
-	semop(misdn_tasks_semid, &semb, 1);
+	sem_post((sem_t *)data);
 
 	while (1) {
 		wait = ast_sched_wait(misdn_tasks);
@@ -480,44 +475,21 @@
 
 static void misdn_tasks_init (void)
 {
-	key_t key;
-	union {
-		int val;
-		struct semid_ds *buf;
-		unsigned short *array;
-		struct seminfo *__buf;
-	} semu;
-	struct sembuf semb = {
-		.sem_num = 0,
-		.sem_op = -1,
-		.sem_flg = 0
-	};
-	
-	chan_misdn_log(4, 0, "Starting misdn_tasks thread\n");
-	
-	key = ftok("/etc/asterisk/misdn.conf", 'E');
-	if (key == -1) {
-		perror("chan_misdn: Failed to create a semaphore key!");
-		exit(1);
-	}
-
-	misdn_tasks_semid = semget(key, 10, 0666 | IPC_CREAT);
-	if (misdn_tasks_semid == -1) {
-		perror("chan_misdn: Failed to get a semaphore!");
-		exit(1);
-	}
-
-	semu.val = 0;
-	if (semctl(misdn_tasks_semid, 0, SETVAL, semu) == -1) {
+	sem_t blocker;
+	int i = 5;
+
+	if (sem_init(&blocker, 0, 0)) {
 		perror("chan_misdn: Failed to initialize semaphore!");
 		exit(1);
 	}
 
+	chan_misdn_log(4, 0, "Starting misdn_tasks thread\n");
+	
 	misdn_tasks = sched_context_create();
-	pthread_create(&misdn_tasks_thread, NULL, misdn_tasks_thread_func, NULL);
-
-	semop(misdn_tasks_semid, &semb, 1);
-	semctl(misdn_tasks_semid, 0, IPC_RMID, semu);
+	pthread_create(&misdn_tasks_thread, NULL, misdn_tasks_thread_func, &blocker);
+
+	while (sem_wait(&blocker) && --i);
+	sem_destroy(&blocker);
 }
 
 static void misdn_tasks_destroy (void)
@@ -1751,6 +1723,8 @@
 
 	misdn_cfg_get( port, MISDN_CFG_ALLOWED_BEARERS, &ch->allowed_bearers, BUFFERSIZE);
 	
+  	char faxdetect[BUFFERSIZE+1];
+  	misdn_cfg_get( port, MISDN_CFG_FAXDETECT, faxdetect, BUFFERSIZE);
 	
 	int hdlc=0;
 	misdn_cfg_get( port, MISDN_CFG_HDLC, &hdlc, sizeof(int));
@@ -1803,6 +1777,13 @@
 	if ( orig  == ORG_AST) {
 		misdn_cfg_get( port, MISDN_CFG_TE_CHOOSE_CHANNEL, &(bc->te_choose_channel), sizeof(int));
 		
+ 		if (strstr(faxdetect, "outgoing") || strstr(faxdetect, "both")) {
+ 			if (strstr(faxdetect, "nojump"))
+ 				ch->faxdetect=2;
+ 			else
+ 				ch->faxdetect=1;
+ 		}
+
 		{
 			char callerid[BUFFERSIZE+1];
 			misdn_cfg_get( port, MISDN_CFG_CALLERID, callerid, BUFFERSIZE);
@@ -1827,6 +1808,12 @@
 
 		ch->overlap_dial = 0;
 	} else { /** ORIGINATOR MISDN **/
+ 		if (strstr(faxdetect, "incoming") || strstr(faxdetect, "both")) {
+ 			if (strstr(faxdetect, "nojump"))
+ 				ch->faxdetect=2;
+ 			else
+ 				ch->faxdetect=1;
+ 		}
 	
 		misdn_cfg_get( port, MISDN_CFG_CPNDIALPLAN, &bc->cpnnumplan, sizeof(int));
 		debug_numplan(port, bc->cpnnumplan,"CTON");
@@ -1896,6 +1883,18 @@
 		misdn_cfg_get(bc->port, MISDN_CFG_OVERLAP_DIAL, &ch->overlap_dial, sizeof(ch->overlap_dial));
 		ast_mutex_init(&ch->overlap_tv_lock);
 	} /* ORIG MISDN END */
+
+	ch->overlap_dial_task = -1;
+	
+	if (ch->faxdetect) {
+		misdn_cfg_get( port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout));
+		if (!ch->dsp)
+			ch->dsp = ast_dsp_new();
+		if (ch->dsp)
+			ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT | DSP_FEATURE_FAX_DETECT);
+		if (!ch->trans)
+			ch->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW);
+	}
 
 	return 0;
 }
@@ -2468,44 +2467,65 @@
 struct ast_frame *process_ast_dsp(struct chan_list *tmp, struct ast_frame *frame)
 {
 	struct ast_frame *f,*f2;
-	if (tmp->trans)
-		f2=ast_translate(tmp->trans, frame,0);
-	else {
+ 
+ 	if (tmp->trans) {
+ 		f2 = ast_translate(tmp->trans, frame, 0);
+ 		f = ast_dsp_process(tmp->ast, tmp->dsp, f2);
+ 	} else {
 		chan_misdn_log(0, tmp->bc->port, "No T-Path found\n");
 		return NULL;
 	}
-	
-	f = ast_dsp_process(tmp->ast, tmp->dsp, f2);
-	if (f && (f->frametype == AST_FRAME_DTMF)) {
-		ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c", f->subclass);
-		if (f->subclass == 'f' && tmp->faxdetect) {
-			/* Fax tone -- Handle and return NULL */
-			struct ast_channel *ast = tmp->ast;
-			if (!tmp->faxhandled) {
-				tmp->faxhandled++;
-				if (strcmp(ast->exten, "fax")) {
-					if (ast_exists_extension(ast, ast_strlen_zero(ast->macrocontext)? ast->context : ast->macrocontext, "fax", 1, AST_CID_P(ast))) {
-						if (option_verbose > 2)
-							ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
-						/* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
-						pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten);
-						if (ast_async_goto(ast, ast->context, "fax", 1))
-							ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, ast->context);
-					} else
-						ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n",ast->context, ast->exten);
-				} else
-					ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
-			} else
-				ast_log(LOG_DEBUG, "Fax already handled\n");
-			
-		}  else if ( tmp->ast_dsp) {
-			chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n",f->subclass);
-			return f;
-		}
-	}
-
-	frame->frametype = AST_FRAME_NULL;
-	frame->subclass = 0;
+
+ 
+ 	if (!f || (f->frametype != AST_FRAME_DTMF))
+ 		return frame;
+ 
+ 	ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c", f->subclass);
+ 
+ 	if (tmp->faxdetect && (f->subclass == 'f')) {
+ 		/* Fax tone -- Handle and return NULL */
+ 		if (!tmp->faxhandled) {
+  			struct ast_channel *ast = tmp->ast;
+ 			tmp->faxhandled++;
+ 			chan_misdn_log(0, tmp->bc->port, "Fax detected, preparing %s for fax transfer.\n", ast->name);
+ 			tmp->bc->rxgain = 0;
+ 			isdn_lib_update_rxgain(tmp->bc);
+ 			tmp->bc->txgain = 0;
+ 			isdn_lib_update_txgain(tmp->bc);
+ 			tmp->bc->ec_enable = 0;
+ 			isdn_lib_update_ec(tmp->bc);
+ 			isdn_lib_stop_dtmf(tmp->bc);
+ 			switch (tmp->faxdetect) {
+ 			case 1:
+  				if (strcmp(ast->exten, "fax")) {
+ 					char *context;
+ 					char context_tmp[BUFFERSIZE];
+ 					misdn_cfg_get(tmp->bc->port, MISDN_CFG_FAXDETECT_CONTEXT, &context_tmp, sizeof(context_tmp));
+ 					context = ast_strlen_zero(context_tmp) ? (ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext) : context_tmp;
+ 					if (ast_exists_extension(ast, context, "fax", 1, AST_CID_P(ast))) {
+  						if (option_verbose > 2)
+ 							ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension (context:%s)\n", ast->name, context);
+  						/* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
+  						pbx_builtin_setvar_helper(ast,"FAXEXTEN",ast->exten);
+ 						if (ast_async_goto(ast, context, "fax", 1))
+ 							ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, context);
+  					} else
+ 						ast_log(LOG_NOTICE, "Fax detected, but no fax extension ctx:%s exten:%s\n", context, ast->exten);
+ 				} else 
+  					ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
+ 				break;
+ 			case 2:
+ 				ast_verbose(VERBOSE_PREFIX_3 "Not redirecting %s to fax extension, nojump is set.\n", ast->name);
+ 				break;
+ 			}
+ 		} else
+ 			ast_log(LOG_DEBUG, "Fax already handled\n");
+  	}
+ 	
+ 	if (tmp->ast_dsp && (f->subclass != 'f')) {
+ 		chan_misdn_log(2, tmp->bc->port, " --> * SEND: DTMF (AST_DSP) :%c\n", f->subclass);
+ 	}
+
 	return frame;
 }
 
@@ -2519,7 +2539,7 @@
 		chan_misdn_log(1,0,"misdn_read called without ast\n");
 		return NULL;
 	}
-	if (! (tmp=MISDN_ASTERISK_TECH_PVT(ast)) ) {
+ 	if (!(tmp=MISDN_ASTERISK_TECH_PVT(ast))) {
 		chan_misdn_log(1,0,"misdn_read called without ast->pvt\n");
 		return NULL;
 	}
@@ -2539,17 +2559,40 @@
 	tmp->frame.frametype  = AST_FRAME_VOICE;
 	tmp->frame.subclass = AST_FORMAT_ALAW;
 	tmp->frame.datalen = len;
-	tmp->frame.samples = len ;
-	tmp->frame.mallocd =0 ;
-	tmp->frame.offset= 0 ;
+	tmp->frame.samples = len;
+	tmp->frame.mallocd = 0;
+	tmp->frame.offset = 0;
 	tmp->frame.src = NULL;
-	tmp->frame.data = tmp->ast_rd_buf ;
-	
-	if (tmp->faxdetect || tmp->ast_dsp ) {
-		return process_ast_dsp(tmp, &tmp->frame);
-	}
-	
-	return &tmp->frame;
+	tmp->frame.data = tmp->ast_rd_buf;
+
+	if (tmp->faxdetect && !tmp->faxhandled) {
+		if (tmp->faxdetect_timeout) {
+			if (ast_tvzero(tmp->faxdetect_tv)) {
+				tmp->faxdetect_tv = ast_tvnow();
+				chan_misdn_log(2,tmp->bc->port,"faxdetect: starting detection with timeout: %ds ...\n", tmp->faxdetect_timeout);
+				return process_ast_dsp(tmp, &tmp->frame);
+			} else {
+				struct timeval tv_now = ast_tvnow();
+				int diff = ast_tvdiff_ms(tv_now, tmp->faxdetect_tv);
+				if (diff <= (tmp->faxdetect_timeout * 1000)) {
+					chan_misdn_log(5,tmp->bc->port,"faxdetect: detecting ...\n");
+					return process_ast_dsp(tmp, &tmp->frame);
+				} else {
+					chan_misdn_log(2,tmp->bc->port,"faxdetect: stopping detection (time ran out) ...\n");
+					tmp->faxdetect = 0;
+					return &tmp->frame;
+				}
+			}
+		} else {
+			chan_misdn_log(5,tmp->bc->port,"faxdetect: detecting ... (no timeout)\n");
+			return process_ast_dsp(tmp, &tmp->frame);
+		}
+	} else {
+		if (tmp->ast_dsp)
+			return process_ast_dsp(tmp, &tmp->frame);
+		else
+			return &tmp->frame;
+	}
 }
 
 
@@ -2629,7 +2672,6 @@
 	}
 
 	chan_misdn_log(9, ch->bc->port, "Sending :%d bytes 2 MISDN\n",frame->samples);
-	
 	if ( !ch->bc->nojitter && misdn_cap_is_speech(ch->bc->capability) ) {
 		/* Buffered Transmit (triggert by read from isdn side)*/
 		if (misdn_jb_fill(ch->jb,frame->data,frame->samples) < 0) {
@@ -3586,6 +3628,7 @@
 			case EVENT_PORT_ALARM:
 			case EVENT_RETRIEVE:
 			case EVENT_NEW_BC:
+			case EVENT_FACILITY:
 				break;
 			case EVENT_RELEASE_COMPLETE:
 				chan_misdn_log(1, bc->port, " --> no Ch, so we've already released.\n");
@@ -4442,6 +4485,8 @@
 			struct ast_channel *bridged=AST_BRIDGED_P(ch->ast);
 			struct chan_list *ch;
 			
+			misdn_lib_send_event(bc, EVENT_DISCONNECT);
+
 			if (bridged && MISDN_ASTERISK_TECH_PVT(bridged)) {
 				ch=MISDN_ASTERISK_TECH_PVT(bridged);
 				/*ch->state=MISDN_FACILITY_DEFLECTED;*/
@@ -4455,7 +4500,7 @@
 		
 		break;
 		default:
-			chan_misdn_log(1, bc->port," --> not yet handled\n");
+			chan_misdn_log(0, bc->port," --> not yet handled: facility type:%p\n", bc->fac_type);
 		}
 		
 		break;
@@ -4550,8 +4595,10 @@
 		return -1;
 	}
 	
-	
-	misdn_cfg_init(max_ports);
+	if (misdn_cfg_init(max_ports)) {
+		ast_log(LOG_ERROR, "Unable to initialize misdn_config.\n");
+		return -1;
+	}
 	g_config_initialized=1;
 	
 	misdn_debug = (int *)malloc(sizeof(int) * (max_ports+1));
@@ -4891,6 +4938,7 @@
 		case 'f':
 			chan_misdn_log(1, ch->bc->port, "SETOPT: Faxdetect\n");
 			ch->faxdetect=1;
+			misdn_cfg_get(ch->bc->port, MISDN_CFG_FAXDETECT_TIMEOUT, &ch->faxdetect_timeout, sizeof(ch->faxdetect_timeout));
 			break;
 
 		case 'a':
@@ -4921,7 +4969,6 @@
 	
 	
 	if (ch->faxdetect || ch->ast_dsp) {
-		
 		if (!ch->dsp) ch->dsp = ast_dsp_new();
 		if (ch->dsp) ast_dsp_set_features(ch->dsp, DSP_FEATURE_DTMF_DETECT| DSP_FEATURE_FAX_DETECT);
 		if (!ch->trans) ch->trans=ast_translator_build_path(AST_FORMAT_SLINEAR, AST_FORMAT_ALAW);

Modified: trunk/channels/misdn/Makefile
URL: http://svn.digium.com/view/asterisk/trunk/channels/misdn/Makefile?rev=39378&r1=39377&r2=39378&view=diff
==============================================================================
--- trunk/channels/misdn/Makefile (original)
+++ trunk/channels/misdn/Makefile Tue Aug  8 13:13:40 2006
@@ -11,14 +11,14 @@
 endif
 SOURCES		= isdn_lib.c isdn_msg_parser.c 
 OBJDIR		= .
-OBJS		= isdn_lib.o isdn_msg_parser.o fac.o
+OBJS		= isdn_lib.o isdn_msg_parser.o fac.o asn1.o
 
 ifneq ($(wildcard $(CROSS_COMPILE_TARGET)/usr/lib/libbnec.so),)
 CFLAGS+=-DBEROEC_VERSION=1
 CFLAGS+=-DWITH_BEROEC
 endif
 
-
+CFLAGS+=-DFACILITY_DEBUG
 
 all: chan_misdn_lib.a 
 

Added: trunk/channels/misdn/asn1.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/misdn/asn1.c?rev=39378&view=auto
==============================================================================
--- trunk/channels/misdn/asn1.c (added)
+++ trunk/channels/misdn/asn1.c Tue Aug  8 13:13:40 2006
@@ -1,0 +1,181 @@
+
+#include "asn1.h"
+#include <string.h>
+
+/*
+** ASN.1 Encoding
+*/
+
+int _enc_null (__u8 *dest, int tag)
+{
+	dest[0] = tag;
+	dest[1] = 0;
+	return 2;
+}
+
+int _enc_bool (__u8 *dest, __u32 i, int tag)
+{
+	dest[0] = tag;
+	dest[1] = 1;
+	dest[2] = i ? 1:0;
+	return 3;
+}
+
+int _enc_int (__u8 *dest, __u32 i, int tag)
+{
+	__u8 *p;
+	dest[0] = tag;
+	p = &dest[2];
+	do {
+		*p++ = i;
+		i >>= 8;
+	} while (i);
+	dest[1] = p - &dest[2];
+	return p - dest;
+}
+
+int _enc_enum (__u8 *dest, __u32 i, int tag)
+{
+	__u8 *p;
+
+	dest[0] = tag;
+	p = &dest[2];
+	do {
+		*p++ = i;
+		i >>= 8;
+	} while (i);
+	dest[1] = p - &dest[2];
+	return p - dest;
+}
+
+int _enc_num_string (__u8 *dest, __u8 *nd, __u8 len, int tag)
+{
+	__u8 *p;
+	int i;
+
+	dest[0] = tag;
+	p = &dest[2];
+	for (i = 0; i < len; i++)
+		*p++ = *nd++;
+	dest[1] = p - &dest[2];
+	return p - dest;
+}
+
+int _enc_sequence_start (__u8 *dest, __u8 **id, int tag)
+{
+	dest[0] = tag;
+	*id = &dest[1];
+	return 2;
+}
+
+int _enc_sequence_end (__u8 *dest, __u8 *id, int tag_dummy)
+{
+	*id = dest - id - 1;
+	return 0;
+}
+
+/*
+** ASN.1 Decoding
+*/
+
+#define CHECK_P 						\
+	do { \
+		if (p >= end) \
+			return -1; \
+	} while (0) 
+
+#define CallASN1(ret, p, end, todo)		\
+	do { \
+		ret = todo; \
+		if (ret < 0) { \
+			return -1; \
+		} \
+		p += ret; \
+	} while (0)
+
+#define INIT 							\
+	int len, ret; \
+	__u8 *begin = p; \
+	if (tag) \
+		*tag = *p; \
+	p++; \
+	CallASN1(ret, p, end, dec_len(p, &len)); \
+	if (len >= 0) { \
+		if (p + len > end) \
+			return -1; \
+		end = p + len; \
+	}
+
+int _dec_null (__u8 *p, __u8 *end, int *tag)
+{
+	INIT;
+	return p - begin;
+}
+
+int _dec_bool (__u8 *p, __u8 *end, int *i, int *tag)
+{
+	INIT;
+	*i = 0;
+	while (len--) {
+		CHECK_P;
+		*i = (*i >> 8) + *p;
+		p++;
+	}
+	return p - begin;
+}
+
+int _dec_int (__u8 *p, __u8 *end, int *i, int *tag)
+{
+	INIT;
+
+	*i = 0;
+	while (len--) {
+		CHECK_P;
+		*i = (*i << 8) + *p;
+		p++;
+	}
+	return p - begin;
+}
+
+int _dec_enum (__u8 *p, __u8 *end, int *i, int *tag)
+{
+	INIT;
+
+	*i = 0;
+	while (len--) {
+		CHECK_P;
+		*i = (*i << 8) + *p;
+		p++;
+	}
+	return p - begin;
+}
+
+int _dec_num_string (__u8 *p, __u8 *end, char *str, int *tag)
+{
+	INIT;
+
+	while (len--) {
+		CHECK_P;
+		*str++ = *p;
+		p++;
+	}
+	*str = 0;
+	return p - begin;
+}
+
+int _dec_octet_string (__u8 *p, __u8 *end, char *str, int *tag)
+{
+	return _dec_num_string(p, end, str, tag);
+}
+
+int _dec_sequence (__u8 *p, __u8 *end, int *tag)
+{
+	INIT;
+	return p - begin;
+}
+
+int dec_len (__u8 *p, int *len)
+{
+	*len = *p;
+	return 1;
+}

Propchange: trunk/channels/misdn/asn1.c
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: trunk/channels/misdn/asn1.c
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: trunk/channels/misdn/asn1.c
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: trunk/channels/misdn/asn1.h
URL: http://svn.digium.com/view/asterisk/trunk/channels/misdn/asn1.h?rev=39378&view=auto
==============================================================================
--- trunk/channels/misdn/asn1.h (added)
+++ trunk/channels/misdn/asn1.h Tue Aug  8 13:13:40 2006
@@ -1,0 +1,72 @@
+#ifndef __ASN1_H__
+#define __ASN1_H__
+
+#include <asm/types.h>
+
+/*
+** ASN.1 Tags
+*/
+
+#define ASN1_TAG_BOOLEAN           (0x01)
+#define ASN1_TAG_INTEGER           (0x02)
+#define ASN1_TAG_BIT_STRING        (0x03)
+#define ASN1_TAG_OCTET_STRING      (0x04)
+#define ASN1_TAG_NULL              (0x05)
+#define ASN1_TAG_OBJECT_IDENTIFIER (0x06)
+#define ASN1_TAG_ENUM              (0x0a)
+#define ASN1_TAG_SEQUENCE          (0x30)
+#define ASN1_TAG_SET               (0x31)
+#define ASN1_TAG_NUMERIC_STRING    (0x12)
+#define ASN1_TAG_PRINTABLE_STRING  (0x13)
+#define ASN1_TAG_IA5_STRING        (0x16)
+#define ASN1_TAG_UTC_TIME          (0x17)
+#define ASN1_TAG_CONSTRUCTED       (0x20)
+#define ASN1_TAG_CONTEXT_SPECIFIC  (0x80)
+#define ASN1_TAG_EXPLICIT          (0x100)
+#define ASN1_TAG_OPT               (0x200)
+#define ASN1_NOT_TAGGED            (0x400)
+
+/*
+** ASN.1 Encoding
+*/
+
+#define enc_null(dest) _enc_null(dest,ASN1_TAG_NULL)
+#define enc_bool(dest,i) _enc_bool(dest,i,ASN1_TAG_BOOLEAN)
+#define enc_int(dest,i) _enc_int(dest,i,ASN1_TAG_INTEGER)
+#define enc_enum(dest,i) _enc_enum(dest,i,ASN1_TAG_ENUM)
+#define enc_num_string(dest,num,len) _enc_num_string(dest,num,len,ASN1_TAG_NUMERIC_STRING)
+#define enc_sequence_start(dest,id) _enc_sequence_start(dest,id,ASN1_TAG_SEQUENCE)
+#define enc_sequence_end(dest,id) _enc_sequence_end(dest,id,ASN1_TAG_SEQUENCE)
+
+int _enc_null (__u8 *dest, int tag);
+int _enc_bool (__u8 *dest, __u32 i, int tag);
+int _enc_int (__u8 *dest, __u32 i, int tag);
+int _enc_enum (__u8 *dest, __u32 i, int tag);
+int _enc_num_string (__u8 *dest, __u8 *nd, __u8 len, int tag);
+int _enc_sequence_start (__u8 *dest, __u8 **id, int tag);
+int _enc_sequence_end (__u8 *dest, __u8 *id, int tag_dummy);
+
+/*
+** ASN.1 Decoding
+*/
+
+#define dec_null(p, end) _dec_null (p, end, NULL);
+#define dec_bool(p, end,i) _dec_bool (p, end, i, NULL)
+#define dec_int(p, end,i) _dec_int (p, end, i, NULL)
+#define dec_enum(p, end,i) _dec_enum (p, end, i, NULL)
+#define dec_num_string(p, end,str) _dec_num_string (p, end, str, NULL)
+#define dec_octet_string(p, end,str) _dec_octet_string (p, end, str, NULL)
+#define dec_sequence(p, end) _dec_sequence (p, end, NULL)
+
+int _dec_null (__u8 *p, __u8 *end, int *tag);
+int _dec_bool (__u8 *p, __u8 *end, int *i, int *tag);
+int _dec_int (__u8 *p, __u8 *end, int *i, int *tag);
+int _dec_enum (__u8 *p, __u8 *end, int *i, int *tag);
+int _dec_num_string (__u8 *p, __u8 *end, char *str, int *tag);
+int _dec_octet_string (__u8 *p, __u8 *end, char *str, int *tag);
+int _dec_sequence (__u8 *p, __u8 *end, int *tag);
+
+int dec_len (__u8 *p, int *len);
+
+#endif
+

Propchange: trunk/channels/misdn/asn1.h
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: trunk/channels/misdn/asn1.h
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Propchange: trunk/channels/misdn/asn1.h
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: trunk/channels/misdn/chan_misdn_config.h
URL: http://svn.digium.com/view/asterisk/trunk/channels/misdn/chan_misdn_config.h?rev=39378&r1=39377&r2=39378&view=diff
==============================================================================
--- trunk/channels/misdn/chan_misdn_config.h (original)
+++ trunk/channels/misdn/chan_misdn_config.h Tue Aug  8 13:13:40 2006
@@ -75,6 +75,8 @@
 	MISDN_CFG_OVERLAP_DIAL, 	/* int (bool)*/
 	MISDN_CFG_MSNS,                /* char[] */
 	MISDN_CFG_FAXDETECT,           /* char[] */
+ 	MISDN_CFG_FAXDETECT_CONTEXT,   /* char[] */
+ 	MISDN_CFG_FAXDETECT_TIMEOUT,   /* int */
 	MISDN_CFG_PTP,                 /* int (bool) */
 	MISDN_CFG_LAST,
 	
@@ -100,7 +102,7 @@
 };
 
 /* you must call misdn_cfg_init before any other function of this header file */
-void misdn_cfg_init(int max_ports); 
+int misdn_cfg_init(int max_ports); 
 void misdn_cfg_reload(void);
 void misdn_cfg_destroy(void);
 

Modified: trunk/channels/misdn/fac.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/misdn/fac.c?rev=39378&r1=39377&r2=39378&view=diff
==============================================================================
--- trunk/channels/misdn/fac.c (original)
+++ trunk/channels/misdn/fac.c Tue Aug  8 13:13:40 2006
@@ -1,313 +1,267 @@
 
-#include "isdn_lib_intern.h"
-#include "isdn_lib.h"
-
-#include "string.h"
-
-
-
-
-#define CENTREX_ID      0xa1
-#define CALLDEFLECT_ID      0xa1
-
-/**
-   This file covers the encoding and decoding of facility messages and
-   facility information elements.
-
-   There will be 2 Functions as Interface:
-   
-   fac_enc( char **ntmsg, msg_t * msg, enum facility_type type,  union facility fac, struct misdn_bchannel *bc)
-   fac_dec( unsigned char *p, Q931_info_t *qi, enum facility_type *type,  union facility *fac, struct misdn_bchannel *bc);
-
-   Those will either read the union facility or fill it.
-
-   internally, we will have deconding and encoding functions for each facility
-   IE.
-   
-**/
-
-
-/* support stuff */
-static void strnncpy(unsigned char *dest, unsigned char *src, int len, int dst_len)
-{
-	if (len > dst_len-1)
-		len = dst_len-1;
-	strncpy((char *)dest, (char *)src, len);
-	dest[len] = '\0';
-}
-
-
-
-
-/**********************/
-/*** FACILITY STUFF ***/
-/**********************/
-
-
-/* IE_FACILITY */
-void enc_ie_facility(unsigned char **ntmode, msg_t *msg, unsigned char *facility, int facility_len, int nt, struct misdn_bchannel *bc)
-{
-	unsigned char *p;
-	Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
-	int l;
-
-
-	if (!facility || facility_len<=0)
-	{
-		return;
-	}
-
-	
-	l = facility_len;
-	p = msg_put(msg, l+2);
-	if (nt)
-		*ntmode = p+1;
-	else
-		qi->QI_ELEMENT(facility) = p - (unsigned char *)qi - sizeof(Q931_info_t);
-	p[0] = IE_FACILITY;
-	p[1] = l;
-	memcpy(p+2, facility, facility_len);
-}
-
-
-/* facility for siemens CENTEX (known parts implemented only) */
-void enc_ie_facility_centrex(unsigned char **ntmode, msg_t *msg, unsigned char *cnip, int setup, int nt, struct misdn_bchannel *bc)
-{
-	unsigned char centrex[256];
-	int i = 0;
-
-	if (!cnip)
-		return;
-
-	/* centrex facility */
-	centrex[i++] = FACILITY_CENTREX;
-	centrex[i++] = CENTREX_ID;
-
-	/* cnip */
-	if (strlen((char *)cnip) > 15)
-	{
-/* 		if (options.deb & DEBUG_PORT) */
-		cb_log(1,0,"%s: CNIP/CONP text too long (max 13 chars), cutting.\n", __FUNCTION__);
-		cnip[15] = '\0';
-	}
-	/*  dunno what the 8 bytes mean */
-	if (setup)
-	{
-		centrex[i++] = 0x17;
-		centrex[i++] = 0x02;
-		centrex[i++] = 0x02;
-		centrex[i++] = 0x44;
-		centrex[i++] = 0x18;
-		centrex[i++] = 0x02;
-		centrex[i++] = 0x01;
-		centrex[i++] = 0x09;
-	} else
-	{
-		centrex[i++] = 0x18;
-		centrex[i++] = 0x02;
-		centrex[i++] = 0x02;
-		centrex[i++] = 0x81;
-		centrex[i++] = 0x09;
-		centrex[i++] = 0x02;
-		centrex[i++] = 0x01;
-		centrex[i++] = 0x0a;
-	}
-
-	centrex[i++] = 0x80;
-	centrex[i++] = strlen((char *)cnip);
-	strcpy((char *)(&centrex[i]), (char *)cnip);
-	i += strlen((char *)cnip);
-	cb_log(4,0,"    cnip='%s'\n", cnip);
-
-	/* encode facility */
-	enc_ie_facility(ntmode, msg, centrex, i, nt , bc);
-}
-
-void dec_ie_facility_centrex(unsigned char *p, Q931_info_t *qi, unsigned char *centrex, int facility_len, unsigned char *cnip, int cnip_len, int nt, struct misdn_bchannel *bc)
-{
-
-	int i = 0;
-	*cnip = '\0';
-	
-	if (facility_len >= 2)
-	{
-		if (centrex[i++] != FACILITY_CENTREX)
-			return;
-		if (centrex[i++] != CENTREX_ID)
-			return;
-	}
-
-	/* loop sub IEs of facility */
-	while(facility_len > i+1)
-	{
-		if (centrex[i+1]+i+1 > facility_len)
-		{
-			printf("%s: ERROR: short read of centrex facility.\n", __FUNCTION__);
-			return;
-		}
-		switch(centrex[i])
-		{
-		case 0x80:
-			strnncpy(cnip, &centrex[i+2], centrex[i+1], cnip_len);
-			cb_log(4,0,"    CENTREX cnip='%s'\n", cnip);
-			break;
-		}
-		i += 1+centrex[i+1];
-	}
-}
-
-
-
-
-/* facility for CALL Deflect (known parts implemented only) */
-void enc_ie_facility_calldeflect(unsigned char **ntmode, msg_t *msg, unsigned char *nr, int nt, struct misdn_bchannel *bc)
-{
-	unsigned char fac[256];
-	
-	if (!nr)
-		return;
-
-	int len = strlen(nr);
-	/* calldeflect facility */
-	
-	/* cnip */
-	if (strlen((char *)nr) > 15)
-	{
-/* 		if (options.deb & DEBUG_PORT) */
-		cb_log(1,0,"%s: NR text too long (max 13 chars), cutting.\n", __FUNCTION__);
-		nr[15] = '\0';
-	}
-	
-	fac[0]=FACILITY_CALLDEFLECT;	// ..
-	fac[1]=CALLDEFLECT_ID;
-	fac[2]=0x0f + len;	// strlen destination + 15 = 26
-	fac[3]=0x02;
-	fac[4]=0x01;
-	//fac[5]=0x70;
-	fac[5]=0x09;
-	fac[6]=0x02;
-	fac[7]=0x01;
-	fac[8]=0x0d;
-	fac[9]=0x30;
-	fac[10]=0x07 + len;	// strlen destination + 7 = 18
-	fac[11]=0x30;	// ...hm 0x30
-	fac[12]=0x02+ len;	// strlen destination + 2	
-	fac[13]=0x80;	// CLIP
-	fac[14]= len;	//  strlen destination 
-	
-	memcpy((unsigned char *)fac+15,nr,len);
-	fac[15+len]=0x01; //sending complete
-	fac[16+len]=0x01;
-	fac[17+len]=0x80;
-	
-	enc_ie_facility(ntmode, msg, fac, 17+len +1 , nt , bc);
-}
-
-
-void dec_ie_facility_calldeflect(unsigned char *p, Q931_info_t *qi, unsigned char *fac, int fac_len, unsigned char *cd_nr,  int nt, struct misdn_bchannel *bc)
-{
-	*cd_nr = '\0';
-	
-	if (fac_len >= 15)
-	{
-		if (fac[0] != FACILITY_CALLDEFLECT)
-			return;
-		if (fac[1] != CALLDEFLECT_ID)
-			return;
+#include "fac.h"
+#include "asn1.h"
+
+#if 0
++-------------------------------
+| IE_IDENTIFIER
++-------------------------------
+| {length}
++-------------------------------
+|   +---------------------------
+|   | SERVICE_DISCRIMINATOR
+|   +---------------------------
+|   | COMPONENT_TYPE_TAG
+|   +---------------------------
+|   | {length}
+|   +---------------------------
+|   |	+-----------------------
+|   |   | INVOKE_IDENTIFIER_TAG (0x2)
+|   |   +-----------------------
+|   |   | {length}              (0x1)
+|   |   +-----------------------
+|   |   | {value}               (odd integer 0-127)
+|   |   +-----------------------
+|   |   +-----------------------
+|   |   | OPERATION_VALUE_TAG   (0x2)
+|   |   +-----------------------
+|   |   | {length}              (0x1)
+|   |   +-----------------------
+|   |   | {value}
+|   |   +-----------------------
+|   |	+-----------------------
+|   |	| ASN.1 data
++---+---+-----------------------
+#endif
+
+enum {
+	SUPPLEMENTARY_SERVICE 	= 0x91,
+} SERVICE_DISCRIMINATOR;
+
+enum {
+	INVOKE 					= 0xa1,
+	RETURN_RESULT 			= 0xa2,
+	RETURN_ERROR 			= 0xa3,
+	REJECT 					= 0xa4,
+} COMPONENT_TYPE_TAG;
+
+enum {
+	INVOKE_IDENTIFIER 		= 0x02,
+	LINKED_IDENTIFIER 		= 0x80,
+	NULL_IDENTIFIER 		= 0x05,
+} INVOKE_IDENTIFIER_TAG;
+
+enum {
+	OPERATION_VALUE 		= 0x02,
+} OPERATION_VALUE_TAG;
+
+enum {
+	VALUE_QUERY 			= 0x8c,
+	SET_VALUE 				= 0x8d,
+	REQUEST_FEATURE 		= 0x8f,
+	ABORT 					= 0xbe,
+	REDIRECT_CALL 			= 0xce,
+	CALLING_PARTY_TO_HOLD 	= 0xcf,
+	CALLING_PARTY_FROM_HOLD = 0x50,
+	DROP_TARGET_PARTY 		= 0xd1,
+	USER_DATA_TRANSFER 		= 0xd3,
+	APP_SPECIFIC_STATUS 	= 0xd2,
+
+	/* not from document */
+	CALL_DEFLECT 			= 0x0d,
+	AOC 					= 0x22,
+} OPERATION_CODE;
+
+enum {
+	Q931_IE_TAG 			= 0x40,
+} ARGUMENT_TAG;
+
+#ifdef FACILITY_DEBUG
+#define FAC_DUMP(fac,len,bc) fac_dump(fac,len,bc)
+#include <ctype.h>
+static void fac_dump (__u8 *facility, unsigned int fac_len, struct misdn_bchannel *bc)
+{
+	int i;
+	cb_log(0, bc->port, "    --- facility dump start. length:%d\n", fac_len);
+	for (i = 0; i < fac_len; ++i)
+		if (isprint(facility[i]))
+			cb_log(0, bc->port, "    --- %d: %04p (char:%c)\n", i, facility[i], facility[i]);
+		else
+			cb_log(0, bc->port, "    --- %d: %04p\n", i, facility[i]);
+	cb_log(0, bc->port, "    --- facility dump end\n");
+}
+#else
+#define FAC_DUMP(fac,len,bc)
+#endif
+
+/*
+** Facility Encoding
+*/
+
+static int enc_fac_calldeflect (__u8 *dest, char *number, int pres)
+{
+	__u8 *body_len,
+		 *p = dest,
+		 *seq1, *seq2;
+
+	*p++ = SUPPLEMENTARY_SERVICE;
+	*p++ = INVOKE;
+
+	body_len = p++;
+
+	p += _enc_int(p, 0x1 /* some odd integer in (0..127) */, INVOKE_IDENTIFIER);
+	p += _enc_int(p, CALL_DEFLECT, OPERATION_VALUE);
+	p += enc_sequence_start(p, &seq1);
+	  p += enc_sequence_start(p, &seq2);
+	    p += _enc_num_string(p, number, strlen(number), ASN1_TAG_CONTEXT_SPECIFIC);
+	  p += enc_sequence_end(p, seq2);
+	  p += enc_bool(p, pres);
+    p += enc_sequence_end(p, seq1);
+	
+	*body_len = p - &body_len[1];
+	
+	return p - dest;
+}
+
+static void enc_ie_facility (__u8 **ntmode, msg_t *msg, __u8 *facility, int facility_len, struct misdn_bchannel *bc)
+{
+	__u8 *ie_fac;
+	
+	Q931_info_t *qi;
+
+	ie_fac = msg_put(msg, facility_len + 2);
+	if (bc->nt) {
+		*ntmode = ie_fac + 1;
 	} else {
-		cb_log(1,bc->port, "IE too short: FAC_CALLDEFLECT\n");
-		return ;
-	}
-	
-	
-	
-	{
-		int dest_len=fac[2]-0x0f;
-		
-		if (dest_len <0 || dest_len > 15) {
-			cb_log(1,bc->port, "IE is garbage: FAC_CALLDEFLECT\n");
-			return ;
-		}
-		
-		if (fac_len < 15+dest_len) {
-			cb_log(1,bc->port, "IE too short: FAC_CALLDEFLECT\n");
-			return ;
-		}
-		
-		memcpy(cd_nr, &fac[15],dest_len);
-		cd_nr[dest_len]=0;
-		
-		cb_log(5,bc->port, "--> IE CALLDEFLECT NR: %s\n",cd_nr);
-	}
-}
-
-
-
-void fac_enc( unsigned char **ntmsg, msg_t * msg, enum facility_type type,  union facility fac, struct misdn_bchannel *bc)
-{
+		qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
+		qi->QI_ELEMENT(facility) = ie_fac - (__u8 *)qi - sizeof(Q931_info_t);
+	}
+
+	ie_fac[0] = IE_FACILITY;
+	ie_fac[1] = facility_len;
+	memcpy(ie_fac + 2, facility, facility_len);
+
+	FAC_DUMP(ie_fac, facility_len + 2, bc);
+}
+
+void fac_enc (__u8 **ntmsg, msg_t *msg, enum facility_type type,  union facility fac, struct misdn_bchannel *bc)
+{
+	__u8 facility[256];
+	int len;
+
 	switch (type) {
+	case FACILITY_CALLDEFLECT:
+		len = enc_fac_calldeflect(facility, fac.calldeflect_nr, 1);
+		enc_ie_facility(ntmsg, msg, facility, len, bc);
+		break;
 	case FACILITY_CENTREX:
-	{
-		int setup=0;
-		enc_ie_facility_centrex(ntmsg, msg, fac.cnip, setup, bc->nt, bc);
-	}
-		break;
-	case FACILITY_CALLDEFLECT:
-		enc_ie_facility_calldeflect(ntmsg, msg, fac.calldeflect_nr, bc->nt, bc);
+	case FACILITY_NONE:
+		break;
+	}
+}
+
+/*
+** Facility Decoding
+*/
+
+static int dec_fac_calldeflect (__u8 *p, int len, struct misdn_bchannel *bc)
+{
+	__u8 *end = p + len;
+	int offset,
+		pres;
+
+	if ((offset = dec_sequence(p, end)) < 0)
+		return -1;
+	p += offset;
+
+	if ((offset = dec_sequence(p, end)) < 0)
+		return -1;
+	p += offset;
+	
+	if ((offset = dec_num_string(p, end, bc->fac.calldeflect_nr)) < 0)
+		return -1;
+	p += offset;
+
+	if ((offset = dec_bool(p, end, &pres)) < 0)
+		return -1;
+
+	cb_log(0, 0, "CALLDEFLECT: dest:%s pres:%s (not implemented yet)\n", bc->fac.calldeflect_nr, pres ? "yes" : "no");
+	bc->fac_type = FACILITY_CALLDEFLECT;
+
+	return 0;
+}
+
+void fac_dec (__u8 *p, Q931_info_t *qi, enum facility_type *type,  union facility *fac, struct misdn_bchannel *bc)
+{
+	int len,
+		offset,
+		inner_len,
+		invoke_id,
+		op_tag,
+		op_val;
+	__u8 *end,
+				  *begin = p;
+
+	if (!bc->nt) {
+		if (qi->QI_ELEMENT(facility))
+			p = (__u8 *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(facility) + 1;
+		else
+			p = NULL;
+	}
+	if (!p)
+		return;
+
+	offset = dec_len (p, &len);
+	if (offset < 0) {
+		cb_log(0, bc->port, "Could not decode FACILITY: dec_len failed!\n");
+		return;
+	}
+	p += offset;
+	end = p + len;
+
+	FAC_DUMP(p, len, bc);
+
+	if (len < 3 || p[0] != SUPPLEMENTARY_SERVICE || p[1] != INVOKE) {
+		cb_log(0, bc->port, "Could not decode FACILITY: invalid or not supported!\n");
+		return;
+	}
+	p += 2;
+
+	offset = dec_len (p, &inner_len);
+	if (offset < 0) {
+		cb_log(0, bc->port, "Could not decode FACILITY: failed parsing inner length!\n");
+		return;
+	}
+	p += offset;
+
+	offset = dec_int (p, end, &invoke_id);
+	if (offset < 0) {
+		cb_log(0, bc->port, "Could not decode FACILITY: failed parsing invoke identifier!\n");
+		return;
+	}
+	p += offset;
+
+	offset = _dec_int (p, end, &op_val, &op_tag);
+	if (offset < 0) {
+		cb_log(0, bc->port, "Could not decode FACILITY: failed parsing operation value!\n");
+		return;
+	}
+	p += offset;
+
+	if (op_tag != OPERATION_VALUE || offset != 3) {
+		cb_log(0, bc->port, "Could not decode FACILITY: operation value tag 0x%x unknown!\n", op_tag);
+		return;
+	}
+
+	switch (op_val) {
+	case CALL_DEFLECT:
+		cb_log(0, bc->port, "FACILITY: Call Deflect\n");
+		dec_fac_calldeflect(p, len - (p - begin) + 1, bc);
+		break;
+	case AOC:
+		cb_log(0, bc->port, "FACILITY: AOC\n");
 		break;
 	default:
-		cb_log(1,0,"Don't know how handle this facility: %d\n", type);
-	}
-}
-
-void fac_dec( unsigned char *p, Q931_info_t *qi, enum facility_type *type,  union facility *fac, struct misdn_bchannel *bc)
-{
-	int i, fac_len=0;
-	unsigned char facility[256];
-
-	if (!bc->nt)
-	{
-		p = NULL;
-		if (qi->QI_ELEMENT(facility))
-			p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(facility) + 1;
-	}
-	if (!p)
-		return;
-	
-	fac_len = p[0] & 0xff;
-
-	memcpy(facility, p+1, fac_len);
-	
-	switch(facility[0]) {
-	case FACILITY_CENTREX:
-	{
-		int cnip_len=15;
-		
-		dec_ie_facility_centrex(p, qi,facility, fac_len, fac->cnip, cnip_len, bc->nt, bc);
-		
-		*type=FACILITY_CENTREX;
-	}
-	break;
-	case FACILITY_CALLDEFLECT:
-		dec_ie_facility_calldeflect(p, qi,facility, fac_len, fac->calldeflect_nr,  bc->nt, bc);
-		
-		*type=FACILITY_CALLDEFLECT;
-		break;
-	default:
-		cb_log(3, bc->port, "Unknown Facility received: ");
-		i = 0;
-		while(i < fac_len)
-		{
-			cb_log(3, bc->port, " %02x", facility[i]);
-			i++;
-		}
-		cb_log(3, bc->port, "    facility\n");
-		
-		*type=FACILITY_NONE;
-	}
-	
-	
-}
-
-/*** FACILITY END **/
-
+		cb_log(0, bc->port, "FACILITY unknown: operation value 0x%x, ignoring ...\n", op_val);
+	}
+}

Modified: trunk/channels/misdn/fac.h
URL: http://svn.digium.com/view/asterisk/trunk/channels/misdn/fac.h?rev=39378&r1=39377&r2=39378&view=diff
==============================================================================
--- trunk/channels/misdn/fac.h (original)
+++ trunk/channels/misdn/fac.h Tue Aug  8 13:13:40 2006
@@ -1,8 +1,10 @@
-#ifndef FAC_H
-#define FAC_H
+#ifndef __FAC_H__
+#define __FAC_H__
 
-void fac_enc( unsigned char **ntmsg, msg_t * msg, enum facility_type type,  union facility fac, struct misdn_bchannel *bc);
+#include "isdn_lib_intern.h"
 
-void fac_dec( unsigned char *p, Q931_info_t *qi, enum facility_type *type,  union facility *fac, struct misdn_bchannel *bc);
+void fac_enc (__u8 **ntmsg, msg_t *msg, enum facility_type type, union facility fac, struct misdn_bchannel *bc);
+void fac_dec (__u8 *p, Q931_info_t *qi, enum facility_type *type, union facility *fac, struct misdn_bchannel *bc);
 
 #endif
+

Modified: trunk/channels/misdn/isdn_lib.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/misdn/isdn_lib.c?rev=39378&r1=39377&r2=39378&view=diff
==============================================================================
--- trunk/channels/misdn/isdn_lib.c (original)
+++ trunk/channels/misdn/isdn_lib.c Tue Aug  8 13:13:40 2006
@@ -2589,6 +2589,7 @@
     
 		bc=find_bc_by_l3id(stack, frm->dinfo);
     
+handle_frm_bc:
 		if (bc ) {
 			enum event_e event = isdn_msg_get_event(msgs_g, msg, 0);
 			enum event_response_e response=RESPONSE_OK;
@@ -2602,7 +2603,7 @@
       
 			if(!isdn_get_info(msgs_g,event,0)) 
 				cb_log(0, stack->port, "Unknown Event Ind: Addr:%x prim %x dinfo %x\n",frm->addr, frm->prim, frm->dinfo);
-			else 
+			else
 				response=cb_event(event, bc, glob_mgr->user_data);
 #if 1
 			if (event == EVENT_SETUP) {
@@ -2644,7 +2645,13 @@
 #endif
       
 		} else {
-			cb_log(0, stack->port, "NO BC FOR STACK\n");		
+			cb_log(0, stack->port, " --> Didn't find BC so temporarly creating dummy BC (l3id:%x) on this port.\n", frm->dinfo);
+			struct misdn_bchannel dummybc;
+			memset (&dummybc,0,sizeof(dummybc));
+			dummybc.port=stack->port;
+			dummybc.l3_id=frm->dinfo;
+			bc=&dummybc; 
+			goto handle_frm_bc;
 		}
 	}
 
@@ -4024,6 +4031,32 @@
 }
 
 /*
+ * allow live control of channel parameters
+ */
+void isdn_lib_update_rxgain (struct misdn_bchannel *bc)
+{
+	manager_ph_control(bc, VOL_CHANGE_RX, bc->rxgain);
+}
+
+void isdn_lib_update_txgain (struct misdn_bchannel *bc)
+{
+	manager_ph_control(bc, VOL_CHANGE_TX, bc->txgain);
+}
+
+void isdn_lib_update_ec (struct misdn_bchannel *bc)
+{
+	if (bc->ec_enable)
+		manager_ec_enable(bc);
+	else
+		manager_ec_disable(bc);
+}
+
+void isdn_lib_stop_dtmf (struct misdn_bchannel *bc)
+{
+	manager_ph_control(bc, DTMF_TONE_STOP, 0);
+}
+
+/*
  * send control information to the channel (dsp-module)
  */
 void manager_ph_control_block(struct misdn_bchannel *bc, int c1, void *c2, int c2_len)

Modified: trunk/channels/misdn/isdn_lib.h
URL: http://svn.digium.com/view/asterisk/trunk/channels/misdn/isdn_lib.h?rev=39378&r1=39377&r2=39378&view=diff
==============================================================================
--- trunk/channels/misdn/isdn_lib.h (original)
+++ trunk/channels/misdn/isdn_lib.h Tue Aug  8 13:13:40 2006
@@ -406,6 +406,10 @@
 
 void manager_ph_control(struct misdn_bchannel *bc, int c1, int c2);
 
+void isdn_lib_update_rxgain (struct misdn_bchannel *bc);
+void isdn_lib_update_txgain (struct misdn_bchannel *bc);
+void isdn_lib_update_ec (struct misdn_bchannel *bc);
+void isdn_lib_stop_dtmf (struct misdn_bchannel *bc);
 
 int misdn_lib_port_restart(int port);
 int misdn_lib_get_port_info(int port);

Modified: trunk/channels/misdn/isdn_msg_parser.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/misdn/isdn_msg_parser.c?rev=39378&r1=39377&r2=39378&view=diff
==============================================================================
--- trunk/channels/misdn/isdn_msg_parser.c (original)
+++ trunk/channels/misdn/isdn_msg_parser.c Tue Aug  8 13:13:40 2006
@@ -879,8 +879,7 @@
 

[... 185 lines stripped ...]


More information about the asterisk-commits mailing list