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