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