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