[asterisk-commits] branch oej/test-this-branch r10861 - in /team/oej/test-this-branch: ./ channels/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Thu Feb 23 02:13:27 MST 2006


Author: oej
Date: Thu Feb 23 03:13:22 2006
New Revision: 10861

URL: http://svn.digium.com/view/asterisk?rev=10861&view=rev
Log:
Adding chan_zap HDLC support (crich)

Modified:
    team/oej/test-this-branch/README.test-this-branch
    team/oej/test-this-branch/channels/chan_zap.c

Modified: team/oej/test-this-branch/README.test-this-branch
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/README.test-this-branch?rev=10861&r1=10860&r2=10861&view=diff
==============================================================================
--- team/oej/test-this-branch/README.test-this-branch (original)
+++ team/oej/test-this-branch/README.test-this-branch Thu Feb 23 03:13:22 2006
@@ -28,6 +28,7 @@
 - Additional options for the CHANNEL dialplan function (oej)
 - Manager sendtext event (ZX81, #6131)
 - Carrier ENUM support (otmar, #5526)
+- HDLC mode support for ZAP channels (crich, #6251)
 
 Coming here soon:
 - metermaids: Subscription support for parking lots (#5779)
@@ -59,4 +60,61 @@
 "type=peer" instead of "type=friend". Subscriptions will work much better
 with just one object to match.
 
-- 
+* 6251: Support for HDLC mode in ZAP channels
+----------------------------------------------
+The patch adds 2 things to chan_zap:
+
+1. an application: ZapSetHDLC
+2. an option to the dialstring h ( dial(zap/g0h/123) )
+
+This patch adds an application ZapSetHDLC and an option to the zap channel dialstring, 
+which allow incoming and outgoing zap channels to be setted into HDLC Mode. 
+
+The patch adds an element hldc to the zt_pvt struct. When either for incoming calls 
+ZapSetHDLC is called or for outgoing calls the h option is given, the corresponding 
+zap channel is set into HDLC mode via ioctl(ZT_HDLCFCSMODE) in PRI_HANGUP the patch 
+sets back the channel into ZT_AUDIOMODE. 
+
+Additionally in my_zt_write and zt_read it is checked at particular places if hdlc mode 
+is set, and then the sample rate is set directly for example, rather then using 
+READ_SIZE and so forth. 
+
+
+The feature plans are to add a frame subclass AST_MODEM_HDLC. Applications or channels
+that need to transfer data in hdlc mode could just send with that type and the other
+channel driver could activate its hdlc controller. 
+
+With this construction you can make a successful data call between chan_misdn and 
+chan_zap T1/E1 channel.
+
+The Patch does NOT change anything when hdlc mode is not set, which means it will not 
+touch current installations.
+
+* DIALPLAN EXAMPLE:
+
+misdn.conf:
+
+ports=1
+context=bri2Zap
+
+
+extensions.conf:
+
+[bri2Zap]
+exten => _X.,1,misdn_set_opt(h1)
+exten => _X.,1,Dial(Zap/g0h/1234)
+
+
+
+the other way would be:
+
+zapata.conf:
+context=zap2bri
+channels=>1-15,17-31
+
+
+extensions.conf:
+
+[zap2bri]
+exten => _X.,1,ZapSetHDLC()
+exten => _X.,2,Dial(mISDN/g:Computer1/123/h1)

Modified: team/oej/test-this-branch/channels/chan_zap.c
URL: http://svn.digium.com/view/asterisk/team/oej/test-this-branch/channels/chan_zap.c?rev=10861&r1=10860&r2=10861&view=diff
==============================================================================
--- team/oej/test-this-branch/channels/chan_zap.c (original)
+++ team/oej/test-this-branch/channels/chan_zap.c Thu Feb 23 03:13:22 2006
@@ -405,6 +405,7 @@
 
 /*! Chunk size to read -- we use 20ms chunks to make things happy.  */   
 #define READ_SIZE 160
+#define HDLC_READ_SIZE 2051
 
 #define MASK_AVAIL		(1 << 0)	/*!< Channel available for PRI use */
 #define MASK_INUSE		(1 << 1)	/*!< Channel currently in use */
@@ -530,7 +531,8 @@
 	int zfd;
 	struct ast_channel *owner;
 	int chan;
-	short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
+	/* in hdlc mode our buffer must be bigger..*/
+	short buffer[AST_FRIENDLY_OFFSET/2 + HDLC_READ_SIZE];
 	struct ast_frame f;		/*!< One frame for each channel.  How did this ever work before? */
 	unsigned int needringing:1;
 	unsigned int needbusy:1;
@@ -584,6 +586,7 @@
 	unsigned int dialednone:1;
 	unsigned int dialing:1;
 	unsigned int digital:1;
+	unsigned int hdlc:1;
 	unsigned int dnd:1;
 	unsigned int echobreak:1;
 	unsigned int echocanbridged:1;
@@ -2308,6 +2311,41 @@
 	return 0;
 }
 
+static char *zap_set_hdlc_app = "ZapSetHDLC";
+
+static char *zap_set_hdlc_synopsis = "Sets channel into HDLC mode";
+
+static char *zap_set_hdlc_descrip = 
+"  ZapSetHDLC(): This application will set the current channel in hdlc mode\n"
+;
+
+static int zap_set_hdlc_exec(struct ast_channel *chan, void *data)
+{
+	/* Data will be our digit string */
+	struct zt_pvt *p = (struct zt_pvt *)chan->tech_pvt;
+	int x=1;
+	int bs=HDLC_READ_SIZE; /* how large can hdlc frames be on the bchannel ? */
+	
+	if (!p) {
+		ast_log(LOG_WARNING, "Unable to find technology private\n");
+		return -1;
+	}
+
+	ast_mutex_lock(&p->lock);
+	
+	if (ioctl(p->subs[SUB_REAL].zfd, ZT_HDLCFCSMODE, &x) == -1)
+		ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d\n", p->channel, x);
+
+	if (ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BLOCKSIZE, &bs) == -1) 
+		ast_log(LOG_WARNING, "Unable to change the blocksize on channel %d to :%d\n", p->channel, bs);
+
+	p->hdlc=1;
+	
+	ast_mutex_unlock(&p->lock);
+	
+	return 0;
+}
+
 int pri_is_up(struct zt_pri *pri)
 {
 	int x;
@@ -2551,7 +2589,20 @@
 			ast_dsp_free(p->dsp);
 			p->dsp = NULL;
 		}
-
+		
+		if (p->hdlc) {
+			int x=1;
+			res = ioctl(p->subs[SUB_REAL].zfd, ZT_AUDIOMODE, &x);
+			if (res < 0) 
+				ast_log(LOG_WARNING, "Unable to set Audiomode on channel %d to default\n", p->channel);
+			p->hdlc = 0;
+
+			int bs=READ_SIZE;
+			if (ioctl(p->subs[SUB_REAL].zfd, ZT_SET_BLOCKSIZE, &bs) == -1) 
+				ast_log(LOG_WARNING, "Unable to change the blocksize on channel %d to :%d\n", p->channel, bs);
+
+		}
+		
 		law = ZT_LAW_DEFAULT;
 		res = ioctl(p->subs[SUB_REAL].zfd, ZT_SETLAW, &law);
 		if (res < 0) 
@@ -4616,7 +4667,10 @@
 	}
 	readbuf = ((unsigned char *)p->subs[index].buffer) + AST_FRIENDLY_OFFSET;
 	CHECK_BLOCKING(ast);
-	res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
+	if (p->hdlc)
+		res = read(p->subs[index].zfd, readbuf, HDLC_READ_SIZE);
+	else
+		res = read(p->subs[index].zfd, readbuf, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
 	ast_clear_flag(ast, AST_FLAG_BLOCKING);
 	/* Check for hangup */
 	if (res < 0) {
@@ -4634,11 +4688,22 @@
 		ast_mutex_unlock(&p->lock);
 		return f;
 	}
-	if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) {
-		ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
-		f = __zt_exception(ast);
-		ast_mutex_unlock(&p->lock);
-		return f;
+	
+	if ( p->hdlc ) {
+		/*FIXME: last 2 bytes are the Frame check*/
+		res-=2;
+#if 0
+		ast_log(LOG_NOTICE,"READ: %d\n",res);
+#endif
+	} else {
+		
+		if (res != (p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE)) {
+			ast_log(LOG_DEBUG, "Short read (%d/%d), must be an event...\n", res, p->subs[index].linear ? READ_SIZE * 2 : READ_SIZE);
+			f = __zt_exception(ast);
+			ast_mutex_unlock(&p->lock);
+			return f;
+		}
+
 	}
 	if (p->tdd) { /* if in TDD mode, see if we receive that */
 		int c;
@@ -4676,11 +4741,16 @@
 			ast_verbose(VERBOSE_PREFIX_3 "CPE does not support Call Waiting Caller*ID.\n");
 		restore_conference(p);
 	}
-	if (p->subs[index].linear) {
-		p->subs[index].f.datalen = READ_SIZE * 2;
-	} else 
-		p->subs[index].f.datalen = READ_SIZE;
-
+	
+	if ( p->hdlc ) {
+		p->subs[index].f.datalen = res;
+	} else {
+		if (p->subs[index].linear) {
+			p->subs[index].f.datalen = READ_SIZE * 2;
+		} else 
+			p->subs[index].f.datalen = READ_SIZE;
+	}
+	
 	/* Handle CallerID Transmission */
 	if ((p->owner == ast) && p->cidspill &&((ast->_state == AST_STATE_UP) || (ast->rings == p->cidrings))) {
 		send_callerid(p);
@@ -4688,7 +4758,10 @@
 
 	p->subs[index].f.frametype = AST_FRAME_VOICE;
 	p->subs[index].f.subclass = ast->rawreadformat;
-	p->subs[index].f.samples = READ_SIZE;
+	if ( p->hdlc )
+		p->subs[index].f.samples = res;
+	else
+		p->subs[index].f.samples = READ_SIZE;
 	p->subs[index].f.mallocd = 0;
 	p->subs[index].f.offset = AST_FRIENDLY_OFFSET;
 	p->subs[index].f.data = p->subs[index].buffer + AST_FRIENDLY_OFFSET/2;
@@ -4709,7 +4782,7 @@
 		p->subs[index].f.data = NULL;
 		p->subs[index].f.datalen= 0;
 	}
-	if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect  || p->callprogress) && !index) {
+	if (p->dsp && (!p->ignoredtmf || p->callwaitcas || p->busydetect  || p->callprogress) && !index && !p->digital) {
 		/* Perform busy detection. etc on the zap line */
 		f = ast_dsp_process(ast, p->dsp, &p->subs[index].f);
 		if (f) {
@@ -4811,6 +4884,18 @@
 	int res;
 	int fd;
 	fd = p->subs[index].zfd;
+		
+	if ( p->hdlc ) {
+		/*FIXME: 2 bytes for the framecheck*/
+		char mybuf[len+2];
+		memcpy(mybuf,buf,len);
+#if 0
+		ast_log(LOG_NOTICE, "Writing on zap channel  len:%d\n",len);
+#endif
+		write(fd,mybuf,len+2);
+		return 0;
+	} 
+	
 	while(len) {
 		size = len;
 		if (size > (linear ? READ_SIZE * 2 : READ_SIZE))
@@ -7863,6 +7948,15 @@
 					p->digital = 1;
 					if (tmp)
 						tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
+				} else if (opt == 'h') {
+					/* If this is an ISDN call, make it digital + hdlc */
+					ast_log(LOG_NOTICE,"Setting Digital mode with hdlc encryption\n");
+					
+					p->digital = 1;
+					p->hdlc = 1;
+					
+					if (tmp)
+						tmp->transfercapability = AST_TRANS_CAP_DIGITAL;
 				} else {
 					ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data);
 				}
@@ -8595,6 +8689,11 @@
 								}
 							}
 						}
+						
+						if (pri->pvts[chanpos]->digital && pri->pvts[chanpos]->hdlc) {
+							
+							zap_set_hdlc_exec(pri->pvts[chanpos]->owner,NULL);
+						} 
 						ast_mutex_unlock(&pri->pvts[chanpos]->lock);
 					}
 				}
@@ -10296,6 +10395,7 @@
 	}
 	ast_cli_unregister_multiple(zap_pri_cli, sizeof(zap_pri_cli) / sizeof(zap_pri_cli[0]));
 	ast_unregister_application(zap_send_keypad_facility_app);
+	ast_unregister_application(zap_set_hdlc_app);
 #endif
 #ifdef ZAPATA_R2
 	ast_cli_unregister_multiple(zap_r2_cli, sizeof(zap_r2_cli) / sizeof(zap_r2_cli[0]));
@@ -11217,6 +11317,9 @@
 	pri_set_message(zt_pri_message);
 	ast_register_application(zap_send_keypad_facility_app, zap_send_keypad_facility_exec,
 			zap_send_keypad_facility_synopsis, zap_send_keypad_facility_descrip);
+	
+	ast_register_application(zap_set_hdlc_app, zap_set_hdlc_exec,
+				 zap_set_hdlc_synopsis, zap_set_hdlc_descrip);
 #endif
 	res = setup_zap(0);
 	/* Make sure we can register our Zap channel type */



More information about the asterisk-commits mailing list