root/drivers/isdn/pcbit/capi.c

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

DEFINITIONS

This source file includes following definitions.
  1. capi_conn_req
  2. capi_conn_resp
  3. capi_conn_active_req
  4. capi_conn_active_resp
  5. capi_select_proto_req
  6. capi_activate_transp_req
  7. capi_tdata_req
  8. capi_tdata_resp
  9. capi_disc_req
  10. capi_disc_resp
  11. capi_decode_conn_ind
  12. capi_decode_conn_conf
  13. capi_decode_conn_actv_ind
  14. capi_decode_conn_actv_conf
  15. capi_decode_sel_proto_conf
  16. capi_decode_actv_trans_conf
  17. capi_decode_disc_ind
  18. capi_decode_disc_conf
  19. capi_decode_debug_188

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

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