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