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