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(unsigned char **ntmode, msg_t *msg, int complete)
32 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
34 if (complete<0 || complete>1)
36 PERROR("complete(%d) is out of range.\n", complete);
41 printisdn(" complete=%d\n", complete);
50 qi->sending_complete.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
55 void Pdss1::dec_ie_complete(unsigned char *p, Q931_info_t *qi, int *complete)
60 if (qi->sending_complete.off)
67 printisdn(" complete=%d\n", *complete);
72 void Pdss1::enc_ie_bearer(unsigned char **ntmode, msg_t *msg, int coding, int capability, int mode, int rate, int multi, int user)
75 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
78 if (coding<0 || coding>3)
80 PERROR("coding(%d) is out of range.\n", coding);
83 if (capability<0 || capability>31)
85 PERROR("capability(%d) is out of range.\n", capability);
90 PERROR("mode(%d) is out of range.\n", mode);
93 if (rate<0 || rate>31)
95 PERROR("rate(%d) is out of range.\n", rate);
100 PERROR("multi(%d) is out of range.\n", multi);
105 PERROR("user L1(%d) is out of range.\n", user);
108 if (rate!=24 && multi>=0)
110 PERROR("multi(%d) is only possible if rate(%d) would be 24.\n", multi, rate);
114 printisdn(" coding=%d capability=%d mode=%d rate=%d multi=%d user=%d\n", coding, capability, mode, rate, multi, user);
116 l = 2 + (multi>=0) + (user>=0);
117 p = msg_put(msg, l+2);
121 qi->bearer_capability.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
124 p[2] = 0x80 + (coding<<5) + capability;
125 p[3] = 0x80 + (mode<<5) + rate;
129 p[4+(multi>=0)] = 0xa0 + user;
132 void Pdss1::dec_ie_bearer(unsigned char *p, Q931_info_t *qi, int *coding, int *capability, int *mode, int *rate, int *multi, int *user)
144 if (qi->bearer_capability.off)
145 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->bearer_capability.off + 1;
151 PERROR("IE too short (%d).\n", p[0]);
155 *coding = (p[1]&0x60) >> 5;
156 *capability = p[1] & 0x1f;
159 *mode = (p[2]&0x60) >> 5;
162 if (p[0]>=3 && *rate==0x18)
164 *multi = p[3] & 0x7f;
173 printisdn(" coding=%d capability=%d mode=%d rate=%d multi=%d user=%d\n", *coding, *capability, *mode, *rate, *multi, *user);
178 void Pdss1::enc_ie_hlc(unsigned char **ntmode, msg_t *msg, int coding, int interpretation, int presentation, int hlc, int exthlc)
181 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
184 if (coding<0 || coding>3)
186 PERROR("coding(%d) is out of range.\n", coding);
189 if (interpretation<0 || interpretation>7)
191 PERROR("interpretation(%d) is out of range.\n", interpretation);
194 if (presentation<0 || presentation>3)
196 PERROR("presentation(%d) is out of range.\n", presentation);
199 if (hlc<0 || hlc>127)
201 PERROR("hlc(%d) is out of range.\n", hlc);
206 PERROR("hlc(%d) is out of range.\n", exthlc);
210 printisdn(" coding=%d interpretation=%d presentation=%d hlc=%d exthlc=%d\n", coding, interpretation, presentation, hlc, exthlc);
213 p = msg_put(msg, l+2);
217 qi->hlc.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
220 p[2] = 0x80 + (coding<<5) + (interpretation<<2) + presentation;
224 p[4] = 0x80 + exthlc;
229 void Pdss1::dec_ie_hlc(unsigned char *p, Q931_info_t *qi, int *coding, int *interpretation, int *presentation, int *hlc, int *exthlc)
232 *interpretation = -1;
241 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->hlc.off + 1;
247 PERROR("IE too short (%d).\n", p[0]);
251 *coding = (p[1]&0x60) >> 5;
252 *interpretation = (p[1]&0x1c) >> 2;
253 *presentation = p[1] & 0x03;
257 *exthlc = p[3] & 0x7f;
260 printisdn(" coding=%d interpretation=%d presentation=%d hlc=%d exthlc=%d\n", *coding, *interpretation, *presentation, *hlc, *exthlc);
265 void Pdss1::enc_ie_call_id(unsigned char **ntmode, msg_t *msg, unsigned char *callid, int callid_len)
268 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
274 if (!callid || callid_len<=0)
280 PERROR("callid_len(%d) is out of range.\n", callid_len);
285 while(i < callid_len)
287 UPRINT(debug+(i*3), " %02x", callid[i]);
291 printisdn(" callid%s\n", debug);
294 p = msg_put(msg, l+2);
298 qi->call_id.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
301 memcpy(p+2, callid, callid_len);
304 void Pdss1::dec_ie_call_id(unsigned char *p, Q931_info_t *qi, unsigned char *callid, int *callid_len)
315 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->call_id.off + 1;
321 PERROR("IE too long (%d).\n", p[0]);
326 memcpy(callid, p+1, *callid_len);
329 while(i < *callid_len)
331 UPRINT(debug+(i*3), " %02x", callid[i]);
335 printisdn(" callid%s\n", debug);
340 void Pdss1::enc_ie_called_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, unsigned char *number)
343 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
346 if (type<0 || type>7)
348 PERROR("type(%d) is out of range.\n", type);
351 if (plan<0 || plan>15)
353 PERROR("plan(%d) is out of range.\n", plan);
358 PERROR("number is not given.\n");
362 printisdn(" type=%d plan=%d number='%s'\n", type, plan, number);
364 l = 1+strlen((char *)number);
365 p = msg_put(msg, l+2);
369 qi->called_nr.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
372 p[2] = 0x80 + (type<<4) + plan;
373 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
376 void Pdss1::dec_ie_called_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, unsigned char *number, int number_len)
385 if (qi->called_nr.off)
386 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->called_nr.off + 1;
392 PERROR("IE too short (%d).\n", p[0]);
396 *type = (p[1]&0x70) >> 4;
398 strnncpy(number, p+2, p[0]-1, number_len);
400 printisdn(" type=%d plan=%d number='%s'\n", *type, *plan, number);
405 void Pdss1::enc_ie_calling_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, unsigned char *number)
408 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
411 if (type<0 || type>7)
413 PERROR("type(%d) is out of range.\n", type);
416 if (plan<0 || plan>15)
418 PERROR("plan(%d) is out of range.\n", plan);
423 PERROR("present(%d) is out of range.\n", present);
426 if (present >= 0) if (screen<0 || screen>3)
428 PERROR("screen(%d) is out of range.\n", screen);
432 printisdn(" type=%d plan=%d present=%d screen=%d number='%s'\n", type, plan, present, screen, number);
435 if (number) if (number[0])
436 l += strlen((char *)number);
439 p = msg_put(msg, l+2);
443 qi->calling_nr.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
444 p[0] = IE_CALLING_PN;
448 p[2] = 0x00 + (type<<4) + plan;
449 p[3] = 0x80 + (present<<5) + screen;
450 if (number) if (number[0])
451 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
454 p[2] = 0x80 + (type<<4) + plan;
455 if (number) if (number[0])
456 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
460 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)
471 if (qi->calling_nr.off)
472 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->calling_nr.off + 1;
478 PERROR("IE too short (%d).\n", p[0]);
482 *type = (p[1]&0x70) >> 4;
488 PERROR("IE too short (%d).\n", p[0]);
491 *present = (p[2]&0x60) >> 5;
492 *screen = p[2] & 0x3;
493 strnncpy(number, p+3, p[0]-2, number_len);
496 strnncpy(number, p+2, p[0]-1, number_len);
499 printisdn(" type=%d plan=%d present=%d screen=%d number='%s'\n", *type, *plan, *present, *screen, number);
503 /* IE_CONNECTED_PN */
504 void Pdss1::enc_ie_connected_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, unsigned char *number)
507 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
510 if (type<0 || type>7)
512 PERROR("type(%d) is out of range.\n", type);
515 if (plan<0 || plan>15)
517 PERROR("plan(%d) is out of range.\n", plan);
522 PERROR("present(%d) is out of range.\n", present);
525 if (present >= 0) if (screen<0 || screen>3)
527 PERROR("screen(%d) is out of range.\n", screen);
531 printisdn(" type=%d plan=%d present=%d screen=%d number='%s'\n", type, plan, present, screen, number);
534 if (number) if (number[0])
535 l += strlen((char *)number);
538 p = msg_put(msg, l+2);
542 qi->connected_nr.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
543 p[0] = IE_CONNECT_PN;
547 p[2] = 0x00 + (type<<4) + plan;
548 p[3] = 0x80 + (present<<5) + screen;
549 if (number) if (number[0])
550 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
553 p[2] = 0x80 + (type<<4) + plan;
554 if (number) if (number[0])
555 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
559 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)
570 if (qi->connected_nr.off)
571 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->connected_nr.off + 1;
577 PERROR("IE too short (%d).\n", p[0]);
581 *type = (p[1]&0x70) >> 4;
587 PERROR("IE too short (%d).\n", p[0]);
590 *present = (p[2]&0x60) >> 5;
591 *screen = p[2] & 0x3;
592 strnncpy(number, p+3, p[0]-2, number_len);
595 strnncpy(number, p+2, p[0]-1, number_len);
598 printisdn(" type=%d plan=%d present=%d screen=%d number='%s'\n", *type, *plan, *present, *screen, number);
603 void Pdss1::enc_ie_cause(unsigned char **ntmode, msg_t *msg, int location, int cause)
606 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
609 if (location<0 || location>7)
611 PERROR("location(%d) is out of range.\n", location);
614 if (cause<0 || cause>127)
616 PERROR("cause(%d) is out of range.\n", cause);
620 printisdn(" location=%d cause=%d\n", location, cause);
623 p = msg_put(msg, l+2);
627 qi->cause.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
630 p[2] = 0x80 + location;
633 void enc_ie_cause_standalone(unsigned char **ntmode, msg_t *msg, int location, int cause)
635 unsigned char *p = msg_put(msg, 4);
636 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
640 qi->cause.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
643 p[2] = 0x80 + location;
648 void Pdss1::dec_ie_cause(unsigned char *p, Q931_info_t *qi, int *location, int *cause)
657 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->cause.off + 1;
663 PERROR("IE too short (%d).\n", p[0]);
667 *location = p[1] & 0x0f;
668 *cause = p[2] & 0x7f;
670 printisdn(" location=%d cause=%d\n", *location, *cause);
675 void Pdss1::enc_ie_channel_id(unsigned char **ntmode, msg_t *msg, int exclusive, int channel)
678 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
680 int pri = p_m_mISDNport->pri;
682 if (exclusive<0 || exclusive>1)
684 PERROR("exclusive(%d) is out of range.\n", exclusive);
687 if ((channel<=0 && channel!=CHANNEL_NO && channel!=CHANNEL_ANY)
688 || (!pri && channel>2)
689 || (pri && channel>127)
690 || (pri && channel==16))
692 PERROR("channel(%d) is out of range.\n", channel);
696 printisdn(" exclusive=%d channel=%d\n", exclusive, channel);
702 p = msg_put(msg, l+2);
706 qi->channel_id.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
707 p[0] = IE_CHANNEL_ID;
709 if (channel == CHANNEL_NO)
711 else if (channel == CHANNEL_ANY)
713 p[2] = 0x80 + (exclusive<<3) + channel;
717 if (channel == CHANNEL_NO) /* no channel */
718 return; /* IE not present */
719 if (channel == CHANNEL_ANY) /* any channel */
722 p = msg_put(msg, l+2);
726 qi->channel_id.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
727 p[0] = IE_CHANNEL_ID;
729 p[2] = 0x80 + 0x20 + 0x03;
733 p = msg_put(msg, l+2);
737 qi->channel_id.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
738 p[0] = IE_CHANNEL_ID;
740 p[2] = 0x80 + 0x20 + (exclusive<<3) + 0x01;
741 p[3] = 0x80 + 3; /* CCITT, Number, B-type */
742 p[4] = 0x80 + channel;
746 void Pdss1::dec_ie_channel_id(unsigned char *p, Q931_info_t *qi, int *exclusive, int *channel)
748 int pri = p_m_mISDNport->pri;
756 if (qi->channel_id.off)
757 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->channel_id.off + 1;
763 PERROR("IE too short (%d).\n", p[0]);
769 PERROR("refering to channels of other interfaces is not supported.\n");
774 PERROR("using d-channel is not supported.\n");
778 *exclusive = (p[1]&0x08) >> 3;
784 PERROR("extended channel ID with non PRI interface.\n");
787 *channel = p[1] & 0x03;
789 *channel = CHANNEL_ANY;
790 else if (*channel == 0)
791 *channel = CHANNEL_NO;
797 PERROR("IE too short for PRI (%d).\n", p[0]);
802 PERROR("basic channel ID with PRI interface.\n");
805 if ((p[1]&0x03) == 0x00)
808 *channel = CHANNEL_NO;
811 if ((p[1]&0x03) == 0x03)
814 *channel = CHANNEL_ANY;
819 PERROR("%s: ERROR: IE too short for PRI with channel(%d).\n", __FUNCTION__, p[0]);
824 PERROR("channel map not supported.\n");
827 *channel = p[3] & 0x7f;
828 if (*channel<1 | *channel==16)
830 PERROR("PRI interface channel out of range (%d).\n", *channel);
835 printisdn(" exclusive=%d channel=%d\n", *exclusive, *channel);
840 void Pdss1::enc_ie_date(unsigned char **ntmode, msg_t *msg, time_t ti, int no_seconds)
843 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
851 PERROR("localtime() returned NULL.\n");
855 printisdn(" year=%d month=%d day=%d hour=%d minute=%d second=%d\n", tm->tm_year%100, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
857 l = 5 + (!no_seconds);
858 p = msg_put(msg, l+2);
862 qi->date.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
865 p[2] = tm->tm_year % 100;
866 p[3] = tm->tm_mon + 1;
876 void Pdss1::enc_ie_display(unsigned char **ntmode, msg_t *msg, unsigned char *display)
879 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
884 PERROR("display text not given.\n");
888 if (strlen((char *)display) > 80)
890 PERROR("display text too long (max 80 chars), cutting.\n");
894 printisdn(" display='%s' (len=%d)\n", display, strlen((char *)display));
896 l = strlen((char *)display);
897 p = msg_put(msg, l+2);
901 qi->display.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
904 UNCPY((char *)p+2, (char *)display, strlen((char *)display));
907 void Pdss1::dec_ie_display(unsigned char *p, Q931_info_t *qi, unsigned char *display, int display_len)
915 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->display.off + 1;
921 PERROR("IE too short (%d).\n", p[0]);
925 strnncpy(display, p+1, p[0], display_len);
927 printisdn(" display='%s'\n", display);
932 void Pdss1::enc_ie_keypad(unsigned char **ntmode, msg_t *msg, unsigned char *keypad)
935 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
940 PERROR("keypad info not given.\n");
944 printisdn(" keypad='%s'\n", keypad);
946 l = strlen((char *)keypad);
947 p = msg_put(msg, l+2);
951 qi->keypad.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
954 UNCPY((char *)p+2, (char *)keypad, strlen((char *)keypad));
957 void Pdss1::dec_ie_keypad(unsigned char *p, Q931_info_t *qi, unsigned char *keypad, int keypad_len)
965 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->keypad.off + 1;
971 PERROR("IE too short (%d).\n", p[0]);
975 strnncpy(keypad, p+1, p[0], keypad_len);
977 printisdn(" keypad='%s'\n", keypad);
982 void Pdss1::enc_ie_notify(unsigned char **ntmode, msg_t *msg, int notify)
985 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
988 if (notify<0 || notify>0x7f)
990 PERROR("notify(%d) is out of range.\n", notify);
994 printisdn(" notify=%d\n", notify);
997 p = msg_put(msg, l+2);
1001 qi->notify.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
1004 p[2] = 0x80 + notify;
1007 void Pdss1::dec_ie_notify(unsigned char *p, Q931_info_t *qi, int *notify)
1015 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->notify.off + 1;
1021 PERROR("IE too short (%d).\n", p[0]);
1025 *notify = p[1] & 0x7f;
1027 printisdn(" notify=%d\n", *notify);
1032 void Pdss1::enc_ie_progress(unsigned char **ntmode, msg_t *msg, int coding, int location, int progress)
1035 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1038 if (coding<0 || coding>0x03)
1040 PERROR("coding(%d) is out of range.\n", coding);
1043 if (location<0 || location>0x0f)
1045 PERROR("location(%d) is out of range.\n", location);
1048 if (progress<0 || progress>0x7f)
1050 PERROR("progress(%d) is out of range.\n", progress);
1054 printisdn(" coding=%d location=%d progress=%d\n", coding, location, progress);
1057 p = msg_put(msg, l+2);
1061 qi->progress.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
1064 p[2] = 0x80 + (coding<<5) + location;
1065 p[3] = 0x80 + progress;
1068 void Pdss1::dec_ie_progress(unsigned char *p, Q931_info_t *qi, int *coding, int *location, int *progress)
1077 if (qi->progress.off)
1078 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->progress.off + 1;
1084 PERROR("IE too short (%d).\n", p[0]);
1088 *coding = (p[1]&0x60) >> 5;
1089 *location = p[1] & 0x0f;
1090 *progress = p[2] & 0x7f;
1092 printisdn(" coding=%d location=%d progress=%d\n", *coding, *location, *progress);
1096 /* IE_REDIR_NR (redirecting = during MT_SETUP) */
1097 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)
1100 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1103 if (type<0 || type>7)
1105 PERROR("type(%d) is out of range.\n", type);
1108 if (plan<0 || plan>15)
1110 PERROR("plan(%d) is out of range.\n", plan);
1115 PERROR("present(%d) is out of range.\n", present);
1118 if (present >= 0) if (screen<0 || screen>3)
1120 PERROR("screen(%d) is out of range.\n", screen);
1125 PERROR("reason(%d) is out of range.\n", reason);
1129 printisdn(" type=%d plan=%d present=%d screen=%d readon=%d number='%s'\n", type, plan, present, screen, reason, number);
1133 l += strlen((char *)number);
1140 p = msg_put(msg, l+2);
1144 qi->redirect_nr.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
1151 p[2] = 0x00 + (type<<4) + plan;
1152 p[3] = 0x00 + (present<<5) + screen;
1153 p[4] = 0x80 + reason;
1155 UNCPY((char *)p+5, (char *)number, strlen((char *)number));
1158 p[2] = 0x00 + (type<<4) + plan;
1159 p[3] = 0x80 + (present<<5) + screen;
1161 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
1165 p[2] = 0x80 + (type<<4) + plan;
1166 if (number) if (number[0])
1167 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
1171 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)
1183 if (qi->redirect_nr.off)
1184 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->redirect_nr.off + 1;
1190 PERROR("IE too short (%d).\n", p[0]);
1194 *type = (p[1]&0x70) >> 4;
1198 *present = (p[2]&0x60) >> 5;
1199 *screen = p[2] & 0x3;
1202 *reason = p[3] & 0x0f;
1203 strnncpy(number, p+4, p[0]-3, number_len);
1206 strnncpy(number, p+3, p[0]-2, number_len);
1210 strnncpy(number, p+2, p[0]-1, number_len);
1213 printisdn(" type=%d plan=%d present=%d screen=%d reason=%d number='%s'\n", *type, *plan, *present, *screen, *reason, number);
1217 /* IE_REDIR_DN (redirection = during MT_NOTIFY) */
1218 void Pdss1::enc_ie_redir_dn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, unsigned char *number)
1221 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1224 if (type<0 || type>7)
1226 PERROR("type(%d) is out of range.\n", type);
1229 if (plan<0 || plan>15)
1231 PERROR("plan(%d) is out of range.\n", plan);
1236 PERROR("present(%d) is out of range.\n", present);
1240 printisdn(" type=%d plan=%d present=%d number='%s'\n", type, plan, present, number);
1244 l += strlen((char *)number);
1247 p = msg_put(msg, l+2);
1251 qi->redirect_dn.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
1256 p[2] = 0x00 + (type<<4) + plan;
1257 p[3] = 0x80 + (present<<5);
1259 UNCPY((char *)p+4, (char *)number, strlen((char *)number));
1262 p[2] = 0x80 + (type<<4) + plan;
1264 UNCPY((char *)p+3, (char *)number, strlen((char *)number));
1268 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)
1278 if (qi->redirect_dn.off)
1279 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->redirect_dn.off + 1;
1285 PERROR("IE too short (%d).\n", p[0]);
1289 *type = (p[1]&0x70) >> 4;
1293 *present = (p[2]&0x60) >> 5;
1294 strnncpy(number, p+3, p[0]-2, number_len);
1297 strnncpy(number, p+2, p[0]-1, number_len);
1300 printisdn(" type=%d plan=%d present=%d number='%s'\n", *type, *plan, *present, number);
1305 void Pdss1::enc_ie_facility(unsigned char **ntmode, msg_t *msg, unsigned char *facility, int facility_len)
1308 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1314 if (!facility || facility_len<=0)
1320 while(i < facility_len)
1322 UPRINT(debug+(i*3), " %02x", facility[i]);
1326 printisdn(" facility%s\n", debug);
1329 p = msg_put(msg, l+2);
1333 qi->facility.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
1336 memcpy(p+2, facility, facility_len);
1339 void Pdss1::dec_ie_facility(unsigned char *p, Q931_info_t *qi, unsigned char *facility, int *facility_len)
1349 if (qi->facility.off)
1350 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->facility.off + 1;
1355 *facility_len = p[0];
1356 memcpy(facility, p+1, *facility_len);
1359 while(i < *facility_len)
1361 UPRINT(debug+(i*3), " %02x", facility[i]);
1366 printisdn(" facility%s\n", debug);
1370 /* facility for siemens CENTEX (known parts implemented only) */
1371 void Pdss1::enc_facility_centrex(unsigned char **ntmode, msg_t *msg, unsigned char *cnip, int setup)
1373 unsigned char centrex[256];
1379 /* centrex facility */
1380 centrex[i++] = CENTREX_FAC;
1381 centrex[i++] = CENTREX_ID;
1384 if (strlen((char *)cnip) > 15)
1386 PDEBUG(DEBUG_PORT, "%s: CNIP/CONP text too long (max 13 chars), cutting.\n");
1389 // dunno what the 8 bytes mean
1392 centrex[i++] = 0x17;
1393 centrex[i++] = 0x02;
1394 centrex[i++] = 0x02;
1395 centrex[i++] = 0x44;
1396 centrex[i++] = 0x18;
1397 centrex[i++] = 0x02;
1398 centrex[i++] = 0x01;
1399 centrex[i++] = 0x09;
1402 centrex[i++] = 0x18;
1403 centrex[i++] = 0x02;
1404 centrex[i++] = 0x02;
1405 centrex[i++] = 0x81;
1406 centrex[i++] = 0x09;
1407 centrex[i++] = 0x02;
1408 centrex[i++] = 0x01;
1409 centrex[i++] = 0x0a;
1412 centrex[i++] = 0x80;
1413 centrex[i++] = strlen((char *)cnip);
1414 UCPY((char *)(¢rex[i]), (char *)cnip);
1415 i += strlen((char *)cnip);
1416 printisdn(" cnip='%s'\n", cnip);
1418 /* encode facility */
1419 enc_ie_facility(ntmode, msg, centrex, i);
1422 void Pdss1::dec_facility_centrex(unsigned char *p, Q931_info_t *qi, unsigned char *cnip, int cnip_len)
1424 unsigned char centrex[256];
1426 int facility_len = 0;
1430 dec_ie_facility(p, qi, centrex, &facility_len);
1431 if (facility_len >= 2)
1433 if (centrex[i++] != CENTREX_FAC)
1435 if (centrex[i++] != CENTREX_ID)
1439 /* loop sub IEs of facility */
1440 while(facility_len > i+1)
1442 if (centrex[i+1]+i+1 > facility_len)
1444 PERROR("short read of centrex facility.\n");
1450 strnncpy(cnip, ¢rex[i+2], centrex[i+1], cnip_len);
1451 printisdn(" CENTREX cnip='%s'\n", cnip);
1456 while(j < centrex[i+1])
1458 UPRINT(debug+(j*3), " %02x", centrex[i+1+j]);
1461 printisdn(" CENTREX unknown=0x%2x len=%d%s\n", centrex[i], centrex[i+1], debug);
1463 i += 1+centrex[i+1];
1469 void Pdss1::enc_ie_useruser(unsigned char **ntmode, msg_t *msg, int protocol, unsigned char *user, int user_len)
1472 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
1478 if (protocol<0 || protocol>127)
1480 PERROR("protocol(%d) is out of range.\n", protocol);
1483 if (!user || user_len<=0)
1491 UPRINT(debug+(i*3), " %02x", user[i]);
1495 printisdn(" protocol=%d user-user%s\n", protocol, debug);
1498 p = msg_put(msg, l+3);
1502 qi->useruser.off = p - (unsigned char *)qi - sizeof(Q931_info_t);
1503 p[0] = IE_USER_USER;
1505 p[2] = 0x80 + protocol;
1506 memcpy(p+3, user, user_len);
1509 void Pdss1::dec_ie_useruser(unsigned char *p, Q931_info_t *qi, int *protocol, unsigned char *user, int *user_len)
1520 if (qi->useruser.off)
1521 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->useruser.off + 1;
1530 memcpy(user, p+2, (*user_len<=128)?*(user_len):128); /* clip to 128 maximum */
1533 while(i < *user_len)
1535 UPRINT(debug+(i*3), " %02x", user[i]);
1540 printisdn(" protocol=%d user-user%s\n", *protocol, debug);