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