1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#include <linux/kernel.h>
31
32#include <linux/types.h>
33#include <linux/slab.h>
34#include <linux/mm.h>
35
36#include <linux/skbuff.h>
37
38#include <linux/io.h>
39#include <linux/string.h>
40
41#include <linux/isdnif.h>
42
43#include "pcbit.h"
44#include "edss1.h"
45#include "capi.h"
46
47
48
49
50
51
52
53int capi_conn_req(const char *calledPN, struct sk_buff **skb, int proto)
54{
55 ushort len;
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 len = 18 + strlen(calledPN);
74
75 if (proto == ISDN_PROTO_L2_TRANS)
76 len++;
77
78 if ((*skb = dev_alloc_skb(len)) == NULL) {
79
80 printk(KERN_WARNING "capi_conn_req: alloc_skb failed\n");
81 return -1;
82 }
83
84
85 *((ushort *)skb_put(*skb, 2)) = AppInfoMask;
86
87 if (proto == ISDN_PROTO_L2_TRANS)
88 {
89
90 *(skb_put(*skb, 1)) = 3;
91 *(skb_put(*skb, 1)) = 0x80;
92 *(skb_put(*skb, 1)) = 0x10;
93 *(skb_put(*skb, 1)) = 0x23;
94 } else {
95
96 *(skb_put(*skb, 1)) = 2;
97 *(skb_put(*skb, 1)) = 0x88;
98 *(skb_put(*skb, 1)) = 0x90;
99 }
100
101
102 *(skb_put(*skb, 1)) = 0;
103
104 *(skb_put(*skb, 1)) = 1;
105 *(skb_put(*skb, 1)) = 0x83;
106
107 *(skb_put(*skb, 1)) = 0;
108
109
110 *(skb_put(*skb, 1)) = 0;
111 *(skb_put(*skb, 1)) = 0;
112
113
114 *(skb_put(*skb, 1)) = strlen(calledPN) + 1;
115 *(skb_put(*skb, 1)) = 0x81;
116 memcpy(skb_put(*skb, strlen(calledPN)), calledPN, strlen(calledPN));
117
118
119
120 *(skb_put(*skb, 1)) = 0;
121
122
123
124
125
126 memset(skb_put(*skb, 4), 0, 4);
127
128 return len;
129}
130
131int capi_conn_resp(struct pcbit_chan *chan, struct sk_buff **skb)
132{
133
134 if ((*skb = dev_alloc_skb(5)) == NULL) {
135
136 printk(KERN_WARNING "capi_conn_resp: alloc_skb failed\n");
137 return -1;
138 }
139
140 *((ushort *)skb_put(*skb, 2)) = chan->callref;
141 *(skb_put(*skb, 1)) = 0x01;
142 *(skb_put(*skb, 1)) = 0;
143 *(skb_put(*skb, 1)) = 0;
144
145 return 5;
146}
147
148int capi_conn_active_req(struct pcbit_chan *chan, struct sk_buff **skb)
149{
150
151
152
153
154 if ((*skb = dev_alloc_skb(8)) == NULL) {
155
156 printk(KERN_WARNING "capi_conn_active_req: alloc_skb failed\n");
157 return -1;
158 }
159
160 *((ushort *)skb_put(*skb, 2)) = chan->callref;
161
162#ifdef DEBUG
163 printk(KERN_DEBUG "Call Reference: %04x\n", chan->callref);
164#endif
165
166 *(skb_put(*skb, 1)) = 0;
167 *(skb_put(*skb, 1)) = 0;
168 *(skb_put(*skb, 1)) = 0;
169 *(skb_put(*skb, 1)) = 0;
170 *(skb_put(*skb, 1)) = 0;
171 *(skb_put(*skb, 1)) = 0;
172
173 return 8;
174}
175
176int capi_conn_active_resp(struct pcbit_chan *chan, struct sk_buff **skb)
177{
178
179
180
181
182 if ((*skb = dev_alloc_skb(2)) == NULL) {
183
184 printk(KERN_WARNING "capi_conn_active_resp: alloc_skb failed\n");
185 return -1;
186 }
187
188 *((ushort *)skb_put(*skb, 2)) = chan->callref;
189
190 return 2;
191}
192
193
194int capi_select_proto_req(struct pcbit_chan *chan, struct sk_buff **skb,
195 int outgoing)
196{
197
198
199
200
201
202 if ((*skb = dev_alloc_skb(18)) == NULL) {
203
204 printk(KERN_WARNING "capi_select_proto_req: alloc_skb failed\n");
205 return -1;
206 }
207
208 *((ushort *)skb_put(*skb, 2)) = chan->callref;
209
210
211
212 switch (chan->proto) {
213 case ISDN_PROTO_L2_X75I:
214 *(skb_put(*skb, 1)) = 0x05;
215 break;
216 case ISDN_PROTO_L2_HDLC:
217 *(skb_put(*skb, 1)) = 0x02;
218 break;
219 case ISDN_PROTO_L2_TRANS:
220
221
222
223 *(skb_put(*skb, 1)) = 0x06;
224 break;
225 default:
226#ifdef DEBUG
227 printk(KERN_DEBUG "Transparent\n");
228#endif
229 *(skb_put(*skb, 1)) = 0x03;
230 break;
231 }
232
233 *(skb_put(*skb, 1)) = (outgoing ? 0x02 : 0x42);
234 *(skb_put(*skb, 1)) = 0x00;
235
236 *((ushort *) skb_put(*skb, 2)) = MRU;
237
238
239 *(skb_put(*skb, 1)) = 0x08;
240 *(skb_put(*skb, 1)) = 0x07;
241
242 *(skb_put(*skb, 1)) = 0x01;
243
244
245
246
247
248
249
250
251
252
253
254 memset(skb_put(*skb, 8), 0, 8);
255
256 return 18;
257}
258
259
260int capi_activate_transp_req(struct pcbit_chan *chan, struct sk_buff **skb)
261{
262
263 if ((*skb = dev_alloc_skb(7)) == NULL) {
264
265 printk(KERN_WARNING "capi_activate_transp_req: alloc_skb failed\n");
266 return -1;
267 }
268
269 *((ushort *)skb_put(*skb, 2)) = chan->callref;
270
271
272 *(skb_put(*skb, 1)) = chan->layer2link;
273 *(skb_put(*skb, 1)) = 0x00;
274
275 *((ushort *) skb_put(*skb, 2)) = MRU;
276
277 *(skb_put(*skb, 1)) = 0x01;
278
279 return 7;
280}
281
282int capi_tdata_req(struct pcbit_chan *chan, struct sk_buff *skb)
283{
284 ushort data_len;
285
286
287
288
289
290
291
292
293
294
295 data_len = skb->len;
296
297 if (skb_headroom(skb) < 10)
298 {
299 printk(KERN_CRIT "No headspace (%u) on headroom %p for capi header\n", skb_headroom(skb), skb);
300 }
301 else
302 {
303 skb_push(skb, 10);
304 }
305
306 *((u16 *) (skb->data)) = chan->callref;
307 skb->data[2] = chan->layer2link;
308 *((u16 *) (skb->data + 3)) = data_len;
309
310 chan->s_refnum = (chan->s_refnum + 1) % 8;
311 *((u32 *) (skb->data + 5)) = chan->s_refnum;
312
313 skb->data[9] = 0;
314
315 return 10;
316}
317
318int capi_tdata_resp(struct pcbit_chan *chan, struct sk_buff **skb)
319
320{
321 if ((*skb = dev_alloc_skb(4)) == NULL) {
322
323 printk(KERN_WARNING "capi_tdata_resp: alloc_skb failed\n");
324 return -1;
325 }
326
327 *((ushort *)skb_put(*skb, 2)) = chan->callref;
328
329 *(skb_put(*skb, 1)) = chan->layer2link;
330 *(skb_put(*skb, 1)) = chan->r_refnum;
331
332 return (*skb)->len;
333}
334
335int capi_disc_req(ushort callref, struct sk_buff **skb, u_char cause)
336{
337
338 if ((*skb = dev_alloc_skb(6)) == NULL) {
339
340 printk(KERN_WARNING "capi_disc_req: alloc_skb failed\n");
341 return -1;
342 }
343
344 *((ushort *)skb_put(*skb, 2)) = callref;
345
346 *(skb_put(*skb, 1)) = 2;
347 *(skb_put(*skb, 1)) = 0x80;
348 *(skb_put(*skb, 1)) = 0x80 | cause;
349
350
351
352
353
354 *(skb_put(*skb, 1)) = 0;
355
356 return 6;
357}
358
359int capi_disc_resp(struct pcbit_chan *chan, struct sk_buff **skb)
360{
361 if ((*skb = dev_alloc_skb(2)) == NULL) {
362
363 printk(KERN_WARNING "capi_disc_resp: alloc_skb failed\n");
364 return -1;
365 }
366
367 *((ushort *)skb_put(*skb, 2)) = chan->callref;
368
369 return 2;
370}
371
372
373
374
375
376
377
378int capi_decode_conn_ind(struct pcbit_chan *chan,
379 struct sk_buff *skb,
380 struct callb_data *info)
381{
382 int CIlen, len;
383
384
385 chan->callref = *((ushort *)skb->data);
386 skb_pull(skb, 2);
387
388#ifdef DEBUG
389 printk(KERN_DEBUG "Call Reference: %04x\n", chan->callref);
390#endif
391
392
393
394
395
396
397
398
399 CIlen = skb->data[0];
400#ifdef DEBUG
401 if (CIlen == 1) {
402
403 if (((skb->data[1]) & 0xFC) == 0x48)
404 printk(KERN_DEBUG "decode_conn_ind: chan ok\n");
405 printk(KERN_DEBUG "phyChan = %d\n", skb->data[1] & 0x03);
406 }
407 else
408 printk(KERN_DEBUG "conn_ind: CIlen = %d\n", CIlen);
409#endif
410 skb_pull(skb, CIlen + 1);
411
412
413
414
415 len = skb->data[0];
416
417 if (len > 0) {
418 int count = 1;
419
420#ifdef DEBUG
421 printk(KERN_DEBUG "CPN: Octect 3 %02x\n", skb->data[1]);
422#endif
423 if ((skb->data[1] & 0x80) == 0)
424 count = 2;
425
426 if (!(info->data.setup.CallingPN = kmalloc(len - count + 1, GFP_ATOMIC)))
427 return -1;
428
429 skb_copy_from_linear_data_offset(skb, count + 1,
430 info->data.setup.CallingPN,
431 len - count);
432 info->data.setup.CallingPN[len - count] = 0;
433
434 }
435 else {
436 info->data.setup.CallingPN = NULL;
437 printk(KERN_DEBUG "NULL CallingPN\n");
438 }
439
440 skb_pull(skb, len + 1);
441
442
443 skb_pull(skb, skb->data[0] + 1);
444
445
446
447 len = skb->data[0];
448
449 if (len > 0) {
450 int count = 1;
451
452 if ((skb->data[1] & 0x80) == 0)
453 count = 2;
454
455 if (!(info->data.setup.CalledPN = kmalloc(len - count + 1, GFP_ATOMIC)))
456 return -1;
457
458 skb_copy_from_linear_data_offset(skb, count + 1,
459 info->data.setup.CalledPN,
460 len - count);
461 info->data.setup.CalledPN[len - count] = 0;
462
463 }
464 else {
465 info->data.setup.CalledPN = NULL;
466 printk(KERN_DEBUG "NULL CalledPN\n");
467 }
468
469 skb_pull(skb, len + 1);
470
471
472 skb_pull(skb, skb->data[0] + 1);
473
474
475 skb_pull(skb, skb->data[0] + 1);
476
477
478 skb_pull(skb, skb->data[0] + 1);
479
480
481 skb_pull(skb, skb->data[0] + 1);
482
483 return 0;
484}
485
486
487
488
489
490int capi_decode_conn_conf(struct pcbit_chan *chan, struct sk_buff *skb,
491 int *complete)
492{
493 int errcode;
494
495 chan->callref = *((ushort *)skb->data);
496 skb_pull(skb, 2);
497
498 errcode = *((ushort *) skb->data);
499 skb_pull(skb, 2);
500
501 *complete = *(skb->data);
502 skb_pull(skb, 1);
503
504
505
506 if (!*complete)
507 {
508 printk(KERN_DEBUG "complete=%02x\n", *complete);
509 *complete = 1;
510 }
511
512
513
514 skb_pull(skb, *(skb->data) + 1);
515
516
517 skb_pull(skb, *(skb->data) + 1);
518
519
520 skb_pull(skb, *(skb->data) + 1);
521
522 return errcode;
523}
524
525int capi_decode_conn_actv_ind(struct pcbit_chan *chan, struct sk_buff *skb)
526{
527 ushort len;
528#ifdef DEBUG
529 char str[32];
530#endif
531
532
533 skb_pull(skb, *(skb->data) + 1);
534
535
536
537 len = *(skb->data);
538
539#ifdef DEBUG
540 if (len > 1 && len < 31) {
541 skb_copy_from_linear_data_offset(skb, 2, str, len - 1);
542 str[len] = 0;
543 printk(KERN_DEBUG "Connected Party Number: %s\n", str);
544 }
545 else
546 printk(KERN_DEBUG "actv_ind CPN len = %d\n", len);
547#endif
548
549 skb_pull(skb, len + 1);
550
551
552 skb_pull(skb, *(skb->data) + 1);
553
554
555 skb_pull(skb, *(skb->data) + 1);
556
557
558 skb_pull(skb, *(skb->data) + 1);
559
560 return 0;
561}
562
563int capi_decode_conn_actv_conf(struct pcbit_chan *chan, struct sk_buff *skb)
564{
565 ushort errcode;
566
567 errcode = *((ushort *)skb->data);
568 skb_pull(skb, 2);
569
570
571
572
573 return errcode;
574}
575
576
577int capi_decode_sel_proto_conf(struct pcbit_chan *chan, struct sk_buff *skb)
578{
579 ushort errcode;
580
581 chan->layer2link = *(skb->data);
582 skb_pull(skb, 1);
583
584 errcode = *((ushort *)skb->data);
585 skb_pull(skb, 2);
586
587 return errcode;
588}
589
590int capi_decode_actv_trans_conf(struct pcbit_chan *chan, struct sk_buff *skb)
591{
592 ushort errcode;
593
594 if (chan->layer2link != *(skb->data))
595 printk("capi_decode_actv_trans_conf: layer2link doesn't match\n");
596
597 skb_pull(skb, 1);
598
599 errcode = *((ushort *)skb->data);
600 skb_pull(skb, 2);
601
602 return errcode;
603}
604
605int capi_decode_disc_ind(struct pcbit_chan *chan, struct sk_buff *skb)
606{
607 ushort len;
608#ifdef DEBUG
609 int i;
610#endif
611
612
613 len = *(skb->data);
614 skb_pull(skb, 1);
615
616#ifdef DEBUG
617
618 for (i = 0; i < len; i++)
619 printk(KERN_DEBUG "Cause Octect %d: %02x\n", i + 3,
620 *(skb->data + i));
621#endif
622
623 skb_pull(skb, len);
624
625 return 0;
626}
627
628#ifdef DEBUG
629int capi_decode_debug_188(u_char *hdr, ushort hdrlen)
630{
631 char str[64];
632 int len;
633
634 len = hdr[0];
635
636 if (len < 64 && len == hdrlen - 1) {
637 memcpy(str, hdr + 1, hdrlen - 1);
638 str[hdrlen - 1] = 0;
639 printk("%s\n", str);
640 }
641 else
642 printk("debug message incorrect\n");
643
644 return 0;
645}
646#endif
647