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