This source file includes following definitions.
- i_down
- newl3state
- l3_message
- l3s3
- l3s4
- l3s4_1
- l3s5
- l3s6
- l3s7
- l3s8
- l3s11
- l3s12
- l3s13
- l3s15
- l3s16
- l3s17
- l3s18
- l3s19
- l3s20
- l3up
- l3down
- setstack_isdnl3
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #define __NO_VERSION__
15 #define P_1TR6
16 #include "teles.h"
17 #include "l3_1TR6.h"
18 #define DEBUG_1TR6 0
19
20 static void
21 i_down(struct PStack *st,
22 struct BufHeader *ibh)
23 {
24 st->l3.l3l2(st, DL_DATA, ibh);
25 }
26
27 static void
28 newl3state(struct PStack *st, int state)
29 {
30 st->l3.state = state;
31 if (DEBUG_1TR6 > 4)
32 printk(KERN_INFO "isdnl3: bc:%d cr:%x new state %d\n",
33 st->pa->bchannel, st->pa->callref, state);
34
35 }
36
37 static void
38 l3_message(struct PStack *st, int mt)
39 {
40 struct BufHeader *dibh;
41 byte *p;
42 int size;
43
44 BufPoolGet(&dibh, st->l1.sbufpool, GFP_ATOMIC, (void *) st, 18);
45 p = DATAPTR(dibh);
46 p += st->l2.ihsize;
47 size = st->l2.ihsize;
48
49 *p++ = 0x8;
50 *p++ = 0x1;
51 *p++ = st->l3.callref;
52 *p++ = mt;
53 size += 4;
54
55 dibh->datasize = size;
56 i_down(st, dibh);
57 }
58
59 static void
60 l3s3(struct PStack *st, byte pr, void *arg)
61 {
62 l3_message(st, MT_RELEASE);
63 newl3state(st, 19);
64 }
65
66 static void
67 l3s4(struct PStack *st, byte pr, void *arg)
68 {
69 struct BufHeader *ibh = arg;
70
71 BufPoolRelease(ibh);
72 newl3state(st, 0);
73 st->l3.l3l4(st, CC_RELEASE_CNF, NULL);
74 }
75
76 static void
77 l3s4_1(struct PStack *st, byte pr, void *arg)
78 {
79 struct BufHeader *ibh = arg;
80
81 BufPoolRelease(ibh);
82 newl3state(st, 19);
83 l3_message(st, MT_RELEASE);
84 st->l3.l3l4(st, CC_RELEASE_CNF, NULL);
85 }
86
87 static void
88 l3s5(struct PStack *st, byte pr,
89 void *arg)
90 {
91 struct BufHeader *dibh;
92 byte *p;
93 char *teln;
94
95 st->l3.callref = st->pa->callref;
96 BufPoolGet(&dibh, st->l1.sbufpool, GFP_ATOMIC, (void *) st, 19);
97 p = DATAPTR(dibh);
98 p += st->l2.ihsize;
99
100 *p++ = 0x8;
101 *p++ = 0x1;
102 *p++ = st->l3.callref;
103 *p++ = MT_SETUP;
104 *p++ = 0xa1;
105
106
107
108
109 switch (st->pa->info) {
110 case 1:
111 *p++ = 0x4;
112 *p++ = 0x3;
113 *p++ = 0x90;
114 *p++ = 0x90;
115 *p++ = 0xa3;
116 break;
117 case 5:
118 case 7:
119 default:
120 *p++ = 0x4;
121 *p++ = 0x2;
122 *p++ = 0x88;
123 *p++ = 0x90;
124 break;
125 }
126
127
128
129
130 #if 0
131 *p++ = 0x7f;
132 *p++ = 0x2;
133 *p++ = 0x0;
134 *p++ = 66;
135 #endif
136
137 if (st->pa->calling[0] != '\0') {
138 *p++ = 0x6c;
139 *p++ = strlen(st->pa->calling) + 1;
140
141 *p++ = 0x81;
142 teln = st->pa->calling;
143 while (*teln)
144 *p++ = *teln++ & 0x7f;
145 }
146 *p++ = 0x70;
147 *p++ = strlen(st->pa->called) + 1;
148
149 *p++ = 0x81;
150
151 teln = st->pa->called;
152 while (*teln)
153 *p++ = *teln++ & 0x7f;
154
155
156 dibh->datasize = p - DATAPTR(dibh);
157
158 newl3state(st, 1);
159 i_down(st, dibh);
160
161 }
162
163 static void
164 l3s6(struct PStack *st, byte pr, void *arg)
165 {
166 byte *p;
167 struct BufHeader *ibh = arg;
168
169 p = DATAPTR(ibh);
170 if ((p = findie(p + st->l2.ihsize, ibh->datasize - st->l2.ihsize,
171 0x18, 0))) {
172 st->pa->bchannel = p[2] & 0x3;
173 } else
174 printk(KERN_WARNING "octect 3 not found\n");
175
176 BufPoolRelease(ibh);
177 newl3state(st, 3);
178 st->l3.l3l4(st, CC_PROCEEDING_IND, NULL);
179 }
180
181 static void
182 l3s7(struct PStack *st, byte pr, void *arg)
183 {
184 struct BufHeader *ibh = arg;
185
186 BufPoolRelease(ibh);
187 newl3state(st, 12);
188 st->l3.l3l4(st, CC_DISCONNECT_IND, NULL);
189 }
190
191 static void
192 l3s8(struct PStack *st, byte pr, void *arg)
193 {
194 struct BufHeader *ibh = arg;
195
196 BufPoolRelease(ibh);
197 st->l3.l3l4(st, CC_SETUP_CNF, NULL);
198 newl3state(st, 10);
199 }
200
201 static void
202 l3s11(struct PStack *st, byte pr, void *arg)
203 {
204 struct BufHeader *ibh = arg;
205
206 BufPoolRelease(ibh);
207 newl3state(st, 4);
208 st->l3.l3l4(st, CC_ALERTING_IND, NULL);
209 }
210
211 static void
212 l3s12(struct PStack *st, byte pr, void *arg)
213 {
214 byte *p;
215 int bcfound = 0;
216 struct BufHeader *ibh = arg;
217
218 p = DATAPTR(ibh);
219 p += st->l2.uihsize;
220 st->pa->callref = getcallref(p);
221 st->l3.callref = 0x80 + st->pa->callref;
222
223
224
225
226 p = DATAPTR(ibh);
227 if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize,
228 0x18, 0))) {
229 st->pa->bchannel = p[2] & 0x3;
230 bcfound++ ;
231 } else
232 printk(KERN_WARNING "l3s12: Channel ident not found\n");
233
234 p = DATAPTR(ibh);
235 if (st->protocol == ISDN_PTYPE_1TR6) {
236 if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize, 0x01, 6))) {
237 st->pa->info = p[2];
238 st->pa->info2 = p[3];
239 } else
240 printk(KERN_WARNING "l3s12(1TR6): ServiceIndicator not found\n");
241 } else {
242
243
244
245 if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize, 0x04, 0))) {
246 switch (p[2] & 0x1f) {
247 case 0x00:
248
249 case 0x10:
250
251 st->pa->info = 1;
252 break;
253 case 0x08:
254
255 st->pa->info = 7;
256 break;
257 case 0x09:
258
259 st->pa->info = 2;
260 break;
261 case 0x11:
262
263 st->pa->info = 3;
264 break;
265 case 0x18:
266
267 st->pa->info = 4;
268 break;
269 default:
270 st->pa->info = 0;
271 }
272 } else
273 printk(KERN_WARNING "l3s12: Bearer capabilities not found\n");
274 }
275
276 p = DATAPTR(ibh);
277 if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize,
278 0x70, 0)))
279 iecpy(st->pa->called, p, 1);
280 else
281 strcpy(st->pa->called, "");
282
283 p = DATAPTR(ibh);
284 if ((p = findie(p + st->l2.uihsize, ibh->datasize - st->l2.uihsize,
285 0x6c, 0))) {
286 if (st->protocol == ISDN_PTYPE_1TR6)
287 iecpy(st->pa->calling, p, 1);
288 else
289 iecpy(st->pa->calling, p, 2);
290 } else
291 strcpy(st->pa->calling, "");
292 BufPoolRelease(ibh);
293
294 if (bcfound) {
295 if (st->pa->info != 7) {
296 printk(KERN_WARNING "non-digital call: %s -> %s\n",
297 st->pa->calling,
298 st->pa->called);
299 }
300 newl3state(st, 6);
301 st->l3.l3l4(st, CC_SETUP_IND, NULL);
302 }
303 }
304
305 static void
306 l3s13(struct PStack *st, byte pr, void *arg)
307 {
308 newl3state(st, 0);
309 }
310
311 #ifdef DEFINED_BUT_NOT_USED
312 static void
313 l3s15(struct PStack *st, byte pr, void *arg)
314 {
315 newl3state(st, 0);
316 st->l3.l3l4(st, CC_REJECT, NULL);
317 }
318 #endif
319
320 static void
321 l3s16(struct PStack *st, byte pr,
322 void *arg)
323 {
324 st->l3.callref = 0x80 + st->pa->callref;
325 l3_message(st, MT_CONNECT);
326 newl3state(st, 8);
327 }
328
329 static void
330 l3s17(struct PStack *st, byte pr, void *arg)
331 {
332 struct BufHeader *ibh = arg;
333
334 BufPoolRelease(ibh);
335 st->l3.l3l4(st, CC_SETUP_COMPLETE_IND, NULL);
336 newl3state(st, 10);
337 }
338
339 static void
340 l3s18(struct PStack *st, byte pr, void *arg)
341 {
342 struct BufHeader *dibh;
343 byte *p;
344 int size;
345
346 BufPoolGet(&dibh, st->l1.sbufpool, GFP_ATOMIC, (void *) st, 20);
347 p = DATAPTR(dibh);
348 p += st->l2.ihsize;
349 size = st->l2.ihsize;
350
351 *p++ = 0x8;
352 *p++ = 0x1;
353 *p++ = st->l3.callref;
354 *p++ = MT_DISCONNECT;
355 size += 4;
356
357 *p++ = IE_CAUSE;
358 *p++ = 0x2;
359 *p++ = 0x80;
360 *p++ = 0x90;
361 size += 4;
362
363 dibh->datasize = size;
364 i_down(st, dibh);
365
366 newl3state(st, 11);
367 }
368
369 static void
370 l3s19(struct PStack *st, byte pr, void *arg)
371 {
372 struct BufHeader *ibh = arg;
373
374 BufPoolRelease(ibh);
375 newl3state(st, 0);
376 l3_message(st, MT_RELEASE_COMPLETE);
377 st->l3.l3l4(st, CC_RELEASE_IND, NULL);
378 }
379
380 static void
381 l3s20(struct PStack *st, byte pr,
382 void *arg)
383 {
384 l3_message(st, MT_ALERTING);
385 newl3state(st, 7);
386 }
387
388 struct stateentry {
389 int state;
390 byte primitive;
391 void (*rout) (struct PStack *, byte, void *);
392 };
393
394 static struct stateentry downstatelist[] =
395 {
396 {0,CC_SETUP_REQ,l3s5},
397 {1,CC_DISCONNECT_REQ,l3s18},
398 {1,CC_RELEASE_REQ,l3s3},
399 {1,CC_DLRL,l3s13},
400 {3,CC_DISCONNECT_REQ,l3s18},
401 {3,CC_RELEASE_REQ,l3s3},
402 {3,CC_DLRL,l3s13},
403 {4,CC_RELEASE_REQ,l3s3},
404 {4,CC_DISCONNECT_REQ,l3s18},
405 {4,CC_DLRL,l3s13},
406 {6,CC_RELEASE_REQ,l3s3},
407 {6,CC_DISCONNECT_REQ,l3s18},
408 {6,CC_ALERTING_REQ,l3s20},
409 {6,CC_DLRL,l3s13},
410 {7,CC_RELEASE_REQ,l3s3},
411 {7,CC_SETUP_RSP,l3s16},
412 {7,CC_DLRL,l3s13},
413 {8,CC_RELEASE_REQ,l3s3},
414 {8,CC_DISCONNECT_REQ,l3s18},
415 {8,CC_DLRL,l3s13},
416 {10,CC_DISCONNECT_REQ,l3s18},
417 {10,CC_RELEASE_REQ,l3s3},
418 {10,CC_DLRL,l3s13},
419 {11,CC_RELEASE_REQ,l3s3},
420 {12,CC_RELEASE_REQ,l3s3},
421 {19,CC_DLRL,l3s13},
422 };
423
424 static int downsllen = sizeof(downstatelist) /
425 sizeof(struct stateentry);
426
427 static struct stateentry datastatelist[] =
428 {
429 {0,MT_SETUP,l3s12},
430 {1,MT_CALL_PROCEEDING,l3s6},
431 {1,MT_RELEASE_COMPLETE,l3s4},
432 {1,MT_RELEASE,l3s19},
433 {1,MT_DISCONNECT,l3s7},
434 {3,MT_DISCONNECT,l3s7},
435 {3,MT_CONNECT,l3s8},
436 {3,MT_ALERTING,l3s11},
437 {3,MT_RELEASE,l3s19},
438 {3,MT_RELEASE_COMPLETE,l3s4},
439 {4,MT_CONNECT,l3s8},
440 {4,MT_DISCONNECT,l3s7},
441 {4,MT_RELEASE,l3s19},
442 {4,MT_RELEASE_COMPLETE,l3s4},
443 {6,MT_SETUP,l3s12},
444 {7,MT_RELEASE,l3s19},
445 {7,MT_RELEASE_COMPLETE,l3s4_1},
446 {7,MT_DISCONNECT,l3s7},
447 {8,MT_RELEASE,l3s19},
448 {8,MT_CONNECT_ACKNOWLEDGE,l3s17},
449 {8,MT_DISCONNECT,l3s7},
450 {8,MT_RELEASE_COMPLETE,l3s4_1},
451 {10,MT_DISCONNECT,l3s7},
452 {10,MT_RELEASE,l3s19},
453 {10,MT_RELEASE_COMPLETE,l3s4_1},
454 {11,MT_RELEASE,l3s19},
455 {11,MT_RELEASE_COMPLETE,l3s4},
456 {19,MT_RELEASE_COMPLETE,l3s4},
457 };
458
459 static int datasllen = sizeof(datastatelist) /
460 sizeof(struct stateentry);
461
462 #ifdef P_1TR6
463 #include "l3_1TR6.c"
464 #endif
465
466 static void
467 l3up(struct PStack *st,
468 int pr, void *arg)
469 {
470 int i, mt, size;
471 byte *ptr;
472 struct BufHeader *ibh = arg;
473
474 if (pr == DL_DATA) {
475 ptr = DATAPTR(ibh);
476 ptr += st->l2.ihsize;
477 size = ibh->datasize - st->l2.ihsize;
478 if (DEBUG_1TR6 > 6) {
479 printk(KERN_INFO "isdnl3/l3up DL_DATA size=%d\n", size);
480 for (i = 0; i < size; i++)
481 printk(KERN_INFO "l3up data %x\n", ptr[i]);
482 }
483 mt = ptr[3];
484 switch (ptr[0]) {
485 #ifdef P_1TR6
486 case PROTO_DIS_N0:
487 BufPoolRelease(ibh);
488 break;
489 case PROTO_DIS_N1:
490 for (i = 0; i < datasl_1tr6t_len; i++)
491 if ((st->l3.state == datastatelist_1tr6t[i].state) &&
492 (mt == datastatelist_1tr6t[i].primitive))
493 break;
494 if (i == datasl_1tr6t_len) {
495 BufPoolRelease(ibh);
496 if (DEBUG_1TR6 > 0)
497 printk(KERN_INFO "isdnl3up unhandled 1tr6 state %d MT %s\n",
498 st->l3.state, mt_trans(PROTO_DIS_N1, mt));
499 } else
500 datastatelist_1tr6t[i].rout(st, pr, ibh);
501 break;
502 #endif
503 default:
504 for (i = 0; i < datasllen; i++)
505 if ((st->l3.state == datastatelist[i].state) &&
506 (mt == datastatelist[i].primitive))
507 break;
508 if (i == datasllen) {
509 BufPoolRelease(ibh);
510 } else
511 datastatelist[i].rout(st, pr, ibh);
512 }
513 } else if (pr == DL_UNIT_DATA) {
514 ptr = DATAPTR(ibh);
515 ptr += st->l2.uihsize;
516 size = ibh->datasize - st->l2.uihsize;
517 if (DEBUG_1TR6 > 6) {
518 printk(KERN_INFO "isdnl3/l3up DL_UNIT_DATA size=%d\n", size);
519 for (i = 0; i < size; i++)
520 printk(KERN_INFO "l3up data %x\n", ptr[i]);
521 }
522 mt = ptr[3];
523 switch (ptr[0]) {
524 #ifdef P_1TR6
525 case PROTO_DIS_N0:
526 BufPoolRelease(ibh);
527 break;
528 case PROTO_DIS_N1:
529 for (i = 0; i < datasl_1tr6t_len; i++)
530 if ((st->l3.state == datastatelist_1tr6t[i].state) &&
531 (mt == datastatelist_1tr6t[i].primitive))
532 break;
533 if (i == datasl_1tr6t_len) {
534 if (DEBUG_1TR6 > 0) {
535 printk(KERN_INFO "isdnl3up unhandled 1tr6 state %d MT %s\n"
536 ,st->l3.state, mt_trans(PROTO_DIS_N1, mt));
537 }
538 BufPoolRelease(ibh);
539 } else
540 datastatelist_1tr6t[i].rout(st, pr, ibh);
541 break;
542 #endif
543 default:
544 for (i = 0; i < datasllen; i++)
545 if ((st->l3.state == datastatelist[i].state) &&
546 (mt == datastatelist[i].primitive))
547 break;
548 if (i == datasllen) {
549 BufPoolRelease(ibh);
550 } else
551 datastatelist[i].rout(st, pr, ibh);
552 }
553 }
554 }
555
556 static void
557 l3down(struct PStack *st,
558 int pr, void *arg)
559 {
560 int i;
561 struct BufHeader *ibh = arg;
562
563 switch (st->protocol) {
564 #ifdef P_1TR6
565 case ISDN_PTYPE_1TR6:
566 for (i = 0; i < downsl_1tr6t_len; i++)
567 if ((st->l3.state == downstatelist_1tr6t[i].state) &&
568 (pr == downstatelist_1tr6t[i].primitive))
569 break;
570 if (i == downsl_1tr6t_len) {
571 if (DEBUG_1TR6 > 0) {
572 printk(KERN_INFO "isdnl3down unhandled 1tr6 state %d primitive %x\n", st->l3.state, pr);
573 }
574 } else
575 downstatelist_1tr6t[i].rout(st, pr, ibh);
576 break;
577 #endif
578 default:
579 for (i = 0; i < downsllen; i++)
580 if ((st->l3.state == downstatelist[i].state) &&
581 (pr == downstatelist[i].primitive))
582 break;
583 if (i == downsllen) {
584 } else
585 downstatelist[i].rout(st, pr, ibh);
586 }
587 }
588
589 void
590 setstack_isdnl3(struct PStack *st)
591 {
592 st->l4.l4l3 = l3down;
593 st->l2.l2l3 = l3up;
594 st->l3.state = 0;
595 st->l3.callref = 0;
596 st->l3.debug = 0;
597 }