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