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