2 /*****************************************************************************\
6 **---------------------------------------------------------------------------**
7 ** Copyright: Andreas Eversberg **
9 ** information elements encode and decode **
11 \*****************************************************************************/
14 the pointer of enc_ie_* always points to the IE itself
15 if qi is not NULL (TE-mode), offset is set
19 static void strnncpy(unsigned char *dest, unsigned char *src, int len, int dst_len)
23 UNCPY((char *)dest, (char *)src, len);
29 void Pdss1::enc_ie_complete(struct l3_msg *l3m, int complete)
32 if (complete<0 || complete>1)
34 PERROR("complete(%d) is out of range.\n", complete);
40 add_trace("complete", NULL, NULL);
41 l3m->sending_complete++;
45 void Pdss1::dec_ie_complete(struct l3_msg *l3m, int *complete)
48 // special case: p is not a pointer, it's a value
49 unsigned char p = l3m->sending_complete;
54 add_trace("complete", NULL, NULL);
59 void Pdss1::enc_ie_bearer(struct l3_msg *l3m, int coding, int capability, int mode, int rate, int multi, int user)
64 if (coding<0 || coding>3)
66 PERROR("coding(%d) is out of range.\n", coding);
69 if (capability<0 || capability>31)
71 PERROR("capability(%d) is out of range.\n", capability);
76 PERROR("mode(%d) is out of range.\n", mode);
79 if (rate<0 || rate>31)
81 PERROR("rate(%d) is out of range.\n", rate);
86 PERROR("multi(%d) is out of range.\n", multi);
91 PERROR("user L1(%d) is out of range.\n", user);
94 if (rate!=24 && multi>=0)
96 PERROR("multi(%d) is only possible if rate(%d) would be 24.\n", multi, rate);
100 add_trace("bearer", "coding", "%d", coding);
101 add_trace("bearer", "capability", "%d", capability);
102 add_trace("bearer", "mode", "%d", mode);
103 add_trace("bearer", "rate", "%d", rate);
104 add_trace("bearer", "multi", "%d", multi);
105 add_trace("bearer", "user", "%d", user);
107 l = 2 + (multi>=0) + (user>=0);
110 p[2] = 0x80 + (coding<<5) + capability;
111 p[3] = 0x80 + (mode<<5) + rate;
115 p[4+(multi>=0)] = 0xa0 + user;
116 add_layer3_ie(l3m, p[0], p[1], p+2);
119 void Pdss1::dec_ie_bearer(struct l3_msg *l3m, int *coding, int *capability, int *mode, int *rate, int *multi, int *user)
128 unsigned char *p = l3m->bearer_capability;
133 add_trace("bearer", "error", "IE too short (len=%d)", p[0]);
137 *coding = (p[1]&0x60) >> 5;
138 *capability = p[1] & 0x1f;
141 *mode = (p[2]&0x60) >> 5;
144 if (p[0]>=3 && *rate==0x18)
146 *multi = p[3] & 0x7f;
155 add_trace("bearer", "coding", "%d", *coding);
156 add_trace("bearer", "capability", "%d", *capability);
157 add_trace("bearer", "mode", "%d", *mode);
158 add_trace("bearer", "rate", "%d", *rate);
159 add_trace("bearer", "multi", "%d", *multi);
160 add_trace("bearer", "user", "%d", *user);
165 void Pdss1::enc_ie_hlc(struct l3_msg *l3m, int coding, int interpretation, int presentation, int hlc, int exthlc)
167 unsigned char p[256];
170 if (coding<0 || coding>3)
172 PERROR("coding(%d) is out of range.\n", coding);
175 if (interpretation<0 || interpretation>7)
177 PERROR("interpretation(%d) is out of range.\n", interpretation);
180 if (presentation<0 || presentation>3)
182 PERROR("presentation(%d) is out of range.\n", presentation);
185 if (hlc<0 || hlc>127)
187 PERROR("hlc(%d) is out of range.\n", hlc);
192 PERROR("hlc(%d) is out of range.\n", exthlc);
196 add_trace("hlc", "coding", "%d", coding);
197 add_trace("hlc", "interpretation", "%d", interpretation);
198 add_trace("hlc", "presentation", "%d", presentation);
199 add_trace("hlc", "hlc", "%d", hlc);
201 add_trace("hlc", "exthlc", "%d", exthlc);
206 p[2] = 0x80 + (coding<<5) + (interpretation<<2) + presentation;
210 p[4] = 0x80 + exthlc;
213 add_layer3_ie(l3m, p[0], p[1], p+2);
216 void Pdss1::dec_ie_hlc(struct l3_msg *l3m, int *coding, int *interpretation, int *presentation, int *hlc, int *exthlc)
219 *interpretation = -1;
224 unsigned char *p = l3m->hlc;
229 add_trace("hlc", "error", "IE too short (len=%d)", p[0]);
233 *coding = (p[1]&0x60) >> 5;
234 *interpretation = (p[1]&0x1c) >> 2;
235 *presentation = p[1] & 0x03;
239 *exthlc = p[3] & 0x7f;
242 add_trace("hlc", "coding", "%d", *coding);
243 add_trace("hlc", "interpretation", "%d", *interpretation);
244 add_trace("hlc", "presentation", "%d", *presentation);
245 add_trace("hlc", "hlc", "%d", *hlc);
247 add_trace("hlc", "exthlc", "%d", *exthlc);
252 void Pdss1::enc_ie_call_id(struct l3_msg *l3m, unsigned char *callid, int callid_len)
254 unsigned char p[256];
260 if (!callid || callid_len<=0)
266 PERROR("callid_len(%d) is out of range.\n", callid_len);
271 while(i < callid_len)
273 UPRINT(buffer+(i*3), " %02x", callid[i]);
277 add_trace("callid", NULL, "%s", buffer[0]?buffer+1:"<none>");
282 memcpy(p+2, callid, callid_len);
283 add_layer3_ie(l3m, p[0], p[1], p+2);
286 void Pdss1::dec_ie_call_id(struct l3_msg *l3m, unsigned char *callid, int *callid_len)
293 unsigned char *p = l3m->call_id;
298 add_trace("callid", "error", "IE too long (len=%d)", p[0]);
303 memcpy(callid, p+1, *callid_len);
306 while(i < *callid_len)
308 UPRINT(buffer+(i*3), " %02x", callid[i]);
312 add_trace("callid", NULL, "%s", buffer[0]?buffer+1:"<none>");
317 void Pdss1::enc_ie_called_pn(struct l3_msg *l3m, int type, int plan, unsigned char *number)
319 unsigned char p[256];
322 if (type<0 || type>7)
324 PERROR("type(%d) is out of range.\n", type);
327 if (plan<0 || plan>15)
329 PERROR("plan(%d) is out of range.\n", plan);
334 PERROR("number is not given.\n");
338 add_trace("called_pn", "type", "%d", type);
339 add_trace("called_pn", "plan", "%d", plan);
340 add_trace("called_pn", "number", "%s", number);
342 l = 1+strlen((char *)number);
345 p[2] = 0x80 + (type<<4) + plan;
346 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
347 add_layer3_ie(l3m, p[0], p[1], p+2);
350 void Pdss1::dec_ie_called_pn(struct l3_msg *l3m, int *type, int *plan, unsigned char *number, int number_len)
356 unsigned char *p = l3m->called_nr;
361 add_trace("called_pn", "error", "IE too short (len=%d)", p[0]);
365 *type = (p[1]&0x70) >> 4;
367 strnncpy(number, p+2, p[0]-1, number_len);
369 add_trace("called_pn", "type", "%d", *type);
370 add_trace("called_pn", "plan", "%d", *plan);
371 add_trace("called_pn", "number", "%s", number);
376 void Pdss1::enc_ie_calling_pn(struct l3_msg *l3m, int type, int plan, int present, int screen, unsigned char *number, int type2, int plan2, int present2, int screen2, unsigned char *number2)
378 unsigned char p[256];
381 if (type<0 || type>7)
383 PERROR("type(%d) is out of range.\n", type);
386 if (plan<0 || plan>15)
388 PERROR("plan(%d) is out of range.\n", plan);
393 PERROR("present(%d) is out of range.\n", present);
396 if (present >= 0) if (screen<0 || screen>3)
398 PERROR("screen(%d) is out of range.\n", screen);
402 add_trace("calling_pn", "type", "%d", type);
403 add_trace("calling_pn", "plan", "%d", plan);
404 add_trace("calling_pn", "present", "%d", present);
405 add_trace("calling_pn", "screen", "%d", screen);
406 add_trace("calling_pn", "number", "%s", number);
409 if (number) if (number[0])
410 l += strlen((char *)number);
413 p[0] = IE_CALLING_PN;
417 p[2] = 0x00 + (type<<4) + plan;
418 p[3] = 0x80 + (present<<5) + screen;
419 if (number) if (number[0])
420 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
423 p[2] = 0x80 + (type<<4) + plan;
424 if (number) if (number[0])
425 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
427 add_layer3_ie(l3m, p[0], p[1], p+2);
429 /* second calling party number */
435 PERROR("type2(%d) is out of range.\n", type2);
438 if (plan2<0 || plan2>15)
440 PERROR("plan2(%d) is out of range.\n", plan2);
445 PERROR("present2(%d) is out of range.\n", present2);
448 if (present2 >= 0) if (screen2<0 || screen2>3)
450 PERROR("screen2(%d) is out of range.\n", screen2);
454 add_trace("call_pn 2", "type", "%d", type2);
455 add_trace("call_pn 2", "plan", "%d", plan2);
456 add_trace("call_pn 2", "present", "%d", present2);
457 add_trace("call_pn 2", "screen", "%d", screen2);
458 add_trace("call_pn 2", "number", "%s", number2);
461 if (number2) if (number2[0])
462 l += strlen((char *)number2);
465 p[0] = IE_CALLING_PN;
469 p[2] = 0x00 + (type2<<4) + plan2;
470 p[3] = 0x80 + (present2<<5) + screen2;
471 if (number2) if (number2[0])
472 UNCPY((char *)p+4, (char *)number2, strlen((char *)number2));
475 p[2] = 0x80 + (type2<<4) + plan2;
476 if (number2) if (number2[0])
477 UNCPY((char *)p+3, (char *)number2, strlen((char *)number2));
479 add_layer3_ie(l3m, p[0], p[1], p+2);
482 void Pdss1::dec_ie_calling_pn(struct l3_msg *l3m, int *type, int *plan, int *present, int *screen, unsigned char *number, int number_len, int *type2, int *plan2, int *present2, int *screen2, unsigned char *number2, int number_len2)
494 unsigned int numextra = sizeof(l3m->extra) / sizeof(struct m_extie);
497 unsigned char *p = l3m->calling_nr;
502 add_trace("calling_pn", "error", "IE too short (len=%d)", p[0]);
506 *type = (p[1]&0x70) >> 4;
512 add_trace("calling_pn", "error", "IE too short (len=%d)", p[0]);
515 *present = (p[2]&0x60) >> 5;
516 *screen = p[2] & 0x3;
517 strnncpy(number, p+3, p[0]-2, number_len);
520 strnncpy(number, p+2, p[0]-1, number_len);
523 add_trace("calling_pn", "type", "%d", *type);
524 add_trace("calling_pn", "plan", "%d", *plan);
525 add_trace("calling_pn", "present", "%d", *present);
526 add_trace("calling_pn", "screen", "%d", *screen);
527 add_trace("calling_pn", "number", "%s", number);
529 /* second calling party number */
534 if (!l3m->extra[i].val)
536 if (l3m->extra[i].ie == IE_CALLING_PN)
538 p = l3m->extra[i].val;
547 add_trace("calling_pn2", "error", "IE too short (len=%d)", p[0]);
551 *type2 = (p[1]&0x70) >> 4;
557 add_trace("calling_pn2", "error", "IE too short (len=%d)", p[0]);
560 *present2 = (p[2]&0x60) >> 5;
561 *screen2 = p[2] & 0x3;
562 strnncpy(number2, p+3, p[0]-2, number_len2);
565 strnncpy(number2, p+2, p[0]-1, number_len2);
568 add_trace("call_pn 2", "type", "%d", *type2);
569 add_trace("call_pn 2", "plan", "%d", *plan2);
570 add_trace("call_pn 2", "present", "%d", *present2);
571 add_trace("call_pn 2", "screen", "%d", *screen2);
572 add_trace("call_pn 2", "number", "%s", number2);
576 /* IE_CONNECTED_PN */
577 void Pdss1::enc_ie_connected_pn(struct l3_msg *l3m, int type, int plan, int present, int screen, unsigned char *number)
579 unsigned char p[256];
582 if (type<0 || type>7)
584 PERROR("type(%d) is out of range.\n", type);
587 if (plan<0 || plan>15)
589 PERROR("plan(%d) is out of range.\n", plan);
594 PERROR("present(%d) is out of range.\n", present);
597 if (present >= 0) if (screen<0 || screen>3)
599 PERROR("screen(%d) is out of range.\n", screen);
603 add_trace("connect_pn", "type", "%d", type);
604 add_trace("connect_pn", "plan", "%d", plan);
605 add_trace("connect_pn", "present", "%d", present);
606 add_trace("connect_pn", "screen", "%d", screen);
607 add_trace("connect_pn", "number", "%s", number);
610 if (number) if (number[0])
611 l += strlen((char *)number);
614 p[0] = IE_CONNECT_PN;
618 p[2] = 0x00 + (type<<4) + plan;
619 p[3] = 0x80 + (present<<5) + screen;
620 if (number) if (number[0])
621 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
624 p[2] = 0x80 + (type<<4) + plan;
625 if (number) if (number[0])
626 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
628 add_layer3_ie(l3m, p[0], p[1], p+2);
631 void Pdss1::dec_ie_connected_pn(struct l3_msg *l3m, int *type, int *plan, int *present, int *screen, unsigned char *number, int number_len)
639 unsigned char *p = l3m->connected_nr;
644 add_trace("connect_pn", "error", "IE too short (len=%d)", p[0]);
648 *type = (p[1]&0x70) >> 4;
654 add_trace("connect_pn", "error", "IE too short (len=%d)", p[0]);
657 *present = (p[2]&0x60) >> 5;
658 *screen = p[2] & 0x3;
659 strnncpy(number, p+3, p[0]-2, number_len);
662 strnncpy(number, p+2, p[0]-1, number_len);
665 add_trace("connect_pn", "type", "%d", *type);
666 add_trace("connect_pn", "plan", "%d", *plan);
667 add_trace("connect_pn", "present", "%d", *present);
668 add_trace("connect_pn", "screen", "%d", *screen);
669 add_trace("connect_pn", "number", "%s", number);
674 void Pdss1::enc_ie_cause(struct l3_msg *l3m, int location, int cause)
676 unsigned char p[256];
679 if (location<0 || location>7)
681 PERROR("location(%d) is out of range.\n", location);
684 if (cause<0 || cause>127)
686 PERROR("cause(%d) is out of range.\n", cause);
690 add_trace("cause", "location", "%d", location);
691 add_trace("cause", "value", "%d", cause);
696 p[2] = 0x80 + location;
698 add_layer3_ie(l3m, p[0], p[1], p+2);
700 void enc_ie_cause_standalone(struct l3_msg *l3m, int location, int cause)
702 unsigned char p[256];
705 p[2] = 0x80 + location;
707 add_layer3_ie(l3m, p[0], p[1], p+2);
711 void Pdss1::dec_ie_cause(struct l3_msg *l3m, int *location, int *cause)
716 unsigned char *p = l3m->cause;
721 add_trace("cause", "error", "IE too short (len=%d)", p[0]);
725 *location = p[1] & 0x0f;
726 *cause = p[2] & 0x7f;
728 add_trace("cause", "location", "%d", *location);
729 add_trace("cause", "value", "%d", *cause);
734 void Pdss1::enc_ie_channel_id(struct l3_msg *l3m, int exclusive, int channel)
736 unsigned char p[256];
738 int pri = p_m_mISDNport->pri;
740 if (exclusive<0 || exclusive>1)
742 PERROR("exclusive(%d) is out of range.\n", exclusive);
745 if ((channel<=0 && channel!=CHANNEL_NO && channel!=CHANNEL_ANY)
746 || (!pri && channel>2)
747 || (pri && channel>127)
748 || (pri && channel==16))
750 PERROR("channel(%d) is out of range.\n", channel);
754 add_trace("channel_id", "exclusive", "%d", exclusive);
758 add_trace("channel_id", "channel", "any channel");
761 add_trace("channel_id", "channel", "no channel");
764 add_trace("channel_id", "channel", "%d", channel);
771 p[0] = IE_CHANNEL_ID;
773 if (channel == CHANNEL_NO)
775 else if (channel == CHANNEL_ANY)
777 p[2] = 0x80 + (exclusive<<3) + channel;
778 add_layer3_ie(l3m, p[0], p[1], p+2);
782 if (channel == CHANNEL_NO) /* no channel */
783 return; /* IE not present */
784 if (channel == CHANNEL_ANY) /* any channel */
787 p[0] = IE_CHANNEL_ID;
789 p[2] = 0x80 + 0x20 + 0x03;
790 add_layer3_ie(l3m, p[0], p[1], p+2);
794 p[0] = IE_CHANNEL_ID;
796 p[2] = 0x80 + 0x20 + (exclusive<<3) + 0x01;
797 p[3] = 0x80 + 3; /* CCITT, Number, B-type */
798 p[4] = 0x80 + channel;
799 add_layer3_ie(l3m, p[0], p[1], p+2);
803 void Pdss1::dec_ie_channel_id(struct l3_msg *l3m, int *exclusive, int *channel)
805 int pri = p_m_mISDNport->pri;
810 unsigned char *p = l3m->channel_id;
815 add_trace("channel_id", "error", "IE too short (len=%d)", p[0]);
821 add_trace("channel_id", "error", "refering to channels of other interfaces is not supported");
826 add_trace("channel_id", "error", "using d-channel is not supported");
830 *exclusive = (p[1]&0x08) >> 3;
836 add_trace("channel_id", "error", "extended channel ID with non PRI interface");
839 *channel = p[1] & 0x03;
841 *channel = CHANNEL_ANY;
842 else if (*channel == 0)
843 *channel = CHANNEL_NO;
850 add_trace("channel_id", "error", "IE too short for PRI (len=%d)", p[0]);
855 add_trace("channel_id", "error", "basic channel ID with PRI interface");
858 if ((p[1]&0x03) == 0x00)
861 *channel = CHANNEL_NO;
864 if ((p[1]&0x03) == 0x03)
867 *channel = CHANNEL_ANY;
872 add_trace("channel_id", "error", "IE too short for PRI with channel (len=%d)", p[0]);
877 add_trace("channel_id", "error", "channel map not supported");
880 *channel = p[3] & 0x7f;
881 if ((*channel<1) || (*channel==16))
883 add_trace("channel_id", "error", "PRI interface channel out of range (%d)", *channel);
888 add_trace("channel_id", "exclusive", "%d", *exclusive);
892 add_trace("channel_id", "channel", "any channel");
895 add_trace("channel_id", "channel", "no channel");
898 add_trace("channel_id", "channel", "%d", *channel);
904 void Pdss1::enc_ie_date(struct l3_msg *l3m, time_t ti, int no_seconds)
906 unsigned char p[256];
914 PERROR("localtime() returned NULL.\n");
918 add_trace("date", "day", "%d.%d.%d", tm->tm_mday, tm->tm_mon+1, tm->tm_year%100);
919 add_trace("date", "time", "%d:%d:%d", tm->tm_hour, tm->tm_min, tm->tm_sec);
921 l = 5 + (!no_seconds);
924 p[2] = tm->tm_year % 100;
925 p[3] = tm->tm_mon + 1;
931 add_layer3_ie(l3m, p[0], p[1], p+2);
936 void Pdss1::enc_ie_display(struct l3_msg *l3m, unsigned char *display)
938 unsigned char p[256];
943 PERROR("display text not given.\n");
947 if (strlen((char *)display) > 80)
949 PERROR("display text too long (max 80 chars), cutting.\n");
953 add_trace("display", NULL, "%s", display);
955 l = strlen((char *)display);
958 UNCPY((char *)p+2, (char *)display, strlen((char *)display));
959 add_layer3_ie(l3m, p[0], p[1], p+2);
962 void Pdss1::dec_ie_display(struct l3_msg *l3m, unsigned char *display, int display_len)
966 unsigned char *p = l3m->display;
971 add_trace("display", "error", "IE too short (len=%d)", p[0]);
975 strnncpy(display, p+1, p[0], display_len);
977 add_trace("display", NULL, "%s", display);
982 void Pdss1::enc_ie_keypad(struct l3_msg *l3m, unsigned char *keypad)
984 unsigned char p[256];
989 PERROR("keypad info not given.\n");
993 add_trace("keypad", NULL, "%s", keypad);
995 l = strlen((char *)keypad);
998 UNCPY((char *)p+2, (char *)keypad, strlen((char *)keypad));
999 add_layer3_ie(l3m, p[0], p[1], p+2);
1002 void Pdss1::dec_ie_keypad(struct l3_msg *l3m, unsigned char *keypad, int keypad_len)
1006 unsigned char *p = l3m->keypad;
1011 add_trace("keypad", "error", "IE too short (len=%d)", p[0]);
1015 strnncpy(keypad, p+1, p[0], keypad_len);
1017 add_trace("keypad", NULL, "%s", keypad);
1022 void Pdss1::enc_ie_notify(struct l3_msg *l3m, int notify)
1024 unsigned char p[256];
1027 if (notify<0 || notify>0x7f)
1029 PERROR("notify(%d) is out of range.\n", notify);
1033 add_trace("notify", NULL, "%d", notify);
1038 p[2] = 0x80 + notify;
1039 add_layer3_ie(l3m, p[0], p[1], p+2);
1042 void Pdss1::dec_ie_notify(struct l3_msg *l3m, int *notify)
1046 unsigned char *p = l3m->notify;
1051 add_trace("notify", "error", "IE too short (len=%d)", p[0]);
1055 *notify = p[1] & 0x7f;
1057 add_trace("notify", NULL, "%d", *notify);
1062 void Pdss1::enc_ie_progress(struct l3_msg *l3m, int coding, int location, int progress)
1064 unsigned char p[256];
1067 if (coding<0 || coding>0x03)
1069 PERROR("coding(%d) is out of range.\n", coding);
1072 if (location<0 || location>0x0f)
1074 PERROR("location(%d) is out of range.\n", location);
1077 if (progress<0 || progress>0x7f)
1079 PERROR("progress(%d) is out of range.\n", progress);
1083 add_trace("progress", "codeing", "%d", coding);
1084 add_trace("progress", "location", "%d", location);
1085 add_trace("progress", "indicator", "%d", progress);
1090 p[2] = 0x80 + (coding<<5) + location;
1091 p[3] = 0x80 + progress;
1092 add_layer3_ie(l3m, p[0], p[1], p+2);
1095 void Pdss1::dec_ie_progress(struct l3_msg *l3m, int *coding, int *location, int *progress)
1101 unsigned char *p = l3m->progress;
1106 add_trace("progress", "error", "IE too short (len=%d)", p[0]);
1110 *coding = (p[1]&0x60) >> 5;
1111 *location = p[1] & 0x0f;
1112 *progress = p[2] & 0x7f;
1114 add_trace("progress", "codeing", "%d", *coding);
1115 add_trace("progress", "location", "%d", *location);
1116 add_trace("progress", "indicator", "%d", *progress);
1120 /* IE_REDIR_NR (redirecting = during MT_SETUP) */
1121 void Pdss1::enc_ie_redir_nr(struct l3_msg *l3m, int type, int plan, int present, int screen, int reason, unsigned char *number)
1123 unsigned char p[256];
1126 if (type<0 || type>7)
1128 PERROR("type(%d) is out of range.\n", type);
1131 if (plan<0 || plan>15)
1133 PERROR("plan(%d) is out of range.\n", plan);
1138 PERROR("present(%d) is out of range.\n", present);
1141 if (present >= 0) if (screen<0 || screen>3)
1143 PERROR("screen(%d) is out of range.\n", screen);
1148 PERROR("reason(%d) is out of range.\n", reason);
1152 add_trace("redir'ing", "type", "%d", type);
1153 add_trace("redir'ing", "plan", "%d", plan);
1154 add_trace("redir'ing", "present", "%d", present);
1155 add_trace("redir'ing", "screen", "%d", screen);
1156 add_trace("redir'ing", "reason", "%d", reason);
1157 add_trace("redir'ing", "number", "%s", number);
1161 l += strlen((char *)number);
1174 p[2] = 0x00 + (type<<4) + plan;
1175 p[3] = 0x00 + (present<<5) + screen;
1176 p[4] = 0x80 + reason;
1178 UNCPY((char *)p+5, (char *)number, strlen((char *)number));
1181 p[2] = 0x00 + (type<<4) + plan;
1182 p[3] = 0x80 + (present<<5) + screen;
1184 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
1188 p[2] = 0x80 + (type<<4) + plan;
1189 if (number) if (number[0])
1190 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
1192 add_layer3_ie(l3m, p[0], p[1], p+2);
1195 void Pdss1::dec_ie_redir_nr(struct l3_msg *l3m, int *type, int *plan, int *present, int *screen, int *reason, unsigned char *number, int number_len)
1204 unsigned char *p = l3m->redirect_nr;
1209 add_trace("redir'ing", "error", "IE too short (len=%d)", p[0]);
1213 *type = (p[1]&0x70) >> 4;
1217 *present = (p[2]&0x60) >> 5;
1218 *screen = p[2] & 0x3;
1221 *reason = p[3] & 0x0f;
1222 strnncpy(number, p+4, p[0]-3, number_len);
1225 strnncpy(number, p+3, p[0]-2, number_len);
1229 strnncpy(number, p+2, p[0]-1, number_len);
1232 add_trace("redir'ing", "type", "%d", *type);
1233 add_trace("redir'ing", "plan", "%d", *plan);
1234 add_trace("redir'ing", "present", "%d", *present);
1235 add_trace("redir'ing", "screen", "%d", *screen);
1236 add_trace("redir'ing", "reason", "%d", *reason);
1237 add_trace("redir'ing", "number", "%s", number);
1241 /* IE_REDIR_DN (redirection = during MT_NOTIFY) */
1242 void Pdss1::enc_ie_redir_dn(struct l3_msg *l3m, int type, int plan, int present, unsigned char *number)
1244 unsigned char p[256];
1247 if (type<0 || type>7)
1249 PERROR("type(%d) is out of range.\n", type);
1252 if (plan<0 || plan>15)
1254 PERROR("plan(%d) is out of range.\n", plan);
1259 PERROR("present(%d) is out of range.\n", present);
1263 add_trace("redir'tion", "type", "%d", type);
1264 add_trace("redir'tion", "plan", "%d", plan);
1265 add_trace("redir'tion", "present", "%d", present);
1266 add_trace("redir'tion", "number", "%s", number);
1270 l += strlen((char *)number);
1277 p[2] = 0x00 + (type<<4) + plan;
1278 p[3] = 0x80 + (present<<5);
1280 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
1283 p[2] = 0x80 + (type<<4) + plan;
1285 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
1287 add_layer3_ie(l3m, p[0], p[1], p+2);
1290 void Pdss1::dec_ie_redir_dn(struct l3_msg *l3m, int *type, int *plan, int *present, unsigned char *number, int number_len)
1297 unsigned char *p = l3m->redirect_dn;
1302 add_trace("redir'tion", "error", "IE too short (len=%d)", p[0]);
1306 *type = (p[1]&0x70) >> 4;
1310 *present = (p[2]&0x60) >> 5;
1311 strnncpy(number, p+3, p[0]-2, number_len);
1314 strnncpy(number, p+2, p[0]-1, number_len);
1317 add_trace("redir'tion", "type", "%d", *type);
1318 add_trace("redir'tion", "plan", "%d", *plan);
1319 add_trace("redir'tion", "present", "%d", *present);
1320 add_trace("redir'tion", "number", "%s", number);
1325 void Pdss1::enc_ie_facility(struct l3_msg *l3m, unsigned char *facility, int facility_len)
1327 unsigned char p[256];
1333 if (!facility || facility_len<=0)
1339 while(i < facility_len)
1341 UPRINT(buffer+(i*3), " %02x", facility[i]);
1345 add_trace("facility", NULL, "%s", buffer+1);
1350 memcpy(p+2, facility, facility_len);
1351 add_layer3_ie(l3m, p[0], p[1], p+2);
1354 void Pdss1::dec_ie_facility(struct l3_msg *l3m, unsigned char *facility, int *facility_len)
1361 unsigned char *p = l3m->facility;
1365 *facility_len = p[0];
1366 memcpy(facility, p+1, *facility_len);
1369 while(i < *facility_len)
1371 UPRINT(debug+(i*3), " %02x", facility[i]);
1376 add_trace("facility", NULL, "%s", debug[0]?debug+1:"<none>");
1380 void Pdss1::dec_facility_centrex(struct l3_msg *l3m, unsigned char *cnip, int cnip_len)
1382 unsigned char centrex[256];
1384 int facility_len = 0;
1388 dec_ie_facility(l3m, centrex, &facility_len);
1389 if (facility_len >= 2)
1391 if (centrex[i++] != CENTREX_FAC)
1393 if (centrex[i++] != CENTREX_ID)
1397 /* loop sub IEs of facility */
1398 while(facility_len > i+1)
1400 if (centrex[i+1]+i+1 > facility_len)
1402 PERROR("short read of centrex facility.\n");
1408 strnncpy(cnip, ¢rex[i+2], centrex[i+1], cnip_len);
1409 add_trace("facility", "cnip", "%s", cnip);
1414 while(j < centrex[i+1])
1416 UPRINT(debug+(j*3), " %02x", centrex[i+1+j]);
1419 add_trace("facility", "CENTREX", "unknown=0x%02x len=%d%s\n", centrex[i], centrex[i+1], debug);
1421 i += 1+centrex[i+1];
1427 void Pdss1::enc_ie_useruser(struct l3_msg *l3m, int protocol, unsigned char *user, int user_len)
1429 unsigned char p[256];
1435 if (protocol<0 || protocol>127)
1437 PERROR("protocol(%d) is out of range.\n", protocol);
1440 if (!user || user_len<=0)
1448 UPRINT(buffer+(i*3), " %02x", user[i]);
1452 add_trace("useruser", "protocol", "%d", protocol);
1453 add_trace("useruser", "value", "%s", buffer);
1456 p[0] = IE_USER_USER;
1458 p[2] = 0x80 + protocol;
1459 memcpy(p+3, user, user_len);
1460 add_layer3_ie(l3m, p[0], p[1], p+2);
1463 void Pdss1::dec_ie_useruser(struct l3_msg *l3m, int *protocol, unsigned char *user, int *user_len)
1471 unsigned char *p = l3m->useruser;
1479 memcpy(user, p+2, (*user_len<=128)?*(user_len):128); /* clip to 128 maximum */
1482 while(i < *user_len)
1484 UPRINT(buffer+(i*3), " %02x", user[i]);
1489 add_trace("useruser", "protocol", "%d", *protocol);
1490 add_trace("useruser", "value", "%s", buffer);