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)
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);
430 void Pdss1::dec_ie_calling_pn(struct l3_msg *l3m, int *type, int *plan, int *present, int *screen, unsigned char *number, int number_len)
438 unsigned char *p = l3m->calling_nr;
443 add_trace("calling_pn", "error", "IE too short (len=%d)", p[0]);
447 *type = (p[1]&0x70) >> 4;
453 add_trace("calling_pn", "error", "IE too short (len=%d)", p[0]);
456 *present = (p[2]&0x60) >> 5;
457 *screen = p[2] & 0x3;
458 strnncpy(number, p+3, p[0]-2, number_len);
461 strnncpy(number, p+2, p[0]-1, number_len);
464 add_trace("calling_pn", "type", "%d", *type);
465 add_trace("calling_pn", "plan", "%d", *plan);
466 add_trace("calling_pn", "present", "%d", *present);
467 add_trace("calling_pn", "screen", "%d", *screen);
468 add_trace("calling_pn", "number", "%s", number);
472 /* IE_CONNECTED_PN */
473 void Pdss1::enc_ie_connected_pn(struct l3_msg *l3m, int type, int plan, int present, int screen, unsigned char *number)
475 unsigned char p[256];
478 if (type<0 || type>7)
480 PERROR("type(%d) is out of range.\n", type);
483 if (plan<0 || plan>15)
485 PERROR("plan(%d) is out of range.\n", plan);
490 PERROR("present(%d) is out of range.\n", present);
493 if (present >= 0) if (screen<0 || screen>3)
495 PERROR("screen(%d) is out of range.\n", screen);
499 add_trace("connect_pn", "type", "%d", type);
500 add_trace("connect_pn", "plan", "%d", plan);
501 add_trace("connect_pn", "present", "%d", present);
502 add_trace("connect_pn", "screen", "%d", screen);
503 add_trace("connect_pn", "number", "%s", number);
506 if (number) if (number[0])
507 l += strlen((char *)number);
510 p[0] = IE_CONNECT_PN;
514 p[2] = 0x00 + (type<<4) + plan;
515 p[3] = 0x80 + (present<<5) + screen;
516 if (number) if (number[0])
517 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
520 p[2] = 0x80 + (type<<4) + plan;
521 if (number) if (number[0])
522 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
524 add_layer3_ie(l3m, p[0], p[1], p+2);
527 void Pdss1::dec_ie_connected_pn(struct l3_msg *l3m, int *type, int *plan, int *present, int *screen, unsigned char *number, int number_len)
535 unsigned char *p = l3m->connected_nr;
540 add_trace("connect_pn", "error", "IE too short (len=%d)", p[0]);
544 *type = (p[1]&0x70) >> 4;
550 add_trace("connect_pn", "error", "IE too short (len=%d)", p[0]);
553 *present = (p[2]&0x60) >> 5;
554 *screen = p[2] & 0x3;
555 strnncpy(number, p+3, p[0]-2, number_len);
558 strnncpy(number, p+2, p[0]-1, number_len);
561 add_trace("connect_pn", "type", "%d", *type);
562 add_trace("connect_pn", "plan", "%d", *plan);
563 add_trace("connect_pn", "present", "%d", *present);
564 add_trace("connect_pn", "screen", "%d", *screen);
565 add_trace("connect_pn", "number", "%s", number);
570 void Pdss1::enc_ie_cause(struct l3_msg *l3m, int location, int cause)
572 unsigned char p[256];
575 if (location<0 || location>7)
577 PERROR("location(%d) is out of range.\n", location);
580 if (cause<0 || cause>127)
582 PERROR("cause(%d) is out of range.\n", cause);
586 add_trace("cause", "location", "%d", location);
587 add_trace("cause", "value", "%d", cause);
592 p[2] = 0x80 + location;
594 add_layer3_ie(l3m, p[0], p[1], p+2);
596 void enc_ie_cause_standalone(struct l3_msg *l3m, int location, int cause)
598 unsigned char p[256];
601 p[2] = 0x80 + location;
603 add_layer3_ie(l3m, p[0], p[1], p+2);
607 void Pdss1::dec_ie_cause(struct l3_msg *l3m, int *location, int *cause)
612 unsigned char *p = l3m->cause;
617 add_trace("cause", "error", "IE too short (len=%d)", p[0]);
621 *location = p[1] & 0x0f;
622 *cause = p[2] & 0x7f;
624 add_trace("cause", "location", "%d", *location);
625 add_trace("cause", "value", "%d", *cause);
630 void Pdss1::enc_ie_channel_id(struct l3_msg *l3m, int exclusive, int channel)
632 unsigned char p[256];
634 int pri = p_m_mISDNport->pri;
636 if (exclusive<0 || exclusive>1)
638 PERROR("exclusive(%d) is out of range.\n", exclusive);
641 if ((channel<=0 && channel!=CHANNEL_NO && channel!=CHANNEL_ANY)
642 || (!pri && channel>2)
643 || (pri && channel>127)
644 || (pri && channel==16))
646 PERROR("channel(%d) is out of range.\n", channel);
650 add_trace("channel_id", "exclusive", "%d", exclusive);
654 add_trace("channel_id", "channel", "any channel");
657 add_trace("channel_id", "channel", "no channel");
660 add_trace("channel_id", "channel", "%d", channel);
667 p[0] = IE_CHANNEL_ID;
669 if (channel == CHANNEL_NO)
671 else if (channel == CHANNEL_ANY)
673 p[2] = 0x80 + (exclusive<<3) + channel;
674 add_layer3_ie(l3m, p[0], p[1], p+2);
678 if (channel == CHANNEL_NO) /* no channel */
679 return; /* IE not present */
680 if (channel == CHANNEL_ANY) /* any channel */
683 p[0] = IE_CHANNEL_ID;
685 p[2] = 0x80 + 0x20 + 0x03;
686 add_layer3_ie(l3m, p[0], p[1], p+2);
690 p[0] = IE_CHANNEL_ID;
692 p[2] = 0x80 + 0x20 + (exclusive<<3) + 0x01;
693 p[3] = 0x80 + 3; /* CCITT, Number, B-type */
694 p[4] = 0x80 + channel;
695 add_layer3_ie(l3m, p[0], p[1], p+2);
699 void Pdss1::dec_ie_channel_id(struct l3_msg *l3m, int *exclusive, int *channel)
701 int pri = p_m_mISDNport->pri;
706 unsigned char *p = l3m->channel_id;
711 add_trace("channel_id", "error", "IE too short (len=%d)", p[0]);
717 add_trace("channel_id", "error", "refering to channels of other interfaces is not supported");
722 add_trace("channel_id", "error", "using d-channel is not supported");
726 *exclusive = (p[1]&0x08) >> 3;
732 add_trace("channel_id", "error", "extended channel ID with non PRI interface");
735 *channel = p[1] & 0x03;
737 *channel = CHANNEL_ANY;
738 else if (*channel == 0)
739 *channel = CHANNEL_NO;
746 add_trace("channel_id", "error", "IE too short for PRI (len=%d)", p[0]);
751 add_trace("channel_id", "error", "basic channel ID with PRI interface");
754 if ((p[1]&0x03) == 0x00)
757 *channel = CHANNEL_NO;
760 if ((p[1]&0x03) == 0x03)
763 *channel = CHANNEL_ANY;
768 add_trace("channel_id", "error", "IE too short for PRI with channel (len=%d)", p[0]);
773 add_trace("channel_id", "error", "channel map not supported");
776 *channel = p[3] & 0x7f;
777 if ((*channel<1) || (*channel==16))
779 add_trace("channel_id", "error", "PRI interface channel out of range (%d)", *channel);
784 add_trace("channel_id", "exclusive", "%d", *exclusive);
788 add_trace("channel_id", "channel", "any channel");
791 add_trace("channel_id", "channel", "no channel");
794 add_trace("channel_id", "channel", "%d", *channel);
800 void Pdss1::enc_ie_date(struct l3_msg *l3m, time_t ti, int no_seconds)
802 unsigned char p[256];
810 PERROR("localtime() returned NULL.\n");
814 add_trace("date", "day", "%d.%d.%d", tm->tm_mday, tm->tm_mon+1, tm->tm_year%100);
815 add_trace("date", "time", "%d:%d:%d", tm->tm_hour, tm->tm_min, tm->tm_sec);
817 l = 5 + (!no_seconds);
820 p[2] = tm->tm_year % 100;
821 p[3] = tm->tm_mon + 1;
827 add_layer3_ie(l3m, p[0], p[1], p+2);
832 void Pdss1::enc_ie_display(struct l3_msg *l3m, unsigned char *display)
834 unsigned char p[256];
839 PERROR("display text not given.\n");
843 if (strlen((char *)display) > 80)
845 PERROR("display text too long (max 80 chars), cutting.\n");
849 add_trace("display", NULL, "%s", display);
851 l = strlen((char *)display);
854 UNCPY((char *)p+2, (char *)display, strlen((char *)display));
855 add_layer3_ie(l3m, p[0], p[1], p+2);
858 void Pdss1::dec_ie_display(struct l3_msg *l3m, unsigned char *display, int display_len)
862 unsigned char *p = l3m->display;
867 add_trace("display", "error", "IE too short (len=%d)", p[0]);
871 strnncpy(display, p+1, p[0], display_len);
873 add_trace("display", NULL, "%s", display);
878 void Pdss1::enc_ie_keypad(struct l3_msg *l3m, unsigned char *keypad)
880 unsigned char p[256];
885 PERROR("keypad info not given.\n");
889 add_trace("keypad", NULL, "%s", keypad);
891 l = strlen((char *)keypad);
894 UNCPY((char *)p+2, (char *)keypad, strlen((char *)keypad));
895 add_layer3_ie(l3m, p[0], p[1], p+2);
898 void Pdss1::dec_ie_keypad(struct l3_msg *l3m, unsigned char *keypad, int keypad_len)
902 unsigned char *p = l3m->keypad;
907 add_trace("keypad", "error", "IE too short (len=%d)", p[0]);
911 strnncpy(keypad, p+1, p[0], keypad_len);
913 add_trace("keypad", NULL, "%s", keypad);
918 void Pdss1::enc_ie_notify(struct l3_msg *l3m, int notify)
920 unsigned char p[256];
923 if (notify<0 || notify>0x7f)
925 PERROR("notify(%d) is out of range.\n", notify);
929 add_trace("notify", NULL, "%d", notify);
934 p[2] = 0x80 + notify;
935 add_layer3_ie(l3m, p[0], p[1], p+2);
938 void Pdss1::dec_ie_notify(struct l3_msg *l3m, int *notify)
942 unsigned char *p = l3m->notify;
947 add_trace("notify", "error", "IE too short (len=%d)", p[0]);
951 *notify = p[1] & 0x7f;
953 add_trace("notify", NULL, "%d", *notify);
958 void Pdss1::enc_ie_progress(struct l3_msg *l3m, int coding, int location, int progress)
960 unsigned char p[256];
963 if (coding<0 || coding>0x03)
965 PERROR("coding(%d) is out of range.\n", coding);
968 if (location<0 || location>0x0f)
970 PERROR("location(%d) is out of range.\n", location);
973 if (progress<0 || progress>0x7f)
975 PERROR("progress(%d) is out of range.\n", progress);
979 add_trace("progress", "codeing", "%d", coding);
980 add_trace("progress", "location", "%d", location);
981 add_trace("progress", "indicator", "%d", progress);
986 p[2] = 0x80 + (coding<<5) + location;
987 p[3] = 0x80 + progress;
988 add_layer3_ie(l3m, p[0], p[1], p+2);
991 void Pdss1::dec_ie_progress(struct l3_msg *l3m, int *coding, int *location, int *progress)
997 unsigned char *p = l3m->progress;
1002 add_trace("progress", "error", "IE too short (len=%d)", p[0]);
1006 *coding = (p[1]&0x60) >> 5;
1007 *location = p[1] & 0x0f;
1008 *progress = p[2] & 0x7f;
1010 add_trace("progress", "codeing", "%d", *coding);
1011 add_trace("progress", "location", "%d", *location);
1012 add_trace("progress", "indicator", "%d", *progress);
1016 /* IE_REDIR_NR (redirecting = during MT_SETUP) */
1017 void Pdss1::enc_ie_redir_nr(struct l3_msg *l3m, int type, int plan, int present, int screen, int reason, unsigned char *number)
1019 unsigned char p[256];
1022 if (type<0 || type>7)
1024 PERROR("type(%d) is out of range.\n", type);
1027 if (plan<0 || plan>15)
1029 PERROR("plan(%d) is out of range.\n", plan);
1034 PERROR("present(%d) is out of range.\n", present);
1037 if (present >= 0) if (screen<0 || screen>3)
1039 PERROR("screen(%d) is out of range.\n", screen);
1044 PERROR("reason(%d) is out of range.\n", reason);
1048 add_trace("redir'ing", "type", "%d", type);
1049 add_trace("redir'ing", "plan", "%d", plan);
1050 add_trace("redir'ing", "present", "%d", present);
1051 add_trace("redir'ing", "screen", "%d", screen);
1052 add_trace("redir'ing", "reason", "%d", reason);
1053 add_trace("redir'ing", "number", "%s", number);
1057 l += strlen((char *)number);
1070 p[2] = 0x00 + (type<<4) + plan;
1071 p[3] = 0x00 + (present<<5) + screen;
1072 p[4] = 0x80 + reason;
1074 UNCPY((char *)p+5, (char *)number, strlen((char *)number));
1077 p[2] = 0x00 + (type<<4) + plan;
1078 p[3] = 0x80 + (present<<5) + screen;
1080 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
1084 p[2] = 0x80 + (type<<4) + plan;
1085 if (number) if (number[0])
1086 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
1088 add_layer3_ie(l3m, p[0], p[1], p+2);
1091 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)
1100 unsigned char *p = l3m->redirect_nr;
1105 add_trace("redir'ing", "error", "IE too short (len=%d)", p[0]);
1109 *type = (p[1]&0x70) >> 4;
1113 *present = (p[2]&0x60) >> 5;
1114 *screen = p[2] & 0x3;
1117 *reason = p[3] & 0x0f;
1118 strnncpy(number, p+4, p[0]-3, number_len);
1121 strnncpy(number, p+3, p[0]-2, number_len);
1125 strnncpy(number, p+2, p[0]-1, number_len);
1128 add_trace("redir'ing", "type", "%d", *type);
1129 add_trace("redir'ing", "plan", "%d", *plan);
1130 add_trace("redir'ing", "present", "%d", *present);
1131 add_trace("redir'ing", "screen", "%d", *screen);
1132 add_trace("redir'ing", "reason", "%d", *reason);
1133 add_trace("redir'ing", "number", "%s", number);
1137 /* IE_REDIR_DN (redirection = during MT_NOTIFY) */
1138 void Pdss1::enc_ie_redir_dn(struct l3_msg *l3m, int type, int plan, int present, unsigned char *number)
1140 unsigned char p[256];
1143 if (type<0 || type>7)
1145 PERROR("type(%d) is out of range.\n", type);
1148 if (plan<0 || plan>15)
1150 PERROR("plan(%d) is out of range.\n", plan);
1155 PERROR("present(%d) is out of range.\n", present);
1159 add_trace("redir'tion", "type", "%d", type);
1160 add_trace("redir'tion", "plan", "%d", plan);
1161 add_trace("redir'tion", "present", "%d", present);
1162 add_trace("redir'tion", "number", "%s", number);
1166 l += strlen((char *)number);
1173 p[2] = 0x00 + (type<<4) + plan;
1174 p[3] = 0x80 + (present<<5);
1176 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
1179 p[2] = 0x80 + (type<<4) + plan;
1181 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
1183 add_layer3_ie(l3m, p[0], p[1], p+2);
1186 void Pdss1::dec_ie_redir_dn(struct l3_msg *l3m, int *type, int *plan, int *present, unsigned char *number, int number_len)
1193 unsigned char *p = l3m->redirect_dn;
1198 add_trace("redir'tion", "error", "IE too short (len=%d)", p[0]);
1202 *type = (p[1]&0x70) >> 4;
1206 *present = (p[2]&0x60) >> 5;
1207 strnncpy(number, p+3, p[0]-2, number_len);
1210 strnncpy(number, p+2, p[0]-1, number_len);
1213 add_trace("redir'tion", "type", "%d", *type);
1214 add_trace("redir'tion", "plan", "%d", *plan);
1215 add_trace("redir'tion", "present", "%d", *present);
1216 add_trace("redir'tion", "number", "%s", number);
1221 void Pdss1::enc_ie_facility(struct l3_msg *l3m, unsigned char *facility, int facility_len)
1223 unsigned char p[256];
1229 if (!facility || facility_len<=0)
1235 while(i < facility_len)
1237 UPRINT(buffer+(i*3), " %02x", facility[i]);
1241 add_trace("facility", NULL, "%s", buffer+1);
1246 memcpy(p+2, facility, facility_len);
1247 add_layer3_ie(l3m, p[0], p[1], p+2);
1250 void Pdss1::dec_ie_facility(struct l3_msg *l3m, unsigned char *facility, int *facility_len)
1257 unsigned char *p = l3m->facility;
1261 *facility_len = p[0];
1262 memcpy(facility, p+1, *facility_len);
1265 while(i < *facility_len)
1267 UPRINT(debug+(i*3), " %02x", facility[i]);
1272 add_trace("facility", NULL, "%s", debug[0]?debug+1:"<none>");
1276 void Pdss1::dec_facility_centrex(struct l3_msg *l3m, unsigned char *cnip, int cnip_len)
1278 unsigned char centrex[256];
1280 int facility_len = 0;
1284 dec_ie_facility(l3m, centrex, &facility_len);
1285 if (facility_len >= 2)
1287 if (centrex[i++] != CENTREX_FAC)
1289 if (centrex[i++] != CENTREX_ID)
1293 /* loop sub IEs of facility */
1294 while(facility_len > i+1)
1296 if (centrex[i+1]+i+1 > facility_len)
1298 PERROR("short read of centrex facility.\n");
1304 strnncpy(cnip, ¢rex[i+2], centrex[i+1], cnip_len);
1305 add_trace("facility", "cnip", "%s", cnip);
1310 while(j < centrex[i+1])
1312 UPRINT(debug+(j*3), " %02x", centrex[i+1+j]);
1315 add_trace("facility", "CENTREX", "unknown=0x%02x len=%d%s\n", centrex[i], centrex[i+1], debug);
1317 i += 1+centrex[i+1];
1323 void Pdss1::enc_ie_useruser(struct l3_msg *l3m, int protocol, unsigned char *user, int user_len)
1325 unsigned char p[256];
1331 if (protocol<0 || protocol>127)
1333 PERROR("protocol(%d) is out of range.\n", protocol);
1336 if (!user || user_len<=0)
1344 UPRINT(buffer+(i*3), " %02x", user[i]);
1348 add_trace("useruser", "protocol", "%d", protocol);
1349 add_trace("useruser", "value", "%s", buffer);
1352 p[0] = IE_USER_USER;
1354 p[2] = 0x80 + protocol;
1355 memcpy(p+3, user, user_len);
1356 add_layer3_ie(l3m, p[0], p[1], p+2);
1359 void Pdss1::dec_ie_useruser(struct l3_msg *l3m, int *protocol, unsigned char *user, int *user_len)
1367 unsigned char *p = l3m->useruser;
1375 memcpy(user, p+2, (*user_len<=128)?*(user_len):128); /* clip to 128 maximum */
1378 while(i < *user_len)
1380 UPRINT(buffer+(i*3), " %02x", user[i]);
1385 add_trace("useruser", "protocol", "%d", *protocol);
1386 add_trace("useruser", "value", "%s", buffer);