linux/drivers/isdn/pcbit/capi.c
<<
>>
Prefs
   1/*
   2 * CAPI encoder/decoder for
   3 * Portugal Telecom CAPI 2.0
   4 *
   5 * Copyright (C) 1996 Universidade de Lisboa
   6 * 
   7 * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
   8 *
   9 * This software may be used and distributed according to the terms of 
  10 * the GNU General Public License, incorporated herein by reference.
  11 *
  12 * Not compatible with the AVM Gmbh. CAPI 2.0
  13 *
  14 */
  15
  16/*
  17 *        Documentation:
  18 *        - "Common ISDN API - Perfil Português - Versão 2.1",
  19 *           Telecom Portugal, Fev 1992.
  20 *        - "Common ISDN API - Especificação de protocolos para
  21 *           acesso aos canais B", Inesc, Jan 1994.
  22 */
  23
  24/*
  25 *        TODO: better decoding of Information Elements
  26 *              for debug purposes mainly
  27 *              encode our number in CallerPN and ConnectedPN
  28 */
  29
  30#include <linux/string.h>
  31#include <linux/kernel.h>
  32
  33#include <linux/types.h>
  34#include <linux/slab.h>
  35#include <linux/mm.h>
  36
  37#include <linux/skbuff.h>
  38
  39#include <asm/io.h>
  40#include <asm/string.h>
  41
  42#include <linux/isdnif.h>
  43
  44#include "pcbit.h"
  45#include "edss1.h"
  46#include "capi.h"
  47
  48
  49/*
  50 *  Encoding of CAPI messages
  51 *
  52 */
  53
  54int capi_conn_req(const char * calledPN, struct sk_buff **skb, int proto)
  55{
  56        ushort len;
  57
  58        /*
  59         * length
  60         *   AppInfoMask - 2
  61         *   BC0         - 3
  62         *   BC1         - 1
  63         *   Chan        - 2
  64         *   Keypad      - 1
  65         *   CPN         - 1
  66         *   CPSA        - 1
  67         *   CalledPN    - 2 + strlen
  68         *   CalledPSA   - 1
  69         *   rest...     - 4
  70         *   ----------------
  71         *   Total        18 + strlen
  72         */
  73
  74        len = 18 + strlen(calledPN);
  75
  76        if (proto == ISDN_PROTO_L2_TRANS)
  77                len++;
  78
  79        if ((*skb = dev_alloc_skb(len)) == NULL) {
  80    
  81                printk(KERN_WARNING "capi_conn_req: alloc_skb failed\n");
  82                return -1;
  83        }
  84
  85        /* InfoElmMask */
  86        *((ushort*) skb_put(*skb, 2)) = AppInfoMask; 
  87
  88        if (proto == ISDN_PROTO_L2_TRANS)
  89        {
  90                /* Bearer Capability - Mandatory*/
  91                *(skb_put(*skb, 1)) = 3;        /* BC0.Length           */
  92                *(skb_put(*skb, 1)) = 0x80;     /* Speech               */
  93                *(skb_put(*skb, 1)) = 0x10;     /* Circuit Mode         */
  94                *(skb_put(*skb, 1)) = 0x23;     /* A-law                */
  95        }
  96        else
  97        {
  98                /* Bearer Capability - Mandatory*/
  99                *(skb_put(*skb, 1)) = 2;        /* BC0.Length           */
 100                *(skb_put(*skb, 1)) = 0x88;     /* Digital Information  */
 101                *(skb_put(*skb, 1)) = 0x90;     /* BC0.Octect4          */
 102        }
 103
 104        /* Bearer Capability - Optional*/
 105        *(skb_put(*skb, 1)) = 0;        /* BC1.Length = 0                    */
 106
 107        *(skb_put(*skb, 1)) = 1;        /* ChannelID.Length = 1              */
 108        *(skb_put(*skb, 1)) = 0x83;     /* Basic Interface - Any Channel     */
 109
 110        *(skb_put(*skb, 1)) = 0;        /* Keypad.Length = 0                 */
 111                  
 112
 113        *(skb_put(*skb, 1)) = 0;        /* CallingPN.Length = 0              */
 114        *(skb_put(*skb, 1)) = 0;        /* CallingPSA.Length = 0             */
 115
 116        /* Called Party Number */
 117        *(skb_put(*skb, 1)) = strlen(calledPN) + 1;
 118        *(skb_put(*skb, 1)) = 0x81;
 119        memcpy(skb_put(*skb, strlen(calledPN)), calledPN, strlen(calledPN));
 120
 121        /* '#' */
 122
 123        *(skb_put(*skb, 1)) = 0;       /* CalledPSA.Length = 0     */
 124
 125        /* LLC.Length  = 0; */
 126        /* HLC0.Length = 0; */
 127        /* HLC1.Length = 0; */ 
 128        /* UTUS.Length = 0; */
 129        memset(skb_put(*skb, 4), 0, 4);
 130
 131        return len;
 132}
 133
 134int capi_conn_resp(struct pcbit_chan* chan, struct sk_buff **skb)
 135{
 136        
 137        if ((*skb = dev_alloc_skb(5)) == NULL) {
 138    
 139                printk(KERN_WARNING "capi_conn_resp: alloc_skb failed\n");
 140                return -1;
 141        }
 142
 143        *((ushort*) skb_put(*skb, 2) ) = chan->callref;  
 144        *(skb_put(*skb, 1)) = 0x01;  /* ACCEPT_CALL */
 145        *(skb_put(*skb, 1)) = 0;
 146        *(skb_put(*skb, 1)) = 0;
 147
 148        return 5;
 149}
 150
 151int capi_conn_active_req(struct pcbit_chan* chan, struct sk_buff **skb)
 152{
 153        /*
 154         * 8 bytes
 155         */
 156        
 157        if ((*skb = dev_alloc_skb(8)) == NULL) {
 158    
 159                printk(KERN_WARNING "capi_conn_active_req: alloc_skb failed\n");
 160                return -1;
 161        }
 162
 163        *((ushort*) skb_put(*skb, 2) ) = chan->callref;  
 164
 165#ifdef DEBUG
 166        printk(KERN_DEBUG "Call Reference: %04x\n", chan->callref); 
 167#endif
 168
 169        *(skb_put(*skb, 1)) = 0;       /*  BC.Length = 0;          */
 170        *(skb_put(*skb, 1)) = 0;       /*  ConnectedPN.Length = 0  */
 171        *(skb_put(*skb, 1)) = 0;       /*  PSA.Length              */
 172        *(skb_put(*skb, 1)) = 0;       /*  LLC.Length = 0;         */
 173        *(skb_put(*skb, 1)) = 0;       /*  HLC.Length = 0;         */
 174        *(skb_put(*skb, 1)) = 0;       /*  UTUS.Length = 0;        */
 175
 176        return 8;
 177}
 178
 179int capi_conn_active_resp(struct pcbit_chan* chan, struct sk_buff **skb)
 180{
 181        /*
 182         * 2 bytes
 183         */
 184  
 185        if ((*skb = dev_alloc_skb(2)) == NULL) {
 186    
 187                printk(KERN_WARNING "capi_conn_active_resp: alloc_skb failed\n");
 188                return -1;
 189        }
 190
 191        *((ushort*) skb_put(*skb, 2) ) = chan->callref;  
 192
 193        return 2;
 194}
 195
 196
 197int capi_select_proto_req(struct pcbit_chan *chan, struct sk_buff **skb, 
 198                          int outgoing)
 199{
 200
 201        /*
 202         * 18 bytes
 203         */
 204
 205        if ((*skb = dev_alloc_skb(18)) == NULL) {
 206    
 207                printk(KERN_WARNING "capi_select_proto_req: alloc_skb failed\n");
 208                return -1;
 209        }
 210
 211        *((ushort*) skb_put(*skb, 2) ) = chan->callref;  
 212
 213        /* Layer2 protocol */
 214
 215        switch (chan->proto) {
 216        case ISDN_PROTO_L2_X75I: 
 217                *(skb_put(*skb, 1)) = 0x05;            /* LAPB */
 218                break;
 219        case ISDN_PROTO_L2_HDLC:
 220                *(skb_put(*skb, 1)) = 0x02;
 221                break;
 222        case ISDN_PROTO_L2_TRANS:
 223                /* 
 224                 *      Voice (a-law)
 225                 */
 226                *(skb_put(*skb, 1)) = 0x06;
 227                break;
 228        default:
 229#ifdef DEBUG 
 230                printk(KERN_DEBUG "Transparent\n");
 231#endif
 232                *(skb_put(*skb, 1)) = 0x03;
 233                break;
 234        }
 235
 236        *(skb_put(*skb, 1)) = (outgoing ? 0x02 : 0x42);    /* Don't ask */
 237        *(skb_put(*skb, 1)) = 0x00;
 238  
 239        *((ushort *) skb_put(*skb, 2)) = MRU;
 240
 241 
 242        *(skb_put(*skb, 1)) = 0x08;           /* Modulo */
 243        *(skb_put(*skb, 1)) = 0x07;           /* Max Window */
 244  
 245        *(skb_put(*skb, 1)) = 0x01;           /* No Layer3 Protocol */
 246
 247        /*
 248         * 2 - layer3 MTU       [10]
 249         *   - Modulo           [12]
 250         *   - Window           
 251         *   - layer1 proto     [14]
 252         *   - bitrate
 253         *   - sub-channel      [16]
 254         *   - layer1dataformat [17]
 255         */
 256
 257        memset(skb_put(*skb, 8), 0, 8);
 258
 259        return 18;
 260}
 261
 262
 263int capi_activate_transp_req(struct pcbit_chan *chan, struct sk_buff **skb)
 264{
 265
 266        if ((*skb = dev_alloc_skb(7)) == NULL) {
 267    
 268                printk(KERN_WARNING "capi_activate_transp_req: alloc_skb failed\n");
 269                return -1;
 270        }
 271
 272        *((ushort*) skb_put(*skb, 2) ) = chan->callref;  
 273
 274        
 275        *(skb_put(*skb, 1)) = chan->layer2link; /* Layer2 id */
 276        *(skb_put(*skb, 1)) = 0x00;             /* Transmit by default */
 277
 278        *((ushort *) skb_put(*skb, 2)) = MRU;
 279
 280        *(skb_put(*skb, 1)) = 0x01;             /* Enables reception*/
 281
 282        return 7;
 283}
 284
 285int capi_tdata_req(struct pcbit_chan* chan, struct sk_buff *skb)
 286{
 287        ushort data_len;
 288        
 289
 290        /*  
 291         * callref      - 2  
 292         * layer2link   - 1
 293         * wBlockLength - 2 
 294         * data         - 4
 295         * sernum       - 1
 296         */
 297        
 298        data_len = skb->len;
 299
 300        if(skb_headroom(skb) < 10)
 301        {
 302                printk(KERN_CRIT "No headspace (%u) on headroom %p for capi header\n", skb_headroom(skb), skb);
 303        }
 304        else
 305        {       
 306                skb_push(skb, 10);
 307        }
 308
 309        *((u16 *) (skb->data)) = chan->callref;
 310        skb->data[2] = chan->layer2link;
 311        *((u16 *) (skb->data + 3)) = data_len;
 312
 313        chan->s_refnum = (chan->s_refnum + 1) % 8;
 314        *((u32 *) (skb->data + 5)) = chan->s_refnum;
 315
 316        skb->data[9] = 0;                           /* HDLC frame number */
 317
 318        return 10;
 319}
 320
 321int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff ** skb)
 322                    
 323{
 324        if ((*skb = dev_alloc_skb(4)) == NULL) {
 325    
 326                printk(KERN_WARNING "capi_tdata_resp: alloc_skb failed\n");
 327                return -1;
 328        }
 329
 330        *((ushort*) skb_put(*skb, 2) ) = chan->callref;  
 331
 332        *(skb_put(*skb, 1)) = chan->layer2link;
 333        *(skb_put(*skb, 1)) = chan->r_refnum;
 334
 335        return (*skb)->len;
 336}
 337
 338int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause)
 339{
 340
 341        if ((*skb = dev_alloc_skb(6)) == NULL) {
 342    
 343                printk(KERN_WARNING "capi_disc_req: alloc_skb failed\n");
 344                return -1;
 345        }
 346
 347        *((ushort*) skb_put(*skb, 2) ) = callref;  
 348
 349        *(skb_put(*skb, 1)) = 2;                  /* Cause.Length = 2; */
 350        *(skb_put(*skb, 1)) = 0x80;
 351        *(skb_put(*skb, 1)) = 0x80 | cause;           
 352
 353        /* 
 354         * Change it: we should send 'Sic transit gloria Mundi' here ;-) 
 355         */
 356
 357        *(skb_put(*skb, 1)) = 0;                   /* UTUS.Length = 0;  */
 358
 359        return 6;
 360}
 361
 362int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb)
 363{
 364        if ((*skb = dev_alloc_skb(2)) == NULL) {
 365    
 366                printk(KERN_WARNING "capi_disc_resp: alloc_skb failed\n");
 367                return -1;
 368        }
 369
 370        *((ushort*) skb_put(*skb, 2)) = chan->callref;  
 371
 372        return 2;
 373}
 374
 375
 376/*
 377 *  Decoding of CAPI messages
 378 *
 379 */
 380
 381int capi_decode_conn_ind(struct pcbit_chan * chan, 
 382                         struct sk_buff *skb,
 383                         struct callb_data *info) 
 384{
 385        int CIlen, len;
 386
 387        /* Call Reference [CAPI] */
 388        chan->callref = *((ushort*) skb->data);
 389        skb_pull(skb, 2);
 390
 391#ifdef DEBUG
 392        printk(KERN_DEBUG "Call Reference: %04x\n", chan->callref); 
 393#endif
 394
 395        /* Channel Identification */
 396
 397        /* Expect  
 398           Len = 1 
 399           Octect 3 = 0100 10CC - [ 7 Basic, 4 , 2-1 chan ]
 400           */
 401
 402        CIlen = skb->data[0];
 403#ifdef DEBUG
 404        if (CIlen == 1) {
 405
 406                if ( ((skb->data[1]) & 0xFC) == 0x48 )
 407                        printk(KERN_DEBUG "decode_conn_ind: chan ok\n");
 408                printk(KERN_DEBUG "phyChan = %d\n", skb->data[1] & 0x03); 
 409        }
 410        else
 411                printk(KERN_DEBUG "conn_ind: CIlen = %d\n", CIlen);
 412#endif
 413        skb_pull(skb, CIlen + 1);
 414
 415        /* Calling Party Number */
 416        /* An "additional service" as far as Portugal Telecom is concerned */
 417
 418        len = skb->data[0];
 419
 420        if (len > 0) {
 421                int count = 1;
 422                
 423#ifdef DEBUG
 424                printk(KERN_DEBUG "CPN: Octect 3 %02x\n", skb->data[1]);
 425#endif
 426                if ((skb->data[1] & 0x80) == 0)
 427                        count = 2;
 428                
 429                if (!(info->data.setup.CallingPN = kmalloc(len - count + 1, GFP_ATOMIC)))
 430                        return -1;
 431       
 432                skb_copy_from_linear_data_offset(skb, count + 1,
 433                                                 info->data.setup.CallingPN,
 434                                                 len - count);
 435                info->data.setup.CallingPN[len - count] = 0;
 436
 437        }
 438        else {
 439                info->data.setup.CallingPN = NULL;
 440                printk(KERN_DEBUG "NULL CallingPN\n");
 441        }
 442
 443        skb_pull(skb, len + 1);
 444
 445        /* Calling Party Subaddress */
 446        skb_pull(skb, skb->data[0] + 1);
 447
 448        /* Called Party Number */
 449
 450        len = skb->data[0];
 451
 452        if (len > 0) {
 453                int count = 1;
 454                
 455                if ((skb->data[1] & 0x80) == 0)
 456                        count = 2;
 457        
 458                if (!(info->data.setup.CalledPN = kmalloc(len - count + 1, GFP_ATOMIC)))
 459                        return -1;
 460        
 461                skb_copy_from_linear_data_offset(skb, count + 1,
 462                                                 info->data.setup.CalledPN,
 463                                                 len - count);
 464                info->data.setup.CalledPN[len - count] = 0;
 465
 466        }
 467        else {
 468                info->data.setup.CalledPN = NULL;
 469                printk(KERN_DEBUG "NULL CalledPN\n");
 470        }
 471
 472        skb_pull(skb, len + 1);
 473
 474        /* Called Party Subaddress */
 475        skb_pull(skb, skb->data[0] + 1);
 476
 477        /* LLC */
 478        skb_pull(skb, skb->data[0] + 1);
 479
 480        /* HLC */
 481        skb_pull(skb, skb->data[0] + 1);
 482
 483        /* U2U */
 484        skb_pull(skb, skb->data[0] + 1);
 485
 486        return 0;
 487}
 488
 489/*
 490 *  returns errcode
 491 */
 492
 493int capi_decode_conn_conf(struct pcbit_chan * chan, struct sk_buff *skb,
 494                          int *complete) 
 495{
 496        int errcode;
 497  
 498        chan->callref = *((ushort *) skb->data);     /* Update CallReference */
 499        skb_pull(skb, 2);
 500
 501        errcode = *((ushort *) skb->data);   /* read errcode */
 502        skb_pull(skb, 2);
 503
 504        *complete = *(skb->data);
 505        skb_pull(skb, 1);
 506
 507        /* FIX ME */
 508        /* This is actually a firmware bug */
 509        if (!*complete)
 510        {
 511                printk(KERN_DEBUG "complete=%02x\n", *complete);
 512                *complete = 1;
 513        }
 514
 515
 516        /* Optional Bearer Capability */
 517        skb_pull(skb, *(skb->data) + 1);
 518        
 519        /* Channel Identification */
 520        skb_pull(skb, *(skb->data) + 1);
 521
 522        /* High Layer Compatibility follows */
 523        skb_pull(skb, *(skb->data) + 1);
 524
 525        return errcode;
 526}
 527
 528int capi_decode_conn_actv_ind(struct pcbit_chan * chan, struct sk_buff *skb)
 529{
 530        ushort len;
 531#ifdef DEBUG
 532        char str[32];
 533#endif
 534
 535        /* Yet Another Bearer Capability */
 536        skb_pull(skb, *(skb->data) + 1);
 537  
 538
 539        /* Connected Party Number */
 540        len=*(skb->data);
 541
 542#ifdef DEBUG
 543        if (len > 1 && len < 31) {
 544                skb_copy_from_linear_data_offset(skb, 2, str, len - 1);
 545                str[len] = 0;
 546                printk(KERN_DEBUG "Connected Party Number: %s\n", str);
 547        }
 548        else
 549                printk(KERN_DEBUG "actv_ind CPN len = %d\n", len);
 550#endif
 551
 552        skb_pull(skb, len + 1);
 553
 554        /* Connected Subaddress */
 555        skb_pull(skb, *(skb->data) + 1);
 556
 557        /* Low Layer Capability */
 558        skb_pull(skb, *(skb->data) + 1);
 559
 560        /* High Layer Capability */
 561        skb_pull(skb, *(skb->data) + 1);
 562
 563        return 0;
 564}
 565
 566int capi_decode_conn_actv_conf(struct pcbit_chan * chan, struct sk_buff *skb)
 567{
 568        ushort errcode;
 569
 570        errcode = *((ushort*) skb->data);
 571        skb_pull(skb, 2);
 572        
 573        /* Channel Identification 
 574        skb_pull(skb, skb->data[0] + 1);
 575        */
 576        return errcode;
 577}
 578
 579
 580int capi_decode_sel_proto_conf(struct pcbit_chan *chan, struct sk_buff *skb)
 581{
 582        ushort errcode;
 583        
 584        chan->layer2link = *(skb->data);
 585        skb_pull(skb, 1);
 586
 587        errcode = *((ushort*) skb->data);
 588        skb_pull(skb, 2);
 589
 590        return errcode;
 591}
 592
 593int capi_decode_actv_trans_conf(struct pcbit_chan *chan, struct sk_buff *skb)
 594{
 595        ushort errcode;
 596
 597        if (chan->layer2link != *(skb->data) )
 598                printk("capi_decode_actv_trans_conf: layer2link doesn't match\n");
 599
 600        skb_pull(skb, 1);
 601
 602        errcode = *((ushort*) skb->data);
 603        skb_pull(skb, 2);
 604
 605        return errcode;        
 606}
 607
 608int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb)
 609{
 610        ushort len;
 611#ifdef DEBUG
 612        int i;
 613#endif
 614        /* Cause */
 615        
 616        len = *(skb->data);
 617        skb_pull(skb, 1);
 618
 619#ifdef DEBUG
 620
 621        for (i=0; i<len; i++)
 622                printk(KERN_DEBUG "Cause Octect %d: %02x\n", i+3, 
 623                       *(skb->data + i));
 624#endif
 625
 626        skb_pull(skb, len);
 627
 628        return 0;
 629}
 630
 631#ifdef DEBUG
 632int capi_decode_debug_188(u_char *hdr, ushort hdrlen)
 633{
 634        char str[64];
 635        int len;
 636        
 637        len = hdr[0];
 638
 639        if (len < 64 && len == hdrlen - 1) {        
 640                memcpy(str, hdr + 1, hdrlen - 1);
 641                str[hdrlen - 1] = 0;
 642                printk("%s\n", str);
 643        }
 644        else
 645                printk("debug message incorrect\n");
 646
 647        return 0;
 648}
 649#endif
 650
 651
 652
 653
 654
 655