patch-2.2.19 linux/drivers/isdn/hisax/l3dss1.c
Next file: linux/drivers/isdn/hisax/l3dss1.h
Previous file: linux/drivers/isdn/hisax/l3_1tr6.h
Back to the patch index
Back to the overall index
- Lines: 530
- Date:
Sun Mar 25 11:37:33 2001
- Orig file:
v2.2.18/drivers/isdn/hisax/l3dss1.c
- Orig date:
Sun Mar 25 11:13:07 2001
diff -u --new-file --recursive --exclude-from /usr/src/exclude v2.2.18/drivers/isdn/hisax/l3dss1.c linux/drivers/isdn/hisax/l3dss1.c
@@ -1,5 +1,5 @@
-/* $Id: l3dss1.c,v 2.23 2000/02/26 01:38:14 keil Exp $
-
+/* $Id: l3dss1.c,v 2.30 2000/11/19 17:02:48 kai Exp $
+ *
* EURO/DSS1 D-channel protocol
*
* Author Karsten Keil (keil@isdn4linux.de)
@@ -12,91 +12,6 @@
* Thanks to Jan den Ouden
* Fritz Elfert
*
- * $Log: l3dss1.c,v $
- * Revision 2.23 2000/02/26 01:38:14 keil
- * Fixes for V.110 encoding LLC from Jens Jakobsen
- *
- * Revision 2.22 2000/01/20 19:44:20 keil
- * Fixed uninitialiesed location
- * Fixed redirecting number IE in Setup
- * Changes from certification
- * option for disabling use of KEYPAD protocol
- *
- * Revision 2.21 1999/12/19 20:25:17 keil
- * fixed LLC for outgoing analog calls
- * IE Signal is valid on older local switches
- *
- * Revision 2.20 1999/10/11 22:16:27 keil
- * Suspend/Resume is possible without explicit ID too
- *
- * Revision 2.19 1999/08/25 16:55:23 keil
- * Fix for test case TC10011
- *
- * Revision 2.18 1999/08/11 20:54:39 keil
- * High layer compatibility is valid in SETUP
- *
- * Revision 2.17 1999/07/25 16:18:25 keil
- * Fix Suspend/Resume
- *
- * Revision 2.16 1999/07/21 14:46:23 keil
- * changes from EICON certification
- *
- * Revision 2.14 1999/07/09 08:30:08 keil
- * cosmetics
- *
- * Revision 2.13 1999/07/01 08:11:58 keil
- * Common HiSax version for 2.0, 2.1, 2.2 and 2.3 kernel
- *
- * Revision 2.12 1998/11/15 23:55:10 keil
- * changes from 2.0
- *
- * Revision 2.11 1998/08/13 23:36:51 keil
- * HiSax 3.1 - don't work stable with current LinkLevel
- *
- * Revision 2.10 1998/05/25 14:10:20 keil
- * HiSax 3.0
- * X.75 and leased are working again.
- *
- * Revision 2.9 1998/05/25 12:58:17 keil
- * HiSax golden code from certification, Don't use !!!
- * No leased lines, no X75, but many changes.
- *
- * Revision 2.8 1998/03/19 13:18:47 keil
- * Start of a CAPI like interface for supplementary Service
- * first service: SUSPEND
- *
- * Revision 2.7 1998/02/12 23:08:01 keil
- * change for 2.1.86 (removing FREE_READ/FREE_WRITE from [dev]_kfree_skb()
- *
- * Revision 2.6 1998/02/03 23:26:35 keil
- * V110 extensions from Thomas Pfeiffer
- *
- * Revision 2.5 1998/02/02 13:34:28 keil
- * Support australian Microlink net and german AOCD
- *
- * Revision 2.4 1997/11/06 17:12:25 keil
- * KERN_NOTICE --> KERN_INFO
- *
- * Revision 2.3 1997/10/29 19:03:01 keil
- * changes for 2.1
- *
- * Revision 2.2 1997/08/07 17:44:36 keil
- * Fix RESTART
- *
- * Revision 2.1 1997/08/03 14:36:33 keil
- * Implement RESTART procedure
- *
- * Revision 2.0 1997/07/27 21:15:43 keil
- * New Callref based layer3
- *
- * Revision 1.17 1997/06/26 11:11:46 keil
- * SET_SKBFREE now on creation of a SKB
- *
- * Revision 1.15 1997/04/17 11:50:48 keil
- * pa->loc was undefined, if it was not send by the exchange
- *
- * Old log removed /KKe
- *
*/
#define __NO_VERSION__
@@ -107,7 +22,7 @@
#include <linux/config.h>
extern char *HiSax_getrev(const char *revision);
-const char *dss1_revision = "$Revision: 2.23 $";
+const char *dss1_revision = "$Revision: 2.30 $";
#define EXT_BEARER_CAPS 1
@@ -806,6 +721,9 @@
u_char *p, ie;
int l, newpos, oldpos;
int err_seq = 0, err_len = 0, err_compr = 0, err_ureg = 0;
+ u_char codeset = 0;
+ u_char old_codeset = 0;
+ u_char codelock = 1;
p = skb->data;
/* skip cr */
@@ -814,20 +732,34 @@
p += l;
mt = *p++;
oldpos = 0;
-/* shift codeset procedure not implemented in the moment */
while ((p - skb->data) < skb->len) {
- if ((newpos = ie_in_set(pc, *p, cl))) {
- if (newpos > 0) {
- if (newpos < oldpos)
- err_seq++;
+ if ((*p & 0xf0) == 0x90) { /* shift codeset */
+ old_codeset = codeset;
+ codeset = *p & 7;
+ if (*p & 0x08)
+ codelock = 0;
+ else
+ codelock = 1;
+ if (pc->debug & L3_DEB_CHECK)
+ l3_debug(pc->st, "check IE shift%scodeset %d->%d",
+ codelock ? " locking ": " ", old_codeset, codeset);
+ p++;
+ continue;
+ }
+ if (!codeset) { /* only codeset 0 */
+ if ((newpos = ie_in_set(pc, *p, cl))) {
+ if (newpos > 0) {
+ if (newpos < oldpos)
+ err_seq++;
+ else
+ oldpos = newpos;
+ }
+ } else {
+ if (ie_in_set(pc, *p, comp_required))
+ err_compr++;
else
- oldpos = newpos;
+ err_ureg++;
}
- } else {
- if (ie_in_set(pc, *p, comp_required))
- err_compr++;
- else
- err_ureg++;
}
ie = *p++;
if (ie & 0x80) {
@@ -837,12 +769,19 @@
p += l;
l += 2;
}
- if (l > getmax_ie_len(ie))
+ if (!codeset && (l > getmax_ie_len(ie)))
err_len++;
+ if (!codelock) {
+ if (pc->debug & L3_DEB_CHECK)
+ l3_debug(pc->st, "check IE shift back codeset %d->%d",
+ codeset, old_codeset);
+ codeset = old_codeset;
+ codelock = 1;
+ }
}
if (err_compr | err_ureg | err_len | err_seq) {
if (pc->debug & L3_DEB_CHECK)
- l3_debug(pc->st, "check_infoelements mt %x %d/%d/%d/%d",
+ l3_debug(pc->st, "check IE MT(%x) %d/%d/%d/%d",
mt, err_compr, err_ureg, err_len, err_seq);
if (err_compr)
return(ERR_IE_COMPREHENSION);
@@ -1044,7 +983,7 @@
#if EXT_BEARER_CAPS
-u_char *
+static u_char *
EncodeASyncParams(u_char * p, u_char si2)
{ // 7c 06 88 90 21 42 00 bb
@@ -1109,7 +1048,7 @@
return p + 3;
}
-u_char
+static u_char
EncodeSyncParams(u_char si2, u_char ai)
{
@@ -1313,39 +1252,31 @@
/*
* Set Bearer Capability, Map info from 1TR6-convention to EDSS1
*/
- if (!send_keypad)
- switch (pc->para.setup.si1) {
- case 1: /* Telephony */
- *p++ = 0x4; /* BC-IE-code */
- *p++ = 0x3; /* Length */
- *p++ = 0x90; /* Coding Std. CCITT, 3.1 kHz audio */
- *p++ = 0x90; /* Circuit-Mode 64kbps */
- *p++ = 0xa3; /* A-Law Audio */
- break;
- case 5: /* Datatransmission 64k, BTX */
- case 7: /* Datatransmission 64k */
- default:
- *p++ = 0x4; /* BC-IE-code */
- *p++ = 0x2; /* Length */
- *p++ = 0x88; /* Coding Std. CCITT, unrestr. dig. Inform. */
- *p++ = 0x90; /* Circuit-Mode 64kbps */
- break;
- }
- else { *p++ = 0x4; /* assumptions for bearer services with keypad */
- *p++ = 0x3;
- *p++ = 0x80;
- *p++ = 0x90;
- *p++ = 0xa3;
- *p++ = 0x18; /* no specific channel */
- *p++ = 0x01;
- *p++ = 0x83;
- *p++ = 0x2C; /* IE keypad */
+ switch (pc->para.setup.si1) {
+ case 1: /* Telephony */
+ *p++ = IE_BEARER;
+ *p++ = 0x3; /* Length */
+ *p++ = 0x90; /* Coding Std. CCITT, 3.1 kHz audio */
+ *p++ = 0x90; /* Circuit-Mode 64kbps */
+ *p++ = 0xa3; /* A-Law Audio */
+ break;
+ case 5: /* Datatransmission 64k, BTX */
+ case 7: /* Datatransmission 64k */
+ default:
+ *p++ = IE_BEARER;
+ *p++ = 0x2; /* Length */
+ *p++ = 0x88; /* Coding Std. CCITT, unrestr. dig. Inform. */
+ *p++ = 0x90; /* Circuit-Mode 64kbps */
+ break;
+ }
+
+ if (send_keypad) {
+ *p++ = IE_KEYPAD;
*p++ = strlen(teln);
while (*teln)
- *p++ = (*teln++) & 0x7F;
- }
+ *p++ = (*teln++) & 0x7F;
+ }
-
/*
* What about info2? Mapping to High-Layer-Compatibility?
*/
@@ -1394,7 +1325,7 @@
sp++;
}
if (*msn) {
- *p++ = 0x6c;
+ *p++ = IE_CALLING_PN;
*p++ = strlen(msn) + (screen ? 2 : 1);
/* Classify as AnyPref. */
if (screen) {
@@ -1407,7 +1338,7 @@
}
if (sub) {
*sub++ = '.';
- *p++ = 0x6d; /* Calling party subaddress */
+ *p++ = IE_CALLING_SUB;
*p++ = strlen(sub) + 2;
*p++ = 0x80; /* NSAP coded */
*p++ = 0x50; /* local IDI format */
@@ -1425,33 +1356,27 @@
}
if (!send_keypad) {
- *p++ = 0x70;
- *p++ = strlen(teln) + 1;
- /* Classify as AnyPref. */
- *p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
- while (*teln)
- *p++ = *teln++ & 0x7f;
-
- if (sub) {
- *sub++ = '.';
- *p++ = 0x71; /* Called party subaddress */
- *p++ = strlen(sub) + 2;
- *p++ = 0x80; /* NSAP coded */
- *p++ = 0x50; /* local IDI format */
- while (*sub)
- *p++ = *sub++ & 0x7f;
- }
+ *p++ = IE_CALLED_PN;
+ *p++ = strlen(teln) + 1;
+ /* Classify as AnyPref. */
+ *p++ = 0x81; /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
+ while (*teln)
+ *p++ = *teln++ & 0x7f;
+
+ if (sub) {
+ *sub++ = '.';
+ *p++ = IE_CALLED_SUB;
+ *p++ = strlen(sub) + 2;
+ *p++ = 0x80; /* NSAP coded */
+ *p++ = 0x50; /* local IDI format */
+ while (*sub)
+ *p++ = *sub++ & 0x7f;
+ }
}
#if EXT_BEARER_CAPS
- if (send_keypad) { /* special handling independant of si2 */
- *p++ = 0x7c;
- *p++ = 0x03;
- *p++ = 0x80;
- *p++ = 0x90;
- *p++ = 0xa3;
- } else if ((pc->para.setup.si2 >= 160) && (pc->para.setup.si2 <= 175)) { // sync. Bitratenadaption, V.110/X.30
+ if ((pc->para.setup.si2 >= 160) && (pc->para.setup.si2 <= 175)) { // sync. Bitratenadaption, V.110/X.30
- *p++ = 0x7c;
+ *p++ = IE_LLC;
*p++ = 0x04;
*p++ = 0x88;
*p++ = 0x90;
@@ -1459,7 +1384,7 @@
*p++ = EncodeSyncParams(pc->para.setup.si2 - 160, 0x80);
} else if ((pc->para.setup.si2 >= 176) && (pc->para.setup.si2 <= 191)) { // sync. Bitratenadaption, V.120
- *p++ = 0x7c;
+ *p++ = IE_LLC;
*p++ = 0x05;
*p++ = 0x88;
*p++ = 0x90;
@@ -1468,7 +1393,7 @@
*p++ = 0x82;
} else if (pc->para.setup.si2 >= 192) { // async. Bitratenadaption, V.110/X.30
- *p++ = 0x7c;
+ *p++ = IE_LLC;
*p++ = 0x06;
*p++ = 0x88;
*p++ = 0x90;
@@ -1477,18 +1402,18 @@
#ifndef CONFIG_HISAX_NO_LLC
} else {
switch (pc->para.setup.si1) {
- case 1: /* Telephony */
- *p++ = 0x7c; /* BC-IE-code */
- *p++ = 0x3; /* Length */
- *p++ = 0x90; /* Coding Std. CCITT, 3.1 kHz audio */
- *p++ = 0x90; /* Circuit-Mode 64kbps */
- *p++ = 0xa3; /* A-Law Audio */
+ case 1: /* Telephony */
+ *p++ = IE_LLC;
+ *p++ = 0x3; /* Length */
+ *p++ = 0x90; /* Coding Std. CCITT, 3.1 kHz audio */
+ *p++ = 0x90; /* Circuit-Mode 64kbps */
+ *p++ = 0xa3; /* A-Law Audio */
break;
- case 5: /* Datatransmission 64k, BTX */
- case 7: /* Datatransmission 64k */
+ case 5: /* Datatransmission 64k, BTX */
+ case 7: /* Datatransmission 64k */
default:
- *p++ = 0x7c; /* BC-IE-code */
- *p++ = 0x2; /* Length */
+ *p++ = IE_LLC;
+ *p++ = 0x2; /* Length */
*p++ = 0x88; /* Coding Std. CCITT, unrestr. dig. Inform. */
*p++ = 0x90; /* Circuit-Mode 64kbps */
break;
@@ -1988,6 +1913,16 @@
pc->st->l3.l3l4(pc->st, CC_PROCEED_SEND | INDICATION, pc);
}
+static void
+l3dss1_setup_ack_req(struct l3_process *pc, u_char pr,
+ void *arg)
+{
+ newl3state(pc, 25);
+ L3DelTimer(&pc->timer);
+ L3AddTimer(&pc->timer, T302, CC_T302);
+ l3dss1_message(pc, MT_SETUP_ACKNOWLEDGE);
+}
+
/********************************************/
/* deliver a incoming display message to HL */
/********************************************/
@@ -2025,7 +1960,7 @@
if (p[1] != 2) {
err = 1;
pc->para.cause = 100;
- } else if (p[2] & 0x60) {
+ } else if (!(p[2] & 0x70)) {
switch (p[2]) {
case 0x80:
case 0x81:
@@ -2129,9 +2064,22 @@
{
int ret;
struct sk_buff *skb = arg;
+ u_char *p;
+ char tmp[32];
ret = check_infoelements(pc, skb, ie_INFORMATION);
- l3dss1_std_ie_err(pc, ret);
+ if (ret)
+ l3dss1_std_ie_err(pc, ret);
+ if (pc->state == 25) { /* overlap receiving */
+ L3DelTimer(&pc->timer);
+ p = skb->data;
+ if ((p = findie(p, skb->len, 0x70, 0))) {
+ iecpy(tmp, p, 1);
+ strcat(pc->para.setup.eazmsn, tmp);
+ pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc);
+ }
+ L3AddTimer(&pc->timer, T302, CC_T302);
+ }
}
/******************************/
@@ -2357,6 +2305,16 @@
}
static void
+l3dss1_t302(struct l3_process *pc, u_char pr, void *arg)
+{
+ L3DelTimer(&pc->timer);
+ pc->para.loc = 0;
+ pc->para.cause = 28; /* invalid number */
+ l3dss1_disconnect_req(pc, pr, NULL);
+ pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
+}
+
+static void
l3dss1_t303(struct l3_process *pc, u_char pr, void *arg)
{
if (pc->N303 > 0) {
@@ -2375,6 +2333,7 @@
l3dss1_t304(struct l3_process *pc, u_char pr, void *arg)
{
L3DelTimer(&pc->timer);
+ pc->para.loc = 0;
pc->para.cause = 102;
l3dss1_disconnect_req(pc, pr, NULL);
pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
@@ -2414,6 +2373,7 @@
l3dss1_t310(struct l3_process *pc, u_char pr, void *arg)
{
L3DelTimer(&pc->timer);
+ pc->para.loc = 0;
pc->para.cause = 102;
l3dss1_disconnect_req(pc, pr, NULL);
pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
@@ -2423,6 +2383,7 @@
l3dss1_t313(struct l3_process *pc, u_char pr, void *arg)
{
L3DelTimer(&pc->timer);
+ pc->para.loc = 0;
pc->para.cause = 102;
l3dss1_disconnect_req(pc, pr, NULL);
pc->st->l3.l3l4(pc->st, CC_CONNECT_ERR, pc);
@@ -2812,32 +2773,36 @@
CC_SETUP | REQUEST, l3dss1_setup_req},
{SBIT(0),
CC_RESUME | REQUEST, l3dss1_resume_req},
- {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10),
+ {SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(25),
CC_DISCONNECT | REQUEST, l3dss1_disconnect_req},
{SBIT(12),
CC_RELEASE | REQUEST, l3dss1_release_req},
{ALL_STATES,
CC_RESTART | REQUEST, l3dss1_restart},
- {SBIT(6),
+ {SBIT(6) | SBIT(25),
CC_IGNORE | REQUEST, l3dss1_reset},
- {SBIT(6),
+ {SBIT(6) | SBIT(25),
CC_REJECT | REQUEST, l3dss1_reject_req},
- {SBIT(6),
+ {SBIT(6) | SBIT(25),
CC_PROCEED_SEND | REQUEST, l3dss1_proceed_req},
- {SBIT(6) | SBIT(9),
+ {SBIT(6),
+ CC_MORE_INFO | REQUEST, l3dss1_setup_ack_req},
+ {SBIT(25),
+ CC_MORE_INFO | REQUEST, l3dss1_dummy},
+ {SBIT(6) | SBIT(9) | SBIT(25),
CC_ALERTING | REQUEST, l3dss1_alert_req},
- {SBIT(6) | SBIT(7) | SBIT(9),
+ {SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
CC_SETUP | RESPONSE, l3dss1_setup_rsp},
{SBIT(10),
CC_SUSPEND | REQUEST, l3dss1_suspend_req},
- {SBIT(6),
- CC_PROCEED_SEND | REQUEST, l3dss1_proceed_req},
- {SBIT(7) | SBIT(9),
+ {SBIT(7) | SBIT(9) | SBIT(25),
CC_REDIR | REQUEST, l3dss1_redir_req},
{SBIT(6),
CC_REDIR | REQUEST, l3dss1_redir_req_early},
{SBIT(9) | SBIT(25),
CC_DISCONNECT | REQUEST, l3dss1_disconnect_req},
+ {SBIT(25),
+ CC_T302, l3dss1_t302},
{SBIT(1),
CC_T303, l3dss1_t303},
{SBIT(2),
@@ -3180,7 +3145,7 @@
if ((proc = dss1_new_l3_process(st, cr))) {
proc->chan = chan;
chan->proc = proc;
- proc->para.setup = chan->setup;
+ memcpy(&proc->para.setup, &chan->setup, sizeof(setup_parm));
proc->callref = cr;
}
} else {
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)