added bearer capability reject support. we send release instead of disconnect in...
[asterisk/asterisk.git] / channels / misdn / ie.c
1
2 /*
3  * Chan_Misdn -- Channel Driver for Asterisk
4  *
5  * Interface to mISDN
6  *
7  * Copyright (C) 2005, Christian Richter
8  *
9  * Christian Richter <crich@beronet.com>
10  *
11  * heaviliy patched from jollys ie.cpp, jolly gave me ALL
12  * rights for this code, i can even have my own copyright on it.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License
16  */
17
18 /*
19   the pointer of enc_ie_* always points to the IE itself
20   if qi is not NULL (TE-mode), offset is set
21 */
22
23
24 #include <string.h>
25
26 #include <mISDNuser/mISDNlib.h>
27 #include <mISDNuser/isdn_net.h>
28 #include <mISDNuser/l3dss1.h>
29 #include <mISDNuser/net_l3.h>
30
31
32
33 #define MISDN_IE_DEBG 0
34
35 /* support stuff */
36 static void strnncpy(unsigned char *dest, unsigned char *src, int len, int dst_len)
37 {
38         if (len > dst_len-1)
39                 len = dst_len-1;
40         strncpy((char *)dest, (char *)src, len);
41         dest[len] = '\0';
42 }
43
44
45 /* IE_COMPLETE */
46 void enc_ie_complete(unsigned char **ntmode, msg_t *msg, int complete, int nt, struct misdn_bchannel *bc)
47 {
48         unsigned char *p;
49         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
50
51         if (complete<0 || complete>1)
52         {
53                 printf("%s: ERROR: complete(%d) is out of range.\n", __FUNCTION__, complete);
54                 return;
55         }
56
57         if (complete)
58                 if (MISDN_IE_DEBG) printf("    complete=%d\n", complete);
59
60         if (complete)
61         {
62                 p = msg_put(msg, 1);
63                 if (nt)
64                 {
65                         *ntmode = p;
66                 } else
67                         qi->QI_ELEMENT(sending_complete) = p - (unsigned char *)qi - sizeof(Q931_info_t);
68
69                 p[0] = IE_COMPLETE;
70         }
71 }
72
73 void dec_ie_complete(unsigned char *p, Q931_info_t *qi, int *complete, int nt, struct misdn_bchannel *bc)
74 {
75         *complete = 0;
76         if (!nt)
77         {
78                 if (qi->QI_ELEMENT(sending_complete))
79                         *complete = 1;
80         } else
81                 if (p)
82                         *complete = 1;
83
84         if (*complete)
85                 if (MISDN_IE_DEBG) printf("    complete=%d\n", *complete);
86 }
87
88
89 /* IE_BEARER */
90 void enc_ie_bearer(unsigned char **ntmode, msg_t *msg, int coding, int capability, int mode, int rate, int multi, int user, int nt, struct misdn_bchannel *bc)
91 {
92         unsigned char *p;
93         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
94         int l;
95
96         if (coding<0 || coding>3)
97         {
98                 printf("%s: ERROR: coding(%d) is out of range.\n", __FUNCTION__, coding);
99                 return;
100         }
101         if (capability<0 || capability>31)
102         {
103                 printf("%s: ERROR: capability(%d) is out of range.\n", __FUNCTION__, capability);
104                 return;
105         }
106         if (mode<0 || mode>3)
107         {
108                 printf("%s: ERROR: mode(%d) is out of range.\n", __FUNCTION__, mode);
109                 return;
110         }
111         if (rate<0 || rate>31)
112         {
113                 printf("%s: ERROR: rate(%d) is out of range.\n", __FUNCTION__, rate);
114                 return;
115         }
116         if (multi>127)
117         {
118                 printf("%s: ERROR: multi(%d) is out of range.\n", __FUNCTION__, multi);
119                 return;
120         }
121         if (user>31)
122         {
123                 printf("%s: ERROR: user L1(%d) is out of range.\n", __FUNCTION__, rate);
124                 return;
125         }
126         if (rate!=24 && multi>=0)
127         {
128                 printf("%s: WARNING: multi(%d) is only possible if rate(%d) would be 24.\n", __FUNCTION__, multi, rate);
129                 multi = -1;
130         }
131
132         if (MISDN_IE_DEBG) printf("    coding=%d capability=%d mode=%d rate=%d multi=%d user=%d\n", coding, capability, mode, rate, multi, user);
133
134         l = 2 + (multi>=0) + (user>=0);
135         p = msg_put(msg, l+2);
136         if (nt)
137                 *ntmode = p+1;
138         else
139                 qi->QI_ELEMENT(bearer_capability) = p - (unsigned char *)qi - sizeof(Q931_info_t);
140         p[0] = IE_BEARER;
141         p[1] = l;
142         p[2] = 0x80 + (coding<<5) + capability;
143         p[3] = 0x80 + (mode<<5) + rate;
144         if (multi >= 0)
145                 p[4] = 0x80 + multi;
146         if (user >= 0)
147                 p[4+(multi>=0)] = 0xa0 + user;
148 }
149
150 void dec_ie_bearer(unsigned char *p, Q931_info_t *qi, int *coding, int *capability, int *mode, int *rate, int *multi, int *user, 
151                    int *async, int *urate, int *stopbits, int *dbits, int *parity, int nt, struct misdn_bchannel *bc)
152 {
153         int octet;
154         *coding = -1;
155         *capability = -1;
156         *mode = -1;
157         *rate = -1;
158         *multi = -1;
159         *user = -1;
160         *async = -1;
161         *urate = -1;
162         *stopbits = -1;
163         *dbits = -1;
164         *parity = -1;
165         
166         if (!nt)
167         {
168                 p = NULL;
169 #ifdef LLC_SUPPORT
170                 if (qi->QI_ELEMENT(llc)) {
171                         
172                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(llc) + 1;
173                 }
174 #endif
175                 if (qi->QI_ELEMENT(bearer_capability))
176                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(bearer_capability) + 1;
177         }
178         if (!p)
179                 return;
180
181         if (p[0] < 2)
182         {
183                 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
184                 return;
185         }
186         
187         *coding = (p[1]&0x60) >> 5;
188         *capability = p[1] & 0x1f;
189         octet = 2;
190         if (!(p[1] & 0x80))
191                 octet++;
192
193         if (p[0] < octet)
194                 goto done;
195
196         *mode = (p[octet]&0x60) >> 5;
197         *rate = p[octet] & 0x1f;
198
199         octet++;
200
201         if (p[0] < octet)
202                 goto done;
203
204         if (*rate == 0x18) {
205                 /* Rate multiplier only present if 64Kb/s base rate */
206                 *multi = p[octet++] & 0x7f;
207         }
208
209         if (p[0] < octet)
210                 goto done;
211
212         /* Start L1 info */
213         if ((p[octet] & 0x60) == 0x20) {
214                 *user = p[octet] & 0x1f;
215
216                 if (p[0] <= octet)
217                         goto done;
218                 
219                 if (p[octet++] & 0x80)
220                         goto l2;
221
222                 *async = !!(p[octet] & 0x40);
223                 /* 0x20 is inband negotiation */
224                 *urate = p[octet] & 0x1f;
225
226                 if (p[0] <= octet)
227                         goto done;
228                 
229                 if (p[octet++] & 0x80)
230                         goto l2;
231
232                 /* Ignore next byte for now: Intermediate rate, NIC, flow control */
233
234                 if (p[0] <= octet)
235                         goto done;
236                 
237                 if (p[octet++] & 0x80)
238                         goto l2;
239
240                 /* And the next one. Header, multiframe, mode, assignor/ee, negotiation */
241
242                 if (p[0] <= octet)
243                         goto done;
244                 
245                 if (!p[octet++] & 0x80)
246                         goto l2;
247
248                 /* Wheee. V.110 speed information */
249
250                 *stopbits = (p[octet] & 0x60) >> 5;
251                 *dbits = (p[octet] & 0x18) >> 3; 
252                 *parity = p[octet] & 7;
253
254                 octet++;
255         }
256  l2: /* Nobody seems to want the rest so we don't bother (yet) */
257  done:          
258         if (MISDN_IE_DEBG) printf("    coding=%d capability=%d mode=%d rate=%d multi=%d user=%d async=%d urate=%d stopbits=%d dbits=%d parity=%d\n", *coding, *capability, *mode, *rate, *multi, *user, *async, *urate, *stopbits, *dbits, *parity);
259 }
260
261
262 /* IE_CALL_ID */
263 void enc_ie_call_id(unsigned char **ntmode, msg_t *msg, unsigned char *callid, int callid_len, int nt, struct misdn_bchannel *bc)
264 {
265         unsigned char *p;
266         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
267         int l;
268
269         char debug[25];
270         int i;
271
272         if (!callid || callid_len<=0)
273         {
274                 return;
275         }
276         if (callid_len>8)
277         {
278                 printf("%s: ERROR: callid_len(%d) is out of range.\n", __FUNCTION__, callid_len);
279                 return;
280         }
281
282         i = 0;
283         while(i < callid_len)
284         {
285                 if (MISDN_IE_DEBG) printf(debug+(i*3), " %02x", callid[i]);
286                 i++;
287         }
288                 
289         if (MISDN_IE_DEBG) printf("    callid%s\n", debug);
290
291         l = callid_len;
292         p = msg_put(msg, l+2);
293         if (nt)
294                 *ntmode = p+1;
295         else
296                 qi->QI_ELEMENT(call_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
297         p[0] = IE_CALL_ID;
298         p[1] = l;
299         memcpy(p+2, callid, callid_len);
300 }
301
302 void dec_ie_call_id(unsigned char *p, Q931_info_t *qi, unsigned char *callid, int *callid_len, int nt, struct misdn_bchannel *bc)
303 {
304         char debug[25];
305         int i;
306
307         *callid_len = -1;
308
309         if (!nt)
310         {
311                 p = NULL;
312                 if (qi->QI_ELEMENT(call_id))
313                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(call_id) + 1;
314         }
315         if (!p)
316                 return;
317         if (p[0] > 8)
318         {
319                 printf("%s: ERROR: IE too long (%d).\n", __FUNCTION__, p[0]);
320                 return;
321         }
322
323         *callid_len = p[0];
324         memcpy(callid, p+1, *callid_len);
325
326         i = 0;
327         while(i < *callid_len)
328         {
329                 if (MISDN_IE_DEBG) printf(debug+(i*3), " %02x", callid[i]);
330                 i++;
331         }
332                 
333         if (MISDN_IE_DEBG) printf("    callid%s\n", debug);
334 }
335
336
337 /* IE_CALLED_PN */
338 void enc_ie_called_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, unsigned char *number, int nt, struct misdn_bchannel *bc)
339 {
340         unsigned char *p;
341         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
342         int l;
343
344         if (type<0 || type>7)
345         {
346                 printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
347                 return;
348         }
349         if (plan<0 || plan>15)
350         {
351                 printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
352                 return;
353         }
354         if (!number[0])
355         {
356                 printf("%s: ERROR: number is not given.\n", __FUNCTION__);
357                 return;
358         }
359
360         if (MISDN_IE_DEBG) printf("    type=%d plan=%d number='%s'\n", type, plan, number);
361
362         l = 1+strlen((char *)number);
363         p = msg_put(msg, l+2);
364         if (nt)
365                 *ntmode = p+1;
366         else
367                 qi->QI_ELEMENT(called_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
368         p[0] = IE_CALLED_PN;
369         p[1] = l;
370         p[2] = 0x80 + (type<<4) + plan;
371         strncpy((char *)p+3, (char *)number, strlen((char *)number));
372 }
373
374 void dec_ie_called_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, unsigned char *number, int number_len, int nt, struct misdn_bchannel *bc)
375 {
376         *type = -1;
377         *plan = -1;
378         *number = '\0';
379
380         if (!nt)
381         {
382                 p = NULL;
383                 if (qi->QI_ELEMENT(called_nr))
384                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(called_nr) + 1;
385         }
386         if (!p)
387                 return;
388         if (p[0] < 2)
389         {
390                 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
391                 return;
392         }
393
394         *type = (p[1]&0x70) >> 4;
395         *plan = p[1] & 0xf;
396         strnncpy(number, p+2, p[0]-1, number_len);
397
398         if (MISDN_IE_DEBG) printf("    type=%d plan=%d number='%s'\n", *type, *plan, number);
399 }
400
401
402 /* IE_CALLING_PN */
403 void enc_ie_calling_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, unsigned char *number, int nt, struct misdn_bchannel *bc)
404 {
405         unsigned char *p;
406         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
407         int l;
408
409         if (type<0 || type>7)
410         {
411                 printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
412                 return;
413         }
414         if (plan<0 || plan>15)
415         {
416                 printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
417                 return;
418         }
419         if (present>3)
420         {
421                 printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
422                 return;
423         }
424         if (present >= 0) if (screen<0 || screen>3)
425         {
426                 printf("%s: ERROR: screen(%d) is out of range.\n", __FUNCTION__, screen);
427                 return;
428         }
429
430         if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d screen=%d number='%s'\n", type, plan, present, screen, number);
431
432         l = 1;
433         if (number) if (number[0])
434                 l += strlen((char *)number);
435         if (present >= 0)
436                 l += 1;
437         p = msg_put(msg, l+2);
438         if (nt)
439                 *ntmode = p+1;
440         else
441                 qi->QI_ELEMENT(calling_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
442         p[0] = IE_CALLING_PN;
443         p[1] = l;
444         if (present >= 0)
445         {
446                 p[2] = 0x00 + (type<<4) + plan;
447                 p[3] = 0x80 + (present<<5) + screen;
448                 if (number) if (number[0])
449                         strncpy((char *)p+4, (char *)number, strlen((char *)number));
450         } else
451         {
452                 p[2] = 0x80 + (type<<4) + plan;
453                 if (number) if (number[0])
454                         strncpy((char *)p+3, (char *)number, strlen((char *)number));
455         }
456 }
457
458 void dec_ie_calling_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, unsigned char *number, int number_len, int nt, struct misdn_bchannel *bc)
459 {
460         *type = -1;
461         *plan = -1;
462         *present = -1;
463         *screen = -1;
464         *number = '\0';
465
466         if (!nt)
467         {
468                 p = NULL;
469                 if (qi->QI_ELEMENT(calling_nr))
470                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(calling_nr) + 1;
471         }
472         if (!p)
473                 return;
474         if (p[0] < 1)
475         {
476                 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
477                 return;
478         }
479
480         *type = (p[1]&0x70) >> 4;
481         *plan = p[1] & 0xf;
482         if (!(p[1] & 0x80))
483         {
484                 if (p[0] < 2)
485                 {
486                         printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
487                         return;
488                 }
489                 *present = (p[2]&0x60) >> 5;
490                 *screen = p[2] & 0x3;
491                 strnncpy(number, p+3, p[0]-2, number_len);
492         } else
493         {
494                 strnncpy(number, p+2, p[0]-1, number_len);
495                 /* SPECIAL workarround for IBT software bug */ 
496                 /* if (number[0]==0x80) */
497                 /*  strcpy((char *)number, (char *)number+1); */
498         }
499
500         if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d screen=%d number='%s'\n", *type, *plan, *present, *screen, number);
501 }
502
503
504 /* IE_CONNECTED_PN */
505 void enc_ie_connected_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, unsigned char *number, int nt, struct misdn_bchannel *bc)
506 {
507         unsigned char *p;
508         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
509         int l;
510
511         if (type<0 || type>7)
512         {
513                 printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
514                 return;
515         }
516         if (plan<0 || plan>15)
517         {
518                 printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
519                 return;
520         }
521         if (present>3)
522         {
523                 printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
524                 return;
525         }
526         if (present >= 0) if (screen<0 || screen>3)
527         {
528                 printf("%s: ERROR: screen(%d) is out of range.\n", __FUNCTION__, screen);
529                 return;
530         }
531
532         if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d screen=%d number='%s'\n", type, plan, present, screen, number);
533
534         l = 1;
535         if (number) if (number[0])
536                 l += strlen((char *)number);
537         if (present >= 0)
538                 l += 1;
539         p = msg_put(msg, l+2);
540         if (nt)
541                 *ntmode = p+1;
542         else
543                 qi->QI_ELEMENT(connected_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
544         p[0] = IE_CONNECT_PN;
545         p[1] = l;
546         if (present >= 0)
547         {
548                 p[2] = 0x00 + (type<<4) + plan;
549                 p[3] = 0x80 + (present<<5) + screen;
550                 if (number) if (number[0])
551                         strncpy((char *)p+4, (char *)number, strlen((char *)number));
552         } else
553         {
554                 p[2] = 0x80 + (type<<4) + plan;
555                 if (number) if (number[0])
556                         strncpy((char *)p+3, (char *)number, strlen((char *)number));
557         }
558 }
559
560 void dec_ie_connected_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, unsigned char *number, int number_len, int nt, struct misdn_bchannel *bc)
561 {
562         *type = -1;
563         *plan = -1;
564         *present = -1;
565         *screen = -1;
566         *number = '\0';
567
568         if (!nt)
569         {
570                 p = NULL;
571                 if (qi->QI_ELEMENT(connected_nr))
572                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(connected_nr) + 1;
573         }
574         if (!p)
575                 return;
576         if (p[0] < 1)
577         {
578                 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
579                 return;
580         }
581
582         *type = (p[1]&0x70) >> 4;
583         *plan = p[1] & 0xf;
584         if (!(p[1] & 0x80))
585         {
586                 if (p[0] < 2)
587                 {
588                         printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
589                         return;
590                 }
591                 *present = (p[2]&0x60) >> 5;
592                 *screen = p[2] & 0x3;
593                 strnncpy(number, p+3, p[0]-2, number_len);
594         } else
595         {
596                 strnncpy(number, p+2, p[0]-1, number_len);
597         }
598
599         if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d screen=%d number='%s'\n", *type, *plan, *present, *screen, number);
600 }
601
602
603 /* IE_CAUSE */
604 void enc_ie_cause(unsigned char **ntmode, msg_t *msg, int location, int cause, int nt, struct misdn_bchannel *bc)
605 {
606         unsigned char *p;
607         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
608         int l;
609
610         if (location<0 || location>7)
611         {
612                 printf("%s: ERROR: location(%d) is out of range.\n", __FUNCTION__, location);
613                 return;
614         }
615         if (cause<0 || cause>127)
616         {
617                 printf("%s: ERROR: cause(%d) is out of range.\n", __FUNCTION__, cause);
618                 return;
619         }
620
621         if (MISDN_IE_DEBG) printf("    location=%d cause=%d\n", location, cause);
622
623         l = 2;
624         p = msg_put(msg, l+2);
625         if (nt)
626                 *ntmode = p+1;
627         else
628                 qi->QI_ELEMENT(cause) = p - (unsigned char *)qi - sizeof(Q931_info_t);
629         p[0] = IE_CAUSE;
630         p[1] = l;
631         p[2] = 0x80 + location;
632         p[3] = 0x80 + cause;
633 }
634 void enc_ie_cause_standalone(unsigned char **ntmode, msg_t *msg, int location, int cause, int nt, struct misdn_bchannel *bc)
635 {
636         unsigned char *p = msg_put(msg, 4);
637         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
638         if (ntmode)
639                 *ntmode = p+1;
640         else
641                 qi->QI_ELEMENT(cause) = p - (unsigned char *)qi - sizeof(Q931_info_t);
642         p[0] = IE_CAUSE;
643         p[1] = 2;
644         p[2] = 0x80 + location;
645         p[3] = 0x80 + cause;
646 }
647
648
649 void dec_ie_cause(unsigned char *p, Q931_info_t *qi, int *location, int *cause, int nt, struct misdn_bchannel *bc)
650 {
651         *location = -1;
652         *cause = -1;
653
654         if (!nt)
655         {
656                 p = NULL;
657                 if (qi->QI_ELEMENT(cause))
658                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(cause) + 1;
659         }
660         if (!p)
661                 return;
662         if (p[0] < 2)
663         {
664                 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
665                 return;
666         }
667
668         *location = p[1] & 0x0f;
669         *cause = p[2] & 0x7f;
670
671         if (MISDN_IE_DEBG) printf("    location=%d cause=%d\n", *location, *cause);
672 }
673
674
675 /* IE_CHANNEL_ID */
676 void enc_ie_channel_id(unsigned char **ntmode, msg_t *msg, int exclusive, int channel, int nt, struct misdn_bchannel *bc)
677 {
678         unsigned char *p;
679         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
680         int l;
681         struct misdn_stack *stack=get_stack_by_bc(bc);
682         int pri = stack->pri;
683         
684         if (exclusive<0 || exclusive>1)
685         {
686                 printf("%s: ERROR: exclusive(%d) is out of range.\n", __FUNCTION__, exclusive);
687                 return;
688         }
689         if ((channel<0 || channel>0xff)
690             || (!pri && (channel>2 && channel<0xff))
691             || (pri && (channel>31 && channel<0xff))
692             || (pri && channel==16))
693         {
694                 printf("%s: ERROR: channel(%d) is out of range.\n", __FUNCTION__, channel);
695                 return;
696         }
697
698         /* if (MISDN_IE_DEBG) printf("    exclusive=%d channel=%d\n", exclusive, channel); */
699         
700
701         if (!pri)
702         {
703                 /* BRI */
704                 l = 1;
705                 p = msg_put(msg, l+2);
706                 if (nt)
707                         *ntmode = p+1;
708                 else
709                         qi->QI_ELEMENT(channel_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
710                 p[0] = IE_CHANNEL_ID;
711                 p[1] = l;
712                 if (channel == 0xff)
713                         channel = 3;
714                 p[2] = 0x80 + (exclusive<<3) + channel;
715                 /* printf("    exclusive=%d channel=%d\n", exclusive, channel); */
716         } else
717         {
718                 /* PRI */
719                 if (channel == 0) /* no channel */
720                         return; /* IE not present */
721 /*              if (MISDN_IE_DEBG) printf("channel = %d\n", channel); */
722                 if (channel == 0xff) /* any channel */
723                 {
724                         l = 1;
725                         p = msg_put(msg, l+2);
726                         if (nt)
727                                 *ntmode = p+1;
728                         else
729                                 qi->QI_ELEMENT(channel_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
730                         p[0] = IE_CHANNEL_ID;
731                         p[1] = l;
732                         p[2] = 0x80 + 0x20 + 0x03;
733 /*                      if (MISDN_IE_DEBG) printf("%02x\n", p[2]); */
734                         return; /* end */
735                 }
736                 l = 3;
737                 p = msg_put(msg, l+2);
738                 if (nt)
739                         *ntmode = p+1;
740                 else
741                         qi->QI_ELEMENT(channel_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
742                 p[0] = IE_CHANNEL_ID;
743                 p[1] = l;
744                 p[2] = 0x80 + 0x20 + (exclusive<<3) + 0x01;
745                 p[3] = 0x80 + 3; /* CCITT, Number, B-type */
746                 p[4] = 0x80 + channel;
747 /*              if (MISDN_IE_DEBG) printf("%02x %02x %02x\n", p[2], p[3], p[4]); */
748         }
749 }
750
751 void dec_ie_channel_id(unsigned char *p, Q931_info_t *qi, int *exclusive, int *channel, int nt, struct misdn_bchannel *bc)
752 {
753         struct misdn_stack *stack=get_stack_by_bc(bc);
754         int pri =stack->pri;
755
756         *exclusive = -1;
757         *channel = -1;
758
759         if (!nt)
760         {
761                 p = NULL;
762                 if (qi->QI_ELEMENT(channel_id))
763                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(channel_id) + 1;
764         }
765         if (!p)
766                 return;
767         if (p[0] < 1)
768         {
769                 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
770                 return;
771         }
772
773         if (p[1] & 0x40)
774         {
775                 printf("%s: ERROR: refering to channels of other interfaces is not supported.\n", __FUNCTION__);
776                 return;
777         }
778         if (p[1] & 0x04)
779         {
780                 printf("%s: ERROR: using d-channel is not supported.\n", __FUNCTION__);
781                 return;
782         }
783
784         *exclusive = (p[1]&0x08) >> 3;
785         if (!pri)
786         {
787                 /* BRI */
788                 if (p[1] & 0x20)
789                 {
790                         printf("%s: ERROR: extended channel ID with non PRI interface.\n", __FUNCTION__);
791                         return;
792                 }
793                 *channel = p[1] & 0x03;
794                 if (*channel == 3)
795                         *channel = 0xff;
796         } else
797         {
798                 /* PRI */
799                 if (p[0] < 1)
800                 {
801                         printf("%s: ERROR: IE too short for PRI (%d).\n", __FUNCTION__, p[0]);
802                         return;
803                 }
804                 if (!(p[1] & 0x20))
805                 {
806                         printf("%s: ERROR: basic channel ID with PRI interface.\n", __FUNCTION__);
807                         return;
808                 }
809                 if ((p[1]&0x03) == 0x00)
810                 {
811                         /* no channel */
812                         *channel = 0;
813                         return;
814                 }
815                 if ((p[1]&0x03) == 0x03)
816                 {
817                         /* any channel */
818                         *channel = 0xff;
819                         return;
820                 }
821                 if (p[0] < 3)
822                 {
823                         printf("%s: ERROR: IE too short for PRI with channel(%d).\n", __FUNCTION__, p[0]);
824                         return;
825                 }
826                 if (p[2] & 0x10)
827                 {
828                         printf("%s: ERROR: channel map not supported.\n", __FUNCTION__);
829                         return;
830                 }
831                 *channel = p[3] & 0x7f;
832                 if ( (*channel<1) | (*channel==16) | (*channel>31))
833                 {
834                         printf("%s: ERROR: PRI interface channel out of range (%d).\n", __FUNCTION__, *channel);
835                         return;
836                 }
837 /*              if (MISDN_IE_DEBG) printf("%02x %02x %02x\n", p[1], p[2], p[3]); */
838         }
839
840         if (MISDN_IE_DEBG) printf("    exclusive=%d channel=%d\n", *exclusive, *channel);
841 }
842
843
844 /* IE_DATE */
845 void enc_ie_date(unsigned char **ntmode, msg_t *msg, time_t ti, int nt, struct misdn_bchannel *bc)
846 {
847         unsigned char *p;
848         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
849         int l;
850
851         struct tm *tm;
852
853         tm = localtime(&ti);
854         if (!tm)
855         {
856                 printf("%s: ERROR: gettimeofday() returned NULL.\n", __FUNCTION__);
857                 return;
858         }
859
860         if (MISDN_IE_DEBG) printf("    year=%d month=%d day=%d hour=%d minute=%d\n", tm->tm_year%100, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min);
861
862         l = 5;
863         p = msg_put(msg, l+2);
864         if (nt)
865                 *ntmode = p+1;
866         else
867                 qi->QI_ELEMENT(date) = p - (unsigned char *)qi - sizeof(Q931_info_t);
868         p[0] = IE_DATE;
869         p[1] = l;
870         p[2] = tm->tm_year % 100;
871         p[3] = tm->tm_mon + 1;
872         p[4] = tm->tm_mday;
873         p[5] = tm->tm_hour;
874         p[6] = tm->tm_min;
875 }
876
877
878 /* IE_DISPLAY */
879 void enc_ie_display(unsigned char **ntmode, msg_t *msg, unsigned char *display, int nt, struct misdn_bchannel *bc)
880 {
881         unsigned char *p;
882         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
883         int l;
884
885         if (!display[0])
886         {
887                 printf("%s: ERROR: display text not given.\n", __FUNCTION__);
888                 return;
889         }
890
891         if (strlen((char *)display) > 80)
892         {
893                 printf("%s: WARNING: display text too long (max 80 chars), cutting.\n", __FUNCTION__);
894                 display[80] = '\0';
895         }
896
897         /* if (MISDN_IE_DEBG) printf("    display='%s' (len=%d)\n", display, strlen((char *)display)); */
898
899         l = strlen((char *)display);
900         p = msg_put(msg, l+2);
901         if (nt)
902                 *ntmode = p+1;
903         else
904                 qi->QI_ELEMENT(display) = p - (unsigned char *)qi - sizeof(Q931_info_t);
905         p[0] = IE_DISPLAY;
906         p[1] = l;
907         strncpy((char *)p+2, (char *)display, strlen((char *)display));
908 }
909
910 void dec_ie_display(unsigned char *p, Q931_info_t *qi, unsigned char *display, int display_len, int nt, struct misdn_bchannel *bc)
911 {
912         *display = '\0';
913
914         if (!nt)
915         {
916                 p = NULL;
917                 if (qi->QI_ELEMENT(display))
918                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(display) + 1;
919         }
920         if (!p)
921                 return;
922         if (p[0] < 1)
923         {
924                 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
925                 return;
926         }
927
928         strnncpy(display, p+1, p[0], display_len);
929
930         if (MISDN_IE_DEBG) printf("    display='%s'\n", display);
931 }
932
933
934 /* IE_KEYPAD */
935 void enc_ie_keypad(unsigned char **ntmode, msg_t *msg, unsigned char *keypad, int nt, struct misdn_bchannel *bc)
936 {
937         unsigned char *p;
938         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
939         int l;
940
941         if (!keypad[0])
942         {
943                 printf("%s: ERROR: keypad info not given.\n", __FUNCTION__);
944                 return;
945         }
946
947         if (MISDN_IE_DEBG) printf("    keypad='%s'\n", keypad);
948
949         l = strlen((char *)keypad);
950         p = msg_put(msg, l+2);
951         if (nt)
952                 *ntmode = p+1;
953         else
954                 qi->QI_ELEMENT(keypad) = p - (unsigned char *)qi - sizeof(Q931_info_t);
955         p[0] = IE_KEYPAD;
956         p[1] = l;
957         strncpy((char *)p+2, (char *)keypad, strlen((char *)keypad));
958 }
959
960 void dec_ie_keypad(unsigned char *p, Q931_info_t *qi, unsigned char *keypad, int keypad_len, int nt, struct misdn_bchannel *bc)
961 {
962         *keypad = '\0';
963
964         if (!nt)
965         {
966                 p = NULL;
967                 if (qi->QI_ELEMENT(keypad))
968                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(keypad) + 1;
969         }
970         if (!p)
971                 return;
972         if (p[0] < 1)
973         {
974                 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
975                 return;
976         }
977
978         strnncpy(keypad, p+1, p[0], keypad_len);
979
980         if (MISDN_IE_DEBG) printf("    keypad='%s'\n", keypad);
981 }
982
983
984 /* IE_NOTIFY */
985 void enc_ie_notify(unsigned char **ntmode, msg_t *msg, int notify, int nt, struct misdn_bchannel *bc)
986 {
987         unsigned char *p;
988         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
989         int l;
990
991         if (notify<0 || notify>0x7f)
992         {
993                 printf("%s: ERROR: notify(%d) is out of range.\n", __FUNCTION__, notify);
994                 return;
995         }
996
997         if (MISDN_IE_DEBG) printf("    notify=%d\n", notify);
998
999         l = 1;
1000         p = msg_put(msg, l+2);
1001         if (nt)
1002                 *ntmode = p+1;
1003         else
1004                 qi->QI_ELEMENT(notify) = p - (unsigned char *)qi - sizeof(Q931_info_t);
1005         p[0] = IE_NOTIFY;
1006         p[1] = l;
1007         p[2] = 0x80 + notify;
1008 }
1009
1010 void dec_ie_notify(unsigned char *p, Q931_info_t *qi, int *notify, int nt, struct misdn_bchannel *bc)
1011 {
1012         *notify = -1;
1013
1014         if (!nt)
1015         {
1016                 p = NULL;
1017                 if (qi->QI_ELEMENT(notify))
1018                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(notify) + 1;
1019         }
1020         if (!p)
1021                 return;
1022         if (p[0] < 1)
1023         {
1024                 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
1025                 return;
1026         }
1027
1028         *notify = p[1] & 0x7f;
1029
1030         if (MISDN_IE_DEBG) printf("    notify=%d\n", *notify);
1031 }
1032
1033
1034 /* IE_PROGRESS */
1035 void enc_ie_progress(unsigned char **ntmode, msg_t *msg, int coding, int location, int progress, int nt, struct misdn_bchannel *bc)
1036 {
1037         unsigned char *p;
1038         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1039         int l;
1040
1041         if (coding<0 || coding>0x03)
1042         {
1043                 printf("%s: ERROR: coding(%d) is out of range.\n", __FUNCTION__, coding);
1044                 return;
1045         }
1046         if (location<0 || location>0x0f)
1047         {
1048                 printf("%s: ERROR: location(%d) is out of range.\n", __FUNCTION__, location);
1049                 return;
1050         }
1051         if (progress<0 || progress>0x7f)
1052         {
1053                 printf("%s: ERROR: progress(%d) is out of range.\n", __FUNCTION__, progress);
1054                 return;
1055         }
1056
1057         if (MISDN_IE_DEBG) printf("    coding=%d location=%d progress=%d\n", coding, location, progress);
1058
1059         l = 2;
1060         p = msg_put(msg, l+2);
1061         if (nt)
1062                 *ntmode = p+1;
1063         else
1064                 qi->QI_ELEMENT(progress) = p - (unsigned char *)qi - sizeof(Q931_info_t);
1065         p[0] = IE_PROGRESS;
1066         p[1] = l;
1067         p[2] = 0x80 + (coding<<5) + location;
1068         p[3] = 0x80 + progress;
1069 }
1070
1071 void dec_ie_progress(unsigned char *p, Q931_info_t *qi, int *coding, int *location, int *progress, int nt, struct misdn_bchannel *bc)
1072 {
1073         *coding = -1;
1074         *location = -1;
1075         //*progress = -1;
1076         *progress = 0;
1077         
1078         if (!nt)
1079         {
1080                 p = NULL;
1081                 if (qi->QI_ELEMENT(progress))
1082                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(progress) + 1;
1083         }
1084         if (!p)
1085                 return;
1086         if (p[0] < 1)
1087         {
1088                 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
1089                 return;
1090         }
1091
1092         *coding = (p[1]&0x60) >> 5;
1093         *location = p[1] & 0x0f;
1094         *progress = p[2] & 0x7f;
1095
1096         //if (MISDN_IE_DEBG) printf("    coding=%d location=%d progress=%d\n", *coding, *location, *progress);
1097         if (1) printf("    coding=%d location=%d progress=%d\n", *coding, *location, *progress);
1098 }
1099
1100
1101 /* IE_REDIR_NR (redirecting = during MT_SETUP) */
1102 void enc_ie_redir_nr(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, int reason, unsigned char *number, int nt, struct misdn_bchannel *bc)
1103 {
1104         unsigned char *p;
1105         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1106         int l;
1107
1108         if (type<0 || type>7)
1109         {
1110                 printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
1111                 return;
1112         }
1113         if (plan<0 || plan>15)
1114         {
1115                 printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
1116                 return;
1117         }
1118         if (present > 3)
1119         {
1120                 printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
1121                 return;
1122         }
1123         if (present >= 0) if (screen<0 || screen>3)
1124         {
1125                 printf("%s: ERROR: screen(%d) is out of range.\n", __FUNCTION__, screen);
1126                 return;
1127         }
1128         if (reason > 0x0f)
1129         {
1130                 printf("%s: ERROR: reason(%d) is out of range.\n", __FUNCTION__, reason);
1131                 return;
1132         }
1133
1134         if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d screen=%d readon=%d number='%s'\n", type, plan, present, screen, reason, number);
1135
1136         l = 1;
1137         if (number)
1138                 l += strlen((char *)number);
1139         if (present >= 0)
1140         {
1141                 l += 1;
1142                 if (reason >= 0)
1143                         l += 1;
1144         }
1145         p = msg_put(msg, l+2);
1146         if (nt)
1147                 *ntmode = p+1;
1148         else
1149                 qi->QI_ELEMENT(redirect_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
1150         p[0] = IE_REDIR_NR;
1151         p[1] = l;
1152         if (present >= 0)
1153         {
1154                 if (reason >= 0)
1155                 {
1156                         p[2] = 0x00 + (type<<4) + plan;
1157                         p[3] = 0x00 + (present<<5) + screen;
1158                         p[4] = 0x80 + reason;
1159                         if (number)
1160                                 strncpy((char *)p+5, (char *)number, strlen((char *)number));
1161                 } else
1162                 {
1163                         p[2] = 0x00 + (type<<4) + plan;
1164                         p[3] = 0x80 + (present<<5) + screen;
1165                         if (number)
1166                                 strncpy((char *)p+4, (char *)number, strlen((char *)number));
1167                 }
1168         } else
1169         {
1170                 p[2] = 0x80 + (type<<4) + plan;
1171                 if (number) if (number[0])
1172                         strncpy((char *)p+3, (char *)number, strlen((char *)number));
1173         }
1174 }
1175
1176 void dec_ie_redir_nr(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, int *reason, unsigned char *number, int number_len, int nt, struct misdn_bchannel *bc)
1177 {
1178         *type = -1;
1179         *plan = -1;
1180         *present = -1;
1181         *screen = -1;
1182         *reason = -1;
1183         *number = '\0';
1184
1185         if (!nt)
1186         {
1187                 p = NULL;
1188                 if (qi->QI_ELEMENT(redirect_nr))
1189                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(redirect_nr) + 1;
1190         }
1191         if (!p)
1192                 return;
1193         if (p[0] < 1)
1194         {
1195                 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
1196                 return;
1197         }
1198
1199         *type = (p[1]&0x70) >> 4;
1200         *plan = p[1] & 0xf;
1201         if (!(p[1] & 0x80))
1202         {
1203                 *present = (p[2]&0x60) >> 5;
1204                 *screen = p[2] & 0x3;
1205                 if (!(p[2] & 0x80))
1206                 {
1207                         *reason = p[3] & 0x0f;
1208                         strnncpy(number, p+4, p[0]-3, number_len);
1209                 } else
1210                 {
1211                         strnncpy(number, p+3, p[0]-2, number_len);
1212                 }
1213         } else
1214         {
1215                 strnncpy(number, p+2, p[0]-1, number_len);
1216         }
1217
1218         if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d screen=%d reason=%d number='%s'\n", *type, *plan, *present, *screen, *reason, number);
1219 }
1220
1221
1222 /* IE_REDIR_DN (redirection = during MT_NOTIFY) */
1223 void enc_ie_redir_dn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, unsigned char *number, int nt, struct misdn_bchannel *bc)
1224 {
1225         unsigned char *p;
1226 /*      Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN); */
1227         int l;
1228
1229         if (type<0 || type>7)
1230         {
1231                 printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
1232                 return;
1233         }
1234         if (plan<0 || plan>15)
1235         {
1236                 printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
1237                 return;
1238         }
1239         if (present > 3)
1240         {
1241                 printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
1242                 return;
1243         }
1244
1245         if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d number='%s'\n", type, plan, present, number);
1246
1247         l = 1;
1248         if (number)
1249                 l += strlen((char *)number);
1250         if (present >= 0)
1251                 l += 1;
1252         p = msg_put(msg, l+2);
1253         if (nt)
1254                 *ntmode = p+1;
1255         else
1256 /* #warning REINSERT redir_dn, when included in te-mode */
1257                 /*qi->QI_ELEMENT(redir_dn) = p - (unsigned char *)qi - sizeof(Q931_info_t)*/;
1258         p[0] = IE_REDIR_DN;
1259         p[1] = l;
1260         if (present >= 0)
1261         {
1262                 p[2] = 0x00 + (type<<4) + plan;
1263                 p[3] = 0x80 + (present<<5);
1264                 if (number)
1265                         strncpy((char *)p+4, (char *)number, strlen((char *)number));
1266         } else
1267         {
1268                 p[2] = 0x80 + (type<<4) + plan;
1269                 if (number)
1270                         strncpy((char *)p+3, (char *)number, strlen((char *)number));
1271         }
1272 }
1273
1274 void dec_ie_redir_dn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, unsigned char *number, int number_len, int nt, struct misdn_bchannel *bc)
1275 {
1276         *type = -1;
1277         *plan = -1;
1278         *present = -1;
1279         *number = '\0';
1280
1281         if (!nt)
1282         {
1283                 p = NULL;
1284 /* #warning REINSERT redir_dn, when included in te-mode */
1285 /*              if (qi->QI_ELEMENT(redir_dn)) */
1286 /*                      p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(redir_dn) + 1; */
1287         }
1288         if (!p)
1289                 return;
1290         if (p[0] < 1)
1291         {
1292                 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
1293                 return;
1294         }
1295
1296         *type = (p[1]&0x70) >> 4;
1297         *plan = p[1] & 0xf;
1298         if (!(p[1] & 0x80))
1299         {
1300                 *present = (p[2]&0x60) >> 5;
1301                 strnncpy(number, p+3, p[0]-2, number_len);
1302         } else
1303         {
1304                 strnncpy(number, p+2, p[0]-1, number_len);
1305         }
1306
1307         if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d number='%s'\n", *type, *plan, *present, number);
1308 }
1309
1310
1311
1312 /* IE_USERUSER */
1313 void enc_ie_useruser(unsigned char **ntmode, msg_t *msg, int protocol, unsigned char *user, int user_len, int nt, struct misdn_bchannel *bc)
1314 {
1315         unsigned char *p;
1316         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1317         int l;
1318
1319         char debug[768];
1320         int i;
1321
1322         if (protocol<0 || protocol>127)
1323         {
1324                 printf("%s: ERROR: protocol(%d) is out of range.\n", __FUNCTION__, protocol);
1325                 return;
1326         }
1327         if (!user || user_len<=0)
1328         {
1329                 return;
1330         }
1331
1332         i = 0;
1333         while(i < user_len)
1334         {
1335                 if (MISDN_IE_DEBG) printf(debug+(i*3), " %02x", user[i]);
1336                 i++;
1337         }
1338                 
1339         if (MISDN_IE_DEBG) printf("    protocol=%d user-user%s\n", protocol, debug);
1340
1341         l = user_len;
1342         p = msg_put(msg, l+3);
1343         if (nt)
1344                 *ntmode = p+1;
1345         else
1346                 qi->QI_ELEMENT(useruser) = p - (unsigned char *)qi - sizeof(Q931_info_t);
1347         p[0] = IE_USER_USER;
1348         p[1] = l;
1349         p[2] = 0x80 + protocol;
1350         memcpy(p+3, user, user_len);
1351 }
1352
1353 void dec_ie_useruser(unsigned char *p, Q931_info_t *qi, int *protocol, unsigned char *user, int *user_len, int nt, struct misdn_bchannel *bc)
1354 {
1355         char debug[768];
1356         int i;
1357
1358         *user_len = 0;
1359         *protocol = -1;
1360
1361         if (!nt)
1362         {
1363                 p = NULL;
1364                 if (qi->QI_ELEMENT(useruser))
1365                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(useruser) + 1;
1366         }
1367         if (!p)
1368                 return;
1369
1370         *user_len = p[0]-1;
1371         if (p[0] < 1)
1372                 return;
1373         *protocol = p[1];
1374         memcpy(user, p+2, (*user_len<=128)?*(user_len):128); /* clip to 128 maximum */
1375
1376         i = 0;
1377         while(i < *user_len)
1378         {
1379                 if (MISDN_IE_DEBG) printf(debug+(i*3), " %02x", user[i]);
1380                 i++;
1381         }
1382         debug[i*3] = '\0';
1383                 
1384         if (MISDN_IE_DEBG) printf("    protocol=%d user-user%s\n", *protocol, debug);
1385 }
1386
1387
1388
1389