Merged revisions 58825-58826 via svnmerge from
[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
856         struct tm *tm;
857
858         tm = localtime(&ti);
859         if (!tm)
860         {
861                 printf("%s: ERROR: gettimeofday() returned NULL.\n", __FUNCTION__);
862                 return;
863         }
864
865         if (MISDN_IE_DEBG) printf("    year=%d month=%d day=%d hour=%d minute=%d\n", tm->tm_year%100, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min);
866
867         l = 5;
868         p = msg_put(msg, l+2);
869         if (nt)
870                 *ntmode = p+1;
871         else
872                 qi->QI_ELEMENT(date) = p - (unsigned char *)qi - sizeof(Q931_info_t);
873         p[0] = IE_DATE;
874         p[1] = l;
875         p[2] = tm->tm_year % 100;
876         p[3] = tm->tm_mon + 1;
877         p[4] = tm->tm_mday;
878         p[5] = tm->tm_hour;
879         p[6] = tm->tm_min;
880 }
881
882
883 /* IE_DISPLAY */
884 static void enc_ie_display(unsigned char **ntmode, msg_t *msg, char *display, int nt, struct misdn_bchannel *bc)
885 {
886         unsigned char *p;
887         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
888         int l;
889
890         if (!display[0])
891         {
892                 printf("%s: ERROR: display text not given.\n", __FUNCTION__);
893                 return;
894         }
895
896         if (strlen((char *)display) > 80)
897         {
898                 printf("%s: WARNING: display text too long (max 80 chars), cutting.\n", __FUNCTION__);
899                 display[80] = '\0';
900         }
901
902         /* if (MISDN_IE_DEBG) printf("    display='%s' (len=%d)\n", display, strlen((char *)display)); */
903
904         l = strlen((char *)display);
905         p = msg_put(msg, l+2);
906         if (nt)
907                 *ntmode = p+1;
908         else
909                 qi->QI_ELEMENT(display) = p - (unsigned char *)qi - sizeof(Q931_info_t);
910         p[0] = IE_DISPLAY;
911         p[1] = l;
912         strncpy((char *)p+2, (char *)display, strlen((char *)display));
913 }
914
915 #if 0
916 static void dec_ie_display(unsigned char *p, Q931_info_t *qi, char *display, int display_len, int nt, struct misdn_bchannel *bc)
917 {
918         *display = '\0';
919
920         if (!nt)
921         {
922                 p = NULL;
923                 if (qi->QI_ELEMENT(display))
924                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(display) + 1;
925         }
926         if (!p)
927                 return;
928         if (p[0] < 1)
929         {
930                 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
931                 return;
932         }
933
934         strnncpy(display, (char *)p+1, p[0], display_len);
935
936         if (MISDN_IE_DEBG) printf("    display='%s'\n", display);
937 }
938 #endif
939
940 /* IE_KEYPAD */
941 #if 0
942 static void enc_ie_keypad(unsigned char **ntmode, msg_t *msg, char *keypad, int nt, struct misdn_bchannel *bc)
943 {
944         unsigned char *p;
945         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
946         int l;
947
948         if (!keypad[0])
949         {
950                 printf("%s: ERROR: keypad info not given.\n", __FUNCTION__);
951                 return;
952         }
953
954         if (MISDN_IE_DEBG) printf("    keypad='%s'\n", keypad);
955
956         l = strlen((char *)keypad);
957         p = msg_put(msg, l+2);
958         if (nt)
959                 *ntmode = p+1;
960         else
961                 qi->QI_ELEMENT(keypad) = p - (unsigned char *)qi - sizeof(Q931_info_t);
962         p[0] = IE_KEYPAD;
963         p[1] = l;
964         strncpy((char *)p+2, (char *)keypad, strlen((char *)keypad));
965 }
966 #endif
967
968 static void dec_ie_keypad(unsigned char *p, Q931_info_t *qi, char *keypad, int keypad_len, int nt, struct misdn_bchannel *bc)
969 {
970         *keypad = '\0';
971
972         if (!nt)
973         {
974                 p = NULL;
975                 if (qi->QI_ELEMENT(keypad))
976                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(keypad) + 1;
977         }
978         if (!p)
979                 return;
980         if (p[0] < 1)
981         {
982                 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
983                 return;
984         }
985
986         strnncpy(keypad, (char *)p+1, p[0], keypad_len);
987
988         if (MISDN_IE_DEBG) printf("    keypad='%s'\n", keypad);
989 }
990
991
992 /* IE_NOTIFY */
993 #if 0
994 static void enc_ie_notify(unsigned char **ntmode, msg_t *msg, int notify, int nt, struct misdn_bchannel *bc)
995 {
996         unsigned char *p;
997         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
998         int l;
999
1000         if (notify<0 || notify>0x7f)
1001         {
1002                 printf("%s: ERROR: notify(%d) is out of range.\n", __FUNCTION__, notify);
1003                 return;
1004         }
1005
1006         if (MISDN_IE_DEBG) printf("    notify=%d\n", notify);
1007
1008         l = 1;
1009         p = msg_put(msg, l+2);
1010         if (nt)
1011                 *ntmode = p+1;
1012         else
1013                 qi->QI_ELEMENT(notify) = p - (unsigned char *)qi - sizeof(Q931_info_t);
1014         p[0] = IE_NOTIFY;
1015         p[1] = l;
1016         p[2] = 0x80 + notify;
1017 }
1018 #endif
1019
1020 #if 0
1021 static void dec_ie_notify(unsigned char *p, Q931_info_t *qi, int *notify, int nt, struct misdn_bchannel *bc)
1022 {
1023         *notify = -1;
1024
1025         if (!nt)
1026         {
1027                 p = NULL;
1028                 if (qi->QI_ELEMENT(notify))
1029                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(notify) + 1;
1030         }
1031         if (!p)
1032                 return;
1033         if (p[0] < 1)
1034         {
1035                 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
1036                 return;
1037         }
1038
1039         *notify = p[1] & 0x7f;
1040
1041         if (MISDN_IE_DEBG) printf("    notify=%d\n", *notify);
1042 }
1043 #endif
1044
1045
1046 /* IE_PROGRESS */
1047 static void enc_ie_progress(unsigned char **ntmode, msg_t *msg, int coding, int location, int progress, int nt, struct misdn_bchannel *bc)
1048 {
1049         unsigned char *p;
1050         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1051         int l;
1052
1053         if (coding<0 || coding>0x03)
1054         {
1055                 printf("%s: ERROR: coding(%d) is out of range.\n", __FUNCTION__, coding);
1056                 return;
1057         }
1058         if (location<0 || location>0x0f)
1059         {
1060                 printf("%s: ERROR: location(%d) is out of range.\n", __FUNCTION__, location);
1061                 return;
1062         }
1063         if (progress<0 || progress>0x7f)
1064         {
1065                 printf("%s: ERROR: progress(%d) is out of range.\n", __FUNCTION__, progress);
1066                 return;
1067         }
1068
1069         if (MISDN_IE_DEBG) printf("    coding=%d location=%d progress=%d\n", coding, location, progress);
1070
1071         l = 2;
1072         p = msg_put(msg, l+2);
1073         if (nt)
1074                 *ntmode = p+1;
1075         else
1076                 qi->QI_ELEMENT(progress) = p - (unsigned char *)qi - sizeof(Q931_info_t);
1077         p[0] = IE_PROGRESS;
1078         p[1] = l;
1079         p[2] = 0x80 + (coding<<5) + location;
1080         p[3] = 0x80 + progress;
1081 }
1082
1083 static void dec_ie_progress(unsigned char *p, Q931_info_t *qi, int *coding, int *location, int *progress, int nt, struct misdn_bchannel *bc)
1084 {
1085         *coding = -1;
1086         *location = -1;
1087         //*progress = -1;
1088         *progress = 0;
1089         
1090         if (!nt)
1091         {
1092                 p = NULL;
1093                 if (qi->QI_ELEMENT(progress))
1094                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(progress) + 1;
1095         }
1096         if (!p)
1097                 return;
1098         if (p[0] < 1)
1099         {
1100                 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
1101                 return;
1102         }
1103
1104         *coding = (p[1]&0x60) >> 5;
1105         *location = p[1] & 0x0f;
1106         *progress = p[2] & 0x7f;
1107
1108         if (MISDN_IE_DEBG) printf("    coding=%d location=%d progress=%d\n", *coding, *location, *progress);
1109 }
1110
1111
1112 /* IE_REDIR_NR (redirecting = during MT_SETUP) */
1113 static void enc_ie_redir_nr(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, int reason, char *number, int nt, struct misdn_bchannel *bc)
1114 {
1115         unsigned char *p;
1116         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1117         int l;
1118
1119         if (type<0 || type>7)
1120         {
1121                 printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
1122                 return;
1123         }
1124         if (plan<0 || plan>15)
1125         {
1126                 printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
1127                 return;
1128         }
1129         if (present > 3)
1130         {
1131                 printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
1132                 return;
1133         }
1134         if (present >= 0) if (screen<0 || screen>3)
1135         {
1136                 printf("%s: ERROR: screen(%d) is out of range.\n", __FUNCTION__, screen);
1137                 return;
1138         }
1139         if (reason > 0x0f)
1140         {
1141                 printf("%s: ERROR: reason(%d) is out of range.\n", __FUNCTION__, reason);
1142                 return;
1143         }
1144
1145         if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d screen=%d readon=%d number='%s'\n", type, plan, present, screen, reason, number);
1146
1147         l = 1;
1148         if (number)
1149                 l += strlen((char *)number);
1150         if (present >= 0)
1151         {
1152                 l += 1;
1153                 if (reason >= 0)
1154                         l += 1;
1155         }
1156         p = msg_put(msg, l+2);
1157         if (nt)
1158                 *ntmode = p+1;
1159         else
1160                 qi->QI_ELEMENT(redirect_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
1161         p[0] = IE_REDIR_NR;
1162         p[1] = l;
1163         if (present >= 0)
1164         {
1165                 if (reason >= 0)
1166                 {
1167                         p[2] = 0x00 + (type<<4) + plan;
1168                         p[3] = 0x00 + (present<<5) + screen;
1169                         p[4] = 0x80 + reason;
1170                         if (number)
1171                                 strncpy((char *)p+5, (char *)number, strlen((char *)number));
1172                 } else
1173                 {
1174                         p[2] = 0x00 + (type<<4) + plan;
1175                         p[3] = 0x80 + (present<<5) + screen;
1176                         if (number)
1177                                 strncpy((char *)p+4, (char *)number, strlen((char *)number));
1178                 }
1179         } else
1180         {
1181                 p[2] = 0x80 + (type<<4) + plan;
1182                 if (number) if (number[0])
1183                         strncpy((char *)p+3, (char *)number, strlen((char *)number));
1184         }
1185 }
1186
1187 static void dec_ie_redir_nr(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, int *reason, char *number, int number_len, int nt, struct misdn_bchannel *bc)
1188 {
1189         *type = -1;
1190         *plan = -1;
1191         *present = -1;
1192         *screen = -1;
1193         *reason = -1;
1194         *number = '\0';
1195
1196         if (!nt)
1197         {
1198                 p = NULL;
1199                 if (qi->QI_ELEMENT(redirect_nr))
1200                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(redirect_nr) + 1;
1201         }
1202         if (!p)
1203                 return;
1204         if (p[0] < 1)
1205         {
1206                 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
1207                 return;
1208         }
1209
1210         *type = (p[1]&0x70) >> 4;
1211         *plan = p[1] & 0xf;
1212         if (!(p[1] & 0x80))
1213         {
1214                 *present = (p[2]&0x60) >> 5;
1215                 *screen = p[2] & 0x3;
1216                 if (!(p[2] & 0x80))
1217                 {
1218                         *reason = p[3] & 0x0f;
1219                         strnncpy(number, (char *)p+4, p[0]-3, number_len);
1220                 } else
1221                 {
1222                         strnncpy(number, (char *)p+3, p[0]-2, number_len);
1223                 }
1224         } else
1225         {
1226                 strnncpy(number, (char *)p+2, p[0]-1, number_len);
1227         }
1228
1229         if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d screen=%d reason=%d number='%s'\n", *type, *plan, *present, *screen, *reason, number);
1230 }
1231
1232
1233 /* IE_REDIR_DN (redirection = during MT_NOTIFY) */
1234 #if 0
1235 static void enc_ie_redir_dn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, char *number, int nt, struct misdn_bchannel *bc)
1236 {
1237         unsigned char *p;
1238 /*      Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN); */
1239         int l;
1240
1241         if (type<0 || type>7)
1242         {
1243                 printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
1244                 return;
1245         }
1246         if (plan<0 || plan>15)
1247         {
1248                 printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
1249                 return;
1250         }
1251         if (present > 3)
1252         {
1253                 printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
1254                 return;
1255         }
1256
1257         if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d number='%s'\n", type, plan, present, number);
1258
1259         l = 1;
1260         if (number)
1261                 l += strlen((char *)number);
1262         if (present >= 0)
1263                 l += 1;
1264         p = msg_put(msg, l+2);
1265         if (nt)
1266                 *ntmode = p+1;
1267         else
1268 /* #warning REINSERT redir_dn, when included in te-mode */
1269                 /*qi->QI_ELEMENT(redir_dn) = p - (unsigned char *)qi - sizeof(Q931_info_t)*/;
1270         p[0] = IE_REDIR_DN;
1271         p[1] = l;
1272         if (present >= 0)
1273         {
1274                 p[2] = 0x00 + (type<<4) + plan;
1275                 p[3] = 0x80 + (present<<5);
1276                 if (number)
1277                         strncpy((char *)p+4, (char *)number, strlen((char *)number));
1278         } else
1279         {
1280                 p[2] = 0x80 + (type<<4) + plan;
1281                 if (number)
1282                         strncpy((char *)p+3, (char *)number, strlen((char *)number));
1283         }
1284 }
1285 #endif
1286
1287 #if 0
1288 static void dec_ie_redir_dn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, char *number, int number_len, int nt, struct misdn_bchannel *bc)
1289 {
1290         *type = -1;
1291         *plan = -1;
1292         *present = -1;
1293         *number = '\0';
1294
1295         if (!nt)
1296         {
1297                 p = NULL;
1298 /* #warning REINSERT redir_dn, when included in te-mode */
1299 /*              if (qi->QI_ELEMENT(redir_dn)) */
1300 /*                      p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(redir_dn) + 1; */
1301         }
1302         if (!p)
1303                 return;
1304         if (p[0] < 1)
1305         {
1306                 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
1307                 return;
1308         }
1309
1310         *type = (p[1]&0x70) >> 4;
1311         *plan = p[1] & 0xf;
1312         if (!(p[1] & 0x80))
1313         {
1314                 *present = (p[2]&0x60) >> 5;
1315                 strnncpy(number, (char *)p+3, p[0]-2, number_len);
1316         } else
1317         {
1318                 strnncpy(number, (char *)p+2, p[0]-1, number_len);
1319         }
1320
1321         if (MISDN_IE_DEBG) printf("    type=%d plan=%d present=%d number='%s'\n", *type, *plan, *present, number);
1322 }
1323 #endif
1324
1325
1326 /* IE_USERUSER */
1327 #if 1
1328 static void enc_ie_useruser(unsigned char **ntmode, msg_t *msg, int protocol, char *user, int user_len, int nt, struct misdn_bchannel *bc)
1329 {
1330         unsigned char *p;
1331         Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1332         int l;
1333
1334         char debug[768];
1335         int i;
1336
1337         if (protocol<0 || protocol>127)
1338         {
1339                 printf("%s: ERROR: protocol(%d) is out of range.\n", __FUNCTION__, protocol);
1340                 return;
1341         }
1342         if (!user || user_len<=0)
1343         {
1344                 return;
1345         }
1346
1347         i = 0;
1348         while(i < user_len)
1349         {
1350                 if (MISDN_IE_DEBG) printf(debug+(i*3), " %02x", user[i]);
1351                 i++;
1352         }
1353                 
1354         if (MISDN_IE_DEBG) printf("    protocol=%d user-user%s\n", protocol, debug);
1355
1356         l = user_len;
1357         p = msg_put(msg, l+3);
1358         if (nt)
1359                 *ntmode = p+1;
1360         else
1361                 qi->QI_ELEMENT(useruser) = p - (unsigned char *)qi - sizeof(Q931_info_t);
1362         p[0] = IE_USER_USER;
1363         p[1] = l;
1364         p[2] = 0x80 + protocol;
1365         memcpy(p+3, user, user_len);
1366 }
1367 #endif
1368
1369 #if 1
1370 static void dec_ie_useruser(unsigned char *p, Q931_info_t *qi, int *protocol, char *user, int *user_len, int nt, struct misdn_bchannel *bc)
1371 {
1372         char debug[768];
1373         int i;
1374
1375         *user_len = 0;
1376         *protocol = -1;
1377
1378         if (!nt)
1379         {
1380                 p = NULL;
1381                 if (qi->QI_ELEMENT(useruser))
1382                         p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(useruser) + 1;
1383         }
1384         if (!p)
1385                 return;
1386
1387         *user_len = p[0]-1;
1388         if (p[0] < 1)
1389                 return;
1390         *protocol = p[1];
1391         memcpy(user, p+2, (*user_len<=128)?*(user_len):128); /* clip to 128 maximum */
1392
1393         i = 0;
1394         while(i < *user_len)
1395         {
1396                 if (MISDN_IE_DEBG) printf(debug+(i*3), " %02x", user[i]);
1397                 i++;
1398         }
1399         debug[i*3] = '\0';
1400                 
1401         if (MISDN_IE_DEBG) printf("    protocol=%d user-user%s\n", *protocol, debug);
1402 }
1403 #endif
1404