00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "asterisk.h"
00032
00033 #include <string.h>
00034
00035 #include <mISDNuser/mISDNlib.h>
00036 #include <mISDNuser/isdn_net.h>
00037 #include <mISDNuser/l3dss1.h>
00038 #include <mISDNuser/net_l3.h>
00039 #include "asterisk/localtime.h"
00040
00041
00042
00043 #define MISDN_IE_DEBG 0
00044
00045
00046 static void strnncpy(char *dest, const char *src, size_t len, size_t dst_len)
00047 {
00048 if (len > dst_len-1)
00049 len = dst_len-1;
00050 strncpy(dest, src, len);
00051 dest[len] = '\0';
00052 }
00053
00054
00055
00056 static void enc_ie_complete(unsigned char **ntmode, msg_t *msg, int complete, int nt, struct misdn_bchannel *bc)
00057 {
00058 unsigned char *p;
00059 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
00060
00061 if (complete<0 || complete>1)
00062 {
00063 printf("%s: ERROR: complete(%d) is out of range.\n", __FUNCTION__, complete);
00064 return;
00065 }
00066
00067 if (complete)
00068 if (MISDN_IE_DEBG) printf(" complete=%d\n", complete);
00069
00070 if (complete)
00071 {
00072 p = msg_put(msg, 1);
00073 if (nt)
00074 {
00075 *ntmode = p;
00076 } else
00077 qi->QI_ELEMENT(sending_complete) = p - (unsigned char *)qi - sizeof(Q931_info_t);
00078
00079 p[0] = IE_COMPLETE;
00080 }
00081 }
00082
00083 static void dec_ie_complete(unsigned char *p, Q931_info_t *qi, int *complete, int nt, struct misdn_bchannel *bc)
00084 {
00085 *complete = 0;
00086 if (!nt)
00087 {
00088 if (qi->QI_ELEMENT(sending_complete))
00089 *complete = 1;
00090 } else
00091 if (p)
00092 *complete = 1;
00093
00094 if (*complete)
00095 if (MISDN_IE_DEBG) printf(" complete=%d\n", *complete);
00096 }
00097
00098
00099
00100 static void enc_ie_bearer(unsigned char **ntmode, msg_t *msg, int coding, int capability, int mode, int rate, int multi, int user, int nt, struct misdn_bchannel *bc)
00101 {
00102 unsigned char *p;
00103 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
00104 int l;
00105
00106 if (coding<0 || coding>3)
00107 {
00108 printf("%s: ERROR: coding(%d) is out of range.\n", __FUNCTION__, coding);
00109 return;
00110 }
00111 if (capability<0 || capability>31)
00112 {
00113 printf("%s: ERROR: capability(%d) is out of range.\n", __FUNCTION__, capability);
00114 return;
00115 }
00116 if (mode<0 || mode>3)
00117 {
00118 printf("%s: ERROR: mode(%d) is out of range.\n", __FUNCTION__, mode);
00119 return;
00120 }
00121 if (rate<0 || rate>31)
00122 {
00123 printf("%s: ERROR: rate(%d) is out of range.\n", __FUNCTION__, rate);
00124 return;
00125 }
00126 if (multi>127)
00127 {
00128 printf("%s: ERROR: multi(%d) is out of range.\n", __FUNCTION__, multi);
00129 return;
00130 }
00131 if (user>31)
00132 {
00133 printf("%s: ERROR: user L1(%d) is out of range.\n", __FUNCTION__, rate);
00134 return;
00135 }
00136 if (rate!=24 && multi>=0)
00137 {
00138 printf("%s: WARNING: multi(%d) is only possible if rate(%d) would be 24.\n", __FUNCTION__, multi, rate);
00139 multi = -1;
00140 }
00141
00142 if (MISDN_IE_DEBG) printf(" coding=%d capability=%d mode=%d rate=%d multi=%d user=%d\n", coding, capability, mode, rate, multi, user);
00143
00144 l = 2 + (multi>=0) + (user>=0);
00145 p = msg_put(msg, l+2);
00146 if (nt)
00147 *ntmode = p+1;
00148 else
00149 qi->QI_ELEMENT(bearer_capability) = p - (unsigned char *)qi - sizeof(Q931_info_t);
00150 p[0] = IE_BEARER;
00151 p[1] = l;
00152 p[2] = 0x80 + (coding<<5) + capability;
00153 p[3] = 0x80 + (mode<<5) + rate;
00154 if (multi >= 0)
00155 p[4] = 0x80 + multi;
00156 if (user >= 0)
00157 p[4+(multi>=0)] = 0xa0 + user;
00158 }
00159
00160 static void dec_ie_bearer(unsigned char *p, Q931_info_t *qi, int *coding, int *capability, int *mode, int *rate, int *multi, int *user,
00161 int *async, int *urate, int *stopbits, int *dbits, int *parity, int nt, struct misdn_bchannel *bc)
00162 {
00163 int octet;
00164 *coding = -1;
00165 *capability = -1;
00166 *mode = -1;
00167 *rate = -1;
00168 *multi = -1;
00169 *user = -1;
00170 *async = -1;
00171 *urate = -1;
00172 *stopbits = -1;
00173 *dbits = -1;
00174 *parity = -1;
00175
00176 if (!nt)
00177 {
00178 p = NULL;
00179 #ifdef LLC_SUPPORT
00180 if (qi->QI_ELEMENT(llc)) {
00181
00182 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(llc) + 1;
00183 }
00184 #endif
00185 if (qi->QI_ELEMENT(bearer_capability))
00186 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(bearer_capability) + 1;
00187 }
00188 if (!p)
00189 return;
00190
00191 if (p[0] < 2)
00192 {
00193 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
00194 return;
00195 }
00196
00197 *coding = (p[1]&0x60) >> 5;
00198 *capability = p[1] & 0x1f;
00199 octet = 2;
00200 if (!(p[1] & 0x80))
00201 octet++;
00202
00203 if (p[0] < octet)
00204 goto done;
00205
00206 *mode = (p[octet]&0x60) >> 5;
00207 *rate = p[octet] & 0x1f;
00208
00209 octet++;
00210
00211 if (p[0] < octet)
00212 goto done;
00213
00214 if (*rate == 0x18) {
00215
00216 *multi = p[octet++] & 0x7f;
00217 }
00218
00219 if (p[0] < octet)
00220 goto done;
00221
00222
00223 if ((p[octet] & 0x60) == 0x20) {
00224 *user = p[octet] & 0x1f;
00225
00226 if (p[0] <= octet)
00227 goto done;
00228
00229 if (p[octet++] & 0x80)
00230 goto l2;
00231
00232 *async = !!(p[octet] & 0x40);
00233
00234 *urate = p[octet] & 0x1f;
00235
00236 if (p[0] <= octet)
00237 goto done;
00238
00239 if (p[octet++] & 0x80)
00240 goto l2;
00241
00242
00243
00244 if (p[0] <= octet)
00245 goto done;
00246
00247 if (p[octet++] & 0x80)
00248 goto l2;
00249
00250
00251
00252 if (p[0] <= octet)
00253 goto done;
00254
00255 if (~p[octet++] & 0x80)
00256 goto l2;
00257
00258
00259
00260 *stopbits = (p[octet] & 0x60) >> 5;
00261 *dbits = (p[octet] & 0x18) >> 3;
00262 *parity = p[octet] & 7;
00263
00264 octet++;
00265 }
00266 l2:
00267 done:
00268 if (MISDN_IE_DEBG) printf(" coding=%d capability=%d mode=%d rate=%d multi=%d user=%d async=%d urate=%d stopbits=%d dbits=%d parity=%d\n", *coding, *capability, *mode, *rate, *multi, *user, *async, *urate, *stopbits, *dbits, *parity);
00269 }
00270
00271
00272
00273 #if 0
00274 static void enc_ie_call_id(unsigned char **ntmode, msg_t *msg, char *callid, int callid_len, int nt, struct misdn_bchannel *bc)
00275 {
00276 unsigned char *p;
00277 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
00278 int l;
00279
00280 char debug[25];
00281 int i;
00282
00283 if (!callid || callid_len<=0)
00284 {
00285 return;
00286 }
00287 if (callid_len>8)
00288 {
00289 printf("%s: ERROR: callid_len(%d) is out of range.\n", __FUNCTION__, callid_len);
00290 return;
00291 }
00292
00293 i = 0;
00294 while(i < callid_len)
00295 {
00296 if (MISDN_IE_DEBG) printf(debug+(i*3), " %02x", callid[i]);
00297 i++;
00298 }
00299
00300 if (MISDN_IE_DEBG) printf(" callid%s\n", debug);
00301
00302 l = callid_len;
00303 p = msg_put(msg, l+2);
00304 if (nt)
00305 *ntmode = p+1;
00306 else
00307 qi->QI_ELEMENT(call_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
00308 p[0] = IE_CALL_ID;
00309 p[1] = l;
00310 memcpy(p+2, callid, callid_len);
00311 }
00312 #endif
00313
00314 #if 0
00315 static void dec_ie_call_id(unsigned char *p, Q931_info_t *qi, char *callid, int *callid_len, int nt, struct misdn_bchannel *bc)
00316 {
00317 char debug[25];
00318 int i;
00319
00320 *callid_len = -1;
00321
00322 if (!nt)
00323 {
00324 p = NULL;
00325 if (qi->QI_ELEMENT(call_id))
00326 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(call_id) + 1;
00327 }
00328 if (!p)
00329 return;
00330 if (p[0] > 8)
00331 {
00332 printf("%s: ERROR: IE too long (%d).\n", __FUNCTION__, p[0]);
00333 return;
00334 }
00335
00336 *callid_len = p[0];
00337 memcpy(callid, p+1, *callid_len);
00338
00339 i = 0;
00340 while(i < *callid_len)
00341 {
00342 if (MISDN_IE_DEBG) printf(debug+(i*3), " %02x", callid[i]);
00343 i++;
00344 }
00345
00346 if (MISDN_IE_DEBG) printf(" callid%s\n", debug);
00347 }
00348 #endif
00349
00350
00351 static void enc_ie_called_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, char *number, int nt, struct misdn_bchannel *bc)
00352 {
00353 unsigned char *p;
00354 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
00355 int l;
00356
00357 if (type<0 || type>7)
00358 {
00359 printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
00360 return;
00361 }
00362 if (plan<0 || plan>15)
00363 {
00364 printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
00365 return;
00366 }
00367 if (!number[0])
00368 {
00369 printf("%s: ERROR: number is not given.\n", __FUNCTION__);
00370 return;
00371 }
00372
00373 if (MISDN_IE_DEBG) printf(" type=%d plan=%d number='%s'\n", type, plan, number);
00374
00375 l = 1+strlen((char *)number);
00376 p = msg_put(msg, l+2);
00377 if (nt)
00378 *ntmode = p+1;
00379 else
00380 qi->QI_ELEMENT(called_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
00381 p[0] = IE_CALLED_PN;
00382 p[1] = l;
00383 p[2] = 0x80 + (type<<4) + plan;
00384 strncpy((char *)p+3, (char *)number, strlen((char *)number));
00385 }
00386
00387 static void dec_ie_called_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
00388 {
00389 *type = -1;
00390 *plan = -1;
00391 *number = '\0';
00392
00393 if (!nt)
00394 {
00395 p = NULL;
00396 if (qi->QI_ELEMENT(called_nr))
00397 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(called_nr) + 1;
00398 }
00399 if (!p)
00400 return;
00401 if (p[0] < 2)
00402 {
00403 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
00404 return;
00405 }
00406
00407 *type = (p[1]&0x70) >> 4;
00408 *plan = p[1] & 0xf;
00409 strnncpy(number, (char *)p+2, p[0]-1, number_len);
00410
00411 if (MISDN_IE_DEBG) printf(" type=%d plan=%d number='%s'\n", *type, *plan, number);
00412 }
00413
00414
00415
00416 static void enc_ie_calling_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, char *number, int nt, struct misdn_bchannel *bc)
00417 {
00418 unsigned char *p;
00419 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
00420 int l;
00421
00422 if (type<0 || type>7)
00423 {
00424 printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
00425 return;
00426 }
00427 if (plan<0 || plan>15)
00428 {
00429 printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
00430 return;
00431 }
00432 if (present>3)
00433 {
00434 printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
00435 return;
00436 }
00437 if (present >= 0) if (screen<0 || screen>3)
00438 {
00439 printf("%s: ERROR: screen(%d) is out of range.\n", __FUNCTION__, screen);
00440 return;
00441 }
00442
00443 if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d screen=%d number='%s'\n", type, plan, present, screen, number);
00444
00445 l = 1;
00446 if (number) if (number[0])
00447 l += strlen((char *)number);
00448 if (present >= 0)
00449 l += 1;
00450 p = msg_put(msg, l+2);
00451 if (nt)
00452 *ntmode = p+1;
00453 else
00454 qi->QI_ELEMENT(calling_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
00455 p[0] = IE_CALLING_PN;
00456 p[1] = l;
00457 if (present >= 0)
00458 {
00459 p[2] = 0x00 + (type<<4) + plan;
00460 p[3] = 0x80 + (present<<5) + screen;
00461 if (number) if (number[0])
00462 strncpy((char *)p+4, (char *)number, strlen((char *)number));
00463 } else
00464 {
00465 p[2] = 0x80 + (type<<4) + plan;
00466 if (number) if (number[0])
00467 strncpy((char *)p+3, (char *)number, strlen((char *)number));
00468 }
00469 }
00470
00471 static void dec_ie_calling_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
00472 {
00473 *type = -1;
00474 *plan = -1;
00475 *present = -1;
00476 *screen = -1;
00477 *number = '\0';
00478
00479 if (!nt)
00480 {
00481 p = NULL;
00482 if (qi->QI_ELEMENT(calling_nr))
00483 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(calling_nr) + 1;
00484 }
00485 if (!p)
00486 return;
00487 if (p[0] < 1)
00488 {
00489 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
00490 return;
00491 }
00492
00493 *type = (p[1]&0x70) >> 4;
00494 *plan = p[1] & 0xf;
00495 if (!(p[1] & 0x80))
00496 {
00497 if (p[0] < 2)
00498 {
00499 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
00500 return;
00501 }
00502 *present = (p[2]&0x60) >> 5;
00503 *screen = p[2] & 0x3;
00504 strnncpy(number, (char *)p+3, p[0]-2, number_len);
00505 } else
00506 {
00507 strnncpy(number, (char *)p+2, p[0]-1, number_len);
00508
00509
00510
00511 }
00512
00513 if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d screen=%d number='%s'\n", *type, *plan, *present, *screen, number);
00514 }
00515
00516
00517
00518 static void enc_ie_connected_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, char *number, int nt, struct misdn_bchannel *bc)
00519 {
00520 unsigned char *p;
00521 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
00522 int l;
00523
00524 if (type<0 || type>7)
00525 {
00526 printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
00527 return;
00528 }
00529 if (plan<0 || plan>15)
00530 {
00531 printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
00532 return;
00533 }
00534 if (present>3)
00535 {
00536 printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
00537 return;
00538 }
00539 if (present >= 0) if (screen<0 || screen>3)
00540 {
00541 printf("%s: ERROR: screen(%d) is out of range.\n", __FUNCTION__, screen);
00542 return;
00543 }
00544
00545 if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d screen=%d number='%s'\n", type, plan, present, screen, number);
00546
00547 l = 1;
00548 if (number) if (number[0])
00549 l += strlen((char *)number);
00550 if (present >= 0)
00551 l += 1;
00552 p = msg_put(msg, l+2);
00553 if (nt)
00554 *ntmode = p+1;
00555 else
00556 qi->QI_ELEMENT(connected_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
00557 p[0] = IE_CONNECT_PN;
00558 p[1] = l;
00559 if (present >= 0)
00560 {
00561 p[2] = 0x00 + (type<<4) + plan;
00562 p[3] = 0x80 + (present<<5) + screen;
00563 if (number) if (number[0])
00564 strncpy((char *)p+4, (char *)number, strlen((char *)number));
00565 } else
00566 {
00567 p[2] = 0x80 + (type<<4) + plan;
00568 if (number) if (number[0])
00569 strncpy((char *)p+3, (char *)number, strlen((char *)number));
00570 }
00571 }
00572
00573 static void dec_ie_connected_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
00574 {
00575 *type = -1;
00576 *plan = -1;
00577 *present = -1;
00578 *screen = -1;
00579 *number = '\0';
00580
00581 if (!nt)
00582 {
00583 p = NULL;
00584 if (qi->QI_ELEMENT(connected_nr))
00585 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(connected_nr) + 1;
00586 }
00587 if (!p)
00588 return;
00589 if (p[0] < 1)
00590 {
00591 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
00592 return;
00593 }
00594
00595 *type = (p[1]&0x70) >> 4;
00596 *plan = p[1] & 0xf;
00597 if (!(p[1] & 0x80))
00598 {
00599 if (p[0] < 2)
00600 {
00601 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
00602 return;
00603 }
00604 *present = (p[2]&0x60) >> 5;
00605 *screen = p[2] & 0x3;
00606 strnncpy(number, (char *)p+3, p[0]-2, number_len);
00607 } else
00608 {
00609 strnncpy(number, (char *)p+2, p[0]-1, number_len);
00610 }
00611
00612 if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d screen=%d number='%s'\n", *type, *plan, *present, *screen, number);
00613 }
00614
00615
00616
00617 static void enc_ie_cause(unsigned char **ntmode, msg_t *msg, int location, int cause, int nt, struct misdn_bchannel *bc)
00618 {
00619 unsigned char *p;
00620 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
00621 int l;
00622
00623 if (location<0 || location>7)
00624 {
00625 printf("%s: ERROR: location(%d) is out of range.\n", __FUNCTION__, location);
00626 return;
00627 }
00628 if (cause<0 || cause>127)
00629 {
00630 printf("%s: ERROR: cause(%d) is out of range.\n", __FUNCTION__, cause);
00631 return;
00632 }
00633
00634 if (MISDN_IE_DEBG) printf(" location=%d cause=%d\n", location, cause);
00635
00636 l = 2;
00637 p = msg_put(msg, l+2);
00638 if (nt)
00639 *ntmode = p+1;
00640 else
00641 qi->QI_ELEMENT(cause) = p - (unsigned char *)qi - sizeof(Q931_info_t);
00642 p[0] = IE_CAUSE;
00643 p[1] = l;
00644 p[2] = 0x80 + location;
00645 p[3] = 0x80 + cause;
00646 }
00647
00648 #if 0
00649 static void enc_ie_cause_standalone(unsigned char **ntmode, msg_t *msg, int location, int cause, int nt, struct misdn_bchannel *bc)
00650 {
00651 unsigned char *p = msg_put(msg, 4);
00652 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
00653 if (ntmode)
00654 *ntmode = p+1;
00655 else
00656 qi->QI_ELEMENT(cause) = p - (unsigned char *)qi - sizeof(Q931_info_t);
00657 p[0] = IE_CAUSE;
00658 p[1] = 2;
00659 p[2] = 0x80 + location;
00660 p[3] = 0x80 + cause;
00661 }
00662 #endif
00663
00664 static void dec_ie_cause(unsigned char *p, Q931_info_t *qi, int *location, int *cause, int nt, struct misdn_bchannel *bc)
00665 {
00666 *location = -1;
00667 *cause = -1;
00668
00669 if (!nt)
00670 {
00671 p = NULL;
00672 if (qi->QI_ELEMENT(cause))
00673 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(cause) + 1;
00674 }
00675 if (!p)
00676 return;
00677 if (p[0] < 2)
00678 {
00679 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
00680 return;
00681 }
00682
00683 *location = p[1] & 0x0f;
00684 *cause = p[2] & 0x7f;
00685
00686 if (MISDN_IE_DEBG) printf(" location=%d cause=%d\n", *location, *cause);
00687 }
00688
00689
00690
00691 static void enc_ie_channel_id(unsigned char **ntmode, msg_t *msg, int exclusive, int channel, int nt, struct misdn_bchannel *bc)
00692 {
00693 unsigned char *p;
00694 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
00695 int l;
00696 struct misdn_stack *stack=get_stack_by_bc(bc);
00697 int pri = stack->pri;
00698
00699 if (exclusive<0 || exclusive>1)
00700 {
00701 printf("%s: ERROR: exclusive(%d) is out of range.\n", __FUNCTION__, exclusive);
00702 return;
00703 }
00704 if ((channel<0 || channel>0xff)
00705 || (!pri && (channel>2 && channel<0xff))
00706 || (pri && (channel>31 && channel<0xff))
00707 || (pri && channel==16))
00708 {
00709 printf("%s: ERROR: channel(%d) is out of range.\n", __FUNCTION__, channel);
00710 return;
00711 }
00712
00713
00714
00715
00716 if (!pri)
00717 {
00718
00719 l = 1;
00720 p = msg_put(msg, l+2);
00721 if (nt)
00722 *ntmode = p+1;
00723 else
00724 qi->QI_ELEMENT(channel_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
00725 p[0] = IE_CHANNEL_ID;
00726 p[1] = l;
00727 if (channel == 0xff)
00728 channel = 3;
00729 p[2] = 0x80 + (exclusive<<3) + channel;
00730
00731 } else
00732 {
00733
00734 if (channel == 0)
00735 return;
00736
00737 if (channel == 0xff)
00738 {
00739 l = 1;
00740 p = msg_put(msg, l+2);
00741 if (nt)
00742 *ntmode = p+1;
00743 else
00744 qi->QI_ELEMENT(channel_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
00745 p[0] = IE_CHANNEL_ID;
00746 p[1] = l;
00747 p[2] = 0x80 + 0x20 + 0x03;
00748
00749 return;
00750 }
00751 l = 3;
00752 p = msg_put(msg, l+2);
00753 if (nt)
00754 *ntmode = p+1;
00755 else
00756 qi->QI_ELEMENT(channel_id) = p - (unsigned char *)qi - sizeof(Q931_info_t);
00757 p[0] = IE_CHANNEL_ID;
00758 p[1] = l;
00759 p[2] = 0x80 + 0x20 + (exclusive<<3) + 0x01;
00760 p[3] = 0x80 + 3;
00761 p[4] = 0x80 + channel;
00762
00763 }
00764 }
00765
00766 static void dec_ie_channel_id(unsigned char *p, Q931_info_t *qi, int *exclusive, int *channel, int nt, struct misdn_bchannel *bc)
00767 {
00768 struct misdn_stack *stack=get_stack_by_bc(bc);
00769 int pri =stack->pri;
00770
00771 *exclusive = -1;
00772 *channel = -1;
00773
00774 if (!nt)
00775 {
00776 p = NULL;
00777 if (qi->QI_ELEMENT(channel_id))
00778 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(channel_id) + 1;
00779 }
00780 if (!p)
00781 return;
00782 if (p[0] < 1)
00783 {
00784 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
00785 return;
00786 }
00787
00788 if (p[1] & 0x40)
00789 {
00790 printf("%s: ERROR: refering to channels of other interfaces is not supported.\n", __FUNCTION__);
00791 return;
00792 }
00793 if (p[1] & 0x04)
00794 {
00795 printf("%s: ERROR: using d-channel is not supported.\n", __FUNCTION__);
00796 return;
00797 }
00798
00799 *exclusive = (p[1]&0x08) >> 3;
00800 if (!pri)
00801 {
00802
00803 if (p[1] & 0x20)
00804 {
00805 printf("%s: ERROR: extended channel ID with non PRI interface.\n", __FUNCTION__);
00806 return;
00807 }
00808 *channel = p[1] & 0x03;
00809 if (*channel == 3)
00810 *channel = 0xff;
00811 } else
00812 {
00813
00814 if (p[0] < 1)
00815 {
00816 printf("%s: ERROR: IE too short for PRI (%d).\n", __FUNCTION__, p[0]);
00817 return;
00818 }
00819 if (!(p[1] & 0x20))
00820 {
00821 printf("%s: ERROR: basic channel ID with PRI interface.\n", __FUNCTION__);
00822 return;
00823 }
00824 if ((p[1]&0x03) == 0x00)
00825 {
00826
00827 *channel = 0;
00828 return;
00829 }
00830 if ((p[1]&0x03) == 0x03)
00831 {
00832
00833 *channel = 0xff;
00834 return;
00835 }
00836 if (p[0] < 3)
00837 {
00838 printf("%s: ERROR: IE too short for PRI with channel(%d).\n", __FUNCTION__, p[0]);
00839 return;
00840 }
00841 if (p[2] & 0x10)
00842 {
00843 printf("%s: ERROR: channel map not supported.\n", __FUNCTION__);
00844 return;
00845 }
00846 *channel = p[3] & 0x7f;
00847 if ( (*channel<1) | (*channel==16) | (*channel>31))
00848 {
00849 printf("%s: ERROR: PRI interface channel out of range (%d).\n", __FUNCTION__, *channel);
00850 return;
00851 }
00852
00853 }
00854
00855 if (MISDN_IE_DEBG) printf(" exclusive=%d channel=%d\n", *exclusive, *channel);
00856 }
00857
00858
00859
00860 static void enc_ie_date(unsigned char **ntmode, msg_t *msg, time_t ti, int nt, struct misdn_bchannel *bc)
00861 {
00862 unsigned char *p;
00863 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
00864 int l;
00865 struct timeval tv = { ti, 0 };
00866 struct ast_tm tm;
00867
00868 ast_localtime(&tv, &tm, NULL);
00869 if (MISDN_IE_DEBG) printf(" year=%d month=%d day=%d hour=%d minute=%d\n", tm.tm_year%100, tm.tm_mon+1, tm.tm_mday, tm.tm_hour, tm.tm_min);
00870
00871 l = 5;
00872 p = msg_put(msg, l+2);
00873 if (nt)
00874 *ntmode = p+1;
00875 else
00876 qi->QI_ELEMENT(date) = p - (unsigned char *)qi - sizeof(Q931_info_t);
00877 p[0] = IE_DATE;
00878 p[1] = l;
00879 p[2] = tm.tm_year % 100;
00880 p[3] = tm.tm_mon + 1;
00881 p[4] = tm.tm_mday;
00882 p[5] = tm.tm_hour;
00883 p[6] = tm.tm_min;
00884 }
00885
00886
00887
00888 static void enc_ie_display(unsigned char **ntmode, msg_t *msg, char *display, int nt, struct misdn_bchannel *bc)
00889 {
00890 unsigned char *p;
00891 Q931_info_t *qi = (Q931_info_t *) (msg->data + mISDN_HEADER_LEN);
00892 int l;
00893
00894 if (!display[0])
00895 {
00896 printf("%s: ERROR: display text not given.\n", __FUNCTION__);
00897 return;
00898 }
00899
00900 l = strlen(display);
00901 if (80 < l)
00902 {
00903 l = 80;
00904 printf("%s: WARNING: display text too long (max %d chars), cutting.\n", __FUNCTION__, l);
00905 display[l] = '\0';
00906 }
00907
00908
00909
00910 p = msg_put(msg, l + 2);
00911 if (nt)
00912 *ntmode = p + 1;
00913 else
00914 qi->QI_ELEMENT(display) = p - (unsigned char *) qi - sizeof(Q931_info_t);
00915 p[0] = IE_DISPLAY;
00916 p[1] = l;
00917 strncpy((char *) p + 2, display, l);
00918 }
00919
00920 #if 0
00921 static void dec_ie_display(unsigned char *p, Q931_info_t *qi, char *display, size_t display_len, int nt, struct misdn_bchannel *bc)
00922 {
00923 *display = '\0';
00924
00925 if (!nt)
00926 {
00927 p = NULL;
00928 if (qi->QI_ELEMENT(display))
00929 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(display) + 1;
00930 }
00931 if (!p)
00932 return;
00933 if (p[0] < 1)
00934 {
00935 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
00936 return;
00937 }
00938
00939 strnncpy(display, (char *)p+1, p[0], display_len);
00940
00941 if (MISDN_IE_DEBG) printf(" display='%s'\n", display);
00942 }
00943 #endif
00944
00945
00946 #if 1
00947 static void enc_ie_keypad(unsigned char **ntmode, msg_t *msg, char *keypad, int nt, struct misdn_bchannel *bc)
00948 {
00949 unsigned char *p;
00950 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
00951 int l;
00952
00953 if (!keypad[0])
00954 {
00955 printf("%s: ERROR: keypad info not given.\n", __FUNCTION__);
00956 return;
00957 }
00958
00959 if (MISDN_IE_DEBG) printf(" keypad='%s'\n", keypad);
00960
00961 l = strlen(keypad);
00962 p = msg_put(msg, l+2);
00963 if (nt)
00964 *ntmode = p+1;
00965 else
00966 qi->QI_ELEMENT(keypad) = p - (unsigned char *)qi - sizeof(Q931_info_t);
00967 p[0] = IE_KEYPAD;
00968 p[1] = l;
00969 strncpy((char *)p+2, keypad, strlen(keypad));
00970 }
00971 #endif
00972
00973 static void dec_ie_keypad(unsigned char *p, Q931_info_t *qi, char *keypad, size_t keypad_len, int nt, struct misdn_bchannel *bc)
00974 {
00975 *keypad = '\0';
00976
00977 if (!nt)
00978 {
00979 p = NULL;
00980 if (qi->QI_ELEMENT(keypad))
00981 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(keypad) + 1;
00982 }
00983 if (!p)
00984 return;
00985 if (p[0] < 1)
00986 {
00987 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
00988 return;
00989 }
00990
00991 strnncpy(keypad, (char *)p+1, p[0], keypad_len);
00992
00993 if (MISDN_IE_DEBG) printf(" keypad='%s'\n", keypad);
00994 }
00995
00996
00997
00998 static void enc_ie_notify(unsigned char **ntmode, msg_t *msg, int notify, int nt, struct misdn_bchannel *bc)
00999 {
01000 unsigned char *p;
01001 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
01002 int l;
01003
01004 if (notify<0 || notify>0x7f)
01005 {
01006 printf("%s: ERROR: notify(%d) is out of range.\n", __FUNCTION__, notify);
01007 return;
01008 }
01009
01010 if (MISDN_IE_DEBG) printf(" notify=%d\n", notify);
01011
01012 l = 1;
01013 p = msg_put(msg, l+2);
01014 if (nt)
01015 *ntmode = p+1;
01016 else
01017 qi->QI_ELEMENT(notify) = p - (unsigned char *)qi - sizeof(Q931_info_t);
01018 p[0] = IE_NOTIFY;
01019 p[1] = l;
01020 p[2] = 0x80 + notify;
01021 }
01022
01023 static void dec_ie_notify(unsigned char *p, Q931_info_t *qi, int *notify, int nt, struct misdn_bchannel *bc)
01024 {
01025 *notify = -1;
01026
01027 if (!nt)
01028 {
01029 p = NULL;
01030 if (qi->QI_ELEMENT(notify))
01031 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(notify) + 1;
01032 }
01033 if (!p)
01034 return;
01035 if (p[0] < 1)
01036 {
01037 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
01038 return;
01039 }
01040
01041 *notify = p[1] & 0x7f;
01042
01043 if (MISDN_IE_DEBG) printf(" notify=%d\n", *notify);
01044 }
01045
01046
01047
01048 static void enc_ie_progress(unsigned char **ntmode, msg_t *msg, int coding, int location, int progress, int nt, struct misdn_bchannel *bc)
01049 {
01050 unsigned char *p;
01051 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
01052 int l;
01053
01054 if (coding<0 || coding>0x03)
01055 {
01056 printf("%s: ERROR: coding(%d) is out of range.\n", __FUNCTION__, coding);
01057 return;
01058 }
01059 if (location<0 || location>0x0f)
01060 {
01061 printf("%s: ERROR: location(%d) is out of range.\n", __FUNCTION__, location);
01062 return;
01063 }
01064 if (progress<0 || progress>0x7f)
01065 {
01066 printf("%s: ERROR: progress(%d) is out of range.\n", __FUNCTION__, progress);
01067 return;
01068 }
01069
01070 if (MISDN_IE_DEBG) printf(" coding=%d location=%d progress=%d\n", coding, location, progress);
01071
01072 l = 2;
01073 p = msg_put(msg, l+2);
01074 if (nt)
01075 *ntmode = p+1;
01076 else
01077 qi->QI_ELEMENT(progress) = p - (unsigned char *)qi - sizeof(Q931_info_t);
01078 p[0] = IE_PROGRESS;
01079 p[1] = l;
01080 p[2] = 0x80 + (coding<<5) + location;
01081 p[3] = 0x80 + progress;
01082 }
01083
01084 static void dec_ie_progress(unsigned char *p, Q931_info_t *qi, int *coding, int *location, int *progress, int nt, struct misdn_bchannel *bc)
01085 {
01086 *coding = -1;
01087 *location = -1;
01088
01089 *progress = 0;
01090
01091 if (!nt)
01092 {
01093 p = NULL;
01094 if (qi->QI_ELEMENT(progress))
01095 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(progress) + 1;
01096 }
01097 if (!p)
01098 return;
01099 if (p[0] < 1)
01100 {
01101 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
01102 return;
01103 }
01104
01105 *coding = (p[1]&0x60) >> 5;
01106 *location = p[1] & 0x0f;
01107 *progress = p[2] & 0x7f;
01108
01109 if (MISDN_IE_DEBG) printf(" coding=%d location=%d progress=%d\n", *coding, *location, *progress);
01110 }
01111
01112
01113
01114 static void enc_ie_redir_nr(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, int reason, char *number, int nt, struct misdn_bchannel *bc)
01115 {
01116 unsigned char *p;
01117 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
01118 int l;
01119
01120 if (type<0 || type>7)
01121 {
01122 printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
01123 return;
01124 }
01125 if (plan<0 || plan>15)
01126 {
01127 printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
01128 return;
01129 }
01130 if (present > 3)
01131 {
01132 printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
01133 return;
01134 }
01135 if (present >= 0) if (screen<0 || screen>3)
01136 {
01137 printf("%s: ERROR: screen(%d) is out of range.\n", __FUNCTION__, screen);
01138 return;
01139 }
01140 if (reason > 0x0f)
01141 {
01142 printf("%s: ERROR: reason(%d) is out of range.\n", __FUNCTION__, reason);
01143 return;
01144 }
01145
01146 if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d screen=%d readon=%d number='%s'\n", type, plan, present, screen, reason, number);
01147
01148 l = 1;
01149 if (number)
01150 l += strlen((char *)number);
01151 if (present >= 0)
01152 {
01153 l += 1;
01154 if (reason >= 0)
01155 l += 1;
01156 }
01157 p = msg_put(msg, l+2);
01158 if (nt)
01159 *ntmode = p+1;
01160 else
01161 qi->QI_ELEMENT(redirect_nr) = p - (unsigned char *)qi - sizeof(Q931_info_t);
01162 p[0] = IE_REDIR_NR;
01163 p[1] = l;
01164 if (present >= 0)
01165 {
01166 if (reason >= 0)
01167 {
01168 p[2] = 0x00 + (type<<4) + plan;
01169 p[3] = 0x00 + (present<<5) + screen;
01170 p[4] = 0x80 + reason;
01171 if (number)
01172 strncpy((char *)p+5, (char *)number, strlen((char *)number));
01173 } else
01174 {
01175 p[2] = 0x00 + (type<<4) + plan;
01176 p[3] = 0x80 + (present<<5) + screen;
01177 if (number)
01178 strncpy((char *)p+4, (char *)number, strlen((char *)number));
01179 }
01180 } else
01181 {
01182 p[2] = 0x80 + (type<<4) + plan;
01183 if (number) if (number[0])
01184 strncpy((char *)p+3, (char *)number, strlen((char *)number));
01185 }
01186 }
01187
01188 static void dec_ie_redir_nr(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, int *reason, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
01189 {
01190 *type = -1;
01191 *plan = -1;
01192 *present = -1;
01193 *screen = -1;
01194 *reason = -1;
01195 *number = '\0';
01196
01197 if (!nt)
01198 {
01199 p = NULL;
01200 if (qi->QI_ELEMENT(redirect_nr))
01201 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(redirect_nr) + 1;
01202 }
01203 if (!p)
01204 return;
01205 if (p[0] < 1)
01206 {
01207 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
01208 return;
01209 }
01210
01211 *type = (p[1]&0x70) >> 4;
01212 *plan = p[1] & 0xf;
01213 if (!(p[1] & 0x80))
01214 {
01215 *present = (p[2]&0x60) >> 5;
01216 *screen = p[2] & 0x3;
01217 if (!(p[2] & 0x80))
01218 {
01219 *reason = p[3] & 0x0f;
01220 strnncpy(number, (char *)p+4, p[0]-3, number_len);
01221 } else
01222 {
01223 strnncpy(number, (char *)p+3, p[0]-2, number_len);
01224 }
01225 } else
01226 {
01227 strnncpy(number, (char *)p+2, p[0]-1, number_len);
01228 }
01229
01230 if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d screen=%d reason=%d number='%s'\n", *type, *plan, *present, *screen, *reason, number);
01231 }
01232
01233
01234
01235 static void enc_ie_redir_dn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, char *number, int nt, struct misdn_bchannel *bc)
01236 {
01237 unsigned char *p;
01238 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
01239 int l;
01240
01241 if (type<0 || type>7)
01242 {
01243 printf("%s: ERROR: type(%d) is out of range.\n", __FUNCTION__, type);
01244 return;
01245 }
01246 if (plan<0 || plan>15)
01247 {
01248 printf("%s: ERROR: plan(%d) is out of range.\n", __FUNCTION__, plan);
01249 return;
01250 }
01251 if (present > 3)
01252 {
01253 printf("%s: ERROR: present(%d) is out of range.\n", __FUNCTION__, present);
01254 return;
01255 }
01256
01257 if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d number='%s'\n", type, plan, present, number);
01258
01259 l = 1;
01260 if (number)
01261 l += strlen((char *)number);
01262 if (present >= 0)
01263 l += 1;
01264 p = msg_put(msg, l+2);
01265 if (nt)
01266 *ntmode = p+1;
01267 else {
01268 qi->QI_ELEMENT(redirect_dn) = p - (unsigned char *)qi - sizeof(Q931_info_t);
01269 }
01270 p[0] = IE_REDIR_DN;
01271 p[1] = l;
01272 if (present >= 0)
01273 {
01274 p[2] = 0x00 + (type<<4) + plan;
01275 p[3] = 0x80 + (present<<5);
01276 if (number)
01277 strncpy((char *)p+4, (char *)number, strlen((char *)number));
01278 } else
01279 {
01280 p[2] = 0x80 + (type<<4) + plan;
01281 if (number)
01282 strncpy((char *)p+3, (char *)number, strlen((char *)number));
01283 }
01284 }
01285
01286 static void dec_ie_redir_dn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, char *number, size_t number_len, int nt, struct misdn_bchannel *bc)
01287 {
01288 *type = -1;
01289 *plan = -1;
01290 *present = -1;
01291 *number = '\0';
01292
01293 if (!nt)
01294 {
01295 p = NULL;
01296 if (qi->QI_ELEMENT(redirect_dn))
01297 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(redirect_dn) + 1;
01298 }
01299 if (!p)
01300 return;
01301 if (p[0] < 1)
01302 {
01303 printf("%s: ERROR: IE too short (%d).\n", __FUNCTION__, p[0]);
01304 return;
01305 }
01306
01307 *type = (p[1]&0x70) >> 4;
01308 *plan = p[1] & 0xf;
01309 if (!(p[1] & 0x80))
01310 {
01311 *present = (p[2]&0x60) >> 5;
01312 strnncpy(number, (char *)p+3, p[0]-2, number_len);
01313 } else
01314 {
01315 strnncpy(number, (char *)p+2, p[0]-1, number_len);
01316 }
01317
01318 if (MISDN_IE_DEBG) printf(" type=%d plan=%d present=%d number='%s'\n", *type, *plan, *present, number);
01319 }
01320
01321
01322
01323 #if 1
01324 static void enc_ie_useruser(unsigned char **ntmode, msg_t *msg, int protocol, char *user, int user_len, int nt, struct misdn_bchannel *bc)
01325 {
01326 unsigned char *p;
01327 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
01328 int l;
01329
01330 if (protocol<0 || protocol>127)
01331 {
01332 printf("%s: ERROR: protocol(%d) is out of range.\n", __FUNCTION__, protocol);
01333 return;
01334 }
01335 if (!user || user_len<=0)
01336 {
01337 return;
01338 }
01339
01340 if (MISDN_IE_DEBG) {
01341 size_t i;
01342 char debug[768];
01343
01344 for (i = 0; i < user_len; ++i) {
01345 sprintf(debug + (i * 3), " %02x", user[i]);
01346 }
01347 debug[i * 3] = 0;
01348 printf(" protocol=%d user-user%s\n", protocol, debug);
01349 }
01350
01351 l = user_len+1;
01352 p = msg_put(msg, l+3);
01353 if (nt)
01354 *ntmode = p+1;
01355 else
01356 qi->QI_ELEMENT(useruser) = p - (unsigned char *)qi - sizeof(Q931_info_t);
01357 p[0] = IE_USER_USER;
01358 p[1] = l;
01359 p[2] = protocol;
01360 memcpy(p+3, user, user_len);
01361 }
01362 #endif
01363
01364 #if 1
01365 static void dec_ie_useruser(unsigned char *p, Q931_info_t *qi, int *protocol, char *user, int *user_len, int nt, struct misdn_bchannel *bc)
01366 {
01367 *user_len = 0;
01368 *protocol = -1;
01369
01370 if (!nt)
01371 {
01372 p = NULL;
01373 if (qi->QI_ELEMENT(useruser))
01374 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(useruser) + 1;
01375 }
01376 if (!p)
01377 return;
01378
01379 *user_len = p[0]-1;
01380 if (p[0] < 1)
01381 return;
01382 *protocol = p[1];
01383 memcpy(user, p+2, (*user_len<=128)?*(user_len):128);
01384
01385 if (MISDN_IE_DEBG) {
01386 int i;
01387 char debug[768];
01388
01389 for (i = 0; i < *user_len; ++i) {
01390 sprintf(debug + (i * 3), " %02x", user[i]);
01391 }
01392 debug[i * 3] = 0;
01393 printf(" protocol=%d user-user%s\n", *protocol, debug);
01394 }
01395 }
01396 #endif
01397
01398
01399 static void enc_ie_restart_ind(unsigned char **ntmode, msg_t *msg, unsigned char rind, int nt, struct misdn_bchannel *bc)
01400 {
01401 unsigned char *p;
01402 Q931_info_t *qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
01403
01404
01405 p = msg_put(msg, 3);
01406 if (nt)
01407 *ntmode = p+1;
01408 else
01409 qi->QI_ELEMENT(restart_ind) = p - (unsigned char *)qi - sizeof(Q931_info_t);
01410 p[0] = IE_RESTART_IND;
01411 p[1] = 1;
01412 p[2] = rind;
01413
01414 }
01415