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);
30 void Pdss1::enc_ie_complete(struct l3_msg *l3m, int complete)
32 void Pdss1::enc_ie_complete(unsigned char **ntmode, msg_t *msg, int complete)
37 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
40 if (complete<0 || complete>1)
42 PERROR("complete(%d) is out of range.\n", complete);
48 add_trace("complete", NULL, NULL);
55 qi->sending_complete.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
58 l3m->sending_complete++;
64 void Pdss1::dec_ie_complete(struct l3_msg *l3m, int *complete)
66 void Pdss1::dec_ie_complete(unsigned char *p, Q931_info_t *qi, int *complete)
73 if (qi->sending_complete.off)
77 // special case: p is not a pointer, it's a value
78 unsigned char p = l3m->sending_complete;
84 add_trace("complete", NULL, NULL);
90 void Pdss1::enc_ie_bearer(struct l3_msg *l3m, int coding, int capability, int mode, int rate, int multi, int user)
92 void Pdss1::enc_ie_bearer(unsigned char **ntmode, msg_t *msg, int coding, int capability, int mode, int rate, int multi, int user)
99 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
103 if (coding<0 || coding>3)
105 PERROR("coding(%d) is out of range.\n", coding);
108 if (capability<0 || capability>31)
110 PERROR("capability(%d) is out of range.\n", capability);
113 if (mode<0 || mode>3)
115 PERROR("mode(%d) is out of range.\n", mode);
118 if (rate<0 || rate>31)
120 PERROR("rate(%d) is out of range.\n", rate);
125 PERROR("multi(%d) is out of range.\n", multi);
130 PERROR("user L1(%d) is out of range.\n", user);
133 if (rate!=24 && multi>=0)
135 PERROR("multi(%d) is only possible if rate(%d) would be 24.\n", multi, rate);
139 add_trace("bearer", "coding", "%d", coding);
140 add_trace("bearer", "capability", "%d", capability);
141 add_trace("bearer", "mode", "%d", mode);
142 add_trace("bearer", "rate", "%d", rate);
143 add_trace("bearer", "multi", "%d", multi);
144 add_trace("bearer", "user", "%d", user);
146 l = 2 + (multi>=0) + (user>=0);
148 p = msg_put(msg, l+2);
152 qi->bearer_capability.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
156 p[2] = 0x80 + (coding<<5) + capability;
157 p[3] = 0x80 + (mode<<5) + rate;
161 p[4+(multi>=0)] = 0xa0 + user;
163 add_layer3_ie(l3m, p[0], p[1], p+2);
168 void Pdss1::dec_ie_bearer(struct l3_msg *l3m, int *coding, int *capability, int *mode, int *rate, int *multi, int *user)
170 void Pdss1::dec_ie_bearer(unsigned char *p, Q931_info_t *qi, int *coding, int *capability, int *mode, int *rate, int *multi, int *user)
184 if (qi->bearer_capability.off)
185 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->bearer_capability.off + 1;
188 unsigned char *p = l3m->bearer_capability;
194 add_trace("bearer", "error", "IE too short (len=%d)", p[0]);
198 *coding = (p[1]&0x60) >> 5;
199 *capability = p[1] & 0x1f;
202 *mode = (p[2]&0x60) >> 5;
205 if (p[0]>=3 && *rate==0x18)
207 *multi = p[3] & 0x7f;
216 add_trace("bearer", "coding", "%d", *coding);
217 add_trace("bearer", "capability", "%d", *capability);
218 add_trace("bearer", "mode", "%d", *mode);
219 add_trace("bearer", "rate", "%d", *rate);
220 add_trace("bearer", "multi", "%d", *multi);
221 add_trace("bearer", "user", "%d", *user);
227 void Pdss1::enc_ie_hlc(struct l3_msg *l3m, int coding, int interpretation, int presentation, int hlc, int exthlc)
229 void Pdss1::enc_ie_hlc(unsigned char **ntmode, msg_t *msg, int coding, int interpretation, int presentation, int hlc, int exthlc)
233 unsigned char p[256];
236 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
240 if (coding<0 || coding>3)
242 PERROR("coding(%d) is out of range.\n", coding);
245 if (interpretation<0 || interpretation>7)
247 PERROR("interpretation(%d) is out of range.\n", interpretation);
250 if (presentation<0 || presentation>3)
252 PERROR("presentation(%d) is out of range.\n", presentation);
255 if (hlc<0 || hlc>127)
257 PERROR("hlc(%d) is out of range.\n", hlc);
262 PERROR("hlc(%d) is out of range.\n", exthlc);
266 add_trace("hlc", "coding", "%d", coding);
267 add_trace("hlc", "interpretation", "%d", interpretation);
268 add_trace("hlc", "presentation", "%d", presentation);
269 add_trace("hlc", "hlc", "%d", hlc);
271 add_trace("hlc", "exthlc", "%d", exthlc);
275 p = msg_put(msg, l+2);
279 qi->hlc.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
283 p[2] = 0x80 + (coding<<5) + (interpretation<<2) + presentation;
287 p[4] = 0x80 + exthlc;
291 add_layer3_ie(l3m, p[0], p[1], p+2);
296 void Pdss1::dec_ie_hlc(struct l3_msg *l3m, int *coding, int *interpretation, int *presentation, int *hlc, int *exthlc)
298 void Pdss1::dec_ie_hlc(unsigned char *p, Q931_info_t *qi, int *coding, int *interpretation, int *presentation, int *hlc, int *exthlc)
302 *interpretation = -1;
312 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->hlc.off + 1;
315 unsigned char *p = l3m->hlc;
321 add_trace("hlc", "error", "IE too short (len=%d)", p[0]);
325 *coding = (p[1]&0x60) >> 5;
326 *interpretation = (p[1]&0x1c) >> 2;
327 *presentation = p[1] & 0x03;
331 *exthlc = p[3] & 0x7f;
334 add_trace("hlc", "coding", "%d", *coding);
335 add_trace("hlc", "interpretation", "%d", *interpretation);
336 add_trace("hlc", "presentation", "%d", *presentation);
337 add_trace("hlc", "hlc", "%d", *hlc);
339 add_trace("hlc", "exthlc", "%d", *exthlc);
345 void Pdss1::enc_ie_call_id(struct l3_msg *l3m, unsigned char *callid, int callid_len)
347 void Pdss1::enc_ie_call_id(unsigned char **ntmode, msg_t *msg, unsigned char *callid, int callid_len)
351 unsigned char p[256];
354 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
361 if (!callid || callid_len<=0)
367 PERROR("callid_len(%d) is out of range.\n", callid_len);
372 while(i < callid_len)
374 UPRINT(buffer+(i*3), " %02x", callid[i]);
378 add_trace("callid", NULL, "%s", buffer[0]?buffer+1:"<none>");
382 p = msg_put(msg, l+2);
386 qi->call_id.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
390 memcpy(p+2, callid, callid_len);
392 add_layer3_ie(l3m, p[0], p[1], p+2);
397 void Pdss1::dec_ie_call_id(struct l3_msg *l3m, unsigned char *callid, int *callid_len)
399 void Pdss1::dec_ie_call_id(unsigned char *p, Q931_info_t *qi, unsigned char *callid, int *callid_len)
412 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->call_id.off + 1;
415 unsigned char *p = l3m->call_id;
421 add_trace("callid", "error", "IE too long (len=%d)", p[0]);
426 memcpy(callid, p+1, *callid_len);
429 while(i < *callid_len)
431 UPRINT(buffer+(i*3), " %02x", callid[i]);
435 add_trace("callid", NULL, "%s", buffer[0]?buffer+1:"<none>");
441 void Pdss1::enc_ie_called_pn(struct l3_msg *l3m, int type, int plan, unsigned char *number)
443 void Pdss1::enc_ie_called_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, unsigned char *number)
447 unsigned char p[256];
450 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
454 if (type<0 || type>7)
456 PERROR("type(%d) is out of range.\n", type);
459 if (plan<0 || plan>15)
461 PERROR("plan(%d) is out of range.\n", plan);
466 PERROR("number is not given.\n");
470 add_trace("called_pn", "type", "%d", type);
471 add_trace("called_pn", "plan", "%d", plan);
472 add_trace("called_pn", "number", "%s", number);
474 l = 1+strlen((char *)number);
476 p = msg_put(msg, l+2);
480 qi->called_nr.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
484 p[2] = 0x80 + (type<<4) + plan;
485 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
487 add_layer3_ie(l3m, p[0], p[1], p+2);
492 void Pdss1::dec_ie_called_pn(struct l3_msg *l3m, int *type, int *plan, unsigned char *number, int number_len)
494 void Pdss1::dec_ie_called_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, unsigned char *number, int number_len)
505 if (qi->called_nr.off)
506 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->called_nr.off + 1;
509 unsigned char *p = l3m->called_nr;
515 add_trace("called_pn", "error", "IE too short (len=%d)", p[0]);
519 *type = (p[1]&0x70) >> 4;
521 strnncpy(number, p+2, p[0]-1, number_len);
523 add_trace("called_pn", "type", "%d", *type);
524 add_trace("called_pn", "plan", "%d", *plan);
525 add_trace("called_pn", "number", "%s", number);
531 void Pdss1::enc_ie_calling_pn(struct l3_msg *l3m, int type, int plan, int present, int screen, unsigned char *number)
533 void Pdss1::enc_ie_calling_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, unsigned char *number)
537 unsigned char p[256];
540 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
544 if (type<0 || type>7)
546 PERROR("type(%d) is out of range.\n", type);
549 if (plan<0 || plan>15)
551 PERROR("plan(%d) is out of range.\n", plan);
556 PERROR("present(%d) is out of range.\n", present);
559 if (present >= 0) if (screen<0 || screen>3)
561 PERROR("screen(%d) is out of range.\n", screen);
565 add_trace("calling_pn", "type", "%d", type);
566 add_trace("calling_pn", "plan", "%d", plan);
567 add_trace("calling_pn", "present", "%d", present);
568 add_trace("calling_pn", "screen", "%d", screen);
569 add_trace("calling_pn", "number", "%s", number);
572 if (number) if (number[0])
573 l += strlen((char *)number);
577 p = msg_put(msg, l+2);
581 qi->calling_nr.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
583 p[0] = IE_CALLING_PN;
587 p[2] = 0x00 + (type<<4) + plan;
588 p[3] = 0x80 + (present<<5) + screen;
589 if (number) if (number[0])
590 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
593 p[2] = 0x80 + (type<<4) + plan;
594 if (number) if (number[0])
595 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
598 add_layer3_ie(l3m, p[0], p[1], p+2);
603 void Pdss1::dec_ie_calling_pn(struct l3_msg *l3m, int *type, int *plan, int *present, int *screen, unsigned char *number, int number_len)
605 void Pdss1::dec_ie_calling_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, unsigned char *number, int number_len)
618 if (qi->calling_nr.off)
619 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->calling_nr.off + 1;
622 unsigned char *p = l3m->calling_nr;
628 add_trace("calling_pn", "error", "IE too short (len=%d)", p[0]);
632 *type = (p[1]&0x70) >> 4;
638 add_trace("calling_pn", "error", "IE too short (len=%d)", p[0]);
641 *present = (p[2]&0x60) >> 5;
642 *screen = p[2] & 0x3;
643 strnncpy(number, p+3, p[0]-2, number_len);
646 strnncpy(number, p+2, p[0]-1, number_len);
649 add_trace("calling_pn", "type", "%d", *type);
650 add_trace("calling_pn", "plan", "%d", *plan);
651 add_trace("calling_pn", "present", "%d", *present);
652 add_trace("calling_pn", "screen", "%d", *screen);
653 add_trace("calling_pn", "number", "%s", number);
657 /* IE_CONNECTED_PN */
659 void Pdss1::enc_ie_connected_pn(struct l3_msg *l3m, int type, int plan, int present, int screen, unsigned char *number)
661 void Pdss1::enc_ie_connected_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, unsigned char *number)
665 unsigned char p[256];
668 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
672 if (type<0 || type>7)
674 PERROR("type(%d) is out of range.\n", type);
677 if (plan<0 || plan>15)
679 PERROR("plan(%d) is out of range.\n", plan);
684 PERROR("present(%d) is out of range.\n", present);
687 if (present >= 0) if (screen<0 || screen>3)
689 PERROR("screen(%d) is out of range.\n", screen);
693 add_trace("connect_pn", "type", "%d", type);
694 add_trace("connect_pn", "plan", "%d", plan);
695 add_trace("connect_pn", "present", "%d", present);
696 add_trace("connect_pn", "screen", "%d", screen);
697 add_trace("connect_pn", "number", "%s", number);
700 if (number) if (number[0])
701 l += strlen((char *)number);
705 p = msg_put(msg, l+2);
709 qi->connected_nr.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
711 p[0] = IE_CONNECT_PN;
715 p[2] = 0x00 + (type<<4) + plan;
716 p[3] = 0x80 + (present<<5) + screen;
717 if (number) if (number[0])
718 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
721 p[2] = 0x80 + (type<<4) + plan;
722 if (number) if (number[0])
723 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
726 add_layer3_ie(l3m, p[0], p[1], p+2);
731 void Pdss1::dec_ie_connected_pn(struct l3_msg *l3m, int *type, int *plan, int *present, int *screen, unsigned char *number, int number_len)
733 void Pdss1::dec_ie_connected_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, unsigned char *number, int number_len)
746 if (qi->connected_nr.off)
747 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->connected_nr.off + 1;
750 unsigned char *p = l3m->connected_nr;
756 add_trace("connect_pn", "error", "IE too short (len=%d)", p[0]);
760 *type = (p[1]&0x70) >> 4;
766 add_trace("connect_pn", "error", "IE too short (len=%d)", p[0]);
769 *present = (p[2]&0x60) >> 5;
770 *screen = p[2] & 0x3;
771 strnncpy(number, p+3, p[0]-2, number_len);
774 strnncpy(number, p+2, p[0]-1, number_len);
777 add_trace("connect_pn", "type", "%d", *type);
778 add_trace("connect_pn", "plan", "%d", *plan);
779 add_trace("connect_pn", "present", "%d", *present);
780 add_trace("connect_pn", "screen", "%d", *screen);
781 add_trace("connect_pn", "number", "%s", number);
787 void Pdss1::enc_ie_cause(struct l3_msg *l3m, int location, int cause)
789 void Pdss1::enc_ie_cause(unsigned char **ntmode, msg_t *msg, int location, int cause)
793 unsigned char p[256];
796 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
800 if (location<0 || location>7)
802 PERROR("location(%d) is out of range.\n", location);
805 if (cause<0 || cause>127)
807 PERROR("cause(%d) is out of range.\n", cause);
811 add_trace("cause", "location", "%d", location);
812 add_trace("cause", "value", "%d", cause);
816 p = msg_put(msg, l+2);
820 qi->cause.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
824 p[2] = 0x80 + location;
827 add_layer3_ie(l3m, p[0], p[1], p+2);
831 void enc_ie_cause_standalone(struct l3_msg *l3m, int location, int cause)
833 void enc_ie_cause_standalone(unsigned char **ntmode, msg_t *msg, int location, int cause)
837 unsigned char p[256];
839 unsigned char *p = msg_put(msg, 4);
840 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
844 qi->cause.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
848 p[2] = 0x80 + location;
851 add_layer3_ie(l3m, p[0], p[1], p+2);
857 void Pdss1::dec_ie_cause(struct l3_msg *l3m, int *location, int *cause)
859 void Pdss1::dec_ie_cause(unsigned char *p, Q931_info_t *qi, int *location, int *cause)
870 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->cause.off + 1;
873 unsigned char *p = l3m->cause;
879 add_trace("cause", "error", "IE too short (len=%d)", p[0]);
883 *location = p[1] & 0x0f;
884 *cause = p[2] & 0x7f;
886 add_trace("cause", "location", "%d", *location);
887 add_trace("cause", "value", "%d", *cause);
893 void Pdss1::enc_ie_channel_id(struct l3_msg *l3m, int exclusive, int channel)
895 void Pdss1::enc_ie_channel_id(unsigned char **ntmode, msg_t *msg, int exclusive, int channel)
899 unsigned char p[256];
902 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
905 int pri = p_m_mISDNport->pri;
907 if (exclusive<0 || exclusive>1)
909 PERROR("exclusive(%d) is out of range.\n", exclusive);
912 if ((channel<=0 && channel!=CHANNEL_NO && channel!=CHANNEL_ANY)
913 || (!pri && channel>2)
914 || (pri && channel>127)
915 || (pri && channel==16))
917 PERROR("channel(%d) is out of range.\n", channel);
921 add_trace("channel_id", "exclusive", "%d", exclusive);
925 add_trace("channel_id", "channel", "any channel");
928 add_trace("channel_id", "channel", "no channel");
931 add_trace("channel_id", "channel", "%d", channel);
939 p = msg_put(msg, l+2);
943 qi->channel_id.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
945 p[0] = IE_CHANNEL_ID;
947 if (channel == CHANNEL_NO)
949 else if (channel == CHANNEL_ANY)
951 p[2] = 0x80 + (exclusive<<3) + channel;
953 add_layer3_ie(l3m, p[0], p[1], p+2);
958 if (channel == CHANNEL_NO) /* no channel */
959 return; /* IE not present */
960 if (channel == CHANNEL_ANY) /* any channel */
964 p = msg_put(msg, l+2);
968 qi->channel_id.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
970 p[0] = IE_CHANNEL_ID;
972 p[2] = 0x80 + 0x20 + 0x03;
974 add_layer3_ie(l3m, p[0], p[1], p+2);
980 p = msg_put(msg, l+2);
984 qi->channel_id.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
986 p[0] = IE_CHANNEL_ID;
988 p[2] = 0x80 + 0x20 + (exclusive<<3) + 0x01;
989 p[3] = 0x80 + 3; /* CCITT, Number, B-type */
990 p[4] = 0x80 + channel;
992 add_layer3_ie(l3m, p[0], p[1], p+2);
998 void Pdss1::dec_ie_channel_id(struct l3_msg *l3m, int *exclusive, int *channel)
1000 void Pdss1::dec_ie_channel_id(unsigned char *p, Q931_info_t *qi, int *exclusive, int *channel)
1003 int pri = p_m_mISDNport->pri;
1008 #ifndef SOCKET_MISDN
1012 if (qi->channel_id.off)
1013 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->channel_id.off + 1;
1016 unsigned char *p = l3m->channel_id;
1022 add_trace("channel_id", "error", "IE too short (len=%d)", p[0]);
1028 add_trace("channel_id", "error", "refering to channels of other interfaces is not supported");
1033 add_trace("channel_id", "error", "using d-channel is not supported");
1037 *exclusive = (p[1]&0x08) >> 3;
1043 add_trace("channel_id", "error", "extended channel ID with non PRI interface");
1046 *channel = p[1] & 0x03;
1048 *channel = CHANNEL_ANY;
1049 else if (*channel == 0)
1050 *channel = CHANNEL_NO;
1057 add_trace("channel_id", "error", "IE too short for PRI (len=%d)", p[0]);
1062 add_trace("channel_id", "error", "basic channel ID with PRI interface");
1065 if ((p[1]&0x03) == 0x00)
1068 *channel = CHANNEL_NO;
1071 if ((p[1]&0x03) == 0x03)
1074 *channel = CHANNEL_ANY;
1079 add_trace("channel_id", "error", "IE too short for PRI with channel (len=%d)", p[0]);
1084 add_trace("channel_id", "error", "channel map not supported");
1087 *channel = p[3] & 0x7f;
1088 if (*channel<1 | *channel==16)
1090 add_trace("channel_id", "error", "PRI interface channel out of range (%d)", *channel);
1095 add_trace("channel_id", "exclusive", "%d", *exclusive);
1099 add_trace("channel_id", "channel", "any channel");
1102 add_trace("channel_id", "channel", "no channel");
1105 add_trace("channel_id", "channel", "%d", *channel);
1112 void Pdss1::enc_ie_date(struct l3_msg *l3m, time_t ti, int no_seconds)
1114 void Pdss1::enc_ie_date(unsigned char **ntmode, msg_t *msg, time_t ti, int no_seconds)
1118 unsigned char p[256];
1121 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1127 tm = localtime(&ti);
1130 PERROR("localtime() returned NULL.\n");
1134 add_trace("date", "day", "%d.%d.%d", tm->tm_mday, tm->tm_mon+1, tm->tm_year%100);
1135 add_trace("date", "time", "%d:%d:%d", tm->tm_hour, tm->tm_min, tm->tm_sec);
1137 l = 5 + (!no_seconds);
1138 #ifndef SOCKET_MISDN
1139 p = msg_put(msg, l+2);
1143 qi->date.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
1147 p[2] = tm->tm_year % 100;
1148 p[3] = tm->tm_mon + 1;
1155 add_layer3_ie(l3m, p[0], p[1], p+2);
1162 void Pdss1::enc_ie_display(struct l3_msg *l3m, unsigned char *display)
1164 void Pdss1::enc_ie_display(unsigned char **ntmode, msg_t *msg, unsigned char *display)
1168 unsigned char p[256];
1171 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1177 PERROR("display text not given.\n");
1181 if (strlen((char *)display) > 80)
1183 PERROR("display text too long (max 80 chars), cutting.\n");
1187 add_trace("display", NULL, "%s", display);
1189 l = strlen((char *)display);
1190 #ifndef SOCKET_MISDN
1191 p = msg_put(msg, l+2);
1195 qi->display.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
1199 UNCPY((char *)p+2, (char *)display, strlen((char *)display));
1201 add_layer3_ie(l3m, p[0], p[1], p+2);
1206 void Pdss1::dec_ie_display(struct l3_msg *l3m, unsigned char *display, int display_len)
1208 void Pdss1::dec_ie_display(unsigned char *p, Q931_info_t *qi, unsigned char *display, int display_len)
1213 #ifndef SOCKET_MISDN
1217 if (qi->display.off)
1218 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->display.off + 1;
1221 unsigned char *p = l3m->display;
1227 add_trace("display", "error", "IE too short (len=%d)", p[0]);
1231 strnncpy(display, p+1, p[0], display_len);
1233 add_trace("display", NULL, "%s", display);
1239 void Pdss1::enc_ie_keypad(struct l3_msg *l3m, unsigned char *keypad)
1241 void Pdss1::enc_ie_keypad(unsigned char **ntmode, msg_t *msg, unsigned char *keypad)
1245 unsigned char p[256];
1248 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1254 PERROR("keypad info not given.\n");
1258 add_trace("keypad", NULL, "%s", keypad);
1260 l = strlen((char *)keypad);
1261 #ifndef SOCKET_MISDN
1262 p = msg_put(msg, l+2);
1266 qi->keypad.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
1270 UNCPY((char *)p+2, (char *)keypad, strlen((char *)keypad));
1272 add_layer3_ie(l3m, p[0], p[1], p+2);
1277 void Pdss1::dec_ie_keypad(struct l3_msg *l3m, unsigned char *keypad, int keypad_len)
1279 void Pdss1::dec_ie_keypad(unsigned char *p, Q931_info_t *qi, unsigned char *keypad, int keypad_len)
1284 #ifndef SOCKET_MISDN
1289 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->keypad.off + 1;
1292 unsigned char *p = l3m->keypad;
1298 add_trace("keypad", "error", "IE too short (len=%d)", p[0]);
1302 strnncpy(keypad, p+1, p[0], keypad_len);
1304 add_trace("keypad", NULL, "%s", keypad);
1310 void Pdss1::enc_ie_notify(struct l3_msg *l3m, int notify)
1312 void Pdss1::enc_ie_notify(unsigned char **ntmode, msg_t *msg, int notify)
1316 unsigned char p[256];
1319 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1323 if (notify<0 || notify>0x7f)
1325 PERROR("notify(%d) is out of range.\n", notify);
1329 add_trace("notify", NULL, "%d", notify);
1332 #ifndef SOCKET_MISDN
1333 p = msg_put(msg, l+2);
1337 qi->notify.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
1341 p[2] = 0x80 + notify;
1343 add_layer3_ie(l3m, p[0], p[1], p+2);
1348 void Pdss1::dec_ie_notify(struct l3_msg *l3m, int *notify)
1350 void Pdss1::dec_ie_notify(unsigned char *p, Q931_info_t *qi, int *notify)
1355 #ifndef SOCKET_MISDN
1360 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->notify.off + 1;
1363 unsigned char *p = l3m->notify;
1369 add_trace("notify", "error", "IE too short (len=%d)", p[0]);
1373 *notify = p[1] & 0x7f;
1375 add_trace("notify", NULL, "%d", *notify);
1381 void Pdss1::enc_ie_progress(struct l3_msg *l3m, int coding, int location, int progress)
1383 void Pdss1::enc_ie_progress(unsigned char **ntmode, msg_t *msg, int coding, int location, int progress)
1387 unsigned char p[256];
1390 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1394 if (coding<0 || coding>0x03)
1396 PERROR("coding(%d) is out of range.\n", coding);
1399 if (location<0 || location>0x0f)
1401 PERROR("location(%d) is out of range.\n", location);
1404 if (progress<0 || progress>0x7f)
1406 PERROR("progress(%d) is out of range.\n", progress);
1410 add_trace("progress", "codeing", "%d", coding);
1411 add_trace("progress", "location", "%d", location);
1412 add_trace("progress", "indicator", "%d", progress);
1415 #ifndef SOCKET_MISDN
1416 p = msg_put(msg, l+2);
1420 qi->progress.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
1424 p[2] = 0x80 + (coding<<5) + location;
1425 p[3] = 0x80 + progress;
1427 add_layer3_ie(l3m, p[0], p[1], p+2);
1432 void Pdss1::dec_ie_progress(struct l3_msg *l3m, int *coding, int *location, int *progress)
1434 void Pdss1::dec_ie_progress(unsigned char *p, Q931_info_t *qi, int *coding, int *location, int *progress)
1441 #ifndef SOCKET_MISDN
1445 if (qi->progress.off)
1446 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->progress.off + 1;
1449 unsigned char *p = l3m->progress;
1455 add_trace("progress", "error", "IE too short (len=%d)", p[0]);
1459 *coding = (p[1]&0x60) >> 5;
1460 *location = p[1] & 0x0f;
1461 *progress = p[2] & 0x7f;
1463 add_trace("progress", "codeing", "%d", *coding);
1464 add_trace("progress", "location", "%d", *location);
1465 add_trace("progress", "indicator", "%d", *progress);
1469 /* IE_REDIR_NR (redirecting = during MT_SETUP) */
1471 void Pdss1::enc_ie_redir_nr(struct l3_msg *l3m, int type, int plan, int present, int screen, int reason, unsigned char *number)
1473 void Pdss1::enc_ie_redir_nr(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, int reason, unsigned char *number)
1477 unsigned char p[256];
1480 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1484 if (type<0 || type>7)
1486 PERROR("type(%d) is out of range.\n", type);
1489 if (plan<0 || plan>15)
1491 PERROR("plan(%d) is out of range.\n", plan);
1496 PERROR("present(%d) is out of range.\n", present);
1499 if (present >= 0) if (screen<0 || screen>3)
1501 PERROR("screen(%d) is out of range.\n", screen);
1506 PERROR("reason(%d) is out of range.\n", reason);
1510 add_trace("redir'ing", "type", "%d", type);
1511 add_trace("redir'ing", "plan", "%d", plan);
1512 add_trace("redir'ing", "present", "%d", present);
1513 add_trace("redir'ing", "screen", "%d", screen);
1514 add_trace("redir'ing", "reason", "%d", reason);
1515 add_trace("redir'ing", "number", "%s", number);
1519 l += strlen((char *)number);
1526 #ifndef SOCKET_MISDN
1527 p = msg_put(msg, l+2);
1531 qi->redirect_nr.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
1539 p[2] = 0x00 + (type<<4) + plan;
1540 p[3] = 0x00 + (present<<5) + screen;
1541 p[4] = 0x80 + reason;
1543 UNCPY((char *)p+5, (char *)number, strlen((char *)number));
1546 p[2] = 0x00 + (type<<4) + plan;
1547 p[3] = 0x80 + (present<<5) + screen;
1549 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
1553 p[2] = 0x80 + (type<<4) + plan;
1554 if (number) if (number[0])
1555 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
1558 add_layer3_ie(l3m, p[0], p[1], p+2);
1563 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)
1565 void Pdss1::dec_ie_redir_nr(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, int *reason, unsigned char *number, int number_len)
1575 #ifndef SOCKET_MISDN
1579 if (qi->redirect_nr.off)
1580 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->redirect_nr.off + 1;
1583 unsigned char *p = l3m->redirect_nr;
1589 add_trace("redir'ing", "error", "IE too short (len=%d)", p[0]);
1593 *type = (p[1]&0x70) >> 4;
1597 *present = (p[2]&0x60) >> 5;
1598 *screen = p[2] & 0x3;
1601 *reason = p[3] & 0x0f;
1602 strnncpy(number, p+4, p[0]-3, number_len);
1605 strnncpy(number, p+3, p[0]-2, number_len);
1609 strnncpy(number, p+2, p[0]-1, number_len);
1612 add_trace("redir'ing", "type", "%d", *type);
1613 add_trace("redir'ing", "plan", "%d", *plan);
1614 add_trace("redir'ing", "present", "%d", *present);
1615 add_trace("redir'ing", "screen", "%d", *screen);
1616 add_trace("redir'ing", "reason", "%d", *reason);
1617 add_trace("redir'ing", "number", "%s", number);
1621 /* IE_REDIR_DN (redirection = during MT_NOTIFY) */
1623 void Pdss1::enc_ie_redir_dn(struct l3_msg *l3m, int type, int plan, int present, unsigned char *number)
1625 void Pdss1::enc_ie_redir_dn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, unsigned char *number)
1629 unsigned char p[256];
1632 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1636 if (type<0 || type>7)
1638 PERROR("type(%d) is out of range.\n", type);
1641 if (plan<0 || plan>15)
1643 PERROR("plan(%d) is out of range.\n", plan);
1648 PERROR("present(%d) is out of range.\n", present);
1652 add_trace("redir'tion", "type", "%d", type);
1653 add_trace("redir'tion", "plan", "%d", plan);
1654 add_trace("redir'tion", "present", "%d", present);
1655 add_trace("redir'tion", "number", "%s", number);
1659 l += strlen((char *)number);
1662 #ifndef SOCKET_MISDN
1663 p = msg_put(msg, l+2);
1667 qi->redirect_dn.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
1673 p[2] = 0x00 + (type<<4) + plan;
1674 p[3] = 0x80 + (present<<5);
1676 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
1679 p[2] = 0x80 + (type<<4) + plan;
1681 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
1684 add_layer3_ie(l3m, p[0], p[1], p+2);
1689 void Pdss1::dec_ie_redir_dn(struct l3_msg *l3m, int *type, int *plan, int *present, unsigned char *number, int number_len)
1691 void Pdss1::dec_ie_redir_dn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, unsigned char *number, int number_len)
1699 #ifndef SOCKET_MISDN
1703 if (qi->redirect_dn.off)
1704 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->redirect_dn.off + 1;
1707 unsigned char *p = l3m->redirect_dn;
1713 add_trace("redir'tion", "error", "IE too short (len=%d)", p[0]);
1717 *type = (p[1]&0x70) >> 4;
1721 *present = (p[2]&0x60) >> 5;
1722 strnncpy(number, p+3, p[0]-2, number_len);
1725 strnncpy(number, p+2, p[0]-1, number_len);
1728 add_trace("redir'tion", "type", "%d", *type);
1729 add_trace("redir'tion", "plan", "%d", *plan);
1730 add_trace("redir'tion", "present", "%d", *present);
1731 add_trace("redir'tion", "number", "%s", number);
1737 void Pdss1::enc_ie_facility(struct l3_msg *l3m, unsigned char *facility, int facility_len)
1739 void Pdss1::enc_ie_facility(unsigned char **ntmode, msg_t *msg, unsigned char *facility, int facility_len)
1743 unsigned char p[256];
1746 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1753 if (!facility || facility_len<=0)
1759 while(i < facility_len)
1761 UPRINT(buffer+(i*3), " %02x", facility[i]);
1765 add_trace("facility", NULL, "%s", buffer+1);
1768 #ifndef SOCKET_MISDN
1769 p = msg_put(msg, l+2);
1773 qi->facility.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
1777 memcpy(p+2, facility, facility_len);
1779 add_layer3_ie(l3m, p[0], p[1], p+2);
1784 void Pdss1::dec_ie_facility(struct l3_msg *l3m, unsigned char *facility, int *facility_len)
1786 void Pdss1::dec_ie_facility(unsigned char *p, Q931_info_t *qi, unsigned char *facility, int *facility_len)
1794 #ifndef SOCKET_MISDN
1798 if (qi->facility.off)
1799 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->facility.off + 1;
1802 unsigned char *p = l3m->facility;
1807 *facility_len = p[0];
1808 memcpy(facility, p+1, *facility_len);
1811 while(i < *facility_len)
1813 UPRINT(debug+(i*3), " %02x", facility[i]);
1818 add_trace("facility", NULL, "%s", debug[0]?debug+1:"<none>");
1823 void Pdss1::dec_facility_centrex(struct l3_msg *l3m, unsigned char *cnip, int cnip_len)
1825 void Pdss1::dec_facility_centrex(unsigned char *p, Q931_info_t *qi, unsigned char *cnip, int cnip_len)
1828 unsigned char centrex[256];
1830 int facility_len = 0;
1835 dec_ie_facility(l3m, centrex, &facility_len);
1837 dec_ie_facility(p, qi, centrex, &facility_len);
1839 if (facility_len >= 2)
1841 if (centrex[i++] != CENTREX_FAC)
1843 if (centrex[i++] != CENTREX_ID)
1847 /* loop sub IEs of facility */
1848 while(facility_len > i+1)
1850 if (centrex[i+1]+i+1 > facility_len)
1852 PERROR("short read of centrex facility.\n");
1858 strnncpy(cnip, ¢rex[i+2], centrex[i+1], cnip_len);
1859 add_trace("facility", "cnip", "%s", cnip);
1864 while(j < centrex[i+1])
1866 UPRINT(debug+(j*3), " %02x", centrex[i+1+j]);
1869 add_trace("facility", "CENTREX", "unknown=0x%02x len=%d%s\n", centrex[i], centrex[i+1], debug);
1871 i += 1+centrex[i+1];
1878 void Pdss1::enc_ie_useruser(struct l3_msg *l3m, int protocol, unsigned char *user, int user_len)
1880 void Pdss1::enc_ie_useruser(unsigned char **ntmode, msg_t *msg, int protocol, unsigned char *user, int user_len)
1884 unsigned char p[256];
1887 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1894 if (protocol<0 || protocol>127)
1896 PERROR("protocol(%d) is out of range.\n", protocol);
1899 if (!user || user_len<=0)
1907 UPRINT(buffer+(i*3), " %02x", user[i]);
1911 add_trace("useruser", "protocol", "%d", protocol);
1912 add_trace("useruser", "value", "%s", buffer);
1915 #ifndef SOCKET_MISDN
1916 p = msg_put(msg, l+3);
1920 qi->useruser.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
1922 p[0] = IE_USER_USER;
1924 p[2] = 0x80 + protocol;
1925 memcpy(p+3, user, user_len);
1927 add_layer3_ie(l3m, p[0], p[1], p+2);
1932 void Pdss1::dec_ie_useruser(struct l3_msg *l3m, int *protocol, unsigned char *user, int *user_len)
1934 void Pdss1::dec_ie_useruser(unsigned char *p, Q931_info_t *qi, int *protocol, unsigned char *user, int *user_len)
1943 #ifndef SOCKET_MISDN
1947 if (qi->useruser.off)
1948 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->useruser.off + 1;
1951 unsigned char *p = l3m->useruser;
1960 memcpy(user, p+2, (*user_len<=128)?*(user_len):128); /* clip to 128 maximum */
1963 while(i < *user_len)
1965 UPRINT(buffer+(i*3), " %02x", user[i]);
1970 add_trace("useruser", "protocol", "%d", *protocol);
1971 add_trace("useruser", "value", "%s", buffer);