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