root/drivers/isdn/teles/isdnl3.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. i_down
  2. newl3state
  3. l3_message
  4. l3s3
  5. l3s4
  6. l3s5
  7. l3s6
  8. l3s7
  9. l3s8
  10. l3s11
  11. l3s12
  12. l3s13
  13. l3s15
  14. l3s16
  15. l3s17
  16. l3s18
  17. l3s19
  18. l3s20
  19. l3up
  20. l3down
  21. setstack_isdnl3

   1 #define __NO_VERSION__
   2 #define P_1TR6
   3 #include "teles.h"
   4 #include "l3_1TR6.h"
   5 #define DEBUG_1TR6 0
   6 
   7 static void
   8 i_down(struct PStack *st,
     /* [previous][next][first][last][top][bottom][index][help] */
   9        struct BufHeader *ibh)
  10 {
  11         st->l3.l3l2(st, DL_DATA, ibh);
  12 }
  13 
  14 static void
  15 newl3state(struct PStack *st, int state)
     /* [previous][next][first][last][top][bottom][index][help] */
  16 {
  17         st->l3.state = state;
  18         if (DEBUG_1TR6 > 4)
  19                 printk(KERN_INFO "isdnl3: bc:%d cr:%x new state %d\n",
  20                        st->pa->bchannel, st->pa->callref, state);
  21 
  22 }
  23 
  24 static void
  25 l3_message(struct PStack *st, int mt)
     /* [previous][next][first][last][top][bottom][index][help] */
  26 {
  27         struct BufHeader *dibh;
  28         byte           *p;
  29         int             size;
  30 
  31         BufPoolGet(&dibh, st->l1.sbufpool, GFP_ATOMIC, (void *) st, 18);
  32         p = DATAPTR(dibh);
  33         p += st->l2.ihsize;
  34         size = st->l2.ihsize;
  35 
  36         *p++ = 0x8;
  37         *p++ = 0x1;
  38         *p++ = st->l3.callref;
  39         *p++ = mt;
  40         size += 4;
  41 
  42         dibh->datasize = size;
  43         i_down(st, dibh);
  44 }
  45 
  46 static void
  47 l3s3(struct PStack *st, byte pr, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
  48 {
  49         l3_message(st, MT_RELEASE);
  50         newl3state(st, 19);
  51 }
  52 
  53 static void
  54 l3s4(struct PStack *st, byte pr, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
  55 {
  56         struct BufHeader *ibh = arg;
  57 
  58         BufPoolRelease(ibh);
  59         newl3state(st, 0);
  60         st->l3.l3l4(st, CC_RELEASE_CNF, NULL);
  61 }
  62 
  63 static void
  64 l3s5(struct PStack *st, byte pr,
     /* [previous][next][first][last][top][bottom][index][help] */
  65      void *arg)
  66 {
  67         struct BufHeader *dibh;
  68         byte           *p;
  69         char           *teln;
  70 
  71         st->l3.callref = st->pa->callref;
  72         BufPoolGet(&dibh, st->l1.sbufpool, GFP_ATOMIC, (void *) st, 19);
  73         p = DATAPTR(dibh);
  74         p += st->l2.ihsize;
  75 
  76         *p++ = 0x8;
  77         *p++ = 0x1;
  78         *p++ = st->l3.callref;
  79         *p++ = MT_SETUP;
  80         *p++ = 0xa1;
  81 
  82         /*
  83          * Set Bearer Capability, Map info from 1TR6-convention to EDSS1
  84          */
  85         switch (st->pa->info) {
  86           case 1:               /* Telephony                               */
  87                   *p++ = 0x4;   /* BC-IE-code                              */
  88                   *p++ = 0x3;   /* Length                                  */
  89                   *p++ = 0x90;  /* Coding Std. national, 3.1 kHz audio     */
  90                   *p++ = 0x90;  /* Circuit-Mode 64kbps                     */
  91                   *p++ = 0xa3;  /* A-Law Audio                             */
  92                   break;
  93           case 5:               /* Datatransmission 64k, BTX               */
  94           case 7:               /* Datatransmission 64k                    */
  95           default:
  96                   *p++ = 0x4;   /* BC-IE-code                              */
  97                   *p++ = 0x2;   /* Length                                  */
  98                   *p++ = 0x88;  /* Coding Std. nat., unrestr. dig. Inform. */
  99                   *p++ = 0x90;  /* Packet-Mode 64kbps                      */
 100                   break;
 101         }
 102 /*
 103  * What about info2? Mapping to High-Layer-Compatibility?
 104  */
 105 
 106 #if 0                           /* user-user not allowed in The Netherlands! */
 107         *p++ = 0x7f;
 108         *p++ = 0x2;
 109         *p++ = 0x0;
 110         *p++ = 66;
 111 #endif
 112 
 113         if (st->pa->calling[0] != '\0') {
 114                 *p++ = 0x6c;
 115                 *p++ = strlen(st->pa->calling) + 1;
 116                 /* Classify as AnyPref. */
 117                 *p++ = 0x81;    /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
 118                 teln = st->pa->calling;
 119                 while (*teln)
 120                         *p++ = *teln++ & 0x7f;
 121         }
 122         *p++ = 0x70;
 123         *p++ = strlen(st->pa->called) + 1;
 124         /* Classify as AnyPref. */
 125         *p++ = 0x81;            /* Ext = '1'B, Type = '000'B, Plan = '0001'B. */
 126 
 127         teln = st->pa->called;
 128         while (*teln)
 129                 *p++ = *teln++ & 0x7f;
 130 
 131 
 132         dibh->datasize = p - DATAPTR(dibh);
 133 
 134         newl3state(st, 1);
 135         i_down(st, dibh);
 136 
 137 }
 138 
 139 static void
 140 l3s6(struct PStack *st, byte pr, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 141 {
 142         byte           *p;
 143         struct BufHeader *ibh = arg;
 144 
 145         p = DATAPTR(ibh);
 146         if ((p = findie(p + st->l2.ihsize, ibh->datasize - st->l2.ihsize,
 147                         0x18, 0))) {
 148                 st->pa->bchannel = p[2] & 0x3;
 149         } else
 150                 printk(KERN_WARNING "octect 3 not found\n");
 151 
 152         BufPoolRelease(ibh);
 153         newl3state(st, 3);
 154         st->l3.l3l4(st, CC_PROCEEDING_IND, NULL);
 155 }
 156 
 157 static void
 158 l3s7(struct PStack *st, byte pr, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 159 {
 160         struct BufHeader *ibh = arg;
 161 
 162         BufPoolRelease(ibh);
 163         newl3state(st, 12);
 164         st->l3.l3l4(st, CC_DISCONNECT_IND, NULL);
 165 }
 166 
 167 static void
 168 l3s8(struct PStack *st, byte pr, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 169 {
 170         struct BufHeader *ibh = arg;
 171 
 172         BufPoolRelease(ibh);
 173         st->l3.l3l4(st, CC_SETUP_CNF, NULL);
 174         newl3state(st, 10);
 175 }
 176 
 177 static void
 178 l3s11(struct PStack *st, byte pr, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 179 {
 180         struct BufHeader *ibh = arg;
 181 
 182         BufPoolRelease(ibh);
 183         newl3state(st, 4);
 184         st->l3.l3l4(st, CC_ALERTING_IND, NULL);
 185 }
 186 
 187 static void
 188 l3s12(struct PStack *st, byte pr, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 189 {
 190         byte           *p;
 191         struct BufHeader *ibh = arg;
 192 
 193         p = DATAPTR(ibh);
 194         p += st->l2.uihsize;
 195         st->pa->callref = getcallref(p);
 196         st->l3.callref = 0x80 + st->pa->callref;
 197 
 198         /*
 199          * Channel Identification
 200          */
 201         p = DATAPTR(ibh);
 202         if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize,
 203                         0x18, 0))) {
 204                 st->pa->bchannel = p[2] & 0x3;
 205         } else
 206                 printk(KERN_WARNING "l3s12: Channel ident not found\n");
 207 
 208         p = DATAPTR(ibh);
 209         if (st->protocol == ISDN_PTYPE_1TR6) {
 210                 if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize, 0x01, 6))) {
 211                         st->pa->info = p[2];
 212                         st->pa->info2 = p[3];
 213                 } else
 214                         printk(KERN_WARNING "l3s12(1TR6): ServiceIndicator not found\n");
 215         } else {
 216                 /*
 217                  * Bearer Capabilities
 218                  */
 219                 if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize, 0x04, 0))) {
 220                         switch (p[2] & 0x1f) {
 221                           case 0x00:
 222                                   /* Speech */
 223                           case 0x10:
 224                                   /* 3.1 Khz audio */
 225                                   st->pa->info = 1;
 226                                   break;
 227                           case 0x08:
 228                                   /* Unrestricted digital information */
 229                                   st->pa->info = 7;
 230                                   break;
 231                           case 0x09:
 232                                   /* Restricted digital information */
 233                                   st->pa->info = 2;
 234                                   break;
 235                           case 0x11:
 236                                   /* Unrestr. digital information  with tones/announcements */
 237                                   st->pa->info = 3;
 238                                   break;
 239                           case 0x18:
 240                                   /* Video */
 241                                   st->pa->info = 4;
 242                                   break;
 243                           default:
 244                                   st->pa->info = 0;
 245                         }
 246                 } else
 247                         printk(KERN_WARNING "l3s12: Bearer capabilities not found\n");
 248         }
 249 
 250         p = DATAPTR(ibh);
 251         if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize,
 252                         0x70, 0)))
 253                 iecpy(st->pa->called, p, 1);
 254         else
 255                 strcpy(st->pa->called, "");
 256 
 257         p = DATAPTR(ibh);
 258         if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize,
 259                         0x6c, 0))) {
 260                 if (st->protocol == ISDN_PTYPE_1TR6)
 261                         iecpy(st->pa->calling, p, 1);
 262                 else
 263                         iecpy(st->pa->calling, p, 2);
 264         } else
 265                 strcpy(st->pa->calling, "");
 266         BufPoolRelease(ibh);
 267 
 268         if (st->pa->info == 7) {
 269                 newl3state(st, 6);
 270                 st->l3.l3l4(st, CC_SETUP_IND, NULL);
 271         } else {
 272                 printk(KERN_WARNING "non-digital call: %s -> %s\n",
 273                        st->pa->calling,
 274                        st->pa->called);
 275         }
 276 }
 277 
 278 static void
 279 l3s13(struct PStack *st, byte pr, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 280 {
 281         newl3state(st, 0);
 282 }
 283 
 284 #ifdef DEFINED_BUT_NOT_USED
 285 static void
 286 l3s15(struct PStack *st, byte pr, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 287 {
 288         newl3state(st, 0);
 289         st->l3.l3l4(st, CC_REJECT, NULL);
 290 }
 291 #endif
 292 
 293 static void
 294 l3s16(struct PStack *st, byte pr,
     /* [previous][next][first][last][top][bottom][index][help] */
 295       void *arg)
 296 {
 297         st->l3.callref = 0x80 + st->pa->callref;
 298         l3_message(st, MT_CONNECT);
 299         newl3state(st, 8);
 300 }
 301 
 302 static void
 303 l3s17(struct PStack *st, byte pr, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 304 {
 305         struct BufHeader *ibh = arg;
 306 
 307         BufPoolRelease(ibh);
 308         st->l3.l3l4(st, CC_SETUP_COMPLETE_IND, NULL);
 309         newl3state(st, 10);
 310 }
 311 
 312 static void
 313 l3s18(struct PStack *st, byte pr, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 314 {
 315         struct BufHeader *dibh;
 316         byte           *p;
 317         int             size;
 318 
 319         BufPoolGet(&dibh, st->l1.sbufpool, GFP_ATOMIC, (void *) st, 20);
 320         p = DATAPTR(dibh);
 321         p += st->l2.ihsize;
 322         size = st->l2.ihsize;
 323 
 324         *p++ = 0x8;
 325         *p++ = 0x1;
 326         *p++ = st->l3.callref;
 327         *p++ = MT_DISCONNECT;
 328         size += 4;
 329 
 330         *p++ = IE_CAUSE;
 331         *p++ = 0x2;
 332         *p++ = 0x80;
 333         *p++ = 0x90;
 334         size += 4;
 335 
 336         dibh->datasize = size;
 337         i_down(st, dibh);
 338 
 339         newl3state(st, 11);
 340 }
 341 
 342 static void
 343 l3s19(struct PStack *st, byte pr, void *arg)
     /* [previous][next][first][last][top][bottom][index][help] */
 344 {
 345         struct BufHeader *ibh = arg;
 346 
 347         BufPoolRelease(ibh);
 348         newl3state(st, 0);
 349         l3_message(st, MT_RELEASE_COMPLETE);
 350         st->l3.l3l4(st, CC_RELEASE_IND, NULL);
 351 }
 352 
 353 static void
 354 l3s20(struct PStack *st, byte pr,
     /* [previous][next][first][last][top][bottom][index][help] */
 355       void *arg)
 356 {
 357         l3_message(st, MT_ALERTING);
 358         newl3state(st, 7);
 359 }
 360 
 361 struct stateentry {
 362         int             state;
 363         byte            primitive;
 364         void            (*rout) (struct PStack *, byte, void *);
 365 };
 366 
 367 static struct stateentry downstatelist[] =
 368 {
 369         {0, CC_SETUP_REQ, l3s5},
 370         {6, CC_REJECT_REQ, l3s13},
 371         {6, CC_SETUP_RSP, l3s16},
 372         {6, CC_ALERTING_REQ, l3s20},
 373         {7, CC_SETUP_RSP, l3s16},
 374         {10, CC_DISCONNECT_REQ, l3s18},
 375         {12, CC_RELEASE_REQ, l3s3},
 376 };
 377 
 378 static int      downsllen = sizeof(downstatelist) /
 379 sizeof(struct stateentry);
 380 
 381 static struct stateentry datastatelist[] =
 382 {
 383         {0, MT_SETUP, l3s12},
 384         {1, MT_CALL_PROCEEDING, l3s6},
 385         {1, MT_RELEASE_COMPLETE, l3s7},
 386         {3, MT_DISCONNECT, l3s7},
 387         {3, MT_CONNECT, l3s8},
 388         {3, MT_ALERTING, l3s11},
 389         {4, MT_CONNECT, l3s8},
 390         {4, MT_DISCONNECT, l3s7},
 391         {4, MT_RELEASE, l3s19},
 392         {7, MT_RELEASE, l3s19},
 393         {8, MT_CONNECT_ACKNOWLEDGE, l3s17},
 394         {10, MT_DISCONNECT, l3s7},
 395         {11, MT_RELEASE, l3s19},
 396         {19, MT_RELEASE_COMPLETE, l3s4},
 397 };
 398 
 399 static int      datasllen = sizeof(datastatelist) /
 400 sizeof(struct stateentry);
 401 
 402 #ifdef P_1TR6
 403 #include "l3_1TR6.c"
 404 #endif
 405 
 406 static void
 407 l3up(struct PStack *st,
     /* [previous][next][first][last][top][bottom][index][help] */
 408      int pr, void *arg)
 409 {
 410         int             i, mt, size;
 411         byte           *ptr;
 412         struct BufHeader *ibh = arg;
 413 
 414         if (pr == DL_DATA) {
 415                 ptr = DATAPTR(ibh);
 416                 ptr += st->l2.ihsize;
 417                 size = ibh->datasize - st->l2.ihsize;
 418                 if (DEBUG_1TR6 > 6) {
 419                         printk(KERN_INFO "isdnl3/l3up DL_DATA size=%d\n", size);
 420                         for (i = 0; i < size; i++)
 421                                 printk(KERN_INFO "l3up data %x\n", ptr[i]);
 422                 }
 423                 mt = ptr[3];
 424                 switch (ptr[0]) {
 425 #ifdef P_1TR6
 426                   case PROTO_DIS_N0:
 427                           BufPoolRelease(ibh);
 428                           break;
 429                   case PROTO_DIS_N1:
 430                           for (i = 0; i < datasl_1tr6t_len; i++)
 431                                   if ((st->l3.state == datastatelist_1tr6t[i].state) &&
 432                                       (mt == datastatelist_1tr6t[i].primitive))
 433                                           break;
 434                           if (i == datasl_1tr6t_len) {
 435                                   BufPoolRelease(ibh);
 436                                   if (DEBUG_1TR6 > 0)
 437                                           printk(KERN_INFO "isdnl3up unhandled 1tr6 state %d MT %s\n",
 438                                                  st->l3.state, mt_trans(PROTO_DIS_N1, mt));
 439                           } else
 440                                   datastatelist_1tr6t[i].rout(st, pr, ibh);
 441                           break;
 442 #endif
 443                   default:      /* E-DSS1 */
 444                           for (i = 0; i < datasllen; i++)
 445                                   if ((st->l3.state == datastatelist[i].state) &&
 446                                       (mt == datastatelist[i].primitive))
 447                                           break;
 448                           if (i == datasllen) {
 449                                   BufPoolRelease(ibh);
 450                           } else
 451                                   datastatelist[i].rout(st, pr, ibh);
 452                 }
 453         } else if (pr == DL_UNIT_DATA) {
 454                 ptr = DATAPTR(ibh);
 455                 ptr += st->l2.uihsize;
 456                 size = ibh->datasize - st->l2.uihsize;
 457                 if (DEBUG_1TR6 > 6) {
 458                         printk(KERN_INFO "isdnl3/l3up DL_UNIT_DATA size=%d\n", size);
 459                         for (i = 0; i < size; i++)
 460                                 printk(KERN_INFO "l3up data %x\n", ptr[i]);
 461                 }
 462                 mt = ptr[3];
 463                 switch (ptr[0]) {
 464 #ifdef P_1TR6
 465                   case PROTO_DIS_N0:
 466                           BufPoolRelease(ibh);
 467                           break;
 468                   case PROTO_DIS_N1:
 469                           for (i = 0; i < datasl_1tr6t_len; i++)
 470                                   if ((st->l3.state == datastatelist_1tr6t[i].state) &&
 471                                       (mt == datastatelist_1tr6t[i].primitive))
 472                                           break;
 473                           if (i == datasl_1tr6t_len) {
 474                                   if (DEBUG_1TR6 > 0) {
 475                                           printk(KERN_INFO "isdnl3up unhandled 1tr6 state %d MT %s\n"
 476                                                  ,st->l3.state, mt_trans(PROTO_DIS_N1, mt));
 477                                   }
 478                                   BufPoolRelease(ibh);
 479                           } else
 480                                   datastatelist_1tr6t[i].rout(st, pr, ibh);
 481                           break;
 482 #endif
 483                   default:      /* E-DSS1 */
 484                           for (i = 0; i < datasllen; i++)
 485                                   if ((st->l3.state == datastatelist[i].state) &&
 486                                       (mt == datastatelist[i].primitive))
 487                                           break;
 488                           if (i == datasllen) {
 489                                   BufPoolRelease(ibh);
 490                           } else
 491                                   datastatelist[i].rout(st, pr, ibh);
 492                 }
 493         }
 494 }
 495 
 496 static void
 497 l3down(struct PStack *st,
     /* [previous][next][first][last][top][bottom][index][help] */
 498        int pr, void *arg)
 499 {
 500         int             i;
 501         struct BufHeader *ibh = arg;
 502 
 503         switch (st->protocol) {
 504 #ifdef P_1TR6
 505           case ISDN_PTYPE_1TR6:
 506                   for (i = 0; i < downsl_1tr6t_len; i++)
 507                           if ((st->l3.state == downstatelist_1tr6t[i].state) &&
 508                               (pr == downstatelist_1tr6t[i].primitive))
 509                                   break;
 510                   if (i == downsl_1tr6t_len) {
 511                           if (DEBUG_1TR6 > 0) {
 512                                   printk(KERN_INFO "isdnl3down unhandled 1tr6 state %d primitiv %x\n", st->l3.state, pr);
 513                           }
 514                   } else
 515                           downstatelist_1tr6t[i].rout(st, pr, ibh);
 516                   break;
 517 #endif
 518           default:
 519                   for (i = 0; i < downsllen; i++)
 520                           if ((st->l3.state == downstatelist[i].state) &&
 521                               (pr == downstatelist[i].primitive))
 522                                   break;
 523                   if (i == downsllen) {
 524                   } else
 525                           downstatelist[i].rout(st, pr, ibh);
 526         }
 527 }
 528 
 529 void
 530 setstack_isdnl3(struct PStack *st)
     /* [previous][next][first][last][top][bottom][index][help] */
 531 {
 532         st->l4.l4l3 = l3down;
 533         st->l2.l2l3 = l3up;
 534         st->l3.state = 0;
 535         st->l3.callref = 0;
 536         st->l3.debug = 0;
 537 }

/* [previous][next][first][last][top][bottom][index][help] */