• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/isdn/hisax/
1/* $Id: l3dss1.c,v 2.32.2.3 2004/01/13 14:31:25 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 HISAX_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 HISAX_DE_AOC */
426                        l3_debug(st, "invoke break");
427#endif /* not HISAX_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
614static 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 occurence '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 independant 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, cause, 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			cause = 0;
3038			if ((ptr = findie(skb->data, skb->len, IE_CAUSE, 0)) != NULL) {
3039				ptr++;
3040				if (*ptr++ == 2)
3041					ptr++;
3042				cause = *ptr & 0x7f;
3043			}
3044			callState = 0;
3045			if ((ptr = findie(skb->data, skb->len, IE_CALL_STATE, 0)) != NULL) {
3046				ptr++;
3047				if (*ptr++ == 2)
3048					ptr++;
3049				callState = *ptr;
3050			}
3051			/* ETS 300-104 part 2.4.1
3052			 * if setup has not been made and a message type
3053			 * MT_STATUS is received with call state == 0,
3054			 * we must send nothing
3055			 */
3056			if (callState != 0) {
3057				/* ETS 300-104 part 2.4.2
3058				 * if setup has not been made and a message type
3059				 * MT_STATUS is received with call state != 0,
3060				 * we must send MT_RELEASE_COMPLETE cause 101
3061				 */
3062				if ((proc = dss1_new_l3_process(st, cr))) {
3063					proc->para.cause = 101;
3064					l3dss1_msg_without_setup(proc, 0, NULL);
3065				}
3066			}
3067			dev_kfree_skb(skb);
3068			return;
3069		} else if (mt == MT_RELEASE_COMPLETE) {
3070			dev_kfree_skb(skb);
3071			return;
3072		} else {
3073			/* ETS 300-104 part 2
3074			 * if setup has not been made and a message type
3075			 * (except MT_SETUP and RELEASE_COMPLETE) is received,
3076			 * we must send MT_RELEASE_COMPLETE cause 81 */
3077			dev_kfree_skb(skb);
3078			if ((proc = dss1_new_l3_process(st, cr))) {
3079				proc->para.cause = 81;
3080				l3dss1_msg_without_setup(proc, 0, NULL);
3081			}
3082			return;
3083		}
3084	}
3085	if (l3dss1_check_messagetype_validity(proc, mt, skb)) {
3086		dev_kfree_skb(skb);
3087		return;
3088	}
3089	if ((p = findie(skb->data, skb->len, IE_DISPLAY, 0)) != NULL)
3090	  l3dss1_deliver_display(proc, pr, p); /* Display IE included */
3091	for (i = 0; i < ARRAY_SIZE(datastatelist); i++)
3092		if ((mt == datastatelist[i].primitive) &&
3093		    ((1 << proc->state) & datastatelist[i].state))
3094			break;
3095	if (i == ARRAY_SIZE(datastatelist)) {
3096		if (st->l3.debug & L3_DEB_STATE) {
3097			l3_debug(st, "dss1up%sstate %d mt %#x unhandled",
3098				(pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
3099				proc->state, mt);
3100		}
3101		if ((MT_RELEASE_COMPLETE != mt) && (MT_RELEASE != mt)) {
3102			proc->para.cause = 101;
3103			l3dss1_status_send(proc, pr, skb);
3104		}
3105	} else {
3106		if (st->l3.debug & L3_DEB_STATE) {
3107			l3_debug(st, "dss1up%sstate %d mt %x",
3108				(pr == (DL_DATA | INDICATION)) ? " " : "(broadcast) ",
3109				proc->state, mt);
3110		}
3111		datastatelist[i].rout(proc, pr, skb);
3112	}
3113	dev_kfree_skb(skb);
3114	return;
3115}
3116
3117static void
3118dss1down(struct PStack *st, int pr, void *arg)
3119{
3120	int i, cr;
3121	struct l3_process *proc;
3122	struct Channel *chan;
3123
3124	if ((DL_ESTABLISH | REQUEST) == pr) {
3125		l3_msg(st, pr, NULL);
3126		return;
3127	} else if (((CC_SETUP | REQUEST) == pr) || ((CC_RESUME | REQUEST) == pr)) {
3128		chan = arg;
3129		cr = newcallref();
3130		cr |= 0x80;
3131		if ((proc = dss1_new_l3_process(st, cr))) {
3132			proc->chan = chan;
3133			chan->proc = proc;
3134			memcpy(&proc->para.setup, &chan->setup, sizeof(setup_parm));
3135			proc->callref = cr;
3136		}
3137	} else {
3138		proc = arg;
3139	}
3140	if (!proc) {
3141		printk(KERN_ERR "HiSax dss1down without proc pr=%04x\n", pr);
3142		return;
3143	}
3144
3145	if ( pr == (CC_TDSS1_IO | REQUEST)) {
3146		l3dss1_io_timer(proc); /* timer expires */
3147		return;
3148	}
3149
3150	for (i = 0; i < ARRAY_SIZE(downstatelist); i++)
3151		if ((pr == downstatelist[i].primitive) &&
3152		    ((1 << proc->state) & downstatelist[i].state))
3153			break;
3154	if (i == ARRAY_SIZE(downstatelist)) {
3155		if (st->l3.debug & L3_DEB_STATE) {
3156			l3_debug(st, "dss1down state %d prim %#x unhandled",
3157				proc->state, pr);
3158		}
3159	} else {
3160		if (st->l3.debug & L3_DEB_STATE) {
3161			l3_debug(st, "dss1down state %d prim %#x",
3162				proc->state, pr);
3163		}
3164		downstatelist[i].rout(proc, pr, arg);
3165	}
3166}
3167
3168static void
3169dss1man(struct PStack *st, int pr, void *arg)
3170{
3171        int i;
3172        struct l3_process *proc = arg;
3173
3174        if (!proc) {
3175                printk(KERN_ERR "HiSax dss1man without proc pr=%04x\n", pr);
3176                return;
3177        }
3178        for (i = 0; i < ARRAY_SIZE(manstatelist); i++)
3179                if ((pr == manstatelist[i].primitive) &&
3180                    ((1 << proc->state) & manstatelist[i].state))
3181                        break;
3182        if (i == ARRAY_SIZE(manstatelist)) {
3183                if (st->l3.debug & L3_DEB_STATE) {
3184                        l3_debug(st, "cr %d dss1man state %d prim %#x unhandled",
3185                                proc->callref & 0x7f, proc->state, pr);
3186                }
3187        } else {
3188                if (st->l3.debug & L3_DEB_STATE) {
3189                        l3_debug(st, "cr %d dss1man state %d prim %#x",
3190                                proc->callref & 0x7f, proc->state, pr);
3191                }
3192                manstatelist[i].rout(proc, pr, arg);
3193        }
3194}
3195
3196void
3197setstack_dss1(struct PStack *st)
3198{
3199	char tmp[64];
3200	int i;
3201
3202	st->lli.l4l3 = dss1down;
3203	st->lli.l4l3_proto = l3dss1_cmd_global;
3204	st->l2.l2l3 = dss1up;
3205	st->l3.l3ml3 = dss1man;
3206	st->l3.N303 = 1;
3207	st->prot.dss1.last_invoke_id = 0;
3208	st->prot.dss1.invoke_used[0] = 1; /* Bit 0 must always be set to 1 */
3209	i = 1;
3210	while (i < 32)
3211		st->prot.dss1.invoke_used[i++] = 0;
3212
3213	if (!(st->l3.global = kmalloc(sizeof(struct l3_process), GFP_ATOMIC))) {
3214		printk(KERN_ERR "HiSax can't get memory for dss1 global CR\n");
3215	} else {
3216		st->l3.global->state = 0;
3217		st->l3.global->callref = 0;
3218		st->l3.global->next = NULL;
3219		st->l3.global->debug = L3_DEB_WARN;
3220		st->l3.global->st = st;
3221		st->l3.global->N303 = 1;
3222		st->l3.global->prot.dss1.invoke_id = 0;
3223
3224		L3InitTimer(st->l3.global, &st->l3.global->timer);
3225	}
3226	strcpy(tmp, dss1_revision);
3227	printk(KERN_INFO "HiSax: DSS1 Rev. %s\n", HiSax_getrev(tmp));
3228}
3229