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