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