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