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