1/* $Id: l3dss1.c,v 2.32.2.3 2004/01/13 14:31:25 keil Exp $
2 *
3 * EURO/DSS1 D-channel protocol
4 *
5 * German 1TR6 D-channel protocol
6 *
7 * Author       Karsten Keil
8 *              based on the teles driver from Jan den Ouden
9 * Copyright    by Karsten Keil      <keil@isdn4linux.de>
10 *
11 * This software may be used and distributed according to the terms
12 * of the GNU General Public License, incorporated herein by reference.
13 *
14 * For changes and modifications please read
15 * Documentation/isdn/HiSax.cert
16 *
17 * Thanks to    Jan den Ouden
18 *              Fritz Elfert
19 *
20 */
21
22#include "hisax.h"
23#include "isdnl3.h"
24#include "l3dss1.h"
25#include <linux/ctype.h>
26#include <linux/slab.h>
27
28extern char *HiSax_getrev(const char *revision);
29static const char *dss1_revision = "$Revision: 2.32.2.3 $";
30
31#define EXT_BEARER_CAPS 1
32
33#define	MsgHead(ptr, cref, mty)			\
34	*ptr++ = 0x8;				\
35	if (cref == -1) {			\
36		*ptr++ = 0x0;			\
37	} else {				\
38		*ptr++ = 0x1;			\
39		*ptr++ = cref^0x80;		\
40	}					\
41	*ptr++ = mty
42
43
44/**********************************************/
45/* get a new invoke id for remote operations. */
46/* Only a return value != 0 is valid          */
47/**********************************************/
48static unsigned char new_invoke_id(struct PStack *p)
49{
50	unsigned char retval;
51	int i;
52
53	i = 32; /* maximum search depth */
54
55	retval = p->prot.dss1.last_invoke_id + 1; /* try new id */
56	while ((i) && (p->prot.dss1.invoke_used[retval >> 3] == 0xFF)) {
57		p->prot.dss1.last_invoke_id = (retval & 0xF8) + 8;
58		i--;
59	}
60	if (i) {
61		while (p->prot.dss1.invoke_used[retval >> 3] & (1 << (retval & 7)))
62			retval++;
63	} else
64		retval = 0;
65	p->prot.dss1.last_invoke_id = retval;
66	p->prot.dss1.invoke_used[retval >> 3] |= (1 << (retval & 7));
67	return (retval);
68} /* new_invoke_id */
69
70/*************************/
71/* free a used invoke id */
72/*************************/
73static void free_invoke_id(struct PStack *p, unsigned char id)
74{
75
76	if (!id) return; /* 0 = invalid value */
77
78	p->prot.dss1.invoke_used[id >> 3] &= ~(1 << (id & 7));
79} /* free_invoke_id */
80
81
82/**********************************************************/
83/* create a new l3 process and fill in dss1 specific data */
84/**********************************************************/
85static struct l3_process
86*dss1_new_l3_process(struct PStack *st, int cr)
87{  struct l3_process *proc;
88
89	if (!(proc = new_l3_process(st, cr)))
90		return (NULL);
91
92	proc->prot.dss1.invoke_id = 0;
93	proc->prot.dss1.remote_operation = 0;
94	proc->prot.dss1.uus1_data[0] = '\0';
95
96	return (proc);
97} /* dss1_new_l3_process */
98
99/************************************************/
100/* free a l3 process and all dss1 specific data */
101/************************************************/
102static void
103dss1_release_l3_process(struct l3_process *p)
104{
105	free_invoke_id(p->st, p->prot.dss1.invoke_id);
106	release_l3_process(p);
107} /* dss1_release_l3_process */
108
109/********************************************************/
110/* search a process with invoke id id and dummy callref */
111/********************************************************/
112static struct l3_process *
113l3dss1_search_dummy_proc(struct PStack *st, int id)
114{ struct l3_process *pc = st->l3.proc; /* start of processes */
115
116	if (!id) return (NULL);
117
118	while (pc)
119	{ if ((pc->callref == -1) && (pc->prot.dss1.invoke_id == id))
120			return (pc);
121		pc = pc->next;
122	}
123	return (NULL);
124} /* l3dss1_search_dummy_proc */
125
126/*******************************************************************/
127/* called when a facility message with a dummy callref is received */
128/* and a return result is delivered. id specifies the invoke id.   */
129/*******************************************************************/
130static void
131l3dss1_dummy_return_result(struct PStack *st, int id, u_char *p, u_char nlen)
132{ isdn_ctrl ic;
133	struct IsdnCardState *cs;
134	struct l3_process *pc = NULL;
135
136	if ((pc = l3dss1_search_dummy_proc(st, id)))
137	{ L3DelTimer(&pc->timer); /* remove timer */
138
139		cs = pc->st->l1.hardware;
140		ic.driver = cs->myid;
141		ic.command = ISDN_STAT_PROT;
142		ic.arg = DSS1_STAT_INVOKE_RES;
143		ic.parm.dss1_io.hl_id = pc->prot.dss1.invoke_id;
144		ic.parm.dss1_io.ll_id = pc->prot.dss1.ll_id;
145		ic.parm.dss1_io.proc = pc->prot.dss1.proc;
146		ic.parm.dss1_io.timeout = 0;
147		ic.parm.dss1_io.datalen = nlen;
148		ic.parm.dss1_io.data = p;
149		free_invoke_id(pc->st, pc->prot.dss1.invoke_id);
150		pc->prot.dss1.invoke_id = 0; /* reset id */
151
152		cs->iif.statcallb(&ic);
153		dss1_release_l3_process(pc);
154	}
155	else
156		l3_debug(st, "dummy return result id=0x%x result len=%d", id, nlen);
157} /* l3dss1_dummy_return_result */
158
159/*******************************************************************/
160/* called when a facility message with a dummy callref is received */
161/* and a return error is delivered. id specifies the invoke id.    */
162/*******************************************************************/
163static void
164l3dss1_dummy_error_return(struct PStack *st, int id, ulong error)
165{ isdn_ctrl ic;
166	struct IsdnCardState *cs;
167	struct l3_process *pc = NULL;
168
169	if ((pc = l3dss1_search_dummy_proc(st, id)))
170	{ L3DelTimer(&pc->timer); /* remove timer */
171
172		cs = pc->st->l1.hardware;
173		ic.driver = cs->myid;
174		ic.command = ISDN_STAT_PROT;
175		ic.arg = DSS1_STAT_INVOKE_ERR;
176		ic.parm.dss1_io.hl_id = pc->prot.dss1.invoke_id;
177		ic.parm.dss1_io.ll_id = pc->prot.dss1.ll_id;
178		ic.parm.dss1_io.proc = pc->prot.dss1.proc;
179		ic.parm.dss1_io.timeout = error;
180		ic.parm.dss1_io.datalen = 0;
181		ic.parm.dss1_io.data = NULL;
182		free_invoke_id(pc->st, pc->prot.dss1.invoke_id);
183		pc->prot.dss1.invoke_id = 0; /* reset id */
184
185		cs->iif.statcallb(&ic);
186		dss1_release_l3_process(pc);
187	}
188	else
189		l3_debug(st, "dummy return error id=0x%x error=0x%lx", id, error);
190} /* l3dss1_error_return */
191
192/*******************************************************************/
193/* called when a facility message with a dummy callref is received */
194/* and a invoke is delivered. id specifies the invoke id.          */
195/*******************************************************************/
196static void
197l3dss1_dummy_invoke(struct PStack *st, int cr, int id,
198		    int ident, u_char *p, u_char nlen)
199{ isdn_ctrl ic;
200	struct IsdnCardState *cs;
201
202	l3_debug(st, "dummy invoke %s id=0x%x ident=0x%x datalen=%d",
203		 (cr == -1) ? "local" : "broadcast", id, ident, nlen);
204	if (cr >= -1) return; /* ignore local data */
205
206	cs = st->l1.hardware;
207	ic.driver = cs->myid;
208	ic.command = ISDN_STAT_PROT;
209	ic.arg = DSS1_STAT_INVOKE_BRD;
210	ic.parm.dss1_io.hl_id = id;
211	ic.parm.dss1_io.ll_id = 0;
212	ic.parm.dss1_io.proc = ident;
213	ic.parm.dss1_io.timeout = 0;
214	ic.parm.dss1_io.datalen = nlen;
215	ic.parm.dss1_io.data = p;
216
217	cs->iif.statcallb(&ic);
218} /* l3dss1_dummy_invoke */
219
220static void
221l3dss1_parse_facility(struct PStack *st, struct l3_process *pc,
222		      int cr, u_char *p)
223{
224	int qd_len = 0;
225	unsigned char nlen = 0, ilen, cp_tag;
226	int ident, id;
227	ulong err_ret;
228
229	if (pc)
230		st = pc->st; /* valid Stack */
231	else
232		if ((!st) || (cr >= 0)) return; /* neither pc nor st specified */
233
234	p++;
235	qd_len = *p++;
236	if (qd_len == 0) {
237		l3_debug(st, "qd_len == 0");
238		return;
239	}
240	if ((*p & 0x1F) != 0x11) {	/* Service discriminator, supplementary service */
241		l3_debug(st, "supplementary service != 0x11");
242		return;
243	}
244	while (qd_len > 0 && !(*p & 0x80)) {	/* extension ? */
245		p++;
246		qd_len--;
247	}
248	if (qd_len < 2) {
249		l3_debug(st, "qd_len < 2");
250		return;
251	}
252	p++;
253	qd_len--;
254	if ((*p & 0xE0) != 0xA0) {	/* class and form */
255		l3_debug(st, "class and form != 0xA0");
256		return;
257	}
258
259	cp_tag = *p & 0x1F; /* remember tag value */
260
261	p++;
262	qd_len--;
263	if (qd_len < 1)
264	{ l3_debug(st, "qd_len < 1");
265		return;
266	}
267	if (*p & 0x80)
268	{ /* length format indefinite or limited */
269		nlen = *p++ & 0x7F; /* number of len bytes or indefinite */
270		if ((qd_len-- < ((!nlen) ? 3 : (1 + nlen))) ||
271		    (nlen > 1))
272		{ l3_debug(st, "length format error or not implemented");
273			return;
274		}
275		if (nlen == 1)
276		{ nlen = *p++; /* complete length */
277			qd_len--;
278		}
279		else
280		{ qd_len -= 2; /* trailing null bytes */
281			if ((*(p + qd_len)) || (*(p + qd_len + 1)))
282			{ l3_debug(st, "length format indefinite error");
283				return;
284			}
285			nlen = qd_len;
286		}
287	}
288	else
289	{ nlen = *p++;
290		qd_len--;
291	}
292	if (qd_len < nlen)
293	{ l3_debug(st, "qd_len < nlen");
294		return;
295	}
296	qd_len -= nlen;
297
298	if (nlen < 2)
299	{ l3_debug(st, "nlen < 2");
300		return;
301	}
302	if (*p != 0x02)
303	{  /* invoke identifier tag */
304		l3_debug(st, "invoke identifier tag !=0x02");
305		return;
306	}
307	p++;
308	nlen--;
309	if (*p & 0x80)
310	{ /* length format */
311		l3_debug(st, "invoke id length format 2");
312		return;
313	}
314	ilen = *p++;
315	nlen--;
316	if (ilen > nlen || ilen == 0)
317	{ l3_debug(st, "ilen > nlen || ilen == 0");
318		return;
319	}
320	nlen -= ilen;
321	id = 0;
322	while (ilen > 0)
323	{ id = (id << 8) | (*p++ & 0xFF);	/* invoke identifier */
324		ilen--;
325	}
326
327	switch (cp_tag) {	/* component tag */
328	case 1:	/* invoke */
329		if (nlen < 2) {
330			l3_debug(st, "nlen < 2 22");
331			return;
332		}
333		if (*p != 0x02) {	/* operation value */
334			l3_debug(st, "operation value !=0x02");
335			return;
336		}
337		p++;
338		nlen--;
339		ilen = *p++;
340		nlen--;
341		if (ilen > nlen || ilen == 0) {
342			l3_debug(st, "ilen > nlen || ilen == 0 22");
343			return;
344		}
345		nlen -= ilen;
346		ident = 0;
347		while (ilen > 0) {
348			ident = (ident << 8) | (*p++ & 0xFF);
349			ilen--;
350		}
351
352		if (!pc)
353		{ l3dss1_dummy_invoke(st, cr, id, ident, p, nlen);
354			return;
355		}
356#ifdef CONFIG_DE_AOC
357		{
358
359#define FOO1(s, a, b)							\
360			while (nlen > 1) {				\
361				int ilen = p[1];			\
362				if (nlen < ilen + 2) {			\
363					l3_debug(st, "FOO1  nlen < ilen+2"); \
364					return;				\
365				}					\
366				nlen -= ilen + 2;			\
367				if ((*p & 0xFF) == (a)) {		\
368					int nlen = ilen;		\
369					p += 2;				\
370					b;				\
371				} else {				\
372					p += ilen + 2;			\
373				}					\
374			}
375
376			switch (ident) {
377			case 0x22:	/* during */
378				FOO1("1A", 0x30, FOO1("1C", 0xA1, FOO1("1D", 0x30, FOO1("1E", 0x02, ( {
379										ident = 0;
380										nlen = (nlen) ? nlen : 0; /* Make gcc happy */
381										while (ilen > 0) {
382											ident = (ident << 8) | *p++;
383											ilen--;
384										}
385										if (ident > pc->para.chargeinfo) {
386											pc->para.chargeinfo = ident;
387											st->l3.l3l4(st, CC_CHARGE | INDICATION, pc);
388										}
389										if (st->l3.debug & L3_DEB_CHARGE) {
390											if (*(p + 2) == 0) {
391												l3_debug(st, "charging info during %d", pc->para.chargeinfo);
392											}
393											else {
394												l3_debug(st, "charging info final %d", pc->para.chargeinfo);
395											}
396										}
397									}
398									)))))
399					break;
400			case 0x24:	/* final */
401				FOO1("2A", 0x30, FOO1("2B", 0x30, FOO1("2C", 0xA1, FOO1("2D", 0x30, FOO1("2E", 0x02, ( {
402											ident = 0;
403											nlen = (nlen) ? nlen : 0; /* Make gcc happy */
404											while (ilen > 0) {
405												ident = (ident << 8) | *p++;
406												ilen--;
407											}
408											if (ident > pc->para.chargeinfo) {
409												pc->para.chargeinfo = ident;
410												st->l3.l3l4(st, CC_CHARGE | INDICATION, pc);
411											}
412											if (st->l3.debug & L3_DEB_CHARGE) {
413												l3_debug(st, "charging info final %d", pc->para.chargeinfo);
414											}
415										}
416										))))))
417					break;
418			default:
419				l3_debug(st, "invoke break invalid ident %02x", ident);
420				break;
421			}
422#undef FOO1
423
424		}
425#else  /* not CONFIG_DE_AOC */
426		l3_debug(st, "invoke break");
427#endif /* not CONFIG_DE_AOC */
428		break;
429	case 2:	/* return result */
430		/* if no process available handle separately */
431		if (!pc)
432		{ if (cr == -1)
433				l3dss1_dummy_return_result(st, id, p, nlen);
434			return;
435		}
436		if ((pc->prot.dss1.invoke_id) && (pc->prot.dss1.invoke_id == id))
437		{ /* Diversion successful */
438			free_invoke_id(st, pc->prot.dss1.invoke_id);
439			pc->prot.dss1.remote_result = 0; /* success */
440			pc->prot.dss1.invoke_id = 0;
441			pc->redir_result = pc->prot.dss1.remote_result;
442			st->l3.l3l4(st, CC_REDIR | INDICATION, pc);                                  } /* Diversion successful */
443		else
444			l3_debug(st, "return error unknown identifier");
445		break;
446	case 3:	/* return error */
447		err_ret = 0;
448		if (nlen < 2)
449		{ l3_debug(st, "return error nlen < 2");
450			return;
451		}
452		if (*p != 0x02)
453		{ /* result tag */
454			l3_debug(st, "invoke error tag !=0x02");
455			return;
456		}
457		p++;
458		nlen--;
459		if (*p > 4)
460		{ /* length format */
461			l3_debug(st, "invoke return errlen > 4 ");
462			return;
463		}
464		ilen = *p++;
465		nlen--;
466		if (ilen > nlen || ilen == 0)
467		{ l3_debug(st, "error return ilen > nlen || ilen == 0");
468			return;
469		}
470		nlen -= ilen;
471		while (ilen > 0)
472		{ err_ret = (err_ret << 8) | (*p++ & 0xFF);	/* error value */
473			ilen--;
474		}
475		/* if no process available handle separately */
476		if (!pc)
477		{ if (cr == -1)
478				l3dss1_dummy_error_return(st, id, err_ret);
479			return;
480		}
481		if ((pc->prot.dss1.invoke_id) && (pc->prot.dss1.invoke_id == id))
482		{ /* Deflection error */
483			free_invoke_id(st, pc->prot.dss1.invoke_id);
484			pc->prot.dss1.remote_result = err_ret; /* result */
485			pc->prot.dss1.invoke_id = 0;
486			pc->redir_result = pc->prot.dss1.remote_result;
487			st->l3.l3l4(st, CC_REDIR | INDICATION, pc);
488		} /* Deflection error */
489		else
490			l3_debug(st, "return result unknown identifier");
491		break;
492	default:
493		l3_debug(st, "facility default break tag=0x%02x", cp_tag);
494		break;
495	}
496}
497
498static void
499l3dss1_message(struct l3_process *pc, u_char mt)
500{
501	struct sk_buff *skb;
502	u_char *p;
503
504	if (!(skb = l3_alloc_skb(4)))
505		return;
506	p = skb_put(skb, 4);
507	MsgHead(p, pc->callref, mt);
508	l3_msg(pc->st, DL_DATA | REQUEST, skb);
509}
510
511static void
512l3dss1_message_cause(struct l3_process *pc, u_char mt, u_char cause)
513{
514	struct sk_buff *skb;
515	u_char tmp[16];
516	u_char *p = tmp;
517	int l;
518
519	MsgHead(p, pc->callref, mt);
520	*p++ = IE_CAUSE;
521	*p++ = 0x2;
522	*p++ = 0x80;
523	*p++ = cause | 0x80;
524
525	l = p - tmp;
526	if (!(skb = l3_alloc_skb(l)))
527		return;
528	memcpy(skb_put(skb, l), tmp, l);
529	l3_msg(pc->st, DL_DATA | REQUEST, skb);
530}
531
532static void
533l3dss1_status_send(struct l3_process *pc, u_char pr, void *arg)
534{
535	u_char tmp[16];
536	u_char *p = tmp;
537	int l;
538	struct sk_buff *skb;
539
540	MsgHead(p, pc->callref, MT_STATUS);
541
542	*p++ = IE_CAUSE;
543	*p++ = 0x2;
544	*p++ = 0x80;
545	*p++ = pc->para.cause | 0x80;
546
547	*p++ = IE_CALL_STATE;
548	*p++ = 0x1;
549	*p++ = pc->state & 0x3f;
550
551	l = p - tmp;
552	if (!(skb = l3_alloc_skb(l)))
553		return;
554	memcpy(skb_put(skb, l), tmp, l);
555	l3_msg(pc->st, DL_DATA | REQUEST, skb);
556}
557
558static void
559l3dss1_msg_without_setup(struct l3_process *pc, u_char pr, void *arg)
560{
561	/* This routine is called if here was no SETUP made (checks in dss1up and in
562	 * l3dss1_setup) and a RELEASE_COMPLETE have to be sent with an error code
563	 * MT_STATUS_ENQUIRE in the NULL state is handled too
564	 */
565	u_char tmp[16];
566	u_char *p = tmp;
567	int l;
568	struct sk_buff *skb;
569
570	switch (pc->para.cause) {
571	case 81:	/* invalid callreference */
572	case 88:	/* incomp destination */
573	case 96:	/* mandory IE missing */
574	case 100:       /* invalid IE contents */
575	case 101:	/* incompatible Callstate */
576		MsgHead(p, pc->callref, MT_RELEASE_COMPLETE);
577		*p++ = IE_CAUSE;
578		*p++ = 0x2;
579		*p++ = 0x80;
580		*p++ = pc->para.cause | 0x80;
581		break;
582	default:
583		printk(KERN_ERR "HiSax l3dss1_msg_without_setup wrong cause %d\n",
584		       pc->para.cause);
585		return;
586	}
587	l = p - tmp;
588	if (!(skb = l3_alloc_skb(l)))
589		return;
590	memcpy(skb_put(skb, l), tmp, l);
591	l3_msg(pc->st, DL_DATA | REQUEST, skb);
592	dss1_release_l3_process(pc);
593}
594
595static int ie_ALERTING[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1,
596			    IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, IE_HLC,
597			    IE_USER_USER, -1};
598static int ie_CALL_PROCEEDING[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1,
599				   IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_HLC, -1};
600static int ie_CONNECT[] = {IE_BEARER, IE_CHANNEL_ID | IE_MANDATORY_1,
601			   IE_FACILITY, IE_PROGRESS, IE_DISPLAY, IE_DATE, IE_SIGNAL,
602			   IE_CONNECT_PN, IE_CONNECT_SUB, IE_LLC, IE_HLC, IE_USER_USER, -1};
603static int ie_CONNECT_ACKNOWLEDGE[] = {IE_CHANNEL_ID, IE_DISPLAY, IE_SIGNAL, -1};
604static int ie_DISCONNECT[] = {IE_CAUSE | IE_MANDATORY, IE_FACILITY,
605			      IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1};
606static int ie_INFORMATION[] = {IE_COMPLETE, IE_DISPLAY, IE_KEYPAD, IE_SIGNAL,
607			       IE_CALLED_PN, -1};
608static int ie_NOTIFY[] = {IE_BEARER, IE_NOTIFY | IE_MANDATORY, IE_DISPLAY, -1};
609static int ie_PROGRESS[] = {IE_BEARER, IE_CAUSE, IE_FACILITY, IE_PROGRESS |
610			    IE_MANDATORY, IE_DISPLAY, IE_HLC, IE_USER_USER, -1};
611static int ie_RELEASE[] = {IE_CAUSE | IE_MANDATORY_1, IE_FACILITY, IE_DISPLAY,
612			   IE_SIGNAL, IE_USER_USER, -1};
613/* a RELEASE_COMPLETE with errors don't require special actions
614   static int ie_RELEASE_COMPLETE[] = {IE_CAUSE | IE_MANDATORY_1, IE_DISPLAY, IE_SIGNAL, IE_USER_USER, -1};
615*/
616static int ie_RESUME_ACKNOWLEDGE[] = {IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY,
617				      IE_DISPLAY, -1};
618static int ie_RESUME_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};
619static int ie_SETUP[] = {IE_COMPLETE, IE_BEARER  | IE_MANDATORY,
620			 IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY, IE_PROGRESS,
621			 IE_NET_FAC, IE_DISPLAY, IE_KEYPAD, IE_SIGNAL, IE_CALLING_PN,
622			 IE_CALLING_SUB, IE_CALLED_PN, IE_CALLED_SUB, IE_REDIR_NR,
623			 IE_LLC, IE_HLC, IE_USER_USER, -1};
624static int ie_SETUP_ACKNOWLEDGE[] = {IE_CHANNEL_ID | IE_MANDATORY, IE_FACILITY,
625				     IE_PROGRESS, IE_DISPLAY, IE_SIGNAL, -1};
626static int ie_STATUS[] = {IE_CAUSE | IE_MANDATORY, IE_CALL_STATE |
627			  IE_MANDATORY, IE_DISPLAY, -1};
628static int ie_STATUS_ENQUIRY[] = {IE_DISPLAY, -1};
629static int ie_SUSPEND_ACKNOWLEDGE[] = {IE_DISPLAY, IE_FACILITY, -1};
630static int ie_SUSPEND_REJECT[] = {IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};
631/* not used
632 * static int ie_CONGESTION_CONTROL[] = {IE_CONGESTION | IE_MANDATORY,
633 *		IE_CAUSE | IE_MANDATORY, IE_DISPLAY, -1};
634 * static int ie_USER_INFORMATION[] = {IE_MORE_DATA, IE_USER_USER | IE_MANDATORY, -1};
635 * static int ie_RESTART[] = {IE_CHANNEL_ID, IE_DISPLAY, IE_RESTART_IND |
636 *		IE_MANDATORY, -1};
637 */
638static int ie_FACILITY[] = {IE_FACILITY | IE_MANDATORY, IE_DISPLAY, -1};
639static int comp_required[] = {1, 2, 3, 5, 6, 7, 9, 10, 11, 14, 15, -1};
640static int l3_valid_states[] = {0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 15, 17, 19, 25, -1};
641
642struct ie_len {
643	int ie;
644	int len;
645};
646
647static
648struct ie_len max_ie_len[] = {
649	{IE_SEGMENT, 4},
650	{IE_BEARER, 12},
651	{IE_CAUSE, 32},
652	{IE_CALL_ID, 10},
653	{IE_CALL_STATE, 3},
654	{IE_CHANNEL_ID,	34},
655	{IE_FACILITY, 255},
656	{IE_PROGRESS, 4},
657	{IE_NET_FAC, 255},
658	{IE_NOTIFY, 3},
659	{IE_DISPLAY, 82},
660	{IE_DATE, 8},
661	{IE_KEYPAD, 34},
662	{IE_SIGNAL, 3},
663	{IE_INFORATE, 6},
664	{IE_E2E_TDELAY, 11},
665	{IE_TDELAY_SEL, 5},
666	{IE_PACK_BINPARA, 3},
667	{IE_PACK_WINSIZE, 4},
668	{IE_PACK_SIZE, 4},
669	{IE_CUG, 7},
670	{IE_REV_CHARGE, 3},
671	{IE_CALLING_PN, 24},
672	{IE_CALLING_SUB, 23},
673	{IE_CALLED_PN, 24},
674	{IE_CALLED_SUB, 23},
675	{IE_REDIR_NR, 255},
676	{IE_TRANS_SEL, 255},
677	{IE_RESTART_IND, 3},
678	{IE_LLC, 18},
679	{IE_HLC, 5},
680	{IE_USER_USER, 131},
681	{-1, 0},
682};
683
684static int
685getmax_ie_len(u_char ie) {
686	int i = 0;
687	while (max_ie_len[i].ie != -1) {
688		if (max_ie_len[i].ie == ie)
689			return (max_ie_len[i].len);
690		i++;
691	}
692	return (255);
693}
694
695static int
696ie_in_set(struct l3_process *pc, u_char ie, int *checklist) {
697	int ret = 1;
698
699	while (*checklist != -1) {
700		if ((*checklist & 0xff) == ie) {
701			if (ie & 0x80)
702				return (-ret);
703			else
704				return (ret);
705		}
706		ret++;
707		checklist++;
708	}
709	return (0);
710}
711
712static int
713check_infoelements(struct l3_process *pc, struct sk_buff *skb, int *checklist)
714{
715	int *cl = checklist;
716	u_char mt;
717	u_char *p, ie;
718	int l, newpos, oldpos;
719	int err_seq = 0, err_len = 0, err_compr = 0, err_ureg = 0;
720	u_char codeset = 0;
721	u_char old_codeset = 0;
722	u_char codelock = 1;
723
724	p = skb->data;
725	/* skip cr */
726	p++;
727	l = (*p++) & 0xf;
728	p += l;
729	mt = *p++;
730	oldpos = 0;
731	while ((p - skb->data) < skb->len) {
732		if ((*p & 0xf0) == 0x90) { /* shift codeset */
733			old_codeset = codeset;
734			codeset = *p & 7;
735			if (*p & 0x08)
736				codelock = 0;
737			else
738				codelock = 1;
739			if (pc->debug & L3_DEB_CHECK)
740				l3_debug(pc->st, "check IE shift%scodeset %d->%d",
741					 codelock ? " locking " : " ", old_codeset, codeset);
742			p++;
743			continue;
744		}
745		if (!codeset) { /* only codeset 0 */
746			if ((newpos = ie_in_set(pc, *p, cl))) {
747				if (newpos > 0) {
748					if (newpos < oldpos)
749						err_seq++;
750					else
751						oldpos = newpos;
752				}
753			} else {
754				if (ie_in_set(pc, *p, comp_required))
755					err_compr++;
756				else
757					err_ureg++;
758			}
759		}
760		ie = *p++;
761		if (ie & 0x80) {
762			l = 1;
763		} else {
764			l = *p++;
765			p += l;
766			l += 2;
767		}
768		if (!codeset && (l > getmax_ie_len(ie)))
769			err_len++;
770		if (!codelock) {
771			if (pc->debug & L3_DEB_CHECK)
772				l3_debug(pc->st, "check IE shift back codeset %d->%d",
773					 codeset, old_codeset);
774			codeset = old_codeset;
775			codelock = 1;
776		}
777	}
778	if (err_compr | err_ureg | err_len | err_seq) {
779		if (pc->debug & L3_DEB_CHECK)
780			l3_debug(pc->st, "check IE MT(%x) %d/%d/%d/%d",
781				 mt, err_compr, err_ureg, err_len, err_seq);
782		if (err_compr)
783			return (ERR_IE_COMPREHENSION);
784		if (err_ureg)
785			return (ERR_IE_UNRECOGNIZED);
786		if (err_len)
787			return (ERR_IE_LENGTH);
788		if (err_seq)
789			return (ERR_IE_SEQUENCE);
790	}
791	return (0);
792}
793
794/* verify if a message type exists and contain no IE error */
795static int
796l3dss1_check_messagetype_validity(struct l3_process *pc, int mt, void *arg)
797{
798	switch (mt) {
799	case MT_ALERTING:
800	case MT_CALL_PROCEEDING:
801	case MT_CONNECT:
802	case MT_CONNECT_ACKNOWLEDGE:
803	case MT_DISCONNECT:
804	case MT_INFORMATION:
805	case MT_FACILITY:
806	case MT_NOTIFY:
807	case MT_PROGRESS:
808	case MT_RELEASE:
809	case MT_RELEASE_COMPLETE:
810	case MT_SETUP:
811	case MT_SETUP_ACKNOWLEDGE:
812	case MT_RESUME_ACKNOWLEDGE:
813	case MT_RESUME_REJECT:
814	case MT_SUSPEND_ACKNOWLEDGE:
815	case MT_SUSPEND_REJECT:
816	case MT_USER_INFORMATION:
817	case MT_RESTART:
818	case MT_RESTART_ACKNOWLEDGE:
819	case MT_CONGESTION_CONTROL:
820	case MT_STATUS:
821	case MT_STATUS_ENQUIRY:
822		if (pc->debug & L3_DEB_CHECK)
823			l3_debug(pc->st, "l3dss1_check_messagetype_validity mt(%x) OK", mt);
824		break;
825	case MT_RESUME: /* RESUME only in user->net */
826	case MT_SUSPEND: /* SUSPEND only in user->net */
827	default:
828		if (pc->debug & (L3_DEB_CHECK | L3_DEB_WARN))
829			l3_debug(pc->st, "l3dss1_check_messagetype_validity mt(%x) fail", mt);
830		pc->para.cause = 97;
831		l3dss1_status_send(pc, 0, NULL);
832		return (1);
833	}
834	return (0);
835}
836
837static void
838l3dss1_std_ie_err(struct l3_process *pc, int ret) {
839
840	if (pc->debug & L3_DEB_CHECK)
841		l3_debug(pc->st, "check_infoelements ret %d", ret);
842	switch (ret) {
843	case 0:
844		break;
845	case ERR_IE_COMPREHENSION:
846		pc->para.cause = 96;
847		l3dss1_status_send(pc, 0, NULL);
848		break;
849	case ERR_IE_UNRECOGNIZED:
850		pc->para.cause = 99;
851		l3dss1_status_send(pc, 0, NULL);
852		break;
853	case ERR_IE_LENGTH:
854		pc->para.cause = 100;
855		l3dss1_status_send(pc, 0, NULL);
856		break;
857	case ERR_IE_SEQUENCE:
858	default:
859		break;
860	}
861}
862
863static int
864l3dss1_get_channel_id(struct l3_process *pc, struct sk_buff *skb) {
865	u_char *p;
866
867	p = skb->data;
868	if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) {
869		p++;
870		if (*p != 1) { /* len for BRI = 1 */
871			if (pc->debug & L3_DEB_WARN)
872				l3_debug(pc->st, "wrong chid len %d", *p);
873			return (-2);
874		}
875		p++;
876		if (*p & 0x60) { /* only base rate interface */
877			if (pc->debug & L3_DEB_WARN)
878				l3_debug(pc->st, "wrong chid %x", *p);
879			return (-3);
880		}
881		return (*p & 0x3);
882	} else
883		return (-1);
884}
885
886static int
887l3dss1_get_cause(struct l3_process *pc, struct sk_buff *skb) {
888	u_char l, i = 0;
889	u_char *p;
890
891	p = skb->data;
892	pc->para.cause = 31;
893	pc->para.loc = 0;
894	if ((p = findie(p, skb->len, IE_CAUSE, 0))) {
895		p++;
896		l = *p++;
897		if (l > 30)
898			return (1);
899		if (l) {
900			pc->para.loc = *p++;
901			l--;
902		} else {
903			return (2);
904		}
905		if (l && !(pc->para.loc & 0x80)) {
906			l--;
907			p++; /* skip recommendation */
908		}
909		if (l) {
910			pc->para.cause = *p++;
911			l--;
912			if (!(pc->para.cause & 0x80))
913				return (3);
914		} else
915			return (4);
916		while (l && (i < 6)) {
917			pc->para.diag[i++] = *p++;
918			l--;
919		}
920	} else
921		return (-1);
922	return (0);
923}
924
925static void
926l3dss1_msg_with_uus(struct l3_process *pc, u_char cmd)
927{
928	struct sk_buff *skb;
929	u_char tmp[16 + 40];
930	u_char *p = tmp;
931	int l;
932
933	MsgHead(p, pc->callref, cmd);
934
935	if (pc->prot.dss1.uus1_data[0])
936	{ *p++ = IE_USER_USER; /* UUS info element */
937		*p++ = strlen(pc->prot.dss1.uus1_data) + 1;
938		*p++ = 0x04; /* IA5 chars */
939		strcpy(p, pc->prot.dss1.uus1_data);
940		p += strlen(pc->prot.dss1.uus1_data);
941		pc->prot.dss1.uus1_data[0] = '\0';
942	}
943
944	l = p - tmp;
945	if (!(skb = l3_alloc_skb(l)))
946		return;
947	memcpy(skb_put(skb, l), tmp, l);
948	l3_msg(pc->st, DL_DATA | REQUEST, skb);
949} /* l3dss1_msg_with_uus */
950
951static void
952l3dss1_release_req(struct l3_process *pc, u_char pr, void *arg)
953{
954	StopAllL3Timer(pc);
955	newl3state(pc, 19);
956	if (!pc->prot.dss1.uus1_data[0])
957		l3dss1_message(pc, MT_RELEASE);
958	else
959		l3dss1_msg_with_uus(pc, MT_RELEASE);
960	L3AddTimer(&pc->timer, T308, CC_T308_1);
961}
962
963static void
964l3dss1_release_cmpl(struct l3_process *pc, u_char pr, void *arg)
965{
966	struct sk_buff *skb = arg;
967	int ret;
968
969	if ((ret = l3dss1_get_cause(pc, skb)) > 0) {
970		if (pc->debug & L3_DEB_WARN)
971			l3_debug(pc->st, "RELCMPL get_cause ret(%d)", ret);
972	} else if (ret < 0)
973		pc->para.cause = NO_CAUSE;
974	StopAllL3Timer(pc);
975	newl3state(pc, 0);
976	pc->st->l3.l3l4(pc->st, CC_RELEASE | CONFIRM, pc);
977	dss1_release_l3_process(pc);
978}
979
980#ifdef EXT_BEARER_CAPS
981
982static u_char *
983EncodeASyncParams(u_char *p, u_char si2)
984{				// 7c 06 88  90 21 42 00 bb
985
986	p[0] = 0;
987	p[1] = 0x40;		// Intermediate rate: 16 kbit/s jj 2000.02.19
988	p[2] = 0x80;
989	if (si2 & 32)		// 7 data bits
990
991		p[2] += 16;
992	else			// 8 data bits
993
994		p[2] += 24;
995
996	if (si2 & 16)		// 2 stop bits
997
998		p[2] += 96;
999	else			// 1 stop bit
1000
1001		p[2] += 32;
1002
1003	if (si2 & 8)		// even parity
1004
1005		p[2] += 2;
1006	else			// no parity
1007
1008		p[2] += 3;
1009
1010	switch (si2 & 0x07) {
1011	case 0:
1012		p[0] = 66;	// 1200 bit/s
1013
1014		break;
1015	case 1:
1016		p[0] = 88;	// 1200/75 bit/s
1017
1018		break;
1019	case 2:
1020		p[0] = 87;	// 75/1200 bit/s
1021
1022		break;
1023	case 3:
1024		p[0] = 67;	// 2400 bit/s
1025
1026		break;
1027	case 4:
1028		p[0] = 69;	// 4800 bit/s
1029
1030		break;
1031	case 5:
1032		p[0] = 72;	// 9600 bit/s
1033
1034		break;
1035	case 6:
1036		p[0] = 73;	// 14400 bit/s
1037
1038		break;
1039	case 7:
1040		p[0] = 75;	// 19200 bit/s
1041
1042		break;
1043	}
1044	return p + 3;
1045}
1046
1047static  u_char
1048EncodeSyncParams(u_char si2, u_char ai)
1049{
1050
1051	switch (si2) {
1052	case 0:
1053		return ai + 2;	// 1200 bit/s
1054
1055	case 1:
1056		return ai + 24;		// 1200/75 bit/s
1057
1058	case 2:
1059		return ai + 23;		// 75/1200 bit/s
1060
1061	case 3:
1062		return ai + 3;	// 2400 bit/s
1063
1064	case 4:
1065		return ai + 5;	// 4800 bit/s
1066
1067	case 5:
1068		return ai + 8;	// 9600 bit/s
1069
1070	case 6:
1071		return ai + 9;	// 14400 bit/s
1072
1073	case 7:
1074		return ai + 11;		// 19200 bit/s
1075
1076	case 8:
1077		return ai + 14;		// 48000 bit/s
1078
1079	case 9:
1080		return ai + 15;		// 56000 bit/s
1081
1082	case 15:
1083		return ai + 40;		// negotiate bit/s
1084
1085	default:
1086		break;
1087	}
1088	return ai;
1089}
1090
1091
1092static u_char
1093DecodeASyncParams(u_char si2, u_char *p)
1094{
1095	u_char info;
1096
1097	switch (p[5]) {
1098	case 66:	// 1200 bit/s
1099
1100		break;	// si2 don't change
1101
1102	case 88:	// 1200/75 bit/s
1103
1104		si2 += 1;
1105		break;
1106	case 87:	// 75/1200 bit/s
1107
1108		si2 += 2;
1109		break;
1110	case 67:	// 2400 bit/s
1111
1112		si2 += 3;
1113		break;
1114	case 69:	// 4800 bit/s
1115
1116		si2 += 4;
1117		break;
1118	case 72:	// 9600 bit/s
1119
1120		si2 += 5;
1121		break;
1122	case 73:	// 14400 bit/s
1123
1124		si2 += 6;
1125		break;
1126	case 75:	// 19200 bit/s
1127
1128		si2 += 7;
1129		break;
1130	}
1131
1132	info = p[7] & 0x7f;
1133	if ((info & 16) && (!(info & 8)))	// 7 data bits
1134
1135		si2 += 32;	// else 8 data bits
1136
1137	if ((info & 96) == 96)	// 2 stop bits
1138
1139		si2 += 16;	// else 1 stop bit
1140
1141	if ((info & 2) && (!(info & 1)))	// even parity
1142
1143		si2 += 8;	// else no parity
1144
1145	return si2;
1146}
1147
1148
1149static u_char
1150DecodeSyncParams(u_char si2, u_char info)
1151{
1152	info &= 0x7f;
1153	switch (info) {
1154	case 40:	// bit/s negotiation failed  ai := 165 not 175!
1155
1156		return si2 + 15;
1157	case 15:	// 56000 bit/s failed, ai := 0 not 169 !
1158
1159		return si2 + 9;
1160	case 14:	// 48000 bit/s
1161
1162		return si2 + 8;
1163	case 11:	// 19200 bit/s
1164
1165		return si2 + 7;
1166	case 9:	// 14400 bit/s
1167
1168		return si2 + 6;
1169	case 8:	// 9600  bit/s
1170
1171		return si2 + 5;
1172	case 5:	// 4800  bit/s
1173
1174		return si2 + 4;
1175	case 3:	// 2400  bit/s
1176
1177		return si2 + 3;
1178	case 23:	// 75/1200 bit/s
1179
1180		return si2 + 2;
1181	case 24:	// 1200/75 bit/s
1182
1183		return si2 + 1;
1184	default:	// 1200 bit/s
1185
1186		return si2;
1187	}
1188}
1189
1190static u_char
1191DecodeSI2(struct sk_buff *skb)
1192{
1193	u_char *p;		//, *pend=skb->data + skb->len;
1194
1195	if ((p = findie(skb->data, skb->len, 0x7c, 0))) {
1196		switch (p[4] & 0x0f) {
1197		case 0x01:
1198			if (p[1] == 0x04)	// sync. Bitratenadaption
1199
1200				return DecodeSyncParams(160, p[5]);	// V.110/X.30
1201
1202			else if (p[1] == 0x06)	// async. Bitratenadaption
1203
1204				return DecodeASyncParams(192, p);	// V.110/X.30
1205
1206			break;
1207		case 0x08:	// if (p[5] == 0x02) // sync. Bitratenadaption
1208			if (p[1] > 3)
1209				return DecodeSyncParams(176, p[5]);	// V.120
1210			break;
1211		}
1212	}
1213	return 0;
1214}
1215
1216#endif
1217
1218
1219static void
1220l3dss1_setup_req(struct l3_process *pc, u_char pr,
1221		 void *arg)
1222{
1223	struct sk_buff *skb;
1224	u_char tmp[128];
1225	u_char *p = tmp;
1226	u_char channel = 0;
1227
1228	u_char send_keypad;
1229	u_char screen = 0x80;
1230	u_char *teln;
1231	u_char *msn;
1232	u_char *sub;
1233	u_char *sp;
1234	int l;
1235
1236	MsgHead(p, pc->callref, MT_SETUP);
1237
1238	teln = pc->para.setup.phone;
1239#ifndef CONFIG_HISAX_NO_KEYPAD
1240	send_keypad = (strchr(teln, '*') || strchr(teln, '#')) ? 1 : 0;
1241#else
1242	send_keypad = 0;
1243#endif
1244#ifndef CONFIG_HISAX_NO_SENDCOMPLETE
1245	if (!send_keypad)
1246		*p++ = 0xa1;		/* complete indicator */
1247#endif
1248	/*
1249	 * Set Bearer Capability, Map info from 1TR6-convention to EDSS1
1250	 */
1251	switch (pc->para.setup.si1) {
1252	case 1:	                  /* Telephony                                */
1253		*p++ = IE_BEARER;
1254		*p++ = 0x3;	  /* Length                                   */
1255		*p++ = 0x90;	  /* Coding Std. CCITT, 3.1 kHz audio         */
1256		*p++ = 0x90;	  /* Circuit-Mode 64kbps                      */
1257		*p++ = 0xa3;	  /* A-Law Audio                              */
1258		break;
1259	case 5:	                  /* Datatransmission 64k, BTX                */
1260	case 7:	                  /* Datatransmission 64k                     */
1261	default:
1262		*p++ = IE_BEARER;
1263		*p++ = 0x2;	  /* Length                                   */
1264		*p++ = 0x88;	  /* Coding Std. CCITT, unrestr. dig. Inform. */
1265		*p++ = 0x90;	  /* Circuit-Mode 64kbps                      */
1266		break;
1267	}
1268
1269	if (send_keypad) {
1270		*p++ = IE_KEYPAD;
1271		*p++ = strlen(teln);
1272		while (*teln)
1273			*p++ = (*teln++) & 0x7F;
1274	}
1275
1276	/*
1277	 * What about info2? Mapping to High-Layer-Compatibility?
1278	 */
1279	if ((*teln) && (!send_keypad)) {
1280		/* parse number for special things */
1281		if (!isdigit(*teln)) {
1282			switch (0x5f & *teln) {
1283			case 'C':
1284				channel = 0x08;
1285			case 'P':
1286				channel |= 0x80;
1287				teln++;
1288				if (*teln == '1')
1289					channel |= 0x01;
1290				else
1291					channel |= 0x02;
1292				break;
1293			case 'R':
1294				screen = 0xA0;
1295				break;
1296			case 'D':
1297				screen = 0x80;
1298				break;
1299
1300			default:
1301				if (pc->debug & L3_DEB_WARN)
1302					l3_debug(pc->st, "Wrong MSN Code");
1303				break;
1304			}
1305			teln++;
1306		}
1307	}
1308	if (channel) {
1309		*p++ = IE_CHANNEL_ID;
1310		*p++ = 1;
1311		*p++ = channel;
1312	}
1313	msn = pc->para.setup.eazmsn;
1314	sub = NULL;
1315	sp = msn;
1316	while (*sp) {
1317		if ('.' == *sp) {
1318			sub = sp;
1319			*sp = 0;
1320		} else
1321			sp++;
1322	}
1323	if (*msn) {
1324		*p++ = IE_CALLING_PN;
1325		*p++ = strlen(msn) + (screen ? 2 : 1);
1326		/* Classify as AnyPref. */
1327		if (screen) {
1328			*p++ = 0x01;	/* Ext = '0'B, Type = '000'B, Plan = '0001'B. */
1329			*p++ = screen;
1330		} else
1331			*p++ = 0x81;	/* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
1332		while (*msn)
1333			*p++ = *msn++ & 0x7f;
1334	}
1335	if (sub) {
1336		*sub++ = '.';
1337		*p++ = IE_CALLING_SUB;
1338		*p++ = strlen(sub) + 2;
1339		*p++ = 0x80;	/* NSAP coded */
1340		*p++ = 0x50;	/* local IDI format */
1341		while (*sub)
1342			*p++ = *sub++ & 0x7f;
1343	}
1344	sub = NULL;
1345	sp = teln;
1346	while (*sp) {
1347		if ('.' == *sp) {
1348			sub = sp;
1349			*sp = 0;
1350		} else
1351			sp++;
1352	}
1353
1354	if (!send_keypad) {
1355		*p++ = IE_CALLED_PN;
1356		*p++ = strlen(teln) + 1;
1357		/* Classify as AnyPref. */
1358		*p++ = 0x81;		/* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
1359		while (*teln)
1360			*p++ = *teln++ & 0x7f;
1361
1362		if (sub) {
1363			*sub++ = '.';
1364			*p++ = IE_CALLED_SUB;
1365			*p++ = strlen(sub) + 2;
1366			*p++ = 0x80;	/* NSAP coded */
1367			*p++ = 0x50;	/* local IDI format */
1368			while (*sub)
1369				*p++ = *sub++ & 0x7f;
1370		}
1371	}
1372#ifdef EXT_BEARER_CAPS
1373	if ((pc->para.setup.si2 >= 160) && (pc->para.setup.si2 <= 175)) {	// sync. Bitratenadaption, V.110/X.30
1374
1375		*p++ = IE_LLC;
1376		*p++ = 0x04;
1377		*p++ = 0x88;
1378		*p++ = 0x90;
1379		*p++ = 0x21;
1380		*p++ = EncodeSyncParams(pc->para.setup.si2 - 160, 0x80);
1381	} else if ((pc->para.setup.si2 >= 176) && (pc->para.setup.si2 <= 191)) {	// sync. Bitratenadaption, V.120
1382
1383		*p++ = IE_LLC;
1384		*p++ = 0x05;
1385		*p++ = 0x88;
1386		*p++ = 0x90;
1387		*p++ = 0x28;
1388		*p++ = EncodeSyncParams(pc->para.setup.si2 - 176, 0);
1389		*p++ = 0x82;
1390	} else if (pc->para.setup.si2 >= 192) {		// async. Bitratenadaption, V.110/X.30
1391
1392		*p++ = IE_LLC;
1393		*p++ = 0x06;
1394		*p++ = 0x88;
1395		*p++ = 0x90;
1396		*p++ = 0x21;
1397		p = EncodeASyncParams(p, pc->para.setup.si2 - 192);
1398#ifndef CONFIG_HISAX_NO_LLC
1399	} else {
1400		switch (pc->para.setup.si1) {
1401		case 1:	                /* Telephony                                */
1402			*p++ = IE_LLC;
1403			*p++ = 0x3;	/* Length                                   */
1404			*p++ = 0x90;	/* Coding Std. CCITT, 3.1 kHz audio         */
1405			*p++ = 0x90;	/* Circuit-Mode 64kbps                      */
1406			*p++ = 0xa3;	/* A-Law Audio                              */
1407			break;
1408		case 5:	                /* Datatransmission 64k, BTX                */
1409		case 7:	                /* Datatransmission 64k                     */
1410		default:
1411			*p++ = IE_LLC;
1412			*p++ = 0x2;	/* Length                                   */
1413			*p++ = 0x88;	/* Coding Std. CCITT, unrestr. dig. Inform. */
1414			*p++ = 0x90;	/* Circuit-Mode 64kbps                      */
1415			break;
1416		}
1417#endif
1418	}
1419#endif
1420	l = p - tmp;
1421	if (!(skb = l3_alloc_skb(l)))
1422		return;
1423	memcpy(skb_put(skb, l), tmp, l);
1424	L3DelTimer(&pc->timer);
1425	L3AddTimer(&pc->timer, T303, CC_T303);
1426	newl3state(pc, 1);
1427	l3_msg(pc->st, DL_DATA | REQUEST, skb);
1428}
1429
1430static void
1431l3dss1_call_proc(struct l3_process *pc, u_char pr, void *arg)
1432{
1433	struct sk_buff *skb = arg;
1434	int id, ret;
1435
1436	if ((id = l3dss1_get_channel_id(pc, skb)) >= 0) {
1437		if ((0 == id) || ((3 == id) && (0x10 == pc->para.moderate))) {
1438			if (pc->debug & L3_DEB_WARN)
1439				l3_debug(pc->st, "setup answer with wrong chid %x", id);
1440			pc->para.cause = 100;
1441			l3dss1_status_send(pc, pr, NULL);
1442			return;
1443		}
1444		pc->para.bchannel = id;
1445	} else if (1 == pc->state) {
1446		if (pc->debug & L3_DEB_WARN)
1447			l3_debug(pc->st, "setup answer wrong chid (ret %d)", id);
1448		if (id == -1)
1449			pc->para.cause = 96;
1450		else
1451			pc->para.cause = 100;
1452		l3dss1_status_send(pc, pr, NULL);
1453		return;
1454	}
1455	/* Now we are on none mandatory IEs */
1456	ret = check_infoelements(pc, skb, ie_CALL_PROCEEDING);
1457	if (ERR_IE_COMPREHENSION == ret) {
1458		l3dss1_std_ie_err(pc, ret);
1459		return;
1460	}
1461	L3DelTimer(&pc->timer);
1462	newl3state(pc, 3);
1463	L3AddTimer(&pc->timer, T310, CC_T310);
1464	if (ret) /* STATUS for none mandatory IE errors after actions are taken */
1465		l3dss1_std_ie_err(pc, ret);
1466	pc->st->l3.l3l4(pc->st, CC_PROCEEDING | INDICATION, pc);
1467}
1468
1469static void
1470l3dss1_setup_ack(struct l3_process *pc, u_char pr, void *arg)
1471{
1472	struct sk_buff *skb = arg;
1473	int id, ret;
1474
1475	if ((id = l3dss1_get_channel_id(pc, skb)) >= 0) {
1476		if ((0 == id) || ((3 == id) && (0x10 == pc->para.moderate))) {
1477			if (pc->debug & L3_DEB_WARN)
1478				l3_debug(pc->st, "setup answer with wrong chid %x", id);
1479			pc->para.cause = 100;
1480			l3dss1_status_send(pc, pr, NULL);
1481			return;
1482		}
1483		pc->para.bchannel = id;
1484	} else {
1485		if (pc->debug & L3_DEB_WARN)
1486			l3_debug(pc->st, "setup answer wrong chid (ret %d)", id);
1487		if (id == -1)
1488			pc->para.cause = 96;
1489		else
1490			pc->para.cause = 100;
1491		l3dss1_status_send(pc, pr, NULL);
1492		return;
1493	}
1494	/* Now we are on none mandatory IEs */
1495	ret = check_infoelements(pc, skb, ie_SETUP_ACKNOWLEDGE);
1496	if (ERR_IE_COMPREHENSION == ret) {
1497		l3dss1_std_ie_err(pc, ret);
1498		return;
1499	}
1500	L3DelTimer(&pc->timer);
1501	newl3state(pc, 2);
1502	L3AddTimer(&pc->timer, T304, CC_T304);
1503	if (ret) /* STATUS for none mandatory IE errors after actions are taken */
1504		l3dss1_std_ie_err(pc, ret);
1505	pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc);
1506}
1507
1508static void
1509l3dss1_disconnect(struct l3_process *pc, u_char pr, void *arg)
1510{
1511	struct sk_buff *skb = arg;
1512	u_char *p;
1513	int ret;
1514	u_char cause = 0;
1515
1516	StopAllL3Timer(pc);
1517	if ((ret = l3dss1_get_cause(pc, skb))) {
1518		if (pc->debug & L3_DEB_WARN)
1519			l3_debug(pc->st, "DISC get_cause ret(%d)", ret);
1520		if (ret < 0)
1521			cause = 96;
1522		else if (ret > 0)
1523			cause = 100;
1524	}
1525	if ((p = findie(skb->data, skb->len, IE_FACILITY, 0)))
1526		l3dss1_parse_facility(pc->st, pc, pc->callref, p);
1527	ret = check_infoelements(pc, skb, ie_DISCONNECT);
1528	if (ERR_IE_COMPREHENSION == ret)
1529		cause = 96;
1530	else if ((!cause) && (ERR_IE_UNRECOGNIZED == ret))
1531		cause = 99;
1532	ret = pc->state;
1533	newl3state(pc, 12);
1534	if (cause)
1535		newl3state(pc, 19);
1536	if (11 != ret)
1537		pc->st->l3.l3l4(pc->st, CC_DISCONNECT | INDICATION, pc);
1538	else if (!cause)
1539		l3dss1_release_req(pc, pr, NULL);
1540	if (cause) {
1541		l3dss1_message_cause(pc, MT_RELEASE, cause);
1542		L3AddTimer(&pc->timer, T308, CC_T308_1);
1543	}
1544}
1545
1546static void
1547l3dss1_connect(struct l3_process *pc, u_char pr, void *arg)
1548{
1549	struct sk_buff *skb = arg;
1550	int ret;
1551
1552	ret = check_infoelements(pc, skb, ie_CONNECT);
1553	if (ERR_IE_COMPREHENSION == ret) {
1554		l3dss1_std_ie_err(pc, ret);
1555		return;
1556	}
1557	L3DelTimer(&pc->timer);	/* T310 */
1558	newl3state(pc, 10);
1559	pc->para.chargeinfo = 0;
1560	/* here should inserted COLP handling KKe */
1561	if (ret)
1562		l3dss1_std_ie_err(pc, ret);
1563	pc->st->l3.l3l4(pc->st, CC_SETUP | CONFIRM, pc);
1564}
1565
1566static void
1567l3dss1_alerting(struct l3_process *pc, u_char pr, void *arg)
1568{
1569	struct sk_buff *skb = arg;
1570	int ret;
1571
1572	ret = check_infoelements(pc, skb, ie_ALERTING);
1573	if (ERR_IE_COMPREHENSION == ret) {
1574		l3dss1_std_ie_err(pc, ret);
1575		return;
1576	}
1577	L3DelTimer(&pc->timer);	/* T304 */
1578	newl3state(pc, 4);
1579	if (ret)
1580		l3dss1_std_ie_err(pc, ret);
1581	pc->st->l3.l3l4(pc->st, CC_ALERTING | INDICATION, pc);
1582}
1583
1584static void
1585l3dss1_setup(struct l3_process *pc, u_char pr, void *arg)
1586{
1587	u_char *p;
1588	int bcfound = 0;
1589	char tmp[80];
1590	struct sk_buff *skb = arg;
1591	int id;
1592	int err = 0;
1593
1594	/*
1595	 * Bearer Capabilities
1596	 */
1597	p = skb->data;
1598	/* only the first occurrence 'll be detected ! */
1599	if ((p = findie(p, skb->len, 0x04, 0))) {
1600		if ((p[1] < 2) || (p[1] > 11))
1601			err = 1;
1602		else {
1603			pc->para.setup.si2 = 0;
1604			switch (p[2] & 0x7f) {
1605			case 0x00: /* Speech */
1606			case 0x10: /* 3.1 Khz audio */
1607				pc->para.setup.si1 = 1;
1608				break;
1609			case 0x08: /* Unrestricted digital information */
1610				pc->para.setup.si1 = 7;
1611/* JIM, 05.11.97 I wanna set service indicator 2 */
1612#ifdef EXT_BEARER_CAPS
1613				pc->para.setup.si2 = DecodeSI2(skb);
1614#endif
1615				break;
1616			case 0x09: /* Restricted digital information */
1617				pc->para.setup.si1 = 2;
1618				break;
1619			case 0x11:
1620				/* Unrestr. digital information  with
1621				 * tones/announcements ( or 7 kHz audio
1622				 */
1623				pc->para.setup.si1 = 3;
1624				break;
1625			case 0x18: /* Video */
1626				pc->para.setup.si1 = 4;
1627				break;
1628			default:
1629				err = 2;
1630				break;
1631			}
1632			switch (p[3] & 0x7f) {
1633			case 0x40: /* packed mode */
1634				pc->para.setup.si1 = 8;
1635				break;
1636			case 0x10: /* 64 kbit */
1637			case 0x11: /* 2*64 kbit */
1638			case 0x13: /* 384 kbit */
1639			case 0x15: /* 1536 kbit */
1640			case 0x17: /* 1920 kbit */
1641				pc->para.moderate = p[3] & 0x7f;
1642				break;
1643			default:
1644				err = 3;
1645				break;
1646			}
1647		}
1648		if (pc->debug & L3_DEB_SI)
1649			l3_debug(pc->st, "SI=%d, AI=%d",
1650				 pc->para.setup.si1, pc->para.setup.si2);
1651		if (err) {
1652			if (pc->debug & L3_DEB_WARN)
1653				l3_debug(pc->st, "setup with wrong bearer(l=%d:%x,%x)",
1654					 p[1], p[2], p[3]);
1655			pc->para.cause = 100;
1656			l3dss1_msg_without_setup(pc, pr, NULL);
1657			return;
1658		}
1659	} else {
1660		if (pc->debug & L3_DEB_WARN)
1661			l3_debug(pc->st, "setup without bearer capabilities");
1662		/* ETS 300-104 1.3.3 */
1663		pc->para.cause = 96;
1664		l3dss1_msg_without_setup(pc, pr, NULL);
1665		return;
1666	}
1667	/*
1668	 * Channel Identification
1669	 */
1670	if ((id = l3dss1_get_channel_id(pc, skb)) >= 0) {
1671		if ((pc->para.bchannel = id)) {
1672			if ((3 == id) && (0x10 == pc->para.moderate)) {
1673				if (pc->debug & L3_DEB_WARN)
1674					l3_debug(pc->st, "setup with wrong chid %x",
1675						 id);
1676				pc->para.cause = 100;
1677				l3dss1_msg_without_setup(pc, pr, NULL);
1678				return;
1679			}
1680			bcfound++;
1681		} else
1682		{ if (pc->debug & L3_DEB_WARN)
1683				l3_debug(pc->st, "setup without bchannel, call waiting");
1684			bcfound++;
1685		}
1686	} else {
1687		if (pc->debug & L3_DEB_WARN)
1688			l3_debug(pc->st, "setup with wrong chid ret %d", id);
1689		if (id == -1)
1690			pc->para.cause = 96;
1691		else
1692			pc->para.cause = 100;
1693		l3dss1_msg_without_setup(pc, pr, NULL);
1694		return;
1695	}
1696	/* Now we are on none mandatory IEs */
1697	err = check_infoelements(pc, skb, ie_SETUP);
1698	if (ERR_IE_COMPREHENSION == err) {
1699		pc->para.cause = 96;
1700		l3dss1_msg_without_setup(pc, pr, NULL);
1701		return;
1702	}
1703	p = skb->data;
1704	if ((p = findie(p, skb->len, 0x70, 0)))
1705		iecpy(pc->para.setup.eazmsn, p, 1);
1706	else
1707		pc->para.setup.eazmsn[0] = 0;
1708
1709	p = skb->data;
1710	if ((p = findie(p, skb->len, 0x71, 0))) {
1711		/* Called party subaddress */
1712		if ((p[1] >= 2) && (p[2] == 0x80) && (p[3] == 0x50)) {
1713			tmp[0] = '.';
1714			iecpy(&tmp[1], p, 2);
1715			strcat(pc->para.setup.eazmsn, tmp);
1716		} else if (pc->debug & L3_DEB_WARN)
1717			l3_debug(pc->st, "wrong called subaddress");
1718	}
1719	p = skb->data;
1720	if ((p = findie(p, skb->len, 0x6c, 0))) {
1721		pc->para.setup.plan = p[2];
1722		if (p[2] & 0x80) {
1723			iecpy(pc->para.setup.phone, p, 1);
1724			pc->para.setup.screen = 0;
1725		} else {
1726			iecpy(pc->para.setup.phone, p, 2);
1727			pc->para.setup.screen = p[3];
1728		}
1729	} else {
1730		pc->para.setup.phone[0] = 0;
1731		pc->para.setup.plan = 0;
1732		pc->para.setup.screen = 0;
1733	}
1734	p = skb->data;
1735	if ((p = findie(p, skb->len, 0x6d, 0))) {
1736		/* Calling party subaddress */
1737		if ((p[1] >= 2) && (p[2] == 0x80) && (p[3] == 0x50)) {
1738			tmp[0] = '.';
1739			iecpy(&tmp[1], p, 2);
1740			strcat(pc->para.setup.phone, tmp);
1741		} else if (pc->debug & L3_DEB_WARN)
1742			l3_debug(pc->st, "wrong calling subaddress");
1743	}
1744	newl3state(pc, 6);
1745	if (err) /* STATUS for none mandatory IE errors after actions are taken */
1746		l3dss1_std_ie_err(pc, err);
1747	pc->st->l3.l3l4(pc->st, CC_SETUP | INDICATION, pc);
1748}
1749
1750static void
1751l3dss1_reset(struct l3_process *pc, u_char pr, void *arg)
1752{
1753	dss1_release_l3_process(pc);
1754}
1755
1756static void
1757l3dss1_disconnect_req(struct l3_process *pc, u_char pr, void *arg)
1758{
1759	struct sk_buff *skb;
1760	u_char tmp[16 + 40];
1761	u_char *p = tmp;
1762	int l;
1763	u_char cause = 16;
1764
1765	if (pc->para.cause != NO_CAUSE)
1766		cause = pc->para.cause;
1767
1768	StopAllL3Timer(pc);
1769
1770	MsgHead(p, pc->callref, MT_DISCONNECT);
1771
1772	*p++ = IE_CAUSE;
1773	*p++ = 0x2;
1774	*p++ = 0x80;
1775	*p++ = cause | 0x80;
1776
1777	if (pc->prot.dss1.uus1_data[0])
1778	{ *p++ = IE_USER_USER; /* UUS info element */
1779		*p++ = strlen(pc->prot.dss1.uus1_data) + 1;
1780		*p++ = 0x04; /* IA5 chars */
1781		strcpy(p, pc->prot.dss1.uus1_data);
1782		p += strlen(pc->prot.dss1.uus1_data);
1783		pc->prot.dss1.uus1_data[0] = '\0';
1784	}
1785
1786	l = p - tmp;
1787	if (!(skb = l3_alloc_skb(l)))
1788		return;
1789	memcpy(skb_put(skb, l), tmp, l);
1790	newl3state(pc, 11);
1791	l3_msg(pc->st, DL_DATA | REQUEST, skb);
1792	L3AddTimer(&pc->timer, T305, CC_T305);
1793}
1794
1795static void
1796l3dss1_setup_rsp(struct l3_process *pc, u_char pr,
1797		 void *arg)
1798{
1799	if (!pc->para.bchannel)
1800	{ if (pc->debug & L3_DEB_WARN)
1801			l3_debug(pc->st, "D-chan connect for waiting call");
1802		l3dss1_disconnect_req(pc, pr, arg);
1803		return;
1804	}
1805	newl3state(pc, 8);
1806	l3dss1_message(pc, MT_CONNECT);
1807	L3DelTimer(&pc->timer);
1808	L3AddTimer(&pc->timer, T313, CC_T313);
1809}
1810
1811static void
1812l3dss1_connect_ack(struct l3_process *pc, u_char pr, void *arg)
1813{
1814	struct sk_buff *skb = arg;
1815	int ret;
1816
1817	ret = check_infoelements(pc, skb, ie_CONNECT_ACKNOWLEDGE);
1818	if (ERR_IE_COMPREHENSION == ret) {
1819		l3dss1_std_ie_err(pc, ret);
1820		return;
1821	}
1822	newl3state(pc, 10);
1823	L3DelTimer(&pc->timer);
1824	if (ret)
1825		l3dss1_std_ie_err(pc, ret);
1826	pc->st->l3.l3l4(pc->st, CC_SETUP_COMPL | INDICATION, pc);
1827}
1828
1829static void
1830l3dss1_reject_req(struct l3_process *pc, u_char pr, void *arg)
1831{
1832	struct sk_buff *skb;
1833	u_char tmp[16];
1834	u_char *p = tmp;
1835	int l;
1836	u_char cause = 21;
1837
1838	if (pc->para.cause != NO_CAUSE)
1839		cause = pc->para.cause;
1840
1841	MsgHead(p, pc->callref, MT_RELEASE_COMPLETE);
1842
1843	*p++ = IE_CAUSE;
1844	*p++ = 0x2;
1845	*p++ = 0x80;
1846	*p++ = cause | 0x80;
1847
1848	l = p - tmp;
1849	if (!(skb = l3_alloc_skb(l)))
1850		return;
1851	memcpy(skb_put(skb, l), tmp, l);
1852	l3_msg(pc->st, DL_DATA | REQUEST, skb);
1853	pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
1854	newl3state(pc, 0);
1855	dss1_release_l3_process(pc);
1856}
1857
1858static void
1859l3dss1_release(struct l3_process *pc, u_char pr, void *arg)
1860{
1861	struct sk_buff *skb = arg;
1862	u_char *p;
1863	int ret, cause = 0;
1864
1865	StopAllL3Timer(pc);
1866	if ((ret = l3dss1_get_cause(pc, skb)) > 0) {
1867		if (pc->debug & L3_DEB_WARN)
1868			l3_debug(pc->st, "REL get_cause ret(%d)", ret);
1869	} else if (ret < 0)
1870		pc->para.cause = NO_CAUSE;
1871	if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) {
1872		l3dss1_parse_facility(pc->st, pc, pc->callref, p);
1873	}
1874	if ((ret < 0) && (pc->state != 11))
1875		cause = 96;
1876	else if (ret > 0)
1877		cause = 100;
1878	ret = check_infoelements(pc, skb, ie_RELEASE);
1879	if (ERR_IE_COMPREHENSION == ret)
1880		cause = 96;
1881	else if ((ERR_IE_UNRECOGNIZED == ret) && (!cause))
1882		cause = 99;
1883	if (cause)
1884		l3dss1_message_cause(pc, MT_RELEASE_COMPLETE, cause);
1885	else
1886		l3dss1_message(pc, MT_RELEASE_COMPLETE);
1887	pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
1888	newl3state(pc, 0);
1889	dss1_release_l3_process(pc);
1890}
1891
1892static void
1893l3dss1_alert_req(struct l3_process *pc, u_char pr,
1894		 void *arg)
1895{
1896	newl3state(pc, 7);
1897	if (!pc->prot.dss1.uus1_data[0])
1898		l3dss1_message(pc, MT_ALERTING);
1899	else
1900		l3dss1_msg_with_uus(pc, MT_ALERTING);
1901}
1902
1903static void
1904l3dss1_proceed_req(struct l3_process *pc, u_char pr,
1905		   void *arg)
1906{
1907	newl3state(pc, 9);
1908	l3dss1_message(pc, MT_CALL_PROCEEDING);
1909	pc->st->l3.l3l4(pc->st, CC_PROCEED_SEND | INDICATION, pc);
1910}
1911
1912static void
1913l3dss1_setup_ack_req(struct l3_process *pc, u_char pr,
1914		     void *arg)
1915{
1916	newl3state(pc, 25);
1917	L3DelTimer(&pc->timer);
1918	L3AddTimer(&pc->timer, T302, CC_T302);
1919	l3dss1_message(pc, MT_SETUP_ACKNOWLEDGE);
1920}
1921
1922/********************************************/
1923/* deliver a incoming display message to HL */
1924/********************************************/
1925static void
1926l3dss1_deliver_display(struct l3_process *pc, int pr, u_char *infp)
1927{       u_char len;
1928	isdn_ctrl ic;
1929	struct IsdnCardState *cs;
1930	char *p;
1931
1932	if (*infp++ != IE_DISPLAY) return;
1933	if ((len = *infp++) > 80) return; /* total length <= 82 */
1934	if (!pc->chan) return;
1935
1936	p = ic.parm.display;
1937	while (len--)
1938		*p++ = *infp++;
1939	*p = '\0';
1940	ic.command = ISDN_STAT_DISPLAY;
1941	cs = pc->st->l1.hardware;
1942	ic.driver = cs->myid;
1943	ic.arg = pc->chan->chan;
1944	cs->iif.statcallb(&ic);
1945} /* l3dss1_deliver_display */
1946
1947
1948static void
1949l3dss1_progress(struct l3_process *pc, u_char pr, void *arg)
1950{
1951	struct sk_buff *skb = arg;
1952	int err = 0;
1953	u_char *p;
1954
1955	if ((p = findie(skb->data, skb->len, IE_PROGRESS, 0))) {
1956		if (p[1] != 2) {
1957			err = 1;
1958			pc->para.cause = 100;
1959		} else if (!(p[2] & 0x70)) {
1960			switch (p[2]) {
1961			case 0x80:
1962			case 0x81:
1963			case 0x82:
1964			case 0x84:
1965			case 0x85:
1966			case 0x87:
1967			case 0x8a:
1968				switch (p[3]) {
1969				case 0x81:
1970				case 0x82:
1971				case 0x83:
1972				case 0x84:
1973				case 0x88:
1974					break;
1975				default:
1976					err = 2;
1977					pc->para.cause = 100;
1978					break;
1979				}
1980				break;
1981			default:
1982				err = 3;
1983				pc->para.cause = 100;
1984				break;
1985			}
1986		}
1987	} else {
1988		pc->para.cause = 96;
1989		err = 4;
1990	}
1991	if (err) {
1992		if (pc->debug & L3_DEB_WARN)
1993			l3_debug(pc->st, "progress error %d", err);
1994		l3dss1_status_send(pc, pr, NULL);
1995		return;
1996	}
1997	/* Now we are on none mandatory IEs */
1998	err = check_infoelements(pc, skb, ie_PROGRESS);
1999	if (err)
2000		l3dss1_std_ie_err(pc, err);
2001	if (ERR_IE_COMPREHENSION != err)
2002		pc->st->l3.l3l4(pc->st, CC_PROGRESS | INDICATION, pc);
2003}
2004
2005static void
2006l3dss1_notify(struct l3_process *pc, u_char pr, void *arg)
2007{
2008	struct sk_buff *skb = arg;
2009	int err = 0;
2010	u_char *p;
2011
2012	if ((p = findie(skb->data, skb->len, IE_NOTIFY, 0))) {
2013		if (p[1] != 1) {
2014			err = 1;
2015			pc->para.cause = 100;
2016		} else {
2017			switch (p[2]) {
2018			case 0x80:
2019			case 0x81:
2020			case 0x82:
2021				break;
2022			default:
2023				pc->para.cause = 100;
2024				err = 2;
2025				break;
2026			}
2027		}
2028	} else {
2029		pc->para.cause = 96;
2030		err = 3;
2031	}
2032	if (err) {
2033		if (pc->debug & L3_DEB_WARN)
2034			l3_debug(pc->st, "notify error %d", err);
2035		l3dss1_status_send(pc, pr, NULL);
2036		return;
2037	}
2038	/* Now we are on none mandatory IEs */
2039	err = check_infoelements(pc, skb, ie_NOTIFY);
2040	if (err)
2041		l3dss1_std_ie_err(pc, err);
2042	if (ERR_IE_COMPREHENSION != err)
2043		pc->st->l3.l3l4(pc->st, CC_NOTIFY | INDICATION, pc);
2044}
2045
2046static void
2047l3dss1_status_enq(struct l3_process *pc, u_char pr, void *arg)
2048{
2049	int ret;
2050	struct sk_buff *skb = arg;
2051
2052	ret = check_infoelements(pc, skb, ie_STATUS_ENQUIRY);
2053	l3dss1_std_ie_err(pc, ret);
2054	pc->para.cause = 30; /* response to STATUS_ENQUIRY */
2055	l3dss1_status_send(pc, pr, NULL);
2056}
2057
2058static void
2059l3dss1_information(struct l3_process *pc, u_char pr, void *arg)
2060{
2061	int ret;
2062	struct sk_buff *skb = arg;
2063	u_char *p;
2064	char tmp[32];
2065
2066	ret = check_infoelements(pc, skb, ie_INFORMATION);
2067	if (ret)
2068		l3dss1_std_ie_err(pc, ret);
2069	if (pc->state == 25) { /* overlap receiving */
2070		L3DelTimer(&pc->timer);
2071		p = skb->data;
2072		if ((p = findie(p, skb->len, 0x70, 0))) {
2073			iecpy(tmp, p, 1);
2074			strcat(pc->para.setup.eazmsn, tmp);
2075			pc->st->l3.l3l4(pc->st, CC_MORE_INFO | INDICATION, pc);
2076		}
2077		L3AddTimer(&pc->timer, T302, CC_T302);
2078	}
2079}
2080
2081/******************************/
2082/* handle deflection requests */
2083/******************************/
2084static void l3dss1_redir_req(struct l3_process *pc, u_char pr, void *arg)
2085{
2086	struct sk_buff *skb;
2087	u_char tmp[128];
2088	u_char *p = tmp;
2089	u_char *subp;
2090	u_char len_phone = 0;
2091	u_char len_sub = 0;
2092	int l;
2093
2094
2095	strcpy(pc->prot.dss1.uus1_data, pc->chan->setup.eazmsn); /* copy uus element if available */
2096	if (!pc->chan->setup.phone[0])
2097	{ pc->para.cause = -1;
2098		l3dss1_disconnect_req(pc, pr, arg); /* disconnect immediately */
2099		return;
2100	} /* only uus */
2101
2102	if (pc->prot.dss1.invoke_id)
2103		free_invoke_id(pc->st, pc->prot.dss1.invoke_id);
2104
2105	if (!(pc->prot.dss1.invoke_id = new_invoke_id(pc->st)))
2106		return;
2107
2108	MsgHead(p, pc->callref, MT_FACILITY);
2109
2110	for (subp = pc->chan->setup.phone; (*subp) && (*subp != '.'); subp++) len_phone++; /* len of phone number */
2111	if (*subp++ == '.') len_sub = strlen(subp) + 2; /* length including info subaddress element */
2112
2113	*p++ = 0x1c;   /* Facility info element */
2114	*p++ = len_phone + len_sub + 2 + 2 + 8 + 3 + 3; /* length of element */
2115	*p++ = 0x91;  /* remote operations protocol */
2116	*p++ = 0xa1;  /* invoke component */
2117
2118	*p++ = len_phone + len_sub + 2 + 2 + 8 + 3; /* length of data */
2119	*p++ = 0x02;  /* invoke id tag, integer */
2120	*p++ = 0x01;  /* length */
2121	*p++ = pc->prot.dss1.invoke_id;  /* invoke id */
2122	*p++ = 0x02;  /* operation value tag, integer */
2123	*p++ = 0x01;  /* length */
2124	*p++ = 0x0D;  /* Call Deflect */
2125
2126	*p++ = 0x30;  /* sequence phone number */
2127	*p++ = len_phone + 2 + 2 + 3 + len_sub; /* length */
2128
2129	*p++ = 0x30;  /* Deflected to UserNumber */
2130	*p++ = len_phone + 2 + len_sub; /* length */
2131	*p++ = 0x80; /* NumberDigits */
2132	*p++ = len_phone; /* length */
2133	for (l = 0; l < len_phone; l++)
2134		*p++ = pc->chan->setup.phone[l];
2135
2136	if (len_sub)
2137	{ *p++ = 0x04; /* called party subaddress */
2138		*p++ = len_sub - 2;
2139		while (*subp) *p++ = *subp++;
2140	}
2141
2142	*p++ = 0x01; /* screening identifier */
2143	*p++ = 0x01;
2144	*p++ = pc->chan->setup.screen;
2145
2146	l = p - tmp;
2147	if (!(skb = l3_alloc_skb(l))) return;
2148	memcpy(skb_put(skb, l), tmp, l);
2149
2150	l3_msg(pc->st, DL_DATA | REQUEST, skb);
2151} /* l3dss1_redir_req */
2152
2153/********************************************/
2154/* handle deflection request in early state */
2155/********************************************/
2156static void l3dss1_redir_req_early(struct l3_process *pc, u_char pr, void *arg)
2157{
2158	l3dss1_proceed_req(pc, pr, arg);
2159	l3dss1_redir_req(pc, pr, arg);
2160} /* l3dss1_redir_req_early */
2161
2162/***********************************************/
2163/* handle special commands for this protocol.  */
2164/* Examples are call independent services like */
2165/* remote operations with dummy  callref.      */
2166/***********************************************/
2167static int l3dss1_cmd_global(struct PStack *st, isdn_ctrl *ic)
2168{ u_char id;
2169	u_char temp[265];
2170	u_char *p = temp;
2171	int i, l, proc_len;
2172	struct sk_buff *skb;
2173	struct l3_process *pc = NULL;
2174
2175	switch (ic->arg)
2176	{ case DSS1_CMD_INVOKE:
2177			if (ic->parm.dss1_io.datalen < 0) return (-2); /* invalid parameter */
2178
2179			for (proc_len = 1, i = ic->parm.dss1_io.proc >> 8; i; i++)
2180				i = i >> 8; /* add one byte */
2181			l = ic->parm.dss1_io.datalen + proc_len + 8; /* length excluding ie header */
2182			if (l > 255)
2183				return (-2); /* too long */
2184
2185			if (!(id = new_invoke_id(st)))
2186				return (0); /* first get a invoke id -> return if no available */
2187
2188			i = -1;
2189			MsgHead(p, i, MT_FACILITY); /* build message head */
2190			*p++ = 0x1C; /* Facility IE */
2191			*p++ = l; /* length of ie */
2192			*p++ = 0x91; /* remote operations */
2193			*p++ = 0xA1; /* invoke */
2194			*p++ = l - 3; /* length of invoke */
2195			*p++ = 0x02; /* invoke id tag */
2196			*p++ = 0x01; /* length is 1 */
2197			*p++ = id; /* invoke id */
2198			*p++ = 0x02; /* operation */
2199			*p++ = proc_len; /* length of operation */
2200
2201			for (i = proc_len; i; i--)
2202				*p++ = (ic->parm.dss1_io.proc >> (i - 1)) & 0xFF;
2203			memcpy(p, ic->parm.dss1_io.data, ic->parm.dss1_io.datalen); /* copy data */
2204			l = (p - temp) + ic->parm.dss1_io.datalen; /* total length */
2205
2206			if (ic->parm.dss1_io.timeout > 0)
2207				if (!(pc = dss1_new_l3_process(st, -1)))
2208				{ free_invoke_id(st, id);
2209					return (-2);
2210				}
2211			pc->prot.dss1.ll_id = ic->parm.dss1_io.ll_id; /* remember id */
2212			pc->prot.dss1.proc = ic->parm.dss1_io.proc; /* and procedure */
2213
2214			if (!(skb = l3_alloc_skb(l)))
2215			{ free_invoke_id(st, id);
2216				if (pc) dss1_release_l3_process(pc);
2217				return (-2);
2218			}
2219			memcpy(skb_put(skb, l), temp, l);
2220
2221			if (pc)
2222			{ pc->prot.dss1.invoke_id = id; /* remember id */
2223				L3AddTimer(&pc->timer, ic->parm.dss1_io.timeout, CC_TDSS1_IO | REQUEST);
2224			}
2225
2226			l3_msg(st, DL_DATA | REQUEST, skb);
2227			ic->parm.dss1_io.hl_id = id; /* return id */
2228			return (0);
2229
2230	case DSS1_CMD_INVOKE_ABORT:
2231		if ((pc = l3dss1_search_dummy_proc(st, ic->parm.dss1_io.hl_id)))
2232		{ L3DelTimer(&pc->timer); /* remove timer */
2233			dss1_release_l3_process(pc);
2234			return (0);
2235		}
2236		else
2237		{ l3_debug(st, "l3dss1_cmd_global abort unknown id");
2238			return (-2);
2239		}
2240		break;
2241
2242	default:
2243		l3_debug(st, "l3dss1_cmd_global unknown cmd 0x%lx", ic->arg);
2244		return (-1);
2245	} /* switch ic-> arg */
2246	return (-1);
2247} /* l3dss1_cmd_global */
2248
2249static void
2250l3dss1_io_timer(struct l3_process *pc)
2251{ isdn_ctrl ic;
2252	struct IsdnCardState *cs = pc->st->l1.hardware;
2253
2254	L3DelTimer(&pc->timer); /* remove timer */
2255
2256	ic.driver = cs->myid;
2257	ic.command = ISDN_STAT_PROT;
2258	ic.arg = DSS1_STAT_INVOKE_ERR;
2259	ic.parm.dss1_io.hl_id = pc->prot.dss1.invoke_id;
2260	ic.parm.dss1_io.ll_id = pc->prot.dss1.ll_id;
2261	ic.parm.dss1_io.proc = pc->prot.dss1.proc;
2262	ic.parm.dss1_io.timeout = -1;
2263	ic.parm.dss1_io.datalen = 0;
2264	ic.parm.dss1_io.data = NULL;
2265	free_invoke_id(pc->st, pc->prot.dss1.invoke_id);
2266	pc->prot.dss1.invoke_id = 0; /* reset id */
2267
2268	cs->iif.statcallb(&ic);
2269
2270	dss1_release_l3_process(pc);
2271} /* l3dss1_io_timer */
2272
2273static void
2274l3dss1_release_ind(struct l3_process *pc, u_char pr, void *arg)
2275{
2276	u_char *p;
2277	struct sk_buff *skb = arg;
2278	int callState = 0;
2279	p = skb->data;
2280
2281	if ((p = findie(p, skb->len, IE_CALL_STATE, 0))) {
2282		p++;
2283		if (1 == *p++)
2284			callState = *p;
2285	}
2286	if (callState == 0) {
2287		/* ETS 300-104 7.6.1, 8.6.1, 10.6.1... and 16.1
2288		 * set down layer 3 without sending any message
2289		 */
2290		pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
2291		newl3state(pc, 0);
2292		dss1_release_l3_process(pc);
2293	} else {
2294		pc->st->l3.l3l4(pc->st, CC_IGNORE | INDICATION, pc);
2295	}
2296}
2297
2298static void
2299l3dss1_dummy(struct l3_process *pc, u_char pr, void *arg)
2300{
2301}
2302
2303static void
2304l3dss1_t302(struct l3_process *pc, u_char pr, void *arg)
2305{
2306	L3DelTimer(&pc->timer);
2307	pc->para.loc = 0;
2308	pc->para.cause = 28; /* invalid number */
2309	l3dss1_disconnect_req(pc, pr, NULL);
2310	pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
2311}
2312
2313static void
2314l3dss1_t303(struct l3_process *pc, u_char pr, void *arg)
2315{
2316	if (pc->N303 > 0) {
2317		pc->N303--;
2318		L3DelTimer(&pc->timer);
2319		l3dss1_setup_req(pc, pr, arg);
2320	} else {
2321		L3DelTimer(&pc->timer);
2322		l3dss1_message_cause(pc, MT_RELEASE_COMPLETE, 102);
2323		pc->st->l3.l3l4(pc->st, CC_NOSETUP_RSP, pc);
2324		dss1_release_l3_process(pc);
2325	}
2326}
2327
2328static void
2329l3dss1_t304(struct l3_process *pc, u_char pr, void *arg)
2330{
2331	L3DelTimer(&pc->timer);
2332	pc->para.loc = 0;
2333	pc->para.cause = 102;
2334	l3dss1_disconnect_req(pc, pr, NULL);
2335	pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
2336
2337}
2338
2339static void
2340l3dss1_t305(struct l3_process *pc, u_char pr, void *arg)
2341{
2342	u_char tmp[16];
2343	u_char *p = tmp;
2344	int l;
2345	struct sk_buff *skb;
2346	u_char cause = 16;
2347
2348	L3DelTimer(&pc->timer);
2349	if (pc->para.cause != NO_CAUSE)
2350		cause = pc->para.cause;
2351
2352	MsgHead(p, pc->callref, MT_RELEASE);
2353
2354	*p++ = IE_CAUSE;
2355	*p++ = 0x2;
2356	*p++ = 0x80;
2357	*p++ = cause | 0x80;
2358
2359	l = p - tmp;
2360	if (!(skb = l3_alloc_skb(l)))
2361		return;
2362	memcpy(skb_put(skb, l), tmp, l);
2363	newl3state(pc, 19);
2364	l3_msg(pc->st, DL_DATA | REQUEST, skb);
2365	L3AddTimer(&pc->timer, T308, CC_T308_1);
2366}
2367
2368static void
2369l3dss1_t310(struct l3_process *pc, u_char pr, void *arg)
2370{
2371	L3DelTimer(&pc->timer);
2372	pc->para.loc = 0;
2373	pc->para.cause = 102;
2374	l3dss1_disconnect_req(pc, pr, NULL);
2375	pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
2376}
2377
2378static void
2379l3dss1_t313(struct l3_process *pc, u_char pr, void *arg)
2380{
2381	L3DelTimer(&pc->timer);
2382	pc->para.loc = 0;
2383	pc->para.cause = 102;
2384	l3dss1_disconnect_req(pc, pr, NULL);
2385	pc->st->l3.l3l4(pc->st, CC_CONNECT_ERR, pc);
2386}
2387
2388static void
2389l3dss1_t308_1(struct l3_process *pc, u_char pr, void *arg)
2390{
2391	newl3state(pc, 19);
2392	L3DelTimer(&pc->timer);
2393	l3dss1_message(pc, MT_RELEASE);
2394	L3AddTimer(&pc->timer, T308, CC_T308_2);
2395}
2396
2397static void
2398l3dss1_t308_2(struct l3_process *pc, u_char pr, void *arg)
2399{
2400	L3DelTimer(&pc->timer);
2401	pc->st->l3.l3l4(pc->st, CC_RELEASE_ERR, pc);
2402	dss1_release_l3_process(pc);
2403}
2404
2405static void
2406l3dss1_t318(struct l3_process *pc, u_char pr, void *arg)
2407{
2408	L3DelTimer(&pc->timer);
2409	pc->para.cause = 102;	/* Timer expiry */
2410	pc->para.loc = 0;	/* local */
2411	pc->st->l3.l3l4(pc->st, CC_RESUME_ERR, pc);
2412	newl3state(pc, 19);
2413	l3dss1_message(pc, MT_RELEASE);
2414	L3AddTimer(&pc->timer, T308, CC_T308_1);
2415}
2416
2417static void
2418l3dss1_t319(struct l3_process *pc, u_char pr, void *arg)
2419{
2420	L3DelTimer(&pc->timer);
2421	pc->para.cause = 102;	/* Timer expiry */
2422	pc->para.loc = 0;	/* local */
2423	pc->st->l3.l3l4(pc->st, CC_SUSPEND_ERR, pc);
2424	newl3state(pc, 10);
2425}
2426
2427static void
2428l3dss1_restart(struct l3_process *pc, u_char pr, void *arg)
2429{
2430	L3DelTimer(&pc->timer);
2431	pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
2432	dss1_release_l3_process(pc);
2433}
2434
2435static void
2436l3dss1_status(struct l3_process *pc, u_char pr, void *arg)
2437{
2438	u_char *p;
2439	struct sk_buff *skb = arg;
2440	int ret;
2441	u_char cause = 0, callState = 0;
2442
2443	if ((ret = l3dss1_get_cause(pc, skb))) {
2444		if (pc->debug & L3_DEB_WARN)
2445			l3_debug(pc->st, "STATUS get_cause ret(%d)", ret);
2446		if (ret < 0)
2447			cause = 96;
2448		else if (ret > 0)
2449			cause = 100;
2450	}
2451	if ((p = findie(skb->data, skb->len, IE_CALL_STATE, 0))) {
2452		p++;
2453		if (1 == *p++) {
2454			callState = *p;
2455			if (!ie_in_set(pc, *p, l3_valid_states))
2456				cause = 100;
2457		} else
2458			cause = 100;
2459	} else
2460		cause = 96;
2461	if (!cause) { /*  no error before */
2462		ret = check_infoelements(pc, skb, ie_STATUS);
2463		if (ERR_IE_COMPREHENSION == ret)
2464			cause = 96;
2465		else if (ERR_IE_UNRECOGNIZED == ret)
2466			cause = 99;
2467	}
2468	if (cause) {
2469		u_char tmp;
2470
2471		if (pc->debug & L3_DEB_WARN)
2472			l3_debug(pc->st, "STATUS error(%d/%d)", ret, cause);
2473		tmp = pc->para.cause;
2474		pc->para.cause = cause;
2475		l3dss1_status_send(pc, 0, NULL);
2476		if (cause == 99)
2477			pc->para.cause = tmp;
2478		else
2479			return;
2480	}
2481	cause = pc->para.cause;
2482	if (((cause & 0x7f) == 111) && (callState == 0)) {
2483		/* ETS 300-104 7.6.1, 8.6.1, 10.6.1...
2484		 * if received MT_STATUS with cause == 111 and call
2485		 * state == 0, then we must set down layer 3
2486		 */
2487		pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
2488		newl3state(pc, 0);
2489		dss1_release_l3_process(pc);
2490	}
2491}
2492
2493static void
2494l3dss1_facility(struct l3_process *pc, u_char pr, void *arg)
2495{
2496	struct sk_buff *skb = arg;
2497	int ret;
2498
2499	ret = check_infoelements(pc, skb, ie_FACILITY);
2500	l3dss1_std_ie_err(pc, ret);
2501	{
2502		u_char *p;
2503		if ((p = findie(skb->data, skb->len, IE_FACILITY, 0)))
2504			l3dss1_parse_facility(pc->st, pc, pc->callref, p);
2505	}
2506}
2507
2508static void
2509l3dss1_suspend_req(struct l3_process *pc, u_char pr, void *arg)
2510{
2511	struct sk_buff *skb;
2512	u_char tmp[32];
2513	u_char *p = tmp;
2514	u_char i, l;
2515	u_char *msg = pc->chan->setup.phone;
2516
2517	MsgHead(p, pc->callref, MT_SUSPEND);
2518	l = *msg++;
2519	if (l && (l <= 10)) {	/* Max length 10 octets */
2520		*p++ = IE_CALL_ID;
2521		*p++ = l;
2522		for (i = 0; i < l; i++)
2523			*p++ = *msg++;
2524	} else if (l) {
2525		l3_debug(pc->st, "SUS wrong CALL_ID len %d", l);
2526		return;
2527	}
2528	l = p - tmp;
2529	if (!(skb = l3_alloc_skb(l)))
2530		return;
2531	memcpy(skb_put(skb, l), tmp, l);
2532	l3_msg(pc->st, DL_DATA | REQUEST, skb);
2533	newl3state(pc, 15);
2534	L3AddTimer(&pc->timer, T319, CC_T319);
2535}
2536
2537static void
2538l3dss1_suspend_ack(struct l3_process *pc, u_char pr, void *arg)
2539{
2540	struct sk_buff *skb = arg;
2541	int ret;
2542
2543	L3DelTimer(&pc->timer);
2544	newl3state(pc, 0);
2545	pc->para.cause = NO_CAUSE;
2546	pc->st->l3.l3l4(pc->st, CC_SUSPEND | CONFIRM, pc);
2547	/* We don't handle suspend_ack for IE errors now */
2548	if ((ret = check_infoelements(pc, skb, ie_SUSPEND_ACKNOWLEDGE)))
2549		if (pc->debug & L3_DEB_WARN)
2550			l3_debug(pc->st, "SUSPACK check ie(%d)", ret);
2551	dss1_release_l3_process(pc);
2552}
2553
2554static void
2555l3dss1_suspend_rej(struct l3_process *pc, u_char pr, void *arg)
2556{
2557	struct sk_buff *skb = arg;
2558	int ret;
2559
2560	if ((ret = l3dss1_get_cause(pc, skb))) {
2561		if (pc->debug & L3_DEB_WARN)
2562			l3_debug(pc->st, "SUSP_REJ get_cause ret(%d)", ret);
2563		if (ret < 0)
2564			pc->para.cause = 96;
2565		else
2566			pc->para.cause = 100;
2567		l3dss1_status_send(pc, pr, NULL);
2568		return;
2569	}
2570	ret = check_infoelements(pc, skb, ie_SUSPEND_REJECT);
2571	if (ERR_IE_COMPREHENSION == ret) {
2572		l3dss1_std_ie_err(pc, ret);
2573		return;
2574	}
2575	L3DelTimer(&pc->timer);
2576	pc->st->l3.l3l4(pc->st, CC_SUSPEND_ERR, pc);
2577	newl3state(pc, 10);
2578	if (ret) /* STATUS for none mandatory IE errors after actions are taken */
2579		l3dss1_std_ie_err(pc, ret);
2580}
2581
2582static void
2583l3dss1_resume_req(struct l3_process *pc, u_char pr, void *arg)
2584{
2585	struct sk_buff *skb;
2586	u_char tmp[32];
2587	u_char *p = tmp;
2588	u_char i, l;
2589	u_char *msg = pc->para.setup.phone;
2590
2591	MsgHead(p, pc->callref, MT_RESUME);
2592
2593	l = *msg++;
2594	if (l && (l <= 10)) {	/* Max length 10 octets */
2595		*p++ = IE_CALL_ID;
2596		*p++ = l;
2597		for (i = 0; i < l; i++)
2598			*p++ = *msg++;
2599	} else if (l) {
2600		l3_debug(pc->st, "RES wrong CALL_ID len %d", l);
2601		return;
2602	}
2603	l = p - tmp;
2604	if (!(skb = l3_alloc_skb(l)))
2605		return;
2606	memcpy(skb_put(skb, l), tmp, l);
2607	l3_msg(pc->st, DL_DATA | REQUEST, skb);
2608	newl3state(pc, 17);
2609	L3AddTimer(&pc->timer, T318, CC_T318);
2610}
2611
2612static void
2613l3dss1_resume_ack(struct l3_process *pc, u_char pr, void *arg)
2614{
2615	struct sk_buff *skb = arg;
2616	int id, ret;
2617
2618	if ((id = l3dss1_get_channel_id(pc, skb)) > 0) {
2619		if ((0 == id) || ((3 == id) && (0x10 == pc->para.moderate))) {
2620			if (pc->debug & L3_DEB_WARN)
2621				l3_debug(pc->st, "resume ack with wrong chid %x", id);
2622			pc->para.cause = 100;
2623			l3dss1_status_send(pc, pr, NULL);
2624			return;
2625		}
2626		pc->para.bchannel = id;
2627	} else if (1 == pc->state) {
2628		if (pc->debug & L3_DEB_WARN)
2629			l3_debug(pc->st, "resume ack without chid (ret %d)", id);
2630		pc->para.cause = 96;
2631		l3dss1_status_send(pc, pr, NULL);
2632		return;
2633	}
2634	ret = check_infoelements(pc, skb, ie_RESUME_ACKNOWLEDGE);
2635	if (ERR_IE_COMPREHENSION == ret) {
2636		l3dss1_std_ie_err(pc, ret);
2637		return;
2638	}
2639	L3DelTimer(&pc->timer);
2640	pc->st->l3.l3l4(pc->st, CC_RESUME | CONFIRM, pc);
2641	newl3state(pc, 10);
2642	if (ret) /* STATUS for none mandatory IE errors after actions are taken */
2643		l3dss1_std_ie_err(pc, ret);
2644}
2645
2646static void
2647l3dss1_resume_rej(struct l3_process *pc, u_char pr, void *arg)
2648{
2649	struct sk_buff *skb = arg;
2650	int ret;
2651
2652	if ((ret = l3dss1_get_cause(pc, skb))) {
2653		if (pc->debug & L3_DEB_WARN)
2654			l3_debug(pc->st, "RES_REJ get_cause ret(%d)", ret);
2655		if (ret < 0)
2656			pc->para.cause = 96;
2657		else
2658			pc->para.cause = 100;
2659		l3dss1_status_send(pc, pr, NULL);
2660		return;
2661	}
2662	ret = check_infoelements(pc, skb, ie_RESUME_REJECT);
2663	if (ERR_IE_COMPREHENSION == ret) {
2664		l3dss1_std_ie_err(pc, ret);
2665		return;
2666	}
2667	L3DelTimer(&pc->timer);
2668	pc->st->l3.l3l4(pc->st, CC_RESUME_ERR, pc);
2669	newl3state(pc, 0);
2670	if (ret) /* STATUS for none mandatory IE errors after actions are taken */
2671		l3dss1_std_ie_err(pc, ret);
2672	dss1_release_l3_process(pc);
2673}
2674
2675static void
2676l3dss1_global_restart(struct l3_process *pc, u_char pr, void *arg)
2677{
2678	u_char tmp[32];
2679	u_char *p;
2680	u_char ri, ch = 0, chan = 0;
2681	int l;
2682	struct sk_buff *skb = arg;
2683	struct l3_process *up;
2684
2685	newl3state(pc, 2);
2686	L3DelTimer(&pc->timer);
2687	p = skb->data;
2688	if ((p = findie(p, skb->len, IE_RESTART_IND, 0))) {
2689		ri = p[2];
2690		l3_debug(pc->st, "Restart %x", ri);
2691	} else {
2692		l3_debug(pc->st, "Restart without restart IE");
2693		ri = 0x86;
2694	}
2695	p = skb->data;
2696	if ((p = findie(p, skb->len, IE_CHANNEL_ID, 0))) {
2697		chan = p[2] & 3;
2698		ch = p[2];
2699		if (pc->st->l3.debug)
2700			l3_debug(pc->st, "Restart for channel %d", chan);
2701	}
2702	newl3state(pc, 2);
2703	up = pc->st->l3.proc;
2704	while (up) {
2705		if ((ri & 7) == 7)
2706			up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up);
2707		else if (up->para.bchannel == chan)
2708			up->st->lli.l4l3(up->st, CC_RESTART | REQUEST, up);
2709		up = up->next;
2710	}
2711	p = tmp;
2712	MsgHead(p, pc->callref, MT_RESTART_ACKNOWLEDGE);
2713	if (chan) {
2714		*p++ = IE_CHANNEL_ID;
2715		*p++ = 1;
2716		*p++ = ch | 0x80;
2717	}
2718	*p++ = 0x79;		/* RESTART Ind */
2719	*p++ = 1;
2720	*p++ = ri;
2721	l = p - tmp;
2722	if (!(skb = l3_alloc_skb(l)))
2723		return;
2724	memcpy(skb_put(skb, l), tmp, l);
2725	newl3state(pc, 0);
2726	l3_msg(pc->st, DL_DATA | REQUEST, skb);
2727}
2728
2729static void
2730l3dss1_dl_reset(struct l3_process *pc, u_char pr, void *arg)
2731{
2732	pc->para.cause = 0x29;          /* Temporary failure */
2733	pc->para.loc = 0;
2734	l3dss1_disconnect_req(pc, pr, NULL);
2735	pc->st->l3.l3l4(pc->st, CC_SETUP_ERR, pc);
2736}
2737
2738static void
2739l3dss1_dl_release(struct l3_process *pc, u_char pr, void *arg)
2740{
2741	newl3state(pc, 0);
2742	pc->para.cause = 0x1b;          /* Destination out of order */
2743	pc->para.loc = 0;
2744	pc->st->l3.l3l4(pc->st, CC_RELEASE | INDICATION, pc);
2745	release_l3_process(pc);
2746}
2747
2748static void
2749l3dss1_dl_reestablish(struct l3_process *pc, u_char pr, void *arg)
2750{
2751	L3DelTimer(&pc->timer);
2752	L3AddTimer(&pc->timer, T309, CC_T309);
2753	l3_msg(pc->st, DL_ESTABLISH | REQUEST, NULL);
2754}
2755
2756static void
2757l3dss1_dl_reest_status(struct l3_process *pc, u_char pr, void *arg)
2758{
2759	L3DelTimer(&pc->timer);
2760
2761	pc->para.cause = 0x1F; /* normal, unspecified */
2762	l3dss1_status_send(pc, 0, NULL);
2763}
2764
2765/* *INDENT-OFF* */
2766static struct stateentry downstatelist[] =
2767{
2768	{SBIT(0),
2769	 CC_SETUP | REQUEST, l3dss1_setup_req},
2770	{SBIT(0),
2771	 CC_RESUME | REQUEST, l3dss1_resume_req},
2772	{SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(6) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(25),
2773	 CC_DISCONNECT | REQUEST, l3dss1_disconnect_req},
2774	{SBIT(12),
2775	 CC_RELEASE | REQUEST, l3dss1_release_req},
2776	{ALL_STATES,
2777	 CC_RESTART | REQUEST, l3dss1_restart},
2778	{SBIT(6) | SBIT(25),
2779	 CC_IGNORE | REQUEST, l3dss1_reset},
2780	{SBIT(6) | SBIT(25),
2781	 CC_REJECT | REQUEST, l3dss1_reject_req},
2782	{SBIT(6) | SBIT(25),
2783	 CC_PROCEED_SEND | REQUEST, l3dss1_proceed_req},
2784	{SBIT(6),
2785	 CC_MORE_INFO | REQUEST, l3dss1_setup_ack_req},
2786	{SBIT(25),
2787	 CC_MORE_INFO | REQUEST, l3dss1_dummy},
2788	{SBIT(6) | SBIT(9) | SBIT(25),
2789	 CC_ALERTING | REQUEST, l3dss1_alert_req},
2790	{SBIT(6) | SBIT(7) | SBIT(9) | SBIT(25),
2791	 CC_SETUP | RESPONSE, l3dss1_setup_rsp},
2792	{SBIT(10),
2793	 CC_SUSPEND | REQUEST, l3dss1_suspend_req},
2794	{SBIT(7) | SBIT(9) | SBIT(25),
2795	 CC_REDIR | REQUEST, l3dss1_redir_req},
2796	{SBIT(6),
2797	 CC_REDIR | REQUEST, l3dss1_redir_req_early},
2798	{SBIT(9) | SBIT(25),
2799	 CC_DISCONNECT | REQUEST, l3dss1_disconnect_req},
2800	{SBIT(25),
2801	 CC_T302, l3dss1_t302},
2802	{SBIT(1),
2803	 CC_T303, l3dss1_t303},
2804	{SBIT(2),
2805	 CC_T304, l3dss1_t304},
2806	{SBIT(3),
2807	 CC_T310, l3dss1_t310},
2808	{SBIT(8),
2809	 CC_T313, l3dss1_t313},
2810	{SBIT(11),
2811	 CC_T305, l3dss1_t305},
2812	{SBIT(15),
2813	 CC_T319, l3dss1_t319},
2814	{SBIT(17),
2815	 CC_T318, l3dss1_t318},
2816	{SBIT(19),
2817	 CC_T308_1, l3dss1_t308_1},
2818	{SBIT(19),
2819	 CC_T308_2, l3dss1_t308_2},
2820	{SBIT(10),
2821	 CC_T309, l3dss1_dl_release},
2822};
2823
2824static struct stateentry datastatelist[] =
2825{
2826	{ALL_STATES,
2827	 MT_STATUS_ENQUIRY, l3dss1_status_enq},
2828	{ALL_STATES,
2829	 MT_FACILITY, l3dss1_facility},
2830	{SBIT(19),
2831	 MT_STATUS, l3dss1_release_ind},
2832	{ALL_STATES,
2833	 MT_STATUS, l3dss1_status},
2834	{SBIT(0),
2835	 MT_SETUP, l3dss1_setup},
2836	{SBIT(6) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(11) | SBIT(12) |
2837	 SBIT(15) | SBIT(17) | SBIT(19) | SBIT(25),
2838	 MT_SETUP, l3dss1_dummy},
2839	{SBIT(1) | SBIT(2),
2840	 MT_CALL_PROCEEDING, l3dss1_call_proc},
2841	{SBIT(1),
2842	 MT_SETUP_ACKNOWLEDGE, l3dss1_setup_ack},
2843	{SBIT(2) | SBIT(3),
2844	 MT_ALERTING, l3dss1_alerting},
2845	{SBIT(2) | SBIT(3),
2846	 MT_PROGRESS, l3dss1_progress},
2847	{SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) |
2848	 SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19) | SBIT(25),
2849	 MT_INFORMATION, l3dss1_information},
2850	{SBIT(10) | SBIT(11) | SBIT(15),
2851	 MT_NOTIFY, l3dss1_notify},
2852	{SBIT(0) | SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(10) |
2853	 SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(19) | SBIT(25),
2854	 MT_RELEASE_COMPLETE, l3dss1_release_cmpl},
2855	{SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(11) | SBIT(12) | SBIT(15) | SBIT(17) | SBIT(25),
2856	 MT_RELEASE, l3dss1_release},
2857	{SBIT(19),  MT_RELEASE, l3dss1_release_ind},
2858	{SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4) | SBIT(7) | SBIT(8) | SBIT(9) | SBIT(10) | SBIT(11) | SBIT(15) | SBIT(17) | SBIT(25),
2859	 MT_DISCONNECT, l3dss1_disconnect},
2860	{SBIT(19),
2861	 MT_DISCONNECT, l3dss1_dummy},
2862	{SBIT(1) | SBIT(2) | SBIT(3) | SBIT(4),
2863	 MT_CONNECT, l3dss1_connect},
2864	{SBIT(8),
2865	 MT_CONNECT_ACKNOWLEDGE, l3dss1_connect_ack},
2866	{SBIT(15),
2867	 MT_SUSPEND_ACKNOWLEDGE, l3dss1_suspend_ack},
2868	{SBIT(15),
2869	 MT_SUSPEND_REJECT, l3dss1_suspend_rej},
2870	{SBIT(17),
2871	 MT_RESUME_ACKNOWLEDGE, l3dss1_resume_ack},
2872	{SBIT(17),
2873	 MT_RESUME_REJECT, l3dss1_resume_rej},
2874};
2875
2876static struct stateentry globalmes_list[] =
2877{
2878	{ALL_STATES,
2879	 MT_STATUS, l3dss1_status},
2880	{SBIT(0),
2881	 MT_RESTART, l3dss1_global_restart},
2882/*	{SBIT(1),
2883	MT_RESTART_ACKNOWLEDGE, l3dss1_restart_ack},
2884*/
2885};
2886
2887static struct stateentry manstatelist[] =
2888{
2889	{SBIT(2),
2890	 DL_ESTABLISH | INDICATION, l3dss1_dl_reset},
2891	{SBIT(10),
2892	 DL_ESTABLISH | CONFIRM, l3dss1_dl_reest_status},
2893	{SBIT(10),
2894	 DL_RELEASE | INDICATION, l3dss1_dl_reestablish},
2895	{ALL_STATES,
2896	 DL_RELEASE | INDICATION, l3dss1_dl_release},
2897};
2898
2899/* *INDENT-ON* */
2900
2901
2902static void
2903global_handler(struct PStack *st, int mt, struct sk_buff *skb)
2904{
2905	u_char tmp[16];
2906	u_char *p = tmp;
2907	int l;
2908	int i;
2909	struct l3_process *proc = st->l3.global;
2910
2911	proc->callref = skb->data[2]; /* cr flag */
2912	for (i = 0; i < ARRAY_SIZE(globalmes_list); i++)
2913		if ((mt == globalmes_list[i].primitive) &&
2914		    ((1 << proc->state) & globalmes_list[i].state))
2915			break;
2916	if (i == ARRAY_SIZE(globalmes_list)) {
2917		if (st->l3.debug & L3_DEB_STATE) {
2918			l3_debug(st, "dss1 global state %d mt %x unhandled",
2919				 proc->state, mt);
2920		}
2921		MsgHead(p, proc->callref, MT_STATUS);
2922		*p++ = IE_CAUSE;
2923		*p++ = 0x2;
2924		*p++ = 0x80;
2925		*p++ = 81 | 0x80;	/* invalid cr */
2926		*p++ = 0x14;		/* CallState */
2927		*p++ = 0x1;
2928		*p++ = proc->state & 0x3f;
2929		l = p - tmp;
2930		if (!(skb = l3_alloc_skb(l)))
2931			return;
2932		memcpy(skb_put(skb, l), tmp, l);
2933		l3_msg(proc->st, DL_DATA | REQUEST, skb);
2934	} else {
2935		if (st->l3.debug & L3_DEB_STATE) {
2936			l3_debug(st, "dss1 global %d mt %x",
2937				 proc->state, mt);
2938		}
2939		globalmes_list[i].rout(proc, mt, skb);
2940	}
2941}
2942
2943static void
2944dss1up(struct PStack *st, int pr, void *arg)
2945{
2946	int i, mt, cr, callState;
2947	char *ptr;
2948	u_char *p;
2949	struct sk_buff *skb = arg;
2950	struct l3_process *proc;
2951
2952	switch (pr) {
2953	case (DL_DATA | INDICATION):
2954	case (DL_UNIT_DATA | INDICATION):
2955		break;
2956	case (DL_ESTABLISH | CONFIRM):
2957	case (DL_ESTABLISH | INDICATION):
2958	case (DL_RELEASE | INDICATION):
2959	case (DL_RELEASE | CONFIRM):
2960		l3_msg(st, pr, arg);
2961		return;
2962		break;
2963	default:
2964		printk(KERN_ERR "HiSax dss1up unknown pr=%04x\n", pr);
2965		return;
2966	}
2967	if (skb->len < 3) {
2968		l3_debug(st, "dss1up frame too short(%d)", skb->len);
2969		dev_kfree_skb(skb);
2970		return;
2971	}
2972
2973	if (skb->data[0] != PROTO_DIS_EURO) {
2974		if (st->l3.debug & L3_DEB_PROTERR) {
2975			l3_debug(st, "dss1up%sunexpected discriminator %x message len %d",
2976				 (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
2977				 skb->data[0], skb->len);
2978		}
2979		dev_kfree_skb(skb);
2980		return;
2981	}
2982	cr = getcallref(skb->data);
2983	if (skb->len < ((skb->data[1] & 0x0f) + 3)) {
2984		l3_debug(st, "dss1up frame too short(%d)", skb->len);
2985		dev_kfree_skb(skb);
2986		return;
2987	}
2988	mt = skb->data[skb->data[1] + 2];
2989	if (st->l3.debug & L3_DEB_STATE)
2990		l3_debug(st, "dss1up cr %d", cr);
2991	if (cr == -2) {  /* wrong Callref */
2992		if (st->l3.debug & L3_DEB_WARN)
2993			l3_debug(st, "dss1up wrong Callref");
2994		dev_kfree_skb(skb);
2995		return;
2996	} else if (cr == -1) {	/* Dummy Callref */
2997		if (mt == MT_FACILITY)
2998			if ((p = findie(skb->data, skb->len, IE_FACILITY, 0))) {
2999				l3dss1_parse_facility(st, NULL,
3000						      (pr == (DL_DATA | INDICATION)) ? -1 : -2, p);
3001				dev_kfree_skb(skb);
3002				return;
3003			}
3004		if (st->l3.debug & L3_DEB_WARN)
3005			l3_debug(st, "dss1up dummy Callref (no facility msg or ie)");
3006		dev_kfree_skb(skb);
3007		return;
3008	} else if ((((skb->data[1] & 0x0f) == 1) && (0 == (cr & 0x7f))) ||
3009		   (((skb->data[1] & 0x0f) == 2) && (0 == (cr & 0x7fff)))) {	/* Global CallRef */
3010		if (st->l3.debug & L3_DEB_STATE)
3011			l3_debug(st, "dss1up Global CallRef");
3012		global_handler(st, mt, skb);
3013		dev_kfree_skb(skb);
3014		return;
3015	} else if (!(proc = getl3proc(st, cr))) {
3016		/* No transaction process exist, that means no call with
3017		 * this callreference is active
3018		 */
3019		if (mt == MT_SETUP) {
3020			/* Setup creates a new transaction process */
3021			if (skb->data[2] & 0x80) {
3022				/* Setup with wrong CREF flag */
3023				if (st->l3.debug & L3_DEB_STATE)
3024					l3_debug(st, "dss1up wrong CRef flag");
3025				dev_kfree_skb(skb);
3026				return;
3027			}
3028			if (!(proc = dss1_new_l3_process(st, cr))) {
3029				/* May be to answer with RELEASE_COMPLETE and
3030				 * CAUSE 0x2f "Resource unavailable", but this
3031				 * need a new_l3_process too ... arghh
3032				 */
3033				dev_kfree_skb(skb);
3034				return;
3035			}
3036		} else if (mt == MT_STATUS) {
3037			if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) {
3038				ptr++;
3039				if (*ptr++ == 2)
3040					ptr++;
3041			}
3042			callState = 0;
3043			if ((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) {
3044				ptr++;
3045				if (*ptr++ == 2)
3046					ptr++;
3047				callState = *ptr;
3048			}
3049			/* ETS 300-104 part 2.4.1
3050			 * if setup has not been made and a message type
3051			 * MT_STATUS is received with call state == 0,
3052			 * we must send nothing
3053			 */
3054			if (callState != 0) {
3055				/* ETS 300-104 part 2.4.2
3056				 * if setup has not been made and a message type
3057				 * MT_STATUS is received with call state != 0,
3058				 * we must send MT_RELEASE_COMPLETE cause 101
3059				 */
3060				if ((proc = dss1_new_l3_process(st, cr))) {
3061					proc->para.cause = 101;
3062					l3dss1_msg_without_setup(proc, 0, NULL);
3063				}
3064			}
3065			dev_kfree_skb(skb);
3066			return;
3067		} else if (mt == MT_RELEASE_COMPLETE) {
3068			dev_kfree_skb(skb);
3069			return;
3070		} else {
3071			/* ETS 300-104 part 2
3072			 * if setup has not been made and a message type
3073			 * (except MT_SETUP and RELEASE_COMPLETE) is received,
3074			 * we must send MT_RELEASE_COMPLETE cause 81 */
3075			dev_kfree_skb(skb);
3076			if ((proc = dss1_new_l3_process(st, cr))) {
3077				proc->para.cause = 81;
3078				l3dss1_msg_without_setup(proc, 0, NULL);
3079			}
3080			return;
3081		}
3082	}
3083	if (l3dss1_check_messagetype_validity(proc, mt, skb)) {
3084		dev_kfree_skb(skb);
3085		return;
3086	}
3087	if ((p = findie(skb->data, skb->len, IE_DISPLAY, 0)) != NULL)
3088		l3dss1_deliver_display(proc, pr, p); /* Display IE included */
3089	for (i = 0; i < ARRAY_SIZE(datastatelist); i++)
3090		if ((mt == datastatelist[i].primitive) &&
3091		    ((1 << proc->state) & datastatelist[i].state))
3092			break;
3093	if (i == ARRAY_SIZE(datastatelist)) {
3094		if (st->l3.debug & L3_DEB_STATE) {
3095			l3_debug(st, "dss1up%sstate %d mt %#x unhandled",
3096				 (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
3097				 proc->state, mt);
3098		}
3099		if ((MT_RELEASE_COMPLETE != mt) && (MT_RELEASE != mt)) {
3100			proc->para.cause = 101;
3101			l3dss1_status_send(proc, pr, skb);
3102		}
3103	} else {
3104		if (st->l3.debug & L3_DEB_STATE) {
3105			l3_debug(st, "dss1up%sstate %d mt %x",
3106				 (pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
3107				 proc->state, mt);
3108		}
3109		datastatelist[i].rout(proc, pr, skb);
3110	}
3111	dev_kfree_skb(skb);
3112	return;
3113}
3114
3115static void
3116dss1down(struct PStack *st, int pr, void *arg)
3117{
3118	int i, cr;
3119	struct l3_process *proc;
3120	struct Channel *chan;
3121
3122	if ((DL_ESTABLISH | REQUEST) == pr) {
3123		l3_msg(st, pr, NULL);
3124		return;
3125	} else if (((CC_SETUP | REQUEST) == pr) || ((CC_RESUME | REQUEST) == pr)) {
3126		chan = arg;
3127		cr = newcallref();
3128		cr |= 0x80;
3129		if ((proc = dss1_new_l3_process(st, cr))) {
3130			proc->chan = chan;
3131			chan->proc = proc;
3132			memcpy(&proc->para.setup, &chan->setup, sizeof(setup_parm));
3133			proc->callref = cr;
3134		}
3135	} else {
3136		proc = arg;
3137	}
3138	if (!proc) {
3139		printk(KERN_ERR "HiSax dss1down without proc pr=%04x\n", pr);
3140		return;
3141	}
3142
3143	if (pr == (CC_TDSS1_IO | REQUEST)) {
3144		l3dss1_io_timer(proc); /* timer expires */
3145		return;
3146	}
3147
3148	for (i = 0; i < ARRAY_SIZE(downstatelist); i++)
3149		if ((pr == downstatelist[i].primitive) &&
3150		    ((1 << proc->state) & downstatelist[i].state))
3151			break;
3152	if (i == ARRAY_SIZE(downstatelist)) {
3153		if (st->l3.debug & L3_DEB_STATE) {
3154			l3_debug(st, "dss1down state %d prim %#x unhandled",
3155				 proc->state, pr);
3156		}
3157	} else {
3158		if (st->l3.debug & L3_DEB_STATE) {
3159			l3_debug(st, "dss1down state %d prim %#x",
3160				 proc->state, pr);
3161		}
3162		downstatelist[i].rout(proc, pr, arg);
3163	}
3164}
3165
3166static void
3167dss1man(struct PStack *st, int pr, void *arg)
3168{
3169	int i;
3170	struct l3_process *proc = arg;
3171
3172	if (!proc) {
3173		printk(KERN_ERR "HiSax dss1man without proc pr=%04x\n", pr);
3174		return;
3175	}
3176	for (i = 0; i < ARRAY_SIZE(manstatelist); i++)
3177		if ((pr == manstatelist[i].primitive) &&
3178		    ((1 << proc->state) & manstatelist[i].state))
3179			break;
3180	if (i == ARRAY_SIZE(manstatelist)) {
3181		if (st->l3.debug & L3_DEB_STATE) {
3182			l3_debug(st, "cr %d dss1man state %d prim %#x unhandled",
3183				 proc->callref & 0x7f, proc->state, pr);
3184		}
3185	} else {
3186		if (st->l3.debug & L3_DEB_STATE) {
3187			l3_debug(st, "cr %d dss1man state %d prim %#x",
3188				 proc->callref & 0x7f, proc->state, pr);
3189		}
3190		manstatelist[i].rout(proc, pr, arg);
3191	}
3192}
3193
3194void
3195setstack_dss1(struct PStack *st)
3196{
3197	char tmp[64];
3198	int i;
3199
3200	st->lli.l4l3 = dss1down;
3201	st->lli.l4l3_proto = l3dss1_cmd_global;
3202	st->l2.l2l3 = dss1up;
3203	st->l3.l3ml3 = dss1man;
3204	st->l3.N303 = 1;
3205	st->prot.dss1.last_invoke_id = 0;
3206	st->prot.dss1.invoke_used[0] = 1; /* Bit 0 must always be set to 1 */
3207	i = 1;
3208	while (i < 32)
3209		st->prot.dss1.invoke_used[i++] = 0;
3210
3211	if (!(st->l3.global = kmalloc(sizeof(struct l3_process), GFP_ATOMIC))) {
3212		printk(KERN_ERR "HiSax can't get memory for dss1 global CR\n");
3213	} else {
3214		st->l3.global->state = 0;
3215		st->l3.global->callref = 0;
3216		st->l3.global->next = NULL;
3217		st->l3.global->debug = L3_DEB_WARN;
3218		st->l3.global->st = st;
3219		st->l3.global->N303 = 1;
3220		st->l3.global->prot.dss1.invoke_id = 0;
3221
3222		L3InitTimer(st->l3.global, &st->l3.global->timer);
3223	}
3224	strcpy(tmp, dss1_revision);
3225	printk(KERN_INFO "HiSax: DSS1 Rev. %s\n", HiSax_getrev(tmp));
3226}
3227