00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "isdn_lib_intern.h"
00022
00023
00024 #include "isdn_lib.h"
00025
00026 #include "ie.c"
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 static void build_display_str(char *display, size_t display_length, int display_format, const char *name, const char *number)
00041 {
00042 display[0] = 0;
00043 switch (display_format) {
00044 default:
00045 case 0:
00046 break;
00047
00048 case 1:
00049 snprintf(display, display_length, "%s", name);
00050 break;
00051
00052 case 2:
00053 snprintf(display, display_length, "%s", number);
00054 break;
00055
00056 case 3:
00057 if (name[0] || number[0]) {
00058 snprintf(display, display_length, "\"%s\" <%s>", name, number);
00059 }
00060 break;
00061 }
00062 }
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 static void enc_ie_facility(unsigned char **ntmode, msg_t *msg, struct FacParm *fac, int nt)
00076 {
00077 int len;
00078 Q931_info_t *qi;
00079 unsigned char *p;
00080 unsigned char buf[256];
00081
00082 len = encodeFac(buf, fac);
00083 if (len <= 0) {
00084
00085
00086
00087
00088 fac->Function = Fac_None;
00089 return;
00090 }
00091
00092 p = msg_put(msg, len);
00093 if (nt) {
00094 *ntmode = p + 1;
00095 } else {
00096 qi = (Q931_info_t *) (msg->data + mISDN_HEADER_LEN);
00097 qi->QI_ELEMENT(facility) = p - (unsigned char *) qi - sizeof(Q931_info_t);
00098 }
00099
00100 memcpy(p, buf, len);
00101
00102
00103 fac->Function = Fac_None;
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 static void dec_ie_facility(unsigned char *p, Q931_info_t *qi, struct FacParm *fac, int nt, struct misdn_bchannel *bc)
00119 {
00120 fac->Function = Fac_None;
00121
00122 if (!nt) {
00123 p = NULL;
00124 if (qi->QI_ELEMENT(facility)) {
00125 p = (unsigned char *) qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(facility) + 1;
00126 }
00127 }
00128 if (!p) {
00129 return;
00130 }
00131
00132 if (decodeFac(p, fac)) {
00133 cb_log(3, bc->port, "Decoding facility ie failed! Unrecognized facility message?\n");
00134 }
00135 }
00136
00137
00138
00139 static void set_channel(struct misdn_bchannel *bc, int channel)
00140 {
00141
00142 cb_log(3,bc->port,"set_channel: bc->channel:%d channel:%d\n", bc->channel, channel);
00143
00144
00145 if (channel==0xff) {
00146
00147 channel=-1;
00148 }
00149
00150
00151 if (channel > 0 && bc->nt ) {
00152
00153 if (bc->channel && ( bc->channel != 0xff) ) {
00154 cb_log(0,bc->port,"We already have a channel (%d)\n", bc->channel);
00155 } else {
00156 bc->channel = channel;
00157 cb_event(EVENT_NEW_CHANNEL,bc,NULL);
00158 }
00159 }
00160
00161 if (channel > 0 && !bc->nt ) {
00162 bc->channel = channel;
00163 cb_event(EVENT_NEW_CHANNEL,bc,NULL);
00164 }
00165 }
00166
00167 static void parse_proceeding (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00168 {
00169 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00170 CALL_PROCEEDING_t *proceeding = (CALL_PROCEEDING_t *) (msg->data + HEADER_LEN);
00171
00172
00173 {
00174 int exclusive, channel;
00175 dec_ie_channel_id(proceeding->CHANNEL_ID, (Q931_info_t *)proceeding, &exclusive, &channel, nt,bc);
00176
00177 set_channel(bc,channel);
00178
00179 }
00180
00181 dec_ie_progress(proceeding->PROGRESS, (Q931_info_t *)proceeding, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
00182
00183 dec_ie_facility(proceeding->FACILITY, (Q931_info_t *) proceeding, &bc->fac_in, nt, bc);
00184
00185
00186
00187 #ifdef DEBUG
00188 printf("Parsing PROCEEDING Msg\n");
00189 #endif
00190 }
00191 static msg_t *build_proceeding (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00192 {
00193 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00194 CALL_PROCEEDING_t *proceeding;
00195 msg_t *msg =(msg_t*)create_l3msg(CC_PROCEEDING | REQUEST, MT_CALL_PROCEEDING, bc?bc->l3_id:-1, sizeof(CALL_PROCEEDING_t) ,nt);
00196
00197 proceeding=(CALL_PROCEEDING_t*)((msg->data+HEADER_LEN));
00198
00199 enc_ie_channel_id(&proceeding->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
00200
00201 if (nt)
00202 enc_ie_progress(&proceeding->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
00203
00204 if (bc->fac_out.Function != Fac_None) {
00205 enc_ie_facility(&proceeding->FACILITY, msg, &bc->fac_out, nt);
00206 }
00207
00208
00209
00210 #ifdef DEBUG
00211 printf("Building PROCEEDING Msg\n");
00212 #endif
00213 return msg;
00214 }
00215
00216 static void parse_alerting (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00217 {
00218 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00219 ALERTING_t *alerting = (ALERTING_t *) (msg->data + HEADER_LEN);
00220
00221
00222 dec_ie_facility(alerting->FACILITY, (Q931_info_t *) alerting, &bc->fac_in, nt, bc);
00223
00224
00225
00226 dec_ie_progress(alerting->PROGRESS, (Q931_info_t *)alerting, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
00227
00228 #ifdef DEBUG
00229 printf("Parsing ALERTING Msg\n");
00230 #endif
00231
00232
00233 }
00234
00235 static msg_t *build_alerting (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00236 {
00237 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00238 ALERTING_t *alerting;
00239 msg_t *msg =(msg_t*)create_l3msg(CC_ALERTING | REQUEST, MT_ALERTING, bc?bc->l3_id:-1, sizeof(ALERTING_t) ,nt);
00240
00241 alerting=(ALERTING_t*)((msg->data+HEADER_LEN));
00242
00243 enc_ie_channel_id(&alerting->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
00244
00245 if (nt)
00246 enc_ie_progress(&alerting->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
00247
00248 if (bc->fac_out.Function != Fac_None) {
00249 enc_ie_facility(&alerting->FACILITY, msg, &bc->fac_out, nt);
00250 }
00251
00252
00253
00254 #ifdef DEBUG
00255 printf("Building ALERTING Msg\n");
00256 #endif
00257 return msg;
00258 }
00259
00260
00261 static void parse_progress (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00262 {
00263 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00264 PROGRESS_t *progress = (PROGRESS_t *) (msg->data + HEADER_LEN);
00265
00266
00267 dec_ie_progress(progress->PROGRESS, (Q931_info_t *)progress, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
00268
00269 dec_ie_facility(progress->FACILITY, (Q931_info_t *) progress, &bc->fac_in, nt, bc);
00270
00271 #ifdef DEBUG
00272 printf("Parsing PROGRESS Msg\n");
00273 #endif
00274 }
00275
00276 static msg_t *build_progress (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00277 {
00278 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00279 PROGRESS_t *progress;
00280 msg_t *msg =(msg_t*)create_l3msg(CC_PROGRESS | REQUEST, MT_PROGRESS, bc?bc->l3_id:-1, sizeof(PROGRESS_t) ,nt);
00281
00282 progress=(PROGRESS_t*)((msg->data+HEADER_LEN));
00283
00284 if (bc->fac_out.Function != Fac_None) {
00285 enc_ie_facility(&progress->FACILITY, msg, &bc->fac_out, nt);
00286 }
00287
00288 #ifdef DEBUG
00289 printf("Building PROGRESS Msg\n");
00290 #endif
00291 return msg;
00292 }
00293
00294 #if defined(AST_MISDN_ENHANCEMENTS)
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305 static void extract_setup_Bc_Hlc_Llc(SETUP_t *setup, int nt, struct misdn_bchannel *bc)
00306 {
00307 __u8 *p;
00308 Q931_info_t *qi;
00309
00310 qi = (Q931_info_t *) setup;
00311
00312
00313 if (nt) {
00314 p = (__u8 *) setup->BEARER;
00315 } else {
00316 if (qi->QI_ELEMENT(bearer_capability)) {
00317 p = (__u8 *) qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(bearer_capability) + 1;
00318 } else {
00319 p = NULL;
00320 }
00321 }
00322 if (!p || *p == 0 || sizeof(bc->setup_bc_hlc_llc.Bc.Contents) < *p) {
00323 bc->setup_bc_hlc_llc.Bc.Length = 0;
00324 } else {
00325 bc->setup_bc_hlc_llc.Bc.Length = *p;
00326 memcpy(bc->setup_bc_hlc_llc.Bc.Contents, p + 1, *p);
00327 }
00328
00329
00330 if (nt) {
00331 p = (__u8 *) setup->LLC;
00332 } else {
00333 if (qi->QI_ELEMENT(llc)) {
00334 p = (__u8 *) qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(llc) + 1;
00335 } else {
00336 p = NULL;
00337 }
00338 }
00339 if (!p || *p == 0 || sizeof(bc->setup_bc_hlc_llc.Llc.Contents) < *p) {
00340 bc->setup_bc_hlc_llc.Llc.Length = 0;
00341 } else {
00342 bc->setup_bc_hlc_llc.Llc.Length = *p;
00343 memcpy(bc->setup_bc_hlc_llc.Llc.Contents, p + 1, *p);
00344 }
00345
00346
00347 if (nt) {
00348 p = (__u8 *) setup->HLC;
00349 } else {
00350 if (qi->QI_ELEMENT(hlc)) {
00351 p = (__u8 *) qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(hlc) + 1;
00352 } else {
00353 p = NULL;
00354 }
00355 }
00356 if (!p || *p == 0 || sizeof(bc->setup_bc_hlc_llc.Hlc.Contents) < *p) {
00357 bc->setup_bc_hlc_llc.Hlc.Length = 0;
00358 } else {
00359 bc->setup_bc_hlc_llc.Hlc.Length = *p;
00360 memcpy(bc->setup_bc_hlc_llc.Hlc.Contents, p + 1, *p);
00361 }
00362 }
00363 #endif
00364
00365 static void parse_setup (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00366 {
00367 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00368 SETUP_t *setup = (SETUP_t *) (msg->data + HEADER_LEN);
00369 Q931_info_t *qi = (Q931_info_t *) (msg->data + HEADER_LEN);
00370 int type;
00371 int plan;
00372 int present;
00373 int screen;
00374 int reason;
00375
00376 #ifdef DEBUG
00377 printf("Parsing SETUP Msg\n");
00378 #endif
00379
00380 dec_ie_calling_pn(setup->CALLING_PN, qi, &type, &plan, &present, &screen, bc->caller.number, sizeof(bc->caller.number), nt, bc);
00381 bc->caller.number_type = type;
00382 bc->caller.number_plan = plan;
00383 switch (present) {
00384 default:
00385 case 0:
00386 bc->caller.presentation = 0;
00387 break;
00388 case 1:
00389 bc->caller.presentation = 1;
00390 break;
00391 case 2:
00392 bc->caller.presentation = 2;
00393 break;
00394 }
00395 if (0 <= screen) {
00396 bc->caller.screening = screen;
00397 } else {
00398 bc->caller.screening = 0;
00399 }
00400
00401 dec_ie_facility(setup->FACILITY, (Q931_info_t *) setup, &bc->fac_in, nt, bc);
00402
00403 dec_ie_called_pn(setup->CALLED_PN, (Q931_info_t *) setup, &type, &plan, bc->dialed.number, sizeof(bc->dialed.number), nt, bc);
00404 bc->dialed.number_type = type;
00405 bc->dialed.number_plan = plan;
00406
00407 dec_ie_keypad(setup->KEYPAD, (Q931_info_t *) setup, bc->keypad, sizeof(bc->keypad), nt, bc);
00408
00409 dec_ie_complete(setup->COMPLETE, (Q931_info_t *) setup, &bc->sending_complete, nt, bc);
00410
00411 dec_ie_redir_nr(setup->REDIR_NR, (Q931_info_t *) setup, &type, &plan, &present, &screen, &reason, bc->redirecting.from.number, sizeof(bc->redirecting.from.number), nt, bc);
00412 bc->redirecting.from.number_type = type;
00413 bc->redirecting.from.number_plan = plan;
00414 switch (present) {
00415 default:
00416 case 0:
00417 bc->redirecting.from.presentation = 0;
00418 break;
00419 case 1:
00420 bc->redirecting.from.presentation = 1;
00421 break;
00422 case 2:
00423 bc->redirecting.from.presentation = 2;
00424 break;
00425 }
00426 if (0 <= screen) {
00427 bc->redirecting.from.screening = screen;
00428 } else {
00429 bc->redirecting.from.screening = 0;
00430 }
00431 if (0 <= reason) {
00432 bc->redirecting.reason = reason;
00433 } else {
00434 bc->redirecting.reason = mISDN_REDIRECTING_REASON_UNKNOWN;
00435 }
00436
00437 {
00438 int coding, capability, mode, rate, multi, user, async, urate, stopbits, dbits, parity;
00439
00440 dec_ie_bearer(setup->BEARER, (Q931_info_t *)setup, &coding, &capability, &mode, &rate, &multi, &user, &async, &urate, &stopbits, &dbits, &parity, nt,bc);
00441 switch (capability) {
00442 case -1: bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
00443 break;
00444 case 0: bc->capability=INFO_CAPABILITY_SPEECH;
00445 break;
00446 case 18: bc->capability=INFO_CAPABILITY_VIDEO;
00447 break;
00448 case 8: bc->capability=INFO_CAPABILITY_DIGITAL_UNRESTRICTED;
00449 bc->user1 = user;
00450 bc->urate = urate;
00451
00452 bc->rate = rate;
00453 bc->mode = mode;
00454 break;
00455 case 9: bc->capability=INFO_CAPABILITY_DIGITAL_RESTRICTED;
00456 break;
00457 default:
00458 break;
00459 }
00460
00461 switch(user) {
00462 case 2:
00463 bc->law=INFO_CODEC_ULAW;
00464 break;
00465 case 3:
00466 bc->law=INFO_CODEC_ALAW;
00467 break;
00468 default:
00469 bc->law=INFO_CODEC_ALAW;
00470
00471 }
00472
00473 bc->capability=capability;
00474 }
00475 {
00476 int exclusive, channel;
00477 dec_ie_channel_id(setup->CHANNEL_ID, (Q931_info_t *)setup, &exclusive, &channel, nt,bc);
00478
00479 set_channel(bc,channel);
00480 }
00481
00482 {
00483 int protocol ;
00484 dec_ie_useruser(setup->USER_USER, (Q931_info_t *)setup, &protocol, bc->uu, &bc->uulen, nt,bc);
00485 if (bc->uulen) cb_log(1,bc->port,"USERUESRINFO:%s\n",bc->uu);
00486 else
00487 cb_log(1,bc->port,"NO USERUESRINFO\n");
00488 }
00489
00490 dec_ie_progress(setup->PROGRESS, (Q931_info_t *)setup, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
00491
00492 #if defined(AST_MISDN_ENHANCEMENTS)
00493 extract_setup_Bc_Hlc_Llc(setup, nt, bc);
00494 #endif
00495 }
00496
00497 #define ANY_CHANNEL 0xff
00498 static msg_t *build_setup (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00499 {
00500 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00501 SETUP_t *setup;
00502 msg_t *msg =(msg_t*)create_l3msg(CC_SETUP | REQUEST, MT_SETUP, bc?bc->l3_id:-1, sizeof(SETUP_t) ,nt);
00503 int is_ptp;
00504 enum FacFunction fac_type;
00505
00506 setup=(SETUP_t*)((msg->data+HEADER_LEN));
00507
00508 if (bc->channel == 0 || bc->channel == ANY_CHANNEL || bc->channel==-1)
00509 enc_ie_channel_id(&setup->CHANNEL_ID, msg, 0, bc->channel, nt,bc);
00510 else
00511 enc_ie_channel_id(&setup->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
00512
00513 fac_type = bc->fac_out.Function;
00514 if (fac_type != Fac_None) {
00515 enc_ie_facility(&setup->FACILITY, msg, &bc->fac_out, nt);
00516 }
00517
00518 enc_ie_calling_pn(&setup->CALLING_PN, msg, bc->caller.number_type, bc->caller.number_plan,
00519 bc->caller.presentation, bc->caller.screening, bc->caller.number, nt, bc);
00520
00521 if (bc->dialed.number[0]) {
00522 enc_ie_called_pn(&setup->CALLED_PN, msg, bc->dialed.number_type, bc->dialed.number_plan, bc->dialed.number, nt, bc);
00523 }
00524
00525 switch (bc->outgoing_colp) {
00526 case 0:
00527 case 1:
00528 is_ptp = misdn_lib_is_ptp(bc->port);
00529 if (bc->redirecting.from.number[0]
00530 && ((!is_ptp && nt)
00531 || (is_ptp
00532 #if defined(AST_MISDN_ENHANCEMENTS)
00533
00534
00535
00536
00537
00538
00539 && fac_type != Fac_DivertingLegInformation2
00540 #endif
00541 ))) {
00542 #if 1
00543
00544 enc_ie_redir_nr(&setup->REDIR_NR, msg, bc->redirecting.from.number_type,
00545 bc->redirecting.from.number_plan, bc->redirecting.from.presentation, 0,
00546 bc->redirecting.reason, bc->redirecting.from.number, nt, bc);
00547 #else
00548
00549 enc_ie_redir_nr(&setup->REDIR_NR, msg, bc->redirecting.from.number_type,
00550 bc->redirecting.from.number_plan, bc->redirecting.from.presentation,
00551 bc->redirecting.from.screening, bc->redirecting.reason,
00552 bc->redirecting.from.number, nt, bc);
00553 #endif
00554 }
00555 break;
00556 default:
00557 break;
00558 }
00559
00560 if (bc->keypad[0]) {
00561 enc_ie_keypad(&setup->KEYPAD, msg, bc->keypad, nt,bc);
00562 }
00563
00564
00565
00566 if (*bc->display) {
00567 enc_ie_display(&setup->DISPLAY, msg, bc->display, nt, bc);
00568 } else if (nt && bc->caller.presentation == 0) {
00569 char display[sizeof(bc->display)];
00570
00571
00572 build_display_str(display, sizeof(display), bc->display_setup, bc->caller.name, bc->caller.number);
00573 if (display[0]) {
00574 enc_ie_display(&setup->DISPLAY, msg, display, nt, bc);
00575 }
00576 }
00577
00578 {
00579 int coding = 0;
00580 int capability;
00581 int mode = 0;
00582 int user;
00583 int rate = 0x10;
00584
00585 switch (bc->law) {
00586 case INFO_CODEC_ULAW: user=2;
00587 break;
00588 case INFO_CODEC_ALAW: user=3;
00589 break;
00590 default:
00591 user=3;
00592 }
00593
00594 switch (bc->capability) {
00595 case INFO_CAPABILITY_SPEECH: capability = 0;
00596 break;
00597 case INFO_CAPABILITY_DIGITAL_UNRESTRICTED: capability = 8;
00598 user=-1;
00599 mode=bc->mode;
00600 rate=bc->rate;
00601 break;
00602 case INFO_CAPABILITY_DIGITAL_RESTRICTED: capability = 9;
00603 user=-1;
00604 break;
00605 default:
00606 capability=bc->capability;
00607 }
00608
00609 enc_ie_bearer(&setup->BEARER, msg, coding, capability, mode, rate, -1, user, nt,bc);
00610 }
00611
00612 if (bc->sending_complete) {
00613 enc_ie_complete(&setup->COMPLETE,msg, bc->sending_complete, nt, bc);
00614 }
00615
00616 if (bc->uulen) {
00617 int protocol=4;
00618 enc_ie_useruser(&setup->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
00619 cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
00620 }
00621
00622 #if defined(AST_MISDN_ENHANCEMENTS)
00623 extract_setup_Bc_Hlc_Llc(setup, nt, bc);
00624 #endif
00625
00626 #ifdef DEBUG
00627 printf("Building SETUP Msg\n");
00628 #endif
00629 return msg;
00630 }
00631
00632 static void parse_connect (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00633 {
00634 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00635 CONNECT_t *connect = (CONNECT_t *) (msg->data + HEADER_LEN);
00636 int type;
00637 int plan;
00638 int pres;
00639 int screen;
00640
00641 bc->ces = connect->ces;
00642
00643 dec_ie_progress(connect->PROGRESS, (Q931_info_t *)connect, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
00644
00645 dec_ie_connected_pn(connect->CONNECT_PN, (Q931_info_t *) connect, &type, &plan,
00646 &pres, &screen, bc->connected.number, sizeof(bc->connected.number), nt, bc);
00647 bc->connected.number_type = type;
00648 bc->connected.number_plan = plan;
00649 switch (pres) {
00650 default:
00651 case 0:
00652 bc->connected.presentation = 0;
00653 break;
00654 case 1:
00655 bc->connected.presentation = 1;
00656 break;
00657 case 2:
00658 bc->connected.presentation = 2;
00659 break;
00660 }
00661 if (0 <= screen) {
00662 bc->connected.screening = screen;
00663 } else {
00664 bc->connected.screening = 0;
00665 }
00666
00667 dec_ie_facility(connect->FACILITY, (Q931_info_t *) connect, &bc->fac_in, nt, bc);
00668
00669
00670
00671
00672
00673 #ifdef DEBUG
00674 printf("Parsing CONNECT Msg\n");
00675 #endif
00676 }
00677
00678 static msg_t *build_connect (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00679 {
00680 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00681 CONNECT_t *connect;
00682 msg_t *msg =(msg_t*)create_l3msg(CC_CONNECT | REQUEST, MT_CONNECT, bc?bc->l3_id:-1, sizeof(CONNECT_t) ,nt);
00683
00684 cb_log(6,bc->port,"BUILD_CONNECT: bc:%p bc->l3id:%d, nt:%d\n",bc,bc->l3_id,nt);
00685
00686 connect=(CONNECT_t*)((msg->data+HEADER_LEN));
00687
00688 if (nt) {
00689 time_t now;
00690 time(&now);
00691 enc_ie_date(&connect->DATE, msg, now, nt,bc);
00692 }
00693
00694 switch (bc->outgoing_colp) {
00695 case 0:
00696 case 1:
00697 enc_ie_connected_pn(&connect->CONNECT_PN, msg, bc->connected.number_type,
00698 bc->connected.number_plan, bc->connected.presentation,
00699 bc->connected.screening, bc->connected.number, nt, bc);
00700 break;
00701 default:
00702 break;
00703 }
00704
00705 if (nt && bc->connected.presentation == 0) {
00706 char display[sizeof(bc->display)];
00707
00708
00709 build_display_str(display, sizeof(display), bc->display_connected, bc->connected.name, bc->connected.number);
00710 if (display[0]) {
00711 enc_ie_display(&connect->DISPLAY, msg, display, nt, bc);
00712 }
00713 }
00714
00715 if (bc->fac_out.Function != Fac_None) {
00716 enc_ie_facility(&connect->FACILITY, msg, &bc->fac_out, nt);
00717 }
00718
00719 #ifdef DEBUG
00720 printf("Building CONNECT Msg\n");
00721 #endif
00722 return msg;
00723 }
00724
00725 static void parse_setup_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00726 {
00727 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00728 SETUP_ACKNOWLEDGE_t *setup_acknowledge = (SETUP_ACKNOWLEDGE_t *) (msg->data + HEADER_LEN);
00729
00730 {
00731 int exclusive, channel;
00732 dec_ie_channel_id(setup_acknowledge->CHANNEL_ID, (Q931_info_t *)setup_acknowledge, &exclusive, &channel, nt,bc);
00733
00734
00735 set_channel(bc, channel);
00736 }
00737
00738 dec_ie_progress(setup_acknowledge->PROGRESS, (Q931_info_t *)setup_acknowledge, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
00739
00740 dec_ie_facility(setup_acknowledge->FACILITY, (Q931_info_t *) setup_acknowledge, &bc->fac_in, nt, bc);
00741
00742 #ifdef DEBUG
00743 printf("Parsing SETUP_ACKNOWLEDGE Msg\n");
00744 #endif
00745
00746
00747 }
00748
00749 static msg_t *build_setup_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00750 {
00751 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00752 SETUP_ACKNOWLEDGE_t *setup_acknowledge;
00753 msg_t *msg =(msg_t*)create_l3msg(CC_SETUP_ACKNOWLEDGE | REQUEST, MT_SETUP_ACKNOWLEDGE, bc?bc->l3_id:-1, sizeof(SETUP_ACKNOWLEDGE_t) ,nt);
00754
00755 setup_acknowledge=(SETUP_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
00756
00757 enc_ie_channel_id(&setup_acknowledge->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
00758
00759 if (nt)
00760 enc_ie_progress(&setup_acknowledge->PROGRESS, msg, 0, nt?1:5, 8, nt,bc);
00761
00762 if (bc->fac_out.Function != Fac_None) {
00763 enc_ie_facility(&setup_acknowledge->FACILITY, msg, &bc->fac_out, nt);
00764 }
00765
00766 #ifdef DEBUG
00767 printf("Building SETUP_ACKNOWLEDGE Msg\n");
00768 #endif
00769 return msg;
00770 }
00771
00772 static void parse_connect_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00773 {
00774 #ifdef DEBUG
00775 printf("Parsing CONNECT_ACKNOWLEDGE Msg\n");
00776 #endif
00777
00778
00779 }
00780
00781 static msg_t *build_connect_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00782 {
00783 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00784 CONNECT_ACKNOWLEDGE_t *connect_acknowledge;
00785 msg_t *msg =(msg_t*)create_l3msg(CC_CONNECT | RESPONSE, MT_CONNECT, bc?bc->l3_id:-1, sizeof(CONNECT_ACKNOWLEDGE_t) ,nt);
00786
00787 connect_acknowledge=(CONNECT_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
00788
00789 enc_ie_channel_id(&connect_acknowledge->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
00790
00791 #ifdef DEBUG
00792 printf("Building CONNECT_ACKNOWLEDGE Msg\n");
00793 #endif
00794 return msg;
00795 }
00796
00797 static void parse_user_information (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00798 {
00799 #ifdef DEBUG
00800 printf("Parsing USER_INFORMATION Msg\n");
00801 #endif
00802
00803
00804 }
00805
00806 static msg_t *build_user_information (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00807 {
00808 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00809 USER_INFORMATION_t *user_information;
00810 msg_t *msg =(msg_t*)create_l3msg(CC_USER_INFORMATION | REQUEST, MT_USER_INFORMATION, bc?bc->l3_id:-1, sizeof(USER_INFORMATION_t) ,nt);
00811
00812 user_information=(USER_INFORMATION_t*)((msg->data+HEADER_LEN));
00813
00814 #ifdef DEBUG
00815 printf("Building USER_INFORMATION Msg\n");
00816 #endif
00817 return msg;
00818 }
00819
00820 static void parse_suspend_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00821 {
00822 #ifdef DEBUG
00823 printf("Parsing SUSPEND_REJECT Msg\n");
00824 #endif
00825
00826
00827 }
00828
00829 static msg_t *build_suspend_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00830 {
00831 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00832 SUSPEND_REJECT_t *suspend_reject;
00833 msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND_REJECT | REQUEST, MT_SUSPEND_REJECT, bc?bc->l3_id:-1, sizeof(SUSPEND_REJECT_t) ,nt);
00834
00835 suspend_reject=(SUSPEND_REJECT_t*)((msg->data+HEADER_LEN));
00836
00837 #ifdef DEBUG
00838 printf("Building SUSPEND_REJECT Msg\n");
00839 #endif
00840 return msg;
00841 }
00842
00843 static void parse_resume_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00844 {
00845 #ifdef DEBUG
00846 printf("Parsing RESUME_REJECT Msg\n");
00847 #endif
00848
00849
00850 }
00851
00852 static msg_t *build_resume_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00853 {
00854 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00855 RESUME_REJECT_t *resume_reject;
00856 msg_t *msg =(msg_t*)create_l3msg(CC_RESUME_REJECT | REQUEST, MT_RESUME_REJECT, bc?bc->l3_id:-1, sizeof(RESUME_REJECT_t) ,nt);
00857
00858 resume_reject=(RESUME_REJECT_t*)((msg->data+HEADER_LEN));
00859
00860 #ifdef DEBUG
00861 printf("Building RESUME_REJECT Msg\n");
00862 #endif
00863 return msg;
00864 }
00865
00866 static void parse_hold (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00867 {
00868 #ifdef DEBUG
00869 printf("Parsing HOLD Msg\n");
00870 #endif
00871
00872
00873 }
00874
00875 static msg_t *build_hold (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00876 {
00877 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00878 HOLD_t *hold;
00879 msg_t *msg =(msg_t*)create_l3msg(CC_HOLD | REQUEST, MT_HOLD, bc?bc->l3_id:-1, sizeof(HOLD_t) ,nt);
00880
00881 hold=(HOLD_t*)((msg->data+HEADER_LEN));
00882
00883 #ifdef DEBUG
00884 printf("Building HOLD Msg\n");
00885 #endif
00886 return msg;
00887 }
00888
00889 static void parse_suspend (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00890 {
00891 #ifdef DEBUG
00892 printf("Parsing SUSPEND Msg\n");
00893 #endif
00894
00895
00896 }
00897
00898 static msg_t *build_suspend (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00899 {
00900 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00901 SUSPEND_t *suspend;
00902 msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND | REQUEST, MT_SUSPEND, bc?bc->l3_id:-1, sizeof(SUSPEND_t) ,nt);
00903
00904 suspend=(SUSPEND_t*)((msg->data+HEADER_LEN));
00905
00906 #ifdef DEBUG
00907 printf("Building SUSPEND Msg\n");
00908 #endif
00909 return msg;
00910 }
00911
00912 static void parse_resume (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00913 {
00914 #ifdef DEBUG
00915 printf("Parsing RESUME Msg\n");
00916 #endif
00917
00918
00919 }
00920
00921 static msg_t *build_resume (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00922 {
00923 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00924 RESUME_t *resume;
00925 msg_t *msg =(msg_t*)create_l3msg(CC_RESUME | REQUEST, MT_RESUME, bc?bc->l3_id:-1, sizeof(RESUME_t) ,nt);
00926
00927 resume=(RESUME_t*)((msg->data+HEADER_LEN));
00928
00929 #ifdef DEBUG
00930 printf("Building RESUME Msg\n");
00931 #endif
00932 return msg;
00933 }
00934
00935 static void parse_hold_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00936 {
00937 #ifdef DEBUG
00938 printf("Parsing HOLD_ACKNOWLEDGE Msg\n");
00939 #endif
00940
00941
00942 }
00943
00944 static msg_t *build_hold_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00945 {
00946 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00947 HOLD_ACKNOWLEDGE_t *hold_acknowledge;
00948 msg_t *msg =(msg_t*)create_l3msg(CC_HOLD_ACKNOWLEDGE | REQUEST, MT_HOLD_ACKNOWLEDGE, bc?bc->l3_id:-1, sizeof(HOLD_ACKNOWLEDGE_t) ,nt);
00949
00950 hold_acknowledge=(HOLD_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
00951
00952 #ifdef DEBUG
00953 printf("Building HOLD_ACKNOWLEDGE Msg\n");
00954 #endif
00955 return msg;
00956 }
00957
00958 static void parse_suspend_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00959 {
00960 #ifdef DEBUG
00961 printf("Parsing SUSPEND_ACKNOWLEDGE Msg\n");
00962 #endif
00963
00964
00965 }
00966
00967 static msg_t *build_suspend_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00968 {
00969 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00970 SUSPEND_ACKNOWLEDGE_t *suspend_acknowledge;
00971 msg_t *msg =(msg_t*)create_l3msg(CC_SUSPEND_ACKNOWLEDGE | REQUEST, MT_SUSPEND_ACKNOWLEDGE, bc?bc->l3_id:-1, sizeof(SUSPEND_ACKNOWLEDGE_t) ,nt);
00972
00973 suspend_acknowledge=(SUSPEND_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
00974
00975 #ifdef DEBUG
00976 printf("Building SUSPEND_ACKNOWLEDGE Msg\n");
00977 #endif
00978 return msg;
00979 }
00980
00981 static void parse_resume_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
00982 {
00983 #ifdef DEBUG
00984 printf("Parsing RESUME_ACKNOWLEDGE Msg\n");
00985 #endif
00986
00987
00988 }
00989
00990 static msg_t *build_resume_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
00991 {
00992 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
00993 RESUME_ACKNOWLEDGE_t *resume_acknowledge;
00994 msg_t *msg =(msg_t*)create_l3msg(CC_RESUME_ACKNOWLEDGE | REQUEST, MT_RESUME_ACKNOWLEDGE, bc?bc->l3_id:-1, sizeof(RESUME_ACKNOWLEDGE_t) ,nt);
00995
00996 resume_acknowledge=(RESUME_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
00997
00998 #ifdef DEBUG
00999 printf("Building RESUME_ACKNOWLEDGE Msg\n");
01000 #endif
01001 return msg;
01002 }
01003
01004 static void parse_hold_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01005 {
01006 #ifdef DEBUG
01007 printf("Parsing HOLD_REJECT Msg\n");
01008 #endif
01009
01010
01011 }
01012
01013 static msg_t *build_hold_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01014 {
01015 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01016 HOLD_REJECT_t *hold_reject;
01017 msg_t *msg =(msg_t*)create_l3msg(CC_HOLD_REJECT | REQUEST, MT_HOLD_REJECT, bc?bc->l3_id:-1, sizeof(HOLD_REJECT_t) ,nt);
01018
01019 hold_reject=(HOLD_REJECT_t*)((msg->data+HEADER_LEN));
01020
01021 #ifdef DEBUG
01022 printf("Building HOLD_REJECT Msg\n");
01023 #endif
01024 return msg;
01025 }
01026
01027 static void parse_retrieve (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01028 {
01029 #ifdef DEBUG
01030 printf("Parsing RETRIEVE Msg\n");
01031 #endif
01032
01033
01034 }
01035
01036 static msg_t *build_retrieve (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01037 {
01038 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01039 RETRIEVE_t *retrieve;
01040 msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE | REQUEST, MT_RETRIEVE, bc?bc->l3_id:-1, sizeof(RETRIEVE_t) ,nt);
01041
01042 retrieve=(RETRIEVE_t*)((msg->data+HEADER_LEN));
01043
01044 #ifdef DEBUG
01045 printf("Building RETRIEVE Msg\n");
01046 #endif
01047 return msg;
01048 }
01049
01050 static void parse_retrieve_acknowledge (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01051 {
01052 #ifdef DEBUG
01053 printf("Parsing RETRIEVE_ACKNOWLEDGE Msg\n");
01054 #endif
01055
01056
01057 }
01058
01059 static msg_t *build_retrieve_acknowledge (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01060 {
01061 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01062 RETRIEVE_ACKNOWLEDGE_t *retrieve_acknowledge;
01063 msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE_ACKNOWLEDGE | REQUEST, MT_RETRIEVE_ACKNOWLEDGE, bc?bc->l3_id:-1, sizeof(RETRIEVE_ACKNOWLEDGE_t) ,nt);
01064
01065 retrieve_acknowledge=(RETRIEVE_ACKNOWLEDGE_t*)((msg->data+HEADER_LEN));
01066
01067 enc_ie_channel_id(&retrieve_acknowledge->CHANNEL_ID, msg, 1, bc->channel, nt,bc);
01068 #ifdef DEBUG
01069 printf("Building RETRIEVE_ACKNOWLEDGE Msg\n");
01070 #endif
01071 return msg;
01072 }
01073
01074 static void parse_retrieve_reject (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01075 {
01076 #ifdef DEBUG
01077 printf("Parsing RETRIEVE_REJECT Msg\n");
01078 #endif
01079
01080
01081 }
01082
01083 static msg_t *build_retrieve_reject (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01084 {
01085 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01086 RETRIEVE_REJECT_t *retrieve_reject;
01087 msg_t *msg =(msg_t*)create_l3msg(CC_RETRIEVE_REJECT | REQUEST, MT_RETRIEVE_REJECT, bc?bc->l3_id:-1, sizeof(RETRIEVE_REJECT_t) ,nt);
01088
01089 retrieve_reject=(RETRIEVE_REJECT_t*)((msg->data+HEADER_LEN));
01090
01091 #ifdef DEBUG
01092 printf("Building RETRIEVE_REJECT Msg\n");
01093 #endif
01094 return msg;
01095 }
01096
01097 static void parse_disconnect (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01098 {
01099 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01100 DISCONNECT_t *disconnect = (DISCONNECT_t *) (msg->data + HEADER_LEN);
01101 int location;
01102 int cause;
01103 dec_ie_cause(disconnect->CAUSE, (Q931_info_t *)(disconnect), &location, &cause, nt,bc);
01104 if (cause>0) bc->cause=cause;
01105
01106 dec_ie_facility(disconnect->FACILITY, (Q931_info_t *) disconnect, &bc->fac_in, nt, bc);
01107
01108 dec_ie_progress(disconnect->PROGRESS, (Q931_info_t *)disconnect, &bc->progress_coding, &bc->progress_location, &bc->progress_indicator, nt, bc);
01109 #ifdef DEBUG
01110 printf("Parsing DISCONNECT Msg\n");
01111 #endif
01112
01113
01114 }
01115
01116 static msg_t *build_disconnect (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01117 {
01118 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01119 DISCONNECT_t *disconnect;
01120 msg_t *msg =(msg_t*)create_l3msg(CC_DISCONNECT | REQUEST, MT_DISCONNECT, bc?bc->l3_id:-1, sizeof(DISCONNECT_t) ,nt);
01121
01122 disconnect=(DISCONNECT_t*)((msg->data+HEADER_LEN));
01123
01124 enc_ie_cause(&disconnect->CAUSE, msg, (nt)?1:0, bc->out_cause,nt,bc);
01125 if (nt) {
01126 enc_ie_progress(&disconnect->PROGRESS, msg, 0, nt ? 1 : 5, 8, nt, bc);
01127 }
01128
01129 if (bc->fac_out.Function != Fac_None) {
01130 enc_ie_facility(&disconnect->FACILITY, msg, &bc->fac_out, nt);
01131 }
01132
01133 if (bc->uulen) {
01134 int protocol=4;
01135 enc_ie_useruser(&disconnect->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
01136 cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
01137 }
01138
01139 #ifdef DEBUG
01140 printf("Building DISCONNECT Msg\n");
01141 #endif
01142 return msg;
01143 }
01144
01145 static void parse_restart (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01146 {
01147 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01148 RESTART_t *restart = (RESTART_t *) (msg->data + HEADER_LEN);
01149
01150 struct misdn_stack *stack=get_stack_by_bc(bc);
01151
01152 #ifdef DEBUG
01153 printf("Parsing RESTART Msg\n");
01154 #endif
01155
01156 {
01157 int exclusive;
01158 dec_ie_channel_id(restart->CHANNEL_ID, (Q931_info_t *)restart, &exclusive, &bc->restart_channel, nt,bc);
01159 cb_log(3, stack->port, "CC_RESTART Request on channel:%d on this port.\n", bc->restart_channel);
01160 }
01161
01162 }
01163
01164 static msg_t *build_restart (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01165 {
01166 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01167 RESTART_t *restart;
01168 msg_t *msg =(msg_t*)create_l3msg(CC_RESTART | REQUEST, MT_RESTART, bc?bc->l3_id:-1, sizeof(RESTART_t) ,nt);
01169
01170 restart=(RESTART_t*)((msg->data+HEADER_LEN));
01171
01172 #ifdef DEBUG
01173 printf("Building RESTART Msg\n");
01174 #endif
01175
01176 if (bc->channel > 0) {
01177 enc_ie_channel_id(&restart->CHANNEL_ID, msg, 1,bc->channel, nt,bc);
01178 enc_ie_restart_ind(&restart->RESTART_IND, msg, 0x80, nt, bc);
01179 } else {
01180 enc_ie_restart_ind(&restart->RESTART_IND, msg, 0x87, nt, bc);
01181 }
01182
01183 cb_log(0,bc->port, "Restarting channel %d\n", bc->channel);
01184 return msg;
01185 }
01186
01187 static void parse_release (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01188 {
01189 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01190 RELEASE_t *release = (RELEASE_t *) (msg->data + HEADER_LEN);
01191 int location;
01192 int cause;
01193
01194 dec_ie_cause(release->CAUSE, (Q931_info_t *)(release), &location, &cause, nt,bc);
01195 if (cause>0) bc->cause=cause;
01196
01197 dec_ie_facility(release->FACILITY, (Q931_info_t *) release, &bc->fac_in, nt, bc);
01198
01199 #ifdef DEBUG
01200 printf("Parsing RELEASE Msg\n");
01201 #endif
01202
01203
01204 }
01205
01206 static msg_t *build_release (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01207 {
01208 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01209 RELEASE_t *release;
01210 msg_t *msg =(msg_t*)create_l3msg(CC_RELEASE | REQUEST, MT_RELEASE, bc?bc->l3_id:-1, sizeof(RELEASE_t) ,nt);
01211
01212 release=(RELEASE_t*)((msg->data+HEADER_LEN));
01213
01214 if (bc->out_cause>= 0)
01215 enc_ie_cause(&release->CAUSE, msg, nt?1:0, bc->out_cause, nt,bc);
01216
01217 if (bc->fac_out.Function != Fac_None) {
01218 enc_ie_facility(&release->FACILITY, msg, &bc->fac_out, nt);
01219 }
01220
01221 if (bc->uulen) {
01222 int protocol=4;
01223 enc_ie_useruser(&release->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
01224 cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
01225 }
01226
01227 #ifdef DEBUG
01228 printf("Building RELEASE Msg\n");
01229 #endif
01230 return msg;
01231 }
01232
01233 static void parse_release_complete (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01234 {
01235 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01236 RELEASE_COMPLETE_t *release_complete = (RELEASE_COMPLETE_t *) (msg->data + HEADER_LEN);
01237 int location;
01238 int cause;
01239 iframe_t *frm = (iframe_t*) msg->data;
01240
01241 struct misdn_stack *stack=get_stack_by_bc(bc);
01242 mISDNuser_head_t *hh;
01243 hh=(mISDNuser_head_t*)msg->data;
01244
01245
01246
01247
01248 if (nt) {
01249 if (hh->prim == (CC_RELEASE_COMPLETE|CONFIRM)) {
01250 cb_log(0, stack->port, "CC_RELEASE_COMPLETE|CONFIRM [NT] \n");
01251 return;
01252 }
01253 } else {
01254 if (frm->prim == (CC_RELEASE_COMPLETE|CONFIRM)) {
01255 cb_log(0, stack->port, "CC_RELEASE_COMPLETE|CONFIRM [TE] \n");
01256 return;
01257 }
01258 }
01259 dec_ie_cause(release_complete->CAUSE, (Q931_info_t *)(release_complete), &location, &cause, nt,bc);
01260 if (cause>0) bc->cause=cause;
01261
01262 dec_ie_facility(release_complete->FACILITY, (Q931_info_t *) release_complete, &bc->fac_in, nt, bc);
01263
01264 #ifdef DEBUG
01265 printf("Parsing RELEASE_COMPLETE Msg\n");
01266 #endif
01267 }
01268
01269 static msg_t *build_release_complete (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01270 {
01271 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01272 RELEASE_COMPLETE_t *release_complete;
01273 msg_t *msg =(msg_t*)create_l3msg(CC_RELEASE_COMPLETE | REQUEST, MT_RELEASE_COMPLETE, bc?bc->l3_id:-1, sizeof(RELEASE_COMPLETE_t) ,nt);
01274
01275 release_complete=(RELEASE_COMPLETE_t*)((msg->data+HEADER_LEN));
01276
01277 enc_ie_cause(&release_complete->CAUSE, msg, nt?1:0, bc->out_cause, nt,bc);
01278
01279 if (bc->fac_out.Function != Fac_None) {
01280 enc_ie_facility(&release_complete->FACILITY, msg, &bc->fac_out, nt);
01281 }
01282
01283 if (bc->uulen) {
01284 int protocol=4;
01285 enc_ie_useruser(&release_complete->USER_USER, msg, protocol, bc->uu, bc->uulen, nt,bc);
01286 cb_log(1,bc->port,"ENCODING USERUESRINFO:%s\n",bc->uu);
01287 }
01288
01289 #ifdef DEBUG
01290 printf("Building RELEASE_COMPLETE Msg\n");
01291 #endif
01292 return msg;
01293 }
01294
01295 static void parse_facility (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01296 {
01297 int HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
01298 FACILITY_t *facility = (FACILITY_t*)(msg->data+HEADER_LEN);
01299 Q931_info_t *qi = (Q931_info_t*)(msg->data+HEADER_LEN);
01300 unsigned char *p = NULL;
01301 #if defined(AST_MISDN_ENHANCEMENTS)
01302 int description_code;
01303 int type;
01304 int plan;
01305 int present;
01306 char number[sizeof(bc->redirecting.to.number)];
01307 #endif
01308
01309 #ifdef DEBUG
01310 printf("Parsing FACILITY Msg\n");
01311 #endif
01312
01313 bc->fac_in.Function = Fac_None;
01314
01315 if (!bc->nt) {
01316 if (qi->QI_ELEMENT(facility))
01317 p = (unsigned char *)qi + sizeof(Q931_info_t) + qi->QI_ELEMENT(facility) + 1;
01318 } else {
01319 p = facility->FACILITY;
01320 }
01321 if (!p)
01322 return;
01323
01324 if (decodeFac(p, &bc->fac_in)) {
01325 cb_log(3, bc->port, "Decoding facility ie failed! Unrecognized facility message?\n");
01326 }
01327
01328 #if defined(AST_MISDN_ENHANCEMENTS)
01329 dec_ie_notify(facility->NOTIFY, qi, &description_code, nt, bc);
01330 if (description_code < 0) {
01331 bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
01332 } else {
01333 bc->notify_description_code = description_code;
01334 }
01335
01336 dec_ie_redir_dn(facility->REDIR_DN, qi, &type, &plan, &present, number, sizeof(number), nt, bc);
01337 if (0 <= type) {
01338 bc->redirecting.to_changed = 1;
01339
01340 bc->redirecting.to.number_type = type;
01341 bc->redirecting.to.number_plan = plan;
01342 switch (present) {
01343 default:
01344 case 0:
01345 bc->redirecting.to.presentation = 0;
01346 break;
01347 case 1:
01348 bc->redirecting.to.presentation = 1;
01349 break;
01350 case 2:
01351 bc->redirecting.to.presentation = 2;
01352 break;
01353 }
01354 bc->redirecting.to.screening = 0;
01355 strcpy(bc->redirecting.to.number, number);
01356 }
01357 #endif
01358 }
01359
01360 static msg_t *build_facility (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01361 {
01362 int len;
01363 int HEADER_LEN;
01364 unsigned char *ie_fac;
01365 unsigned char fac_tmp[256];
01366 msg_t *msg;
01367 FACILITY_t *facility;
01368 Q931_info_t *qi;
01369
01370 #ifdef DEBUG
01371 printf("Building FACILITY Msg\n");
01372 #endif
01373
01374 len = encodeFac(fac_tmp, &(bc->fac_out));
01375 if (len <= 0) {
01376
01377
01378
01379
01380 bc->fac_out.Function = Fac_None;
01381
01382 #if defined(AST_MISDN_ENHANCEMENTS)
01383
01384 bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
01385 bc->redirecting.to_changed = 0;
01386 #endif
01387 return NULL;
01388 }
01389
01390 msg = (msg_t *) create_l3msg(CC_FACILITY | REQUEST, MT_FACILITY, bc ? bc->l3_id : -1, sizeof(FACILITY_t), nt);
01391 HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
01392 facility = (FACILITY_t *) (msg->data + HEADER_LEN);
01393
01394 ie_fac = msg_put(msg, len);
01395 if (bc->nt) {
01396 facility->FACILITY = ie_fac + 1;
01397 } else {
01398 qi = (Q931_info_t *)(msg->data + mISDN_HEADER_LEN);
01399 qi->QI_ELEMENT(facility) = ie_fac - (unsigned char *)qi - sizeof(Q931_info_t);
01400 }
01401
01402 memcpy(ie_fac, fac_tmp, len);
01403
01404
01405 bc->fac_out.Function = Fac_None;
01406
01407 if (*bc->display) {
01408 #ifdef DEBUG
01409 printf("Sending %s as Display\n", bc->display);
01410 #endif
01411 enc_ie_display(&facility->DISPLAY, msg, bc->display, nt,bc);
01412 }
01413
01414 #if defined(AST_MISDN_ENHANCEMENTS)
01415 if (bc->notify_description_code != mISDN_NOTIFY_CODE_INVALID) {
01416 enc_ie_notify(&facility->NOTIFY, msg, bc->notify_description_code, nt, bc);
01417 bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
01418 }
01419
01420 if (bc->redirecting.to_changed) {
01421 bc->redirecting.to_changed = 0;
01422 switch (bc->outgoing_colp) {
01423 case 0:
01424 case 1:
01425 enc_ie_redir_dn(&facility->REDIR_DN, msg, bc->redirecting.to.number_type,
01426 bc->redirecting.to.number_plan, bc->redirecting.to.presentation,
01427 bc->redirecting.to.number, nt, bc);
01428 break;
01429 default:
01430 break;
01431 }
01432 }
01433 #endif
01434
01435 return msg;
01436 }
01437
01438 #if defined(AST_MISDN_ENHANCEMENTS)
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450 static void parse_register(struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01451 {
01452 int HEADER_LEN;
01453 REGISTER_t *reg;
01454
01455 HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
01456 reg = (REGISTER_t *) (msg->data + HEADER_LEN);
01457
01458
01459
01460
01461
01462
01463 dec_ie_facility(reg->FACILITY, (Q931_info_t *) reg, &bc->fac_in, nt, bc);
01464 }
01465 #endif
01466
01467 #if defined(AST_MISDN_ENHANCEMENTS)
01468
01469
01470
01471
01472
01473
01474
01475
01476
01477
01478 static msg_t *build_register(struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01479 {
01480 int HEADER_LEN;
01481 REGISTER_t *reg;
01482 msg_t *msg;
01483
01484 msg = (msg_t *) create_l3msg(CC_REGISTER | REQUEST, MT_REGISTER, bc ? bc->l3_id : -1, sizeof(REGISTER_t), nt);
01485 HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
01486 reg = (REGISTER_t *) (msg->data + HEADER_LEN);
01487
01488 if (bc->fac_out.Function != Fac_None) {
01489 enc_ie_facility(®->FACILITY, msg, &bc->fac_out, nt);
01490 }
01491
01492 return msg;
01493 }
01494 #endif
01495
01496 static void parse_notify (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01497 {
01498 int HEADER_LEN = nt ? mISDNUSER_HEAD_SIZE : mISDN_HEADER_LEN;
01499 NOTIFY_t *notify = (NOTIFY_t *) (msg->data + HEADER_LEN);
01500 int description_code;
01501 int type;
01502 int plan;
01503 int present;
01504 char number[sizeof(bc->redirecting.to.number)];
01505
01506 #ifdef DEBUG
01507 printf("Parsing NOTIFY Msg\n");
01508 #endif
01509
01510 dec_ie_notify(notify->NOTIFY, (Q931_info_t *) notify, &description_code, nt, bc);
01511 if (description_code < 0) {
01512 bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
01513 } else {
01514 bc->notify_description_code = description_code;
01515 }
01516
01517 dec_ie_redir_dn(notify->REDIR_DN, (Q931_info_t *) notify, &type, &plan, &present, number, sizeof(number), nt, bc);
01518 if (0 <= type) {
01519 bc->redirecting.to_changed = 1;
01520
01521 bc->redirecting.to.number_type = type;
01522 bc->redirecting.to.number_plan = plan;
01523 switch (present) {
01524 default:
01525 case 0:
01526 bc->redirecting.to.presentation = 0;
01527 break;
01528 case 1:
01529 bc->redirecting.to.presentation = 1;
01530 break;
01531 case 2:
01532 bc->redirecting.to.presentation = 2;
01533 break;
01534 }
01535 bc->redirecting.to.screening = 0;
01536 strcpy(bc->redirecting.to.number, number);
01537 }
01538 }
01539
01540 static msg_t *build_notify (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01541 {
01542 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01543 NOTIFY_t *notify;
01544 msg_t *msg =(msg_t*)create_l3msg(CC_NOTIFY | REQUEST, MT_NOTIFY, bc?bc->l3_id:-1, sizeof(NOTIFY_t) ,nt);
01545
01546 #ifdef DEBUG
01547 printf("Building NOTIFY Msg\n");
01548 #endif
01549
01550 notify = (NOTIFY_t *) (msg->data + HEADER_LEN);
01551
01552 enc_ie_notify(¬ify->NOTIFY, msg, bc->notify_description_code, nt, bc);
01553 bc->notify_description_code = mISDN_NOTIFY_CODE_INVALID;
01554
01555 if (bc->redirecting.to_changed) {
01556 bc->redirecting.to_changed = 0;
01557 switch (bc->outgoing_colp) {
01558 case 0:
01559 case 1:
01560 enc_ie_redir_dn(¬ify->REDIR_DN, msg, bc->redirecting.to.number_type,
01561 bc->redirecting.to.number_plan, bc->redirecting.to.presentation,
01562 bc->redirecting.to.number, nt, bc);
01563 break;
01564 default:
01565 break;
01566 }
01567 }
01568 return msg;
01569 }
01570
01571 static void parse_status_enquiry (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01572 {
01573 #ifdef DEBUG
01574 printf("Parsing STATUS_ENQUIRY Msg\n");
01575 #endif
01576 }
01577
01578 static msg_t *build_status_enquiry (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01579 {
01580 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01581 STATUS_ENQUIRY_t *status_enquiry;
01582 msg_t *msg =(msg_t*)create_l3msg(CC_STATUS_ENQUIRY | REQUEST, MT_STATUS_ENQUIRY, bc?bc->l3_id:-1, sizeof(STATUS_ENQUIRY_t) ,nt);
01583
01584 status_enquiry=(STATUS_ENQUIRY_t*)((msg->data+HEADER_LEN));
01585
01586 #ifdef DEBUG
01587 printf("Building STATUS_ENQUIRY Msg\n");
01588 #endif
01589 return msg;
01590 }
01591
01592 static void parse_information (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01593 {
01594 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01595 INFORMATION_t *information = (INFORMATION_t *) (msg->data + HEADER_LEN);
01596 int type, plan;
01597
01598 dec_ie_called_pn(information->CALLED_PN, (Q931_info_t *) information, &type, &plan, bc->info_dad, sizeof(bc->info_dad), nt, bc);
01599 dec_ie_keypad(information->KEYPAD, (Q931_info_t *) information, bc->keypad, sizeof(bc->keypad), nt, bc);
01600
01601 #ifdef DEBUG
01602 printf("Parsing INFORMATION Msg\n");
01603 #endif
01604 }
01605
01606 static msg_t *build_information (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01607 {
01608 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01609 INFORMATION_t *information;
01610 msg_t *msg =(msg_t*)create_l3msg(CC_INFORMATION | REQUEST, MT_INFORMATION, bc?bc->l3_id:-1, sizeof(INFORMATION_t) ,nt);
01611
01612 information=(INFORMATION_t*)((msg->data+HEADER_LEN));
01613
01614 enc_ie_called_pn(&information->CALLED_PN, msg, 0, 1, bc->info_dad, nt,bc);
01615
01616 {
01617 if (*bc->display) {
01618 #ifdef DEBUG
01619 printf("Sending %s as Display\n", bc->display);
01620 #endif
01621 enc_ie_display(&information->DISPLAY, msg, bc->display, nt,bc);
01622 }
01623 }
01624
01625 #ifdef DEBUG
01626 printf("Building INFORMATION Msg\n");
01627 #endif
01628 return msg;
01629 }
01630
01631 static void parse_status (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01632 {
01633 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01634 STATUS_t *status = (STATUS_t *) (msg->data + HEADER_LEN);
01635 int location;
01636 int cause;
01637
01638 dec_ie_cause(status->CAUSE, (Q931_info_t *)(status), &location, &cause, nt,bc);
01639 if (cause>0) bc->cause=cause;
01640
01641 #ifdef DEBUG
01642 printf("Parsing STATUS Msg\n");
01643 #endif
01644 }
01645
01646 static msg_t *build_status (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01647 {
01648 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01649 STATUS_t *status;
01650 msg_t *msg =(msg_t*)create_l3msg(CC_STATUS | REQUEST, MT_STATUS, bc?bc->l3_id:-1, sizeof(STATUS_t) ,nt);
01651
01652 status=(STATUS_t*)((msg->data+HEADER_LEN));
01653
01654 #ifdef DEBUG
01655 printf("Building STATUS Msg\n");
01656 #endif
01657 return msg;
01658 }
01659
01660 static void parse_timeout (struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01661 {
01662 #ifdef DEBUG
01663 printf("Parsing STATUS Msg\n");
01664 #endif
01665 }
01666
01667 static msg_t *build_timeout (struct isdn_msg msgs[], struct misdn_bchannel *bc, int nt)
01668 {
01669 int HEADER_LEN = nt?mISDNUSER_HEAD_SIZE:mISDN_HEADER_LEN;
01670 STATUS_t *status;
01671 msg_t *msg =(msg_t*)create_l3msg(CC_STATUS | REQUEST, MT_STATUS, bc?bc->l3_id:-1, sizeof(STATUS_t) ,nt);
01672
01673 status=(STATUS_t*)((msg->data+HEADER_LEN));
01674
01675 #ifdef DEBUG
01676 printf("Building STATUS Msg\n");
01677 #endif
01678 return msg;
01679 }
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689 struct isdn_msg msgs_g[] = {
01690
01691
01692 { CC_PROCEEDING, EVENT_PROCEEDING, parse_proceeding, build_proceeding, "PROCEEDING" },
01693 { CC_ALERTING, EVENT_ALERTING, parse_alerting, build_alerting, "ALERTING" },
01694 { CC_PROGRESS, EVENT_PROGRESS, parse_progress, build_progress, "PROGRESS" },
01695 { CC_SETUP, EVENT_SETUP, parse_setup, build_setup, "SETUP" },
01696 #if defined(AST_MISDN_ENHANCEMENTS)
01697 { CC_REGISTER, EVENT_REGISTER, parse_register, build_register, "REGISTER" },
01698 #endif
01699 { CC_CONNECT, EVENT_CONNECT, parse_connect, build_connect, "CONNECT" },
01700 { CC_SETUP_ACKNOWLEDGE, EVENT_SETUP_ACKNOWLEDGE, parse_setup_acknowledge, build_setup_acknowledge, "SETUP_ACKNOWLEDGE" },
01701 { CC_CONNECT_ACKNOWLEDGE, EVENT_CONNECT_ACKNOWLEDGE, parse_connect_acknowledge, build_connect_acknowledge, "CONNECT_ACKNOWLEDGE " },
01702 { CC_USER_INFORMATION, EVENT_USER_INFORMATION, parse_user_information, build_user_information, "USER_INFORMATION" },
01703 { CC_SUSPEND_REJECT, EVENT_SUSPEND_REJECT, parse_suspend_reject, build_suspend_reject, "SUSPEND_REJECT" },
01704 { CC_RESUME_REJECT, EVENT_RESUME_REJECT, parse_resume_reject, build_resume_reject, "RESUME_REJECT" },
01705 { CC_HOLD, EVENT_HOLD, parse_hold, build_hold, "HOLD" },
01706 { CC_SUSPEND, EVENT_SUSPEND, parse_suspend, build_suspend, "SUSPEND" },
01707 { CC_RESUME, EVENT_RESUME, parse_resume, build_resume, "RESUME" },
01708 { CC_HOLD_ACKNOWLEDGE, EVENT_HOLD_ACKNOWLEDGE, parse_hold_acknowledge, build_hold_acknowledge, "HOLD_ACKNOWLEDGE" },
01709 { CC_SUSPEND_ACKNOWLEDGE, EVENT_SUSPEND_ACKNOWLEDGE, parse_suspend_acknowledge, build_suspend_acknowledge, "SUSPEND_ACKNOWLEDGE" },
01710 { CC_RESUME_ACKNOWLEDGE, EVENT_RESUME_ACKNOWLEDGE, parse_resume_acknowledge, build_resume_acknowledge, "RESUME_ACKNOWLEDGE" },
01711 { CC_HOLD_REJECT, EVENT_HOLD_REJECT, parse_hold_reject, build_hold_reject, "HOLD_REJECT" },
01712 { CC_RETRIEVE, EVENT_RETRIEVE, parse_retrieve, build_retrieve, "RETRIEVE" },
01713 { CC_RETRIEVE_ACKNOWLEDGE, EVENT_RETRIEVE_ACKNOWLEDGE, parse_retrieve_acknowledge, build_retrieve_acknowledge, "RETRIEVE_ACKNOWLEDGE" },
01714 { CC_RETRIEVE_REJECT, EVENT_RETRIEVE_REJECT, parse_retrieve_reject, build_retrieve_reject, "RETRIEVE_REJECT" },
01715 { CC_DISCONNECT, EVENT_DISCONNECT, parse_disconnect, build_disconnect, "DISCONNECT" },
01716 { CC_RESTART, EVENT_RESTART, parse_restart, build_restart, "RESTART" },
01717 { CC_RELEASE, EVENT_RELEASE, parse_release, build_release, "RELEASE" },
01718 { CC_RELEASE_COMPLETE, EVENT_RELEASE_COMPLETE, parse_release_complete, build_release_complete, "RELEASE_COMPLETE" },
01719 { CC_FACILITY, EVENT_FACILITY, parse_facility, build_facility, "FACILITY" },
01720 { CC_NOTIFY, EVENT_NOTIFY, parse_notify, build_notify, "NOTIFY" },
01721 { CC_STATUS_ENQUIRY, EVENT_STATUS_ENQUIRY, parse_status_enquiry, build_status_enquiry, "STATUS_ENQUIRY" },
01722 { CC_INFORMATION, EVENT_INFORMATION, parse_information, build_information, "INFORMATION" },
01723 { CC_STATUS, EVENT_STATUS, parse_status, build_status, "STATUS" },
01724 { CC_TIMEOUT, EVENT_TIMEOUT, parse_timeout, build_timeout, "TIMEOUT" },
01725 { 0, 0, NULL, NULL, NULL }
01726
01727 };
01728
01729 #define msgs_max (sizeof(msgs_g)/sizeof(struct isdn_msg))
01730
01731
01732 int isdn_msg_get_index(struct isdn_msg msgs[], msg_t *msg, int nt)
01733 {
01734 int i;
01735
01736 if (nt){
01737 mISDNuser_head_t *hh = (mISDNuser_head_t*)msg->data;
01738
01739 for (i=0; i< msgs_max -1; i++) {
01740 if ( (hh->prim&COMMAND_MASK)==(msgs[i].misdn_msg&COMMAND_MASK)) return i;
01741 }
01742
01743 } else {
01744 iframe_t *frm = (iframe_t*)msg->data;
01745
01746 for (i=0; i< msgs_max -1; i++)
01747 if ( (frm->prim&COMMAND_MASK)==(msgs[i].misdn_msg&COMMAND_MASK)) return i;
01748 }
01749
01750 return -1;
01751 }
01752
01753 int isdn_msg_get_index_by_event(struct isdn_msg msgs[], enum event_e event, int nt)
01754 {
01755 int i;
01756 for (i=0; i< msgs_max; i++)
01757 if ( event == msgs[i].event) return i;
01758
01759 cb_log(10,0, "get_index: event not found!\n");
01760
01761 return -1;
01762 }
01763
01764 enum event_e isdn_msg_get_event(struct isdn_msg msgs[], msg_t *msg, int nt)
01765 {
01766 int i=isdn_msg_get_index(msgs, msg, nt);
01767 if(i>=0) return msgs[i].event;
01768 return EVENT_UNKNOWN;
01769 }
01770
01771 char * isdn_msg_get_info(struct isdn_msg msgs[], msg_t *msg, int nt)
01772 {
01773 int i=isdn_msg_get_index(msgs, msg, nt);
01774 if(i>=0) return msgs[i].info;
01775 return NULL;
01776 }
01777
01778
01779 char EVENT_CLEAN_INFO[] = "CLEAN_UP";
01780 char EVENT_DTMF_TONE_INFO[] = "DTMF_TONE";
01781 char EVENT_NEW_L3ID_INFO[] = "NEW_L3ID";
01782 char EVENT_NEW_BC_INFO[] = "NEW_BC";
01783 char EVENT_PORT_ALARM_INFO[] = "ALARM";
01784 char EVENT_NEW_CHANNEL_INFO[] = "NEW_CHANNEL";
01785 char EVENT_BCHAN_DATA_INFO[] = "BCHAN_DATA";
01786 char EVENT_BCHAN_ACTIVATED_INFO[] = "BCHAN_ACTIVATED";
01787 char EVENT_TONE_GENERATE_INFO[] = "TONE_GENERATE";
01788 char EVENT_BCHAN_ERROR_INFO[] = "BCHAN_ERROR";
01789
01790 char * isdn_get_info(struct isdn_msg msgs[], enum event_e event, int nt)
01791 {
01792 int i=isdn_msg_get_index_by_event(msgs, event, nt);
01793
01794 if(i>=0) return msgs[i].info;
01795
01796 if (event == EVENT_CLEANUP) return EVENT_CLEAN_INFO;
01797 if (event == EVENT_DTMF_TONE) return EVENT_DTMF_TONE_INFO;
01798 if (event == EVENT_NEW_L3ID) return EVENT_NEW_L3ID_INFO;
01799 if (event == EVENT_NEW_BC) return EVENT_NEW_BC_INFO;
01800 if (event == EVENT_NEW_CHANNEL) return EVENT_NEW_CHANNEL_INFO;
01801 if (event == EVENT_BCHAN_DATA) return EVENT_BCHAN_DATA_INFO;
01802 if (event == EVENT_BCHAN_ACTIVATED) return EVENT_BCHAN_ACTIVATED_INFO;
01803 if (event == EVENT_TONE_GENERATE) return EVENT_TONE_GENERATE_INFO;
01804 if (event == EVENT_PORT_ALARM) return EVENT_PORT_ALARM_INFO;
01805 if (event == EVENT_BCHAN_ERROR) return EVENT_BCHAN_ERROR_INFO;
01806
01807 return NULL;
01808 }
01809
01810 int isdn_msg_parse_event(struct isdn_msg msgs[], msg_t *msg, struct misdn_bchannel *bc, int nt)
01811 {
01812 int i=isdn_msg_get_index(msgs, msg, nt);
01813 if(i<0) return -1;
01814
01815 msgs[i].msg_parser(msgs, msg, bc, nt);
01816 return 0;
01817 }
01818
01819 msg_t * isdn_msg_build_event(struct isdn_msg msgs[], struct misdn_bchannel *bc, enum event_e event, int nt)
01820 {
01821 int i=isdn_msg_get_index_by_event(msgs, event, nt);
01822 if(i<0) return NULL;
01823
01824 return msgs[i].msg_builder(msgs, bc, nt);
01825 }