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