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