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, int number_len)
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 UNCPY((char *)p, (char *)number, number_len);
341 p[number_len] = '\0';
342 add_trace("called_pn", "number", "%s", p);
347 p[2] = 0x80 + (type<<4) + plan;
348 UNCPY((char *)p+3, (char *)number, number_len);
349 add_layer3_ie(l3m, p[0], p[1], p+2);
352 void Pdss1::dec_ie_called_pn(struct l3_msg *l3m, int *type, int *plan, unsigned char *number, int number_len)
358 unsigned char *p = l3m->called_nr;
363 add_trace("called_pn", "error", "IE too short (len=%d)", p[0]);
367 *type = (p[1]&0x70) >> 4;
369 strnncpy(number, p+2, p[0]-1, number_len);
371 add_trace("called_pn", "type", "%d", *type);
372 add_trace("called_pn", "plan", "%d", *plan);
373 add_trace("called_pn", "number", "%s", number);
378 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)
380 unsigned char p[256];
383 if (type<0 || type>7)
385 PERROR("type(%d) is out of range.\n", type);
388 if (plan<0 || plan>15)
390 PERROR("plan(%d) is out of range.\n", plan);
395 PERROR("present(%d) is out of range.\n", present);
398 if (present >= 0) if (screen<0 || screen>3)
400 PERROR("screen(%d) is out of range.\n", screen);
404 add_trace("calling_pn", "type", "%d", type);
405 add_trace("calling_pn", "plan", "%d", plan);
406 add_trace("calling_pn", "present", "%d", present);
407 add_trace("calling_pn", "screen", "%d", screen);
408 add_trace("calling_pn", "number", "%s", number);
411 if (number) if (number[0])
412 l += strlen((char *)number);
415 p[0] = IE_CALLING_PN;
419 p[2] = 0x00 + (type<<4) + plan;
420 p[3] = 0x80 + (present<<5) + screen;
421 if (number) if (number[0])
422 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
425 p[2] = 0x80 + (type<<4) + plan;
426 if (number) if (number[0])
427 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
429 add_layer3_ie(l3m, p[0], p[1], p+2);
431 /* second calling party number */
437 PERROR("type2(%d) is out of range.\n", type2);
440 if (plan2<0 || plan2>15)
442 PERROR("plan2(%d) is out of range.\n", plan2);
447 PERROR("present2(%d) is out of range.\n", present2);
450 if (present2 >= 0) if (screen2<0 || screen2>3)
452 PERROR("screen2(%d) is out of range.\n", screen2);
456 add_trace("call_pn 2", "type", "%d", type2);
457 add_trace("call_pn 2", "plan", "%d", plan2);
458 add_trace("call_pn 2", "present", "%d", present2);
459 add_trace("call_pn 2", "screen", "%d", screen2);
460 add_trace("call_pn 2", "number", "%s", number2);
463 if (number2) if (number2[0])
464 l += strlen((char *)number2);
467 p[0] = IE_CALLING_PN;
471 p[2] = 0x00 + (type2<<4) + plan2;
472 p[3] = 0x80 + (present2<<5) + screen2;
473 if (number2) if (number2[0])
474 UNCPY((char *)p+4, (char *)number2, strlen((char *)number2));
477 p[2] = 0x80 + (type2<<4) + plan2;
478 if (number2) if (number2[0])
479 UNCPY((char *)p+3, (char *)number2, strlen((char *)number2));
481 add_layer3_ie(l3m, p[0], p[1], p+2);
484 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)
496 unsigned int numextra = sizeof(l3m->extra) / sizeof(struct m_extie);
499 unsigned char *p = l3m->calling_nr;
504 add_trace("calling_pn", "error", "IE too short (len=%d)", p[0]);
508 *type = (p[1]&0x70) >> 4;
514 add_trace("calling_pn", "error", "IE too short (len=%d)", p[0]);
517 *present = (p[2]&0x60) >> 5;
518 *screen = p[2] & 0x3;
519 strnncpy(number, p+3, p[0]-2, number_len);
522 strnncpy(number, p+2, p[0]-1, number_len);
525 add_trace("calling_pn", "type", "%d", *type);
526 add_trace("calling_pn", "plan", "%d", *plan);
527 add_trace("calling_pn", "present", "%d", *present);
528 add_trace("calling_pn", "screen", "%d", *screen);
529 add_trace("calling_pn", "number", "%s", number);
531 /* second calling party number */
536 if (!l3m->extra[i].val)
538 if (l3m->extra[i].ie == IE_CALLING_PN)
540 p = l3m->extra[i].val;
549 add_trace("calling_pn2", "error", "IE too short (len=%d)", p[0]);
553 *type2 = (p[1]&0x70) >> 4;
559 add_trace("calling_pn2", "error", "IE too short (len=%d)", p[0]);
562 *present2 = (p[2]&0x60) >> 5;
563 *screen2 = p[2] & 0x3;
564 strnncpy(number2, p+3, p[0]-2, number_len2);
567 strnncpy(number2, p+2, p[0]-1, number_len2);
570 add_trace("call_pn 2", "type", "%d", *type2);
571 add_trace("call_pn 2", "plan", "%d", *plan2);
572 add_trace("call_pn 2", "present", "%d", *present2);
573 add_trace("call_pn 2", "screen", "%d", *screen2);
574 add_trace("call_pn 2", "number", "%s", number2);
578 /* IE_CONNECTED_PN */
579 void Pdss1::enc_ie_connected_pn(struct l3_msg *l3m, int type, int plan, int present, int screen, unsigned char *number)
581 unsigned char p[256];
584 if (type<0 || type>7)
586 PERROR("type(%d) is out of range.\n", type);
589 if (plan<0 || plan>15)
591 PERROR("plan(%d) is out of range.\n", plan);
596 PERROR("present(%d) is out of range.\n", present);
599 if (present >= 0) if (screen<0 || screen>3)
601 PERROR("screen(%d) is out of range.\n", screen);
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);
612 if (number) if (number[0])
613 l += strlen((char *)number);
616 p[0] = IE_CONNECT_PN;
620 p[2] = 0x00 + (type<<4) + plan;
621 p[3] = 0x80 + (present<<5) + screen;
622 if (number) if (number[0])
623 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
626 p[2] = 0x80 + (type<<4) + plan;
627 if (number) if (number[0])
628 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
630 add_layer3_ie(l3m, p[0], p[1], p+2);
633 void Pdss1::dec_ie_connected_pn(struct l3_msg *l3m, int *type, int *plan, int *present, int *screen, unsigned char *number, int number_len)
641 unsigned char *p = l3m->connected_nr;
646 add_trace("connect_pn", "error", "IE too short (len=%d)", p[0]);
650 *type = (p[1]&0x70) >> 4;
656 add_trace("connect_pn", "error", "IE too short (len=%d)", p[0]);
659 *present = (p[2]&0x60) >> 5;
660 *screen = p[2] & 0x3;
661 strnncpy(number, p+3, p[0]-2, number_len);
664 strnncpy(number, p+2, p[0]-1, number_len);
667 add_trace("connect_pn", "type", "%d", *type);
668 add_trace("connect_pn", "plan", "%d", *plan);
669 add_trace("connect_pn", "present", "%d", *present);
670 add_trace("connect_pn", "screen", "%d", *screen);
671 add_trace("connect_pn", "number", "%s", number);
676 void Pdss1::enc_ie_cause(struct l3_msg *l3m, int location, int cause)
678 unsigned char p[256];
681 if (location<0 || location>7)
683 PERROR("location(%d) is out of range.\n", location);
686 if (cause<0 || cause>127)
688 PERROR("cause(%d) is out of range.\n", cause);
692 add_trace("cause", "location", "%d", location);
693 add_trace("cause", "value", "%d", cause);
698 p[2] = 0x80 + location;
700 add_layer3_ie(l3m, p[0], p[1], p+2);
702 void enc_ie_cause_standalone(struct l3_msg *l3m, int location, int cause)
704 unsigned char p[256];
707 p[2] = 0x80 + location;
709 add_layer3_ie(l3m, p[0], p[1], p+2);
713 void Pdss1::dec_ie_cause(struct l3_msg *l3m, int *location, int *cause)
718 unsigned char *p = l3m->cause;
723 add_trace("cause", "error", "IE too short (len=%d)", p[0]);
727 *location = p[1] & 0x0f;
728 *cause = p[2] & 0x7f;
730 add_trace("cause", "location", "%d", *location);
731 add_trace("cause", "value", "%d", *cause);
736 void Pdss1::enc_ie_channel_id(struct l3_msg *l3m, int exclusive, int channel)
738 unsigned char p[256];
740 int pri = p_m_mISDNport->pri;
742 if (exclusive<0 || exclusive>1)
744 PERROR("exclusive(%d) is out of range.\n", exclusive);
747 if ((channel<=0 && channel!=CHANNEL_NO && channel!=CHANNEL_ANY)
748 || (!pri && channel>2)
749 || (pri && channel>127)
750 || (pri && channel==16))
752 PERROR("channel(%d) is out of range.\n", channel);
756 add_trace("channel_id", "exclusive", "%d", exclusive);
760 add_trace("channel_id", "channel", "any channel");
763 add_trace("channel_id", "channel", "no channel");
766 add_trace("channel_id", "channel", "%d", channel);
773 p[0] = IE_CHANNEL_ID;
775 if (channel == CHANNEL_NO)
777 else if (channel == CHANNEL_ANY)
779 p[2] = 0x80 + (exclusive<<3) + channel;
780 add_layer3_ie(l3m, p[0], p[1], p+2);
784 if (channel == CHANNEL_NO) /* no channel */
785 return; /* IE not present */
786 if (channel == CHANNEL_ANY) /* any channel */
789 p[0] = IE_CHANNEL_ID;
791 p[2] = 0x80 + 0x20 + 0x03;
792 add_layer3_ie(l3m, p[0], p[1], p+2);
796 p[0] = IE_CHANNEL_ID;
798 p[2] = 0x80 + 0x20 + (exclusive<<3) + 0x01;
799 p[3] = 0x80 + 3; /* CCITT, Number, B-type */
800 p[4] = 0x80 + channel;
801 add_layer3_ie(l3m, p[0], p[1], p+2);
805 void Pdss1::dec_ie_channel_id(struct l3_msg *l3m, int *exclusive, int *channel)
807 int pri = p_m_mISDNport->pri;
812 unsigned char *p = l3m->channel_id;
817 add_trace("channel_id", "error", "IE too short (len=%d)", p[0]);
823 add_trace("channel_id", "error", "refering to channels of other interfaces is not supported");
828 add_trace("channel_id", "error", "using d-channel is not supported");
832 *exclusive = (p[1]&0x08) >> 3;
838 add_trace("channel_id", "error", "extended channel ID with non PRI interface");
841 *channel = p[1] & 0x03;
843 *channel = CHANNEL_ANY;
844 else if (*channel == 0)
845 *channel = CHANNEL_NO;
852 add_trace("channel_id", "error", "IE too short for PRI (len=%d)", p[0]);
857 add_trace("channel_id", "error", "basic channel ID with PRI interface");
860 if ((p[1]&0x03) == 0x00)
863 *channel = CHANNEL_NO;
866 if ((p[1]&0x03) == 0x03)
869 *channel = CHANNEL_ANY;
874 add_trace("channel_id", "error", "IE too short for PRI with channel (len=%d)", p[0]);
879 add_trace("channel_id", "error", "channel map not supported");
882 *channel = p[3] & 0x7f;
883 if ((*channel<1) || (*channel==16))
885 add_trace("channel_id", "error", "PRI interface channel out of range (%d)", *channel);
890 add_trace("channel_id", "exclusive", "%d", *exclusive);
894 add_trace("channel_id", "channel", "any channel");
897 add_trace("channel_id", "channel", "no channel");
900 add_trace("channel_id", "channel", "%d", *channel);
906 void Pdss1::enc_ie_date(struct l3_msg *l3m, time_t ti, int no_seconds)
908 unsigned char p[256];
916 PERROR("localtime() returned NULL.\n");
920 add_trace("date", "day", "%d.%d.%d", tm->tm_mday, tm->tm_mon+1, tm->tm_year%100);
921 add_trace("date", "time", "%d:%d:%d", tm->tm_hour, tm->tm_min, tm->tm_sec);
923 l = 5 + (!no_seconds);
926 p[2] = tm->tm_year % 100;
927 p[3] = tm->tm_mon + 1;
933 add_layer3_ie(l3m, p[0], p[1], p+2);
938 void Pdss1::enc_ie_display(struct l3_msg *l3m, unsigned char *display)
940 unsigned char p[256];
945 PERROR("display text not given.\n");
949 if (strlen((char *)display) > 80)
951 PERROR("display text too long (max 80 chars), cutting.\n");
955 add_trace("display", NULL, "%s", display);
957 l = strlen((char *)display);
960 UNCPY((char *)p+2, (char *)display, strlen((char *)display));
961 add_layer3_ie(l3m, p[0], p[1], p+2);
964 void Pdss1::dec_ie_display(struct l3_msg *l3m, unsigned char *display, int display_len)
968 unsigned char *p = l3m->display;
973 add_trace("display", "error", "IE too short (len=%d)", p[0]);
977 strnncpy(display, p+1, p[0], display_len);
979 add_trace("display", NULL, "%s", display);
984 void Pdss1::enc_ie_keypad(struct l3_msg *l3m, unsigned char *keypad)
986 unsigned char p[256];
991 PERROR("keypad info not given.\n");
995 add_trace("keypad", NULL, "%s", keypad);
997 l = strlen((char *)keypad);
1000 UNCPY((char *)p+2, (char *)keypad, strlen((char *)keypad));
1001 add_layer3_ie(l3m, p[0], p[1], p+2);
1004 void Pdss1::dec_ie_keypad(struct l3_msg *l3m, unsigned char *keypad, int keypad_len)
1008 unsigned char *p = l3m->keypad;
1013 add_trace("keypad", "error", "IE too short (len=%d)", p[0]);
1017 strnncpy(keypad, p+1, p[0], keypad_len);
1019 add_trace("keypad", NULL, "%s", keypad);
1024 void Pdss1::enc_ie_notify(struct l3_msg *l3m, int notify)
1026 unsigned char p[256];
1029 if (notify<0 || notify>0x7f)
1031 PERROR("notify(%d) is out of range.\n", notify);
1035 add_trace("notify", NULL, "%d", notify);
1040 p[2] = 0x80 + notify;
1041 add_layer3_ie(l3m, p[0], p[1], p+2);
1044 void Pdss1::dec_ie_notify(struct l3_msg *l3m, int *notify)
1048 unsigned char *p = l3m->notify;
1053 add_trace("notify", "error", "IE too short (len=%d)", p[0]);
1057 *notify = p[1] & 0x7f;
1059 add_trace("notify", NULL, "%d", *notify);
1064 void Pdss1::enc_ie_progress(struct l3_msg *l3m, int coding, int location, int progress)
1066 unsigned char p[256];
1069 if (coding<0 || coding>0x03)
1071 PERROR("coding(%d) is out of range.\n", coding);
1074 if (location<0 || location>0x0f)
1076 PERROR("location(%d) is out of range.\n", location);
1079 if (progress<0 || progress>0x7f)
1081 PERROR("progress(%d) is out of range.\n", progress);
1085 add_trace("progress", "codeing", "%d", coding);
1086 add_trace("progress", "location", "%d", location);
1087 add_trace("progress", "indicator", "%d", progress);
1092 p[2] = 0x80 + (coding<<5) + location;
1093 p[3] = 0x80 + progress;
1094 add_layer3_ie(l3m, p[0], p[1], p+2);
1097 void Pdss1::dec_ie_progress(struct l3_msg *l3m, int *coding, int *location, int *progress)
1103 unsigned char *p = l3m->progress;
1108 add_trace("progress", "error", "IE too short (len=%d)", p[0]);
1112 *coding = (p[1]&0x60) >> 5;
1113 *location = p[1] & 0x0f;
1114 *progress = p[2] & 0x7f;
1116 add_trace("progress", "codeing", "%d", *coding);
1117 add_trace("progress", "location", "%d", *location);
1118 add_trace("progress", "indicator", "%d", *progress);
1122 /* IE_REDIR_NR (redirecting = during MT_SETUP) */
1123 void Pdss1::enc_ie_redir_nr(struct l3_msg *l3m, int type, int plan, int present, int screen, int reason, unsigned char *number)
1125 unsigned char p[256];
1128 if (type<0 || type>7)
1130 PERROR("type(%d) is out of range.\n", type);
1133 if (plan<0 || plan>15)
1135 PERROR("plan(%d) is out of range.\n", plan);
1140 PERROR("present(%d) is out of range.\n", present);
1143 if (present >= 0) if (screen<0 || screen>3)
1145 PERROR("screen(%d) is out of range.\n", screen);
1150 PERROR("reason(%d) is out of range.\n", reason);
1154 add_trace("redir'ing", "type", "%d", type);
1155 add_trace("redir'ing", "plan", "%d", plan);
1156 add_trace("redir'ing", "present", "%d", present);
1157 add_trace("redir'ing", "screen", "%d", screen);
1158 add_trace("redir'ing", "reason", "%d", reason);
1159 add_trace("redir'ing", "number", "%s", number);
1163 l += strlen((char *)number);
1176 p[2] = 0x00 + (type<<4) + plan;
1177 p[3] = 0x00 + (present<<5) + screen;
1178 p[4] = 0x80 + reason;
1180 UNCPY((char *)p+5, (char *)number, strlen((char *)number));
1183 p[2] = 0x00 + (type<<4) + plan;
1184 p[3] = 0x80 + (present<<5) + screen;
1186 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
1190 p[2] = 0x80 + (type<<4) + plan;
1191 if (number) if (number[0])
1192 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
1194 add_layer3_ie(l3m, p[0], p[1], p+2);
1197 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)
1206 unsigned char *p = l3m->redirect_nr;
1211 add_trace("redir'ing", "error", "IE too short (len=%d)", p[0]);
1215 *type = (p[1]&0x70) >> 4;
1219 *present = (p[2]&0x60) >> 5;
1220 *screen = p[2] & 0x3;
1223 *reason = p[3] & 0x0f;
1224 strnncpy(number, p+4, p[0]-3, number_len);
1227 strnncpy(number, p+3, p[0]-2, number_len);
1231 strnncpy(number, p+2, p[0]-1, number_len);
1234 add_trace("redir'ing", "type", "%d", *type);
1235 add_trace("redir'ing", "plan", "%d", *plan);
1236 add_trace("redir'ing", "present", "%d", *present);
1237 add_trace("redir'ing", "screen", "%d", *screen);
1238 add_trace("redir'ing", "reason", "%d", *reason);
1239 add_trace("redir'ing", "number", "%s", number);
1243 /* IE_REDIR_DN (redirection = during MT_NOTIFY) */
1244 void Pdss1::enc_ie_redir_dn(struct l3_msg *l3m, int type, int plan, int present, unsigned char *number)
1246 unsigned char p[256];
1249 if (type<0 || type>7)
1251 PERROR("type(%d) is out of range.\n", type);
1254 if (plan<0 || plan>15)
1256 PERROR("plan(%d) is out of range.\n", plan);
1261 PERROR("present(%d) is out of range.\n", present);
1265 add_trace("redir'tion", "type", "%d", type);
1266 add_trace("redir'tion", "plan", "%d", plan);
1267 add_trace("redir'tion", "present", "%d", present);
1268 add_trace("redir'tion", "number", "%s", number);
1272 l += strlen((char *)number);
1279 p[2] = 0x00 + (type<<4) + plan;
1280 p[3] = 0x80 + (present<<5);
1282 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
1285 p[2] = 0x80 + (type<<4) + plan;
1287 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
1289 add_layer3_ie(l3m, p[0], p[1], p+2);
1292 void Pdss1::dec_ie_redir_dn(struct l3_msg *l3m, int *type, int *plan, int *present, unsigned char *number, int number_len)
1299 unsigned char *p = l3m->redirect_dn;
1304 add_trace("redir'tion", "error", "IE too short (len=%d)", p[0]);
1308 *type = (p[1]&0x70) >> 4;
1312 *present = (p[2]&0x60) >> 5;
1313 strnncpy(number, p+3, p[0]-2, number_len);
1316 strnncpy(number, p+2, p[0]-1, number_len);
1319 add_trace("redir'tion", "type", "%d", *type);
1320 add_trace("redir'tion", "plan", "%d", *plan);
1321 add_trace("redir'tion", "present", "%d", *present);
1322 add_trace("redir'tion", "number", "%s", number);
1327 void Pdss1::enc_ie_facility(struct l3_msg *l3m, unsigned char *facility, int facility_len)
1329 unsigned char p[256];
1335 if (!facility || facility_len<=0)
1341 while(i < facility_len)
1343 UPRINT(buffer+(i*3), " %02x", facility[i]);
1347 add_trace("facility", NULL, "%s", buffer+1);
1352 memcpy(p+2, facility, facility_len);
1353 add_layer3_ie(l3m, p[0], p[1], p+2);
1356 void Pdss1::dec_ie_facility(struct l3_msg *l3m, unsigned char *facility, int *facility_len)
1363 unsigned char *p = l3m->facility;
1367 *facility_len = p[0];
1368 memcpy(facility, p+1, *facility_len);
1371 while(i < *facility_len)
1373 UPRINT(debug+(i*3), " %02x", facility[i]);
1378 add_trace("facility", NULL, "%s", debug[0]?debug+1:"<none>");
1382 void Pdss1::dec_facility_centrex(struct l3_msg *l3m, unsigned char *cnip, int cnip_len)
1384 unsigned char centrex[256];
1386 int facility_len = 0;
1390 dec_ie_facility(l3m, centrex, &facility_len);
1391 if (facility_len >= 2)
1393 if (centrex[i++] != CENTREX_FAC)
1395 if (centrex[i++] != CENTREX_ID)
1399 /* loop sub IEs of facility */
1400 while(facility_len > i+1)
1402 if (centrex[i+1]+i+1 > facility_len)
1404 PERROR("short read of centrex facility.\n");
1410 strnncpy(cnip, ¢rex[i+2], centrex[i+1], cnip_len);
1411 add_trace("facility", "cnip", "%s", cnip);
1416 while(j < centrex[i+1])
1418 UPRINT(debug+(j*3), " %02x", centrex[i+1+j]);
1421 add_trace("facility", "CENTREX", "unknown=0x%02x len=%d%s\n", centrex[i], centrex[i+1], debug);
1423 i += 1+centrex[i+1];
1429 void Pdss1::enc_ie_useruser(struct l3_msg *l3m, int protocol, unsigned char *user, int user_len)
1431 unsigned char p[256];
1437 if (protocol<0 || protocol>127)
1439 PERROR("protocol(%d) is out of range.\n", protocol);
1442 if (!user || user_len<=0)
1450 UPRINT(buffer+(i*3), " %02x", user[i]);
1454 add_trace("useruser", "protocol", "%d", protocol);
1455 add_trace("useruser", "value", "%s", buffer);
1458 p[0] = IE_USER_USER;
1460 p[2] = 0x80 + protocol;
1461 memcpy(p+3, user, user_len);
1462 add_layer3_ie(l3m, p[0], p[1], p+2);
1465 void Pdss1::dec_ie_useruser(struct l3_msg *l3m, int *protocol, unsigned char *user, int *user_len)
1473 unsigned char *p = l3m->useruser;
1481 memcpy(user, p+2, (*user_len<=128)?*(user_len):128); /* clip to 128 maximum */
1484 while(i < *user_len)
1486 UPRINT(buffer+(i*3), " %02x", user[i]);
1491 add_trace("useruser", "protocol", "%d", *protocol);
1492 add_trace("useruser", "value", "%s", buffer);