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) {
33 PERROR("complete(%d) is out of range.\n", complete);
38 add_trace("complete", NULL, NULL);
39 l3m->sending_complete++;
43 void Pdss1::dec_ie_complete(struct l3_msg *l3m, int *complete)
46 // special case: p is not a pointer, it's a value
47 unsigned char p = l3m->sending_complete;
52 add_trace("complete", NULL, NULL);
57 void Pdss1::enc_ie_bearer(struct l3_msg *l3m, int coding, int capability, int mode, int rate, int multi, int user)
62 if (coding<0 || coding>3) {
63 PERROR("coding(%d) is out of range.\n", coding);
66 if (capability<0 || capability>31) {
67 PERROR("capability(%d) is out of range.\n", capability);
70 if (mode<0 || mode>3) {
71 PERROR("mode(%d) is out of range.\n", mode);
74 if (rate<0 || rate>31) {
75 PERROR("rate(%d) is out of range.\n", rate);
79 PERROR("multi(%d) is out of range.\n", multi);
83 PERROR("user L1(%d) is out of range.\n", user);
86 if (rate!=24 && multi>=0) {
87 PERROR("multi(%d) is only possible if rate(%d) would be 24.\n", multi, rate);
91 add_trace("bearer", "coding", "%d", coding);
92 add_trace("bearer", "capability", "%d", capability);
93 add_trace("bearer", "mode", "%d", mode);
94 add_trace("bearer", "rate", "%d", rate);
95 add_trace("bearer", "multi", "%d", multi);
96 add_trace("bearer", "user", "%d", user);
98 l = 2 + (multi>=0) + (user>=0);
101 p[2] = 0x80 + (coding<<5) + capability;
102 p[3] = 0x80 + (mode<<5) + rate;
106 p[4+(multi>=0)] = 0xa0 + user;
107 add_layer3_ie(l3m, p[0], p[1], p+2);
110 void Pdss1::dec_ie_bearer(struct l3_msg *l3m, int *coding, int *capability, int *mode, int *rate, int *multi, int *user)
119 unsigned char *p = l3m->bearer_capability;
123 add_trace("bearer", "error", "IE too short (len=%d)", p[0]);
127 *coding = (p[1]&0x60) >> 5;
128 *capability = p[1] & 0x1f;
130 *mode = (p[2]&0x60) >> 5;
133 if (p[0]>=3 && *rate==0x18) {
134 *multi = p[3] & 0x7f;
142 add_trace("bearer", "coding", "%d", *coding);
143 add_trace("bearer", "capability", "%d", *capability);
144 add_trace("bearer", "mode", "%d", *mode);
145 add_trace("bearer", "rate", "%d", *rate);
146 add_trace("bearer", "multi", "%d", *multi);
147 add_trace("bearer", "user", "%d", *user);
152 void Pdss1::enc_ie_hlc(struct l3_msg *l3m, int coding, int interpretation, int presentation, int hlc, int exthlc)
154 unsigned char p[256];
157 if (coding<0 || coding>3) {
158 PERROR("coding(%d) is out of range.\n", coding);
161 if (interpretation<0 || interpretation>7) {
162 PERROR("interpretation(%d) is out of range.\n", interpretation);
165 if (presentation<0 || presentation>3) {
166 PERROR("presentation(%d) is out of range.\n", presentation);
169 if (hlc<0 || hlc>127) {
170 PERROR("hlc(%d) is out of range.\n", hlc);
174 PERROR("hlc(%d) is out of range.\n", exthlc);
178 add_trace("hlc", "coding", "%d", coding);
179 add_trace("hlc", "interpretation", "%d", interpretation);
180 add_trace("hlc", "presentation", "%d", presentation);
181 add_trace("hlc", "hlc", "%d", hlc);
183 add_trace("hlc", "exthlc", "%d", exthlc);
188 p[2] = 0x80 + (coding<<5) + (interpretation<<2) + presentation;
191 p[4] = 0x80 + exthlc;
194 add_layer3_ie(l3m, p[0], p[1], p+2);
197 void Pdss1::dec_ie_hlc(struct l3_msg *l3m, int *coding, int *interpretation, int *presentation, int *hlc, int *exthlc)
200 *interpretation = -1;
205 unsigned char *p = l3m->hlc;
209 add_trace("hlc", "error", "IE too short (len=%d)", p[0]);
213 *coding = (p[1]&0x60) >> 5;
214 *interpretation = (p[1]&0x1c) >> 2;
215 *presentation = p[1] & 0x03;
218 *exthlc = p[3] & 0x7f;
221 add_trace("hlc", "coding", "%d", *coding);
222 add_trace("hlc", "interpretation", "%d", *interpretation);
223 add_trace("hlc", "presentation", "%d", *presentation);
224 add_trace("hlc", "hlc", "%d", *hlc);
226 add_trace("hlc", "exthlc", "%d", *exthlc);
231 void Pdss1::enc_ie_call_id(struct l3_msg *l3m, unsigned char *callid, int callid_len)
233 unsigned char p[256];
239 if (!callid || callid_len<=0) {
242 if (callid_len > 8) {
243 PERROR("callid_len(%d) is out of range.\n", callid_len);
248 while(i < callid_len) {
249 UPRINT(buffer+(i*3), " %02x", callid[i]);
253 add_trace("callid", NULL, "%s", buffer[0]?buffer+1:"<none>");
258 memcpy(p+2, callid, callid_len);
259 add_layer3_ie(l3m, p[0], p[1], p+2);
262 void Pdss1::dec_ie_call_id(struct l3_msg *l3m, unsigned char *callid, int *callid_len)
269 unsigned char *p = l3m->call_id;
273 add_trace("callid", "error", "IE too long (len=%d)", p[0]);
278 memcpy(callid, p+1, *callid_len);
281 while(i < *callid_len) {
282 UPRINT(buffer+(i*3), " %02x", callid[i]);
286 add_trace("callid", NULL, "%s", buffer[0]?buffer+1:"<none>");
291 void Pdss1::enc_ie_called_pn(struct l3_msg *l3m, int type, int plan, unsigned char *number, int number_len)
293 unsigned char p[256];
296 if (type<0 || type>7) {
297 PERROR("type(%d) is out of range.\n", type);
300 if (plan<0 || plan>15) {
301 PERROR("plan(%d) is out of range.\n", plan);
305 PERROR("number is not given.\n");
309 add_trace("called_pn", "type", "%d", type);
310 add_trace("called_pn", "plan", "%d", plan);
311 UNCPY((char *)p, (char *)number, number_len);
312 p[number_len] = '\0';
313 add_trace("called_pn", "number", "%s", p);
318 p[2] = 0x80 + (type<<4) + plan;
319 UNCPY((char *)p+3, (char *)number, number_len);
320 add_layer3_ie(l3m, p[0], p[1], p+2);
323 void Pdss1::dec_ie_called_pn(struct l3_msg *l3m, int *type, int *plan, unsigned char *number, int number_len)
329 unsigned char *p = l3m->called_nr;
333 add_trace("called_pn", "error", "IE too short (len=%d)", p[0]);
337 *type = (p[1]&0x70) >> 4;
339 strnncpy(number, p+2, p[0]-1, number_len);
341 add_trace("called_pn", "type", "%d", *type);
342 add_trace("called_pn", "plan", "%d", *plan);
343 add_trace("called_pn", "number", "%s", number);
348 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)
350 unsigned char p[256];
353 if (type<0 || type>7) {
354 PERROR("type(%d) is out of range.\n", type);
357 if (plan<0 || plan>15) {
358 PERROR("plan(%d) is out of range.\n", plan);
362 PERROR("present(%d) is out of range.\n", present);
365 if (present >= 0) if (screen<0 || screen>3) {
366 PERROR("screen(%d) is out of range.\n", screen);
370 add_trace("calling_pn", "type", "%d", type);
371 add_trace("calling_pn", "plan", "%d", plan);
372 add_trace("calling_pn", "present", "%d", present);
373 add_trace("calling_pn", "screen", "%d", screen);
374 add_trace("calling_pn", "number", "%s", number);
377 if (number) if (number[0])
378 l += strlen((char *)number);
381 p[0] = IE_CALLING_PN;
384 p[2] = 0x00 + (type<<4) + plan;
385 p[3] = 0x80 + (present<<5) + screen;
386 if (number) if (number[0])
387 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
389 p[2] = 0x80 + (type<<4) + plan;
390 if (number) if (number[0])
391 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
393 add_layer3_ie(l3m, p[0], p[1], p+2);
395 /* second calling party number */
400 PERROR("type2(%d) is out of range.\n", type2);
403 if (plan2<0 || plan2>15) {
404 PERROR("plan2(%d) is out of range.\n", plan2);
408 PERROR("present2(%d) is out of range.\n", present2);
411 if (present2 >= 0) if (screen2<0 || screen2>3) {
412 PERROR("screen2(%d) is out of range.\n", screen2);
416 add_trace("call_pn 2", "type", "%d", type2);
417 add_trace("call_pn 2", "plan", "%d", plan2);
418 add_trace("call_pn 2", "present", "%d", present2);
419 add_trace("call_pn 2", "screen", "%d", screen2);
420 add_trace("call_pn 2", "number", "%s", number2);
423 if (number2) if (number2[0])
424 l += strlen((char *)number2);
427 p[0] = IE_CALLING_PN;
430 p[2] = 0x00 + (type2<<4) + plan2;
431 p[3] = 0x80 + (present2<<5) + screen2;
432 if (number2) if (number2[0])
433 UNCPY((char *)p+4, (char *)number2, strlen((char *)number2));
435 p[2] = 0x80 + (type2<<4) + plan2;
436 if (number2) if (number2[0])
437 UNCPY((char *)p+3, (char *)number2, strlen((char *)number2));
439 add_layer3_ie(l3m, p[0], p[1], p+2);
442 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)
454 unsigned int numextra = sizeof(l3m->extra) / sizeof(struct m_extie);
457 unsigned char *p = l3m->calling_nr;
461 add_trace("calling_pn", "error", "IE too short (len=%d)", p[0]);
465 *type = (p[1]&0x70) >> 4;
467 if (!(p[1] & 0x80)) {
469 add_trace("calling_pn", "error", "IE too short (len=%d)", p[0]);
472 *present = (p[2]&0x60) >> 5;
473 *screen = p[2] & 0x3;
474 strnncpy(number, p+3, p[0]-2, number_len);
476 strnncpy(number, p+2, p[0]-1, number_len);
479 add_trace("calling_pn", "type", "%d", *type);
480 add_trace("calling_pn", "plan", "%d", *plan);
481 add_trace("calling_pn", "present", "%d", *present);
482 add_trace("calling_pn", "screen", "%d", *screen);
483 add_trace("calling_pn", "number", "%s", number);
485 /* second calling party number */
488 while(i < numextra) {
489 if (!l3m->extra[i].val)
491 if (l3m->extra[i].ie == IE_CALLING_PN) {
492 p = l3m->extra[i].val;
500 add_trace("calling_pn2", "error", "IE too short (len=%d)", p[0]);
504 *type2 = (p[1]&0x70) >> 4;
506 if (!(p[1] & 0x80)) {
508 add_trace("calling_pn2", "error", "IE too short (len=%d)", p[0]);
511 *present2 = (p[2]&0x60) >> 5;
512 *screen2 = p[2] & 0x3;
513 strnncpy(number2, p+3, p[0]-2, number_len2);
515 strnncpy(number2, p+2, p[0]-1, number_len2);
518 add_trace("call_pn 2", "type", "%d", *type2);
519 add_trace("call_pn 2", "plan", "%d", *plan2);
520 add_trace("call_pn 2", "present", "%d", *present2);
521 add_trace("call_pn 2", "screen", "%d", *screen2);
522 add_trace("call_pn 2", "number", "%s", number2);
526 /* IE_CONNECTED_PN */
527 void Pdss1::enc_ie_connected_pn(struct l3_msg *l3m, int type, int plan, int present, int screen, unsigned char *number)
529 unsigned char p[256];
532 if (type<0 || type>7) {
533 PERROR("type(%d) is out of range.\n", type);
536 if (plan<0 || plan>15) {
537 PERROR("plan(%d) is out of range.\n", plan);
541 PERROR("present(%d) is out of range.\n", present);
544 if (present >= 0) if (screen<0 || screen>3) {
545 PERROR("screen(%d) is out of range.\n", screen);
549 add_trace("connect_pn", "type", "%d", type);
550 add_trace("connect_pn", "plan", "%d", plan);
551 add_trace("connect_pn", "present", "%d", present);
552 add_trace("connect_pn", "screen", "%d", screen);
553 add_trace("connect_pn", "number", "%s", number);
556 if (number) if (number[0])
557 l += strlen((char *)number);
560 p[0] = IE_CONNECT_PN;
563 p[2] = 0x00 + (type<<4) + plan;
564 p[3] = 0x80 + (present<<5) + screen;
565 if (number) if (number[0])
566 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
568 p[2] = 0x80 + (type<<4) + plan;
569 if (number) if (number[0])
570 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
572 add_layer3_ie(l3m, p[0], p[1], p+2);
575 void Pdss1::dec_ie_connected_pn(struct l3_msg *l3m, int *type, int *plan, int *present, int *screen, unsigned char *number, int number_len)
583 unsigned char *p = l3m->connected_nr;
587 add_trace("connect_pn", "error", "IE too short (len=%d)", p[0]);
591 *type = (p[1]&0x70) >> 4;
593 if (!(p[1] & 0x80)) {
595 add_trace("connect_pn", "error", "IE too short (len=%d)", p[0]);
598 *present = (p[2]&0x60) >> 5;
599 *screen = p[2] & 0x3;
600 strnncpy(number, p+3, p[0]-2, number_len);
602 strnncpy(number, p+2, p[0]-1, number_len);
605 add_trace("connect_pn", "type", "%d", *type);
606 add_trace("connect_pn", "plan", "%d", *plan);
607 add_trace("connect_pn", "present", "%d", *present);
608 add_trace("connect_pn", "screen", "%d", *screen);
609 add_trace("connect_pn", "number", "%s", number);
614 void Pdss1::enc_ie_cause(struct l3_msg *l3m, int location, int cause)
616 unsigned char p[256];
619 if (location<0 || location>7) {
620 PERROR("location(%d) is out of range.\n", location);
623 if (cause<0 || cause>127) {
624 PERROR("cause(%d) is out of range.\n", cause);
628 add_trace("cause", "location", "%d", location);
629 add_trace("cause", "value", "%d", cause);
634 p[2] = 0x80 + location;
636 add_layer3_ie(l3m, p[0], p[1], p+2);
638 void enc_ie_cause_standalone(struct l3_msg *l3m, int location, int cause)
640 unsigned char p[256];
643 p[2] = 0x80 + location;
645 add_layer3_ie(l3m, p[0], p[1], p+2);
649 void Pdss1::dec_ie_cause(struct l3_msg *l3m, int *location, int *cause)
654 unsigned char *p = l3m->cause;
658 add_trace("cause", "error", "IE too short (len=%d)", p[0]);
662 *location = p[1] & 0x0f;
663 *cause = p[2] & 0x7f;
665 add_trace("cause", "location", "%d", *location);
666 add_trace("cause", "value", "%d", *cause);
671 void Pdss1::enc_ie_channel_id(struct l3_msg *l3m, int exclusive, int channel)
673 unsigned char p[256];
675 int pri = p_m_mISDNport->pri;
677 if (exclusive<0 || exclusive>1) {
678 PERROR("exclusive(%d) is out of range.\n", exclusive);
681 if ((channel<=0 && channel!=CHANNEL_NO && channel!=CHANNEL_ANY)
682 || (!pri && channel>2)
683 || (pri && channel>127)
684 || (pri && channel==16)) {
685 PERROR("channel(%d) is out of range.\n", channel);
689 add_trace("channel_id", "exclusive", "%d", exclusive);
692 add_trace("channel_id", "channel", "any channel");
695 add_trace("channel_id", "channel", "no channel");
698 add_trace("channel_id", "channel", "%d", channel);
704 p[0] = IE_CHANNEL_ID;
706 if (channel == CHANNEL_NO)
708 else if (channel == CHANNEL_ANY)
710 p[2] = 0x80 + (exclusive<<3) + channel;
711 add_layer3_ie(l3m, p[0], p[1], p+2);
714 if (channel == CHANNEL_NO) /* no channel */
715 return; /* IE not present */
716 if (channel == CHANNEL_ANY) /* any channel */ {
718 p[0] = IE_CHANNEL_ID;
720 p[2] = 0x80 + 0x20 + 0x03;
721 add_layer3_ie(l3m, p[0], p[1], p+2);
725 p[0] = IE_CHANNEL_ID;
727 p[2] = 0x80 + 0x20 + (exclusive<<3) + 0x01;
728 p[3] = 0x80 + 3; /* CCITT, Number, B-type */
729 p[4] = 0x80 + channel;
730 add_layer3_ie(l3m, p[0], p[1], p+2);
734 void Pdss1::dec_ie_channel_id(struct l3_msg *l3m, int *exclusive, int *channel)
736 int pri = p_m_mISDNport->pri;
741 unsigned char *p = l3m->channel_id;
745 add_trace("channel_id", "error", "IE too short (len=%d)", p[0]);
750 add_trace("channel_id", "error", "refering to channels of other interfaces is not supported");
754 add_trace("channel_id", "error", "using d-channel is not supported");
758 *exclusive = (p[1]&0x08) >> 3;
762 add_trace("channel_id", "error", "extended channel ID with non PRI interface");
765 *channel = p[1] & 0x03;
767 *channel = CHANNEL_ANY;
768 else if (*channel == 0)
769 *channel = CHANNEL_NO;
774 add_trace("channel_id", "error", "IE too short for PRI (len=%d)", p[0]);
777 if (!(p[1] & 0x20)) {
778 add_trace("channel_id", "error", "basic channel ID with PRI interface");
781 if ((p[1]&0x03) == 0x00) {
783 *channel = CHANNEL_NO;
786 if ((p[1]&0x03) == 0x03) {
788 *channel = CHANNEL_ANY;
792 add_trace("channel_id", "error", "IE too short for PRI with channel (len=%d)", p[0]);
796 add_trace("channel_id", "error", "channel map not supported");
799 *channel = p[3] & 0x7f;
800 if ((*channel<1) || (*channel==16)) {
801 add_trace("channel_id", "error", "PRI interface channel out of range (%d)", *channel);
806 add_trace("channel_id", "exclusive", "%d", *exclusive);
809 add_trace("channel_id", "channel", "any channel");
812 add_trace("channel_id", "channel", "no channel");
815 add_trace("channel_id", "channel", "%d", *channel);
821 void Pdss1::enc_ie_date(struct l3_msg *l3m, time_t ti, int no_seconds)
823 unsigned char p[256];
830 PERROR("localtime() returned NULL.\n");
834 add_trace("date", "day", "%d.%d.%d", tm->tm_mday, tm->tm_mon+1, tm->tm_year%100);
835 add_trace("date", "time", "%d:%d:%d", tm->tm_hour, tm->tm_min, tm->tm_sec);
837 l = 5 + (!no_seconds);
840 p[2] = tm->tm_year % 100;
841 p[3] = tm->tm_mon + 1;
847 add_layer3_ie(l3m, p[0], p[1], p+2);
852 void Pdss1::enc_ie_display(struct l3_msg *l3m, unsigned char *display)
854 unsigned char p[256];
858 PERROR("display text not given.\n");
862 if (strlen((char *)display) > 80) {
863 PERROR("display text too long (max 80 chars), cutting.\n");
867 add_trace("display", NULL, "%s", display);
869 l = strlen((char *)display);
872 UNCPY((char *)p+2, (char *)display, strlen((char *)display));
873 add_layer3_ie(l3m, p[0], p[1], p+2);
876 void Pdss1::dec_ie_display(struct l3_msg *l3m, unsigned char *display, int display_len)
880 unsigned char *p = l3m->display;
884 add_trace("display", "error", "IE too short (len=%d)", p[0]);
888 strnncpy(display, p+1, p[0], display_len);
890 add_trace("display", NULL, "%s", display);
895 void Pdss1::enc_ie_keypad(struct l3_msg *l3m, unsigned char *keypad)
897 unsigned char p[256];
901 PERROR("keypad info not given.\n");
905 add_trace("keypad", NULL, "%s", keypad);
907 l = strlen((char *)keypad);
910 UNCPY((char *)p+2, (char *)keypad, strlen((char *)keypad));
911 add_layer3_ie(l3m, p[0], p[1], p+2);
914 void Pdss1::dec_ie_keypad(struct l3_msg *l3m, unsigned char *keypad, int keypad_len)
918 unsigned char *p = l3m->keypad;
922 add_trace("keypad", "error", "IE too short (len=%d)", p[0]);
926 strnncpy(keypad, p+1, p[0], keypad_len);
928 add_trace("keypad", NULL, "%s", keypad);
933 void Pdss1::enc_ie_notify(struct l3_msg *l3m, int notify)
935 unsigned char p[256];
938 if (notify<0 || notify>0x7f) {
939 PERROR("notify(%d) is out of range.\n", notify);
943 add_trace("notify", NULL, "%d", notify);
948 p[2] = 0x80 + notify;
949 add_layer3_ie(l3m, p[0], p[1], p+2);
952 void Pdss1::dec_ie_notify(struct l3_msg *l3m, int *notify)
956 unsigned char *p = l3m->notify;
960 add_trace("notify", "error", "IE too short (len=%d)", p[0]);
964 *notify = p[1] & 0x7f;
966 add_trace("notify", NULL, "%d", *notify);
971 void Pdss1::enc_ie_progress(struct l3_msg *l3m, int coding, int location, int progress)
973 unsigned char p[256];
976 if (coding<0 || coding>0x03) {
977 PERROR("coding(%d) is out of range.\n", coding);
980 if (location<0 || location>0x0f) {
981 PERROR("location(%d) is out of range.\n", location);
984 if (progress<0 || progress>0x7f) {
985 PERROR("progress(%d) is out of range.\n", progress);
989 add_trace("progress", "codeing", "%d", coding);
990 add_trace("progress", "location", "%d", location);
991 add_trace("progress", "indicator", "%d", progress);
996 p[2] = 0x80 + (coding<<5) + location;
997 p[3] = 0x80 + progress;
998 add_layer3_ie(l3m, p[0], p[1], p+2);
1001 void Pdss1::dec_ie_progress(struct l3_msg *l3m, int *coding, int *location, int *progress)
1007 unsigned char *p = l3m->progress;
1011 add_trace("progress", "error", "IE too short (len=%d)", p[0]);
1015 *coding = (p[1]&0x60) >> 5;
1016 *location = p[1] & 0x0f;
1017 *progress = p[2] & 0x7f;
1019 add_trace("progress", "codeing", "%d", *coding);
1020 add_trace("progress", "location", "%d", *location);
1021 add_trace("progress", "indicator", "%d", *progress);
1025 /* IE_REDIR_NR (redirecting = during MT_SETUP) */
1026 void Pdss1::enc_ie_redir_nr(struct l3_msg *l3m, int type, int plan, int present, int screen, int reason, unsigned char *number)
1028 unsigned char p[256];
1031 if (type<0 || type>7) {
1032 PERROR("type(%d) is out of range.\n", type);
1035 if (plan<0 || plan>15) {
1036 PERROR("plan(%d) is out of range.\n", plan);
1040 PERROR("present(%d) is out of range.\n", present);
1043 if (present >= 0) if (screen<0 || screen>3) {
1044 PERROR("screen(%d) is out of range.\n", screen);
1047 if (reason > 0x0f) {
1048 PERROR("reason(%d) is out of range.\n", reason);
1052 add_trace("redir'ing", "type", "%d", type);
1053 add_trace("redir'ing", "plan", "%d", plan);
1054 add_trace("redir'ing", "present", "%d", present);
1055 add_trace("redir'ing", "screen", "%d", screen);
1056 add_trace("redir'ing", "reason", "%d", reason);
1057 add_trace("redir'ing", "number", "%s", number);
1061 l += strlen((char *)number);
1071 p[2] = 0x00 + (type<<4) + plan;
1072 p[3] = 0x00 + (present<<5) + screen;
1073 p[4] = 0x80 + reason;
1075 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));
1083 p[2] = 0x80 + (type<<4) + plan;
1084 if (number) if (number[0])
1085 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
1087 add_layer3_ie(l3m, p[0], p[1], p+2);
1090 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)
1099 unsigned char *p = l3m->redirect_nr;
1103 add_trace("redir'ing", "error", "IE too short (len=%d)", p[0]);
1107 *type = (p[1]&0x70) >> 4;
1109 if (!(p[1] & 0x80)) {
1110 *present = (p[2]&0x60) >> 5;
1111 *screen = p[2] & 0x3;
1112 if (!(p[2] & 0x80)) {
1113 *reason = p[3] & 0x0f;
1114 strnncpy(number, p+4, p[0]-3, number_len);
1116 strnncpy(number, p+3, p[0]-2, number_len);
1119 strnncpy(number, p+2, p[0]-1, number_len);
1122 add_trace("redir'ing", "type", "%d", *type);
1123 add_trace("redir'ing", "plan", "%d", *plan);
1124 add_trace("redir'ing", "present", "%d", *present);
1125 add_trace("redir'ing", "screen", "%d", *screen);
1126 add_trace("redir'ing", "reason", "%d", *reason);
1127 add_trace("redir'ing", "number", "%s", number);
1131 /* IE_REDIR_DN (redirection = during MT_NOTIFY) */
1132 void Pdss1::enc_ie_redir_dn(struct l3_msg *l3m, int type, int plan, int present, unsigned char *number)
1134 unsigned char p[256];
1137 if (type<0 || type>7) {
1138 PERROR("type(%d) is out of range.\n", type);
1141 if (plan<0 || plan>15) {
1142 PERROR("plan(%d) is out of range.\n", plan);
1146 PERROR("present(%d) is out of range.\n", present);
1150 add_trace("redir'tion", "type", "%d", type);
1151 add_trace("redir'tion", "plan", "%d", plan);
1152 add_trace("redir'tion", "present", "%d", present);
1153 add_trace("redir'tion", "number", "%s", number);
1157 l += strlen((char *)number);
1163 p[2] = 0x00 + (type<<4) + plan;
1164 p[3] = 0x80 + (present<<5);
1166 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
1168 p[2] = 0x80 + (type<<4) + plan;
1170 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
1172 add_layer3_ie(l3m, p[0], p[1], p+2);
1175 void Pdss1::dec_ie_redir_dn(struct l3_msg *l3m, int *type, int *plan, int *present, unsigned char *number, int number_len)
1182 unsigned char *p = l3m->redirect_dn;
1186 add_trace("redir'tion", "error", "IE too short (len=%d)", p[0]);
1190 *type = (p[1]&0x70) >> 4;
1192 if (!(p[1] & 0x80)) {
1193 *present = (p[2]&0x60) >> 5;
1194 strnncpy(number, p+3, p[0]-2, number_len);
1196 strnncpy(number, p+2, p[0]-1, number_len);
1199 add_trace("redir'tion", "type", "%d", *type);
1200 add_trace("redir'tion", "plan", "%d", *plan);
1201 add_trace("redir'tion", "present", "%d", *present);
1202 add_trace("redir'tion", "number", "%s", number);
1207 void Pdss1::enc_ie_facility(struct l3_msg *l3m, unsigned char *facility, int facility_len)
1209 unsigned char p[256];
1215 if (!facility || facility_len<=0) {
1220 while(i < facility_len) {
1221 UPRINT(buffer+(i*3), " %02x", facility[i]);
1225 add_trace("facility", NULL, "%s", buffer+1);
1230 memcpy(p+2, facility, facility_len);
1231 add_layer3_ie(l3m, p[0], p[1], p+2);
1234 void Pdss1::dec_ie_facility(struct l3_msg *l3m, unsigned char *facility, int *facility_len)
1241 unsigned char *p = l3m->facility;
1245 *facility_len = p[0];
1246 memcpy(facility, p+1, *facility_len);
1249 while(i < *facility_len) {
1250 UPRINT(debug+(i*3), " %02x", facility[i]);
1255 add_trace("facility", NULL, "%s", debug[0]?debug+1:"<none>");
1259 void Pdss1::dec_facility_centrex(struct l3_msg *l3m, unsigned char *cnip, int cnip_len)
1261 unsigned char centrex[256];
1263 int facility_len = 0;
1267 dec_ie_facility(l3m, centrex, &facility_len);
1268 if (facility_len >= 2) {
1269 if (centrex[i++] != CENTREX_FAC)
1271 if (centrex[i++] != CENTREX_ID)
1275 /* loop sub IEs of facility */
1276 while(facility_len > i+1) {
1277 if (centrex[i+1]+i+1 > facility_len) {
1278 PERROR("short read of centrex facility.\n");
1281 switch(centrex[i]) {
1283 strnncpy(cnip, ¢rex[i+2], centrex[i+1], cnip_len);
1284 add_trace("facility", "cnip", "%s", cnip);
1289 while(j < centrex[i+1]) {
1290 UPRINT(debug+(j*3), " %02x", centrex[i+1+j]);
1293 add_trace("facility", "CENTREX", "unknown=0x%02x len=%d%s\n", centrex[i], centrex[i+1], debug);
1295 i += 1+centrex[i+1];
1301 void Pdss1::enc_ie_useruser(struct l3_msg *l3m, int protocol, unsigned char *user, int user_len)
1303 unsigned char p[256];
1309 if (protocol<0 || protocol>127) {
1310 PERROR("protocol(%d) is out of range.\n", protocol);
1313 if (!user || user_len<=0) {
1318 while(i < user_len) {
1319 UPRINT(buffer+(i*3), " %02x", user[i]);
1323 add_trace("useruser", "protocol", "%d", protocol);
1324 add_trace("useruser", "value", "%s", buffer);
1327 p[0] = IE_USER_USER;
1329 p[2] = 0x80 + protocol;
1330 memcpy(p+3, user, user_len);
1331 add_layer3_ie(l3m, p[0], p[1], p+2);
1334 void Pdss1::dec_ie_useruser(struct l3_msg *l3m, int *protocol, unsigned char *user, int *user_len)
1342 unsigned char *p = l3m->useruser;
1350 memcpy(user, p+2, (*user_len<=128)?*(user_len):128); /* clip to 128 maximum */
1353 while(i < *user_len) {
1354 UPRINT(buffer+(i*3), " %02x", user[i]);
1359 add_trace("useruser", "protocol", "%d", *protocol);
1360 add_trace("useruser", "value", "%s", buffer);