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 #ifdef HAVE_PRI
00030
00031 #include <errno.h>
00032 #include <ctype.h>
00033 #include <signal.h>
00034
00035 #include "asterisk/utils.h"
00036 #include "asterisk/options.h"
00037 #include "asterisk/pbx.h"
00038 #include "asterisk/app.h"
00039 #include "asterisk/file.h"
00040 #include "asterisk/callerid.h"
00041 #include "asterisk/say.h"
00042 #include "asterisk/manager.h"
00043 #include "asterisk/astdb.h"
00044 #include "asterisk/causes.h"
00045 #include "asterisk/musiconhold.h"
00046 #include "asterisk/cli.h"
00047 #include "asterisk/transcap.h"
00048 #include "asterisk/features.h"
00049 #include "asterisk/aoc.h"
00050
00051 #include "sig_pri.h"
00052 #ifndef PRI_EVENT_FACILITY
00053 #error please update libpri
00054 #endif
00055
00056
00057 #undef SUPPORT_USERUSER
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 #define FORCE_RESTART_UNAVAIL_CHANS 1
00073
00074 #if defined(HAVE_PRI_CCSS)
00075 struct sig_pri_cc_agent_prv {
00076
00077 struct sig_pri_span *pri;
00078
00079 long cc_id;
00080
00081 unsigned char cc_request_response_pending;
00082 };
00083
00084 struct sig_pri_cc_monitor_instance {
00085
00086 struct sig_pri_span *pri;
00087
00088 long cc_id;
00089
00090 int core_id;
00091
00092 char name[1];
00093 };
00094
00095
00096 static const char *sig_pri_cc_type_name;
00097
00098 static struct ao2_container *sig_pri_cc_monitors;
00099 #endif
00100
00101 static int pri_matchdigittimeout = 3000;
00102
00103 static int pri_gendigittimeout = 8000;
00104
00105 #define DCHAN_NOTINALARM (1 << 0)
00106 #define DCHAN_UP (1 << 1)
00107
00108
00109 #define PRI_CHANNEL(p) ((p) & 0xff)
00110 #define PRI_SPAN(p) (((p) >> 8) & 0xff)
00111 #define PRI_EXPLICIT (1 << 16)
00112 #define PRI_CIS_CALL (1 << 17)
00113 #define PRI_HELD_CALL (1 << 18)
00114
00115
00116 #define DCHAN_AVAILABLE (DCHAN_NOTINALARM | DCHAN_UP)
00117
00118 #define PRI_DEADLOCK_AVOIDANCE(p) \
00119 do { \
00120 sig_pri_unlock_private(p); \
00121 usleep(1); \
00122 sig_pri_lock_private(p); \
00123 } while (0)
00124
00125 static int pri_active_dchan_index(struct sig_pri_span *pri);
00126
00127 static const char *sig_pri_call_level2str(enum sig_pri_call_level level)
00128 {
00129 switch (level) {
00130 case SIG_PRI_CALL_LEVEL_IDLE:
00131 return "Idle";
00132 case SIG_PRI_CALL_LEVEL_SETUP:
00133 return "Setup";
00134 case SIG_PRI_CALL_LEVEL_OVERLAP:
00135 return "Overlap";
00136 case SIG_PRI_CALL_LEVEL_PROCEEDING:
00137 return "Proceeding";
00138 case SIG_PRI_CALL_LEVEL_ALERTING:
00139 return "Alerting";
00140 case SIG_PRI_CALL_LEVEL_DEFER_DIAL:
00141 return "DeferDial";
00142 case SIG_PRI_CALL_LEVEL_CONNECT:
00143 return "Connect";
00144 }
00145 return "Unknown";
00146 }
00147
00148 static inline void pri_rel(struct sig_pri_span *pri)
00149 {
00150 ast_mutex_unlock(&pri->lock);
00151 }
00152
00153 static unsigned int PVT_TO_CHANNEL(struct sig_pri_chan *p)
00154 {
00155 int res = (((p)->prioffset) | ((p)->logicalspan << 8) | (p->mastertrunkgroup ? PRI_EXPLICIT : 0));
00156 ast_debug(5, "prioffset: %d mastertrunkgroup: %d logicalspan: %d result: %d\n",
00157 p->prioffset, p->mastertrunkgroup, p->logicalspan, res);
00158
00159 return res;
00160 }
00161
00162 static void sig_pri_handle_dchan_exception(struct sig_pri_span *pri, int index)
00163 {
00164 if (pri->calls->handle_dchan_exception)
00165 pri->calls->handle_dchan_exception(pri, index);
00166 }
00167
00168 static void sig_pri_set_dialing(struct sig_pri_chan *p, int is_dialing)
00169 {
00170 if (p->calls->set_dialing) {
00171 p->calls->set_dialing(p->chan_pvt, is_dialing);
00172 }
00173 }
00174
00175 static void sig_pri_set_digital(struct sig_pri_chan *p, int is_digital)
00176 {
00177 p->digital = is_digital;
00178 if (p->calls->set_digital) {
00179 p->calls->set_digital(p->chan_pvt, is_digital);
00180 }
00181 }
00182
00183 static void sig_pri_set_outgoing(struct sig_pri_chan *p, int is_outgoing)
00184 {
00185 p->outgoing = is_outgoing;
00186 if (p->calls->set_outgoing) {
00187 p->calls->set_outgoing(p->chan_pvt, is_outgoing);
00188 }
00189 }
00190
00191 void sig_pri_set_alarm(struct sig_pri_chan *p, int in_alarm)
00192 {
00193 if (sig_pri_is_alarm_ignored(p->pri)) {
00194
00195 in_alarm = 0;
00196 }
00197
00198
00199
00200
00201
00202
00203 p->resetting = SIG_PRI_RESET_IDLE;
00204
00205 p->inalarm = in_alarm;
00206 if (p->calls->set_alarm) {
00207 p->calls->set_alarm(p->chan_pvt, in_alarm);
00208 }
00209 }
00210
00211 static const char *sig_pri_get_orig_dialstring(struct sig_pri_chan *p)
00212 {
00213 if (p->calls->get_orig_dialstring) {
00214 return p->calls->get_orig_dialstring(p->chan_pvt);
00215 }
00216 ast_log(LOG_ERROR, "get_orig_dialstring callback not defined\n");
00217 return "";
00218 }
00219
00220 #if defined(HAVE_PRI_CCSS)
00221 static void sig_pri_make_cc_dialstring(struct sig_pri_chan *p, char *buf, size_t buf_size)
00222 {
00223 if (p->calls->make_cc_dialstring) {
00224 p->calls->make_cc_dialstring(p->chan_pvt, buf, buf_size);
00225 } else {
00226 ast_log(LOG_ERROR, "make_cc_dialstring callback not defined\n");
00227 buf[0] = '\0';
00228 }
00229 }
00230 #endif
00231
00232 static void sig_pri_dial_digits(struct sig_pri_chan *p, const char *dial_string)
00233 {
00234 if (p->calls->dial_digits) {
00235 p->calls->dial_digits(p->chan_pvt, dial_string);
00236 }
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 static void sig_pri_span_devstate_changed(struct sig_pri_span *pri)
00251 {
00252 if (pri->calls->update_span_devstate) {
00253 pri->calls->update_span_devstate(pri);
00254 }
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 static void sig_pri_set_caller_id(struct sig_pri_chan *p)
00267 {
00268 struct ast_party_caller caller;
00269
00270 if (p->calls->set_callerid) {
00271 ast_party_caller_init(&caller);
00272
00273 caller.id.name.str = p->cid_name;
00274 caller.id.name.presentation = p->callingpres;
00275 caller.id.name.valid = 1;
00276
00277 caller.id.number.str = p->cid_num;
00278 caller.id.number.plan = p->cid_ton;
00279 caller.id.number.presentation = p->callingpres;
00280 caller.id.number.valid = 1;
00281
00282 if (!ast_strlen_zero(p->cid_subaddr)) {
00283 caller.id.subaddress.valid = 1;
00284
00285
00286 caller.id.subaddress.str = p->cid_subaddr;
00287 }
00288 caller.id.tag = p->user_tag;
00289
00290 caller.ani.number.str = p->cid_ani;
00291
00292
00293 caller.ani.number.valid = 1;
00294
00295 caller.ani2 = p->cid_ani2;
00296 p->calls->set_callerid(p->chan_pvt, &caller);
00297 }
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310 static void sig_pri_set_dnid(struct sig_pri_chan *p, const char *dnid)
00311 {
00312 if (p->calls->set_dnid) {
00313 p->calls->set_dnid(p->chan_pvt, dnid);
00314 }
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 static void sig_pri_set_rdnis(struct sig_pri_chan *p, const char *rdnis)
00328 {
00329 if (p->calls->set_rdnis) {
00330 p->calls->set_rdnis(p->chan_pvt, rdnis);
00331 }
00332 }
00333
00334 static void sig_pri_unlock_private(struct sig_pri_chan *p)
00335 {
00336 if (p->calls->unlock_private)
00337 p->calls->unlock_private(p->chan_pvt);
00338 }
00339
00340 static void sig_pri_lock_private(struct sig_pri_chan *p)
00341 {
00342 if (p->calls->lock_private)
00343 p->calls->lock_private(p->chan_pvt);
00344 }
00345
00346 static void sig_pri_deadlock_avoidance_private(struct sig_pri_chan *p)
00347 {
00348 if (p->calls->deadlock_avoidance_private) {
00349 p->calls->deadlock_avoidance_private(p->chan_pvt);
00350 } else {
00351
00352 PRI_DEADLOCK_AVOIDANCE(p);
00353 }
00354 }
00355
00356 static void pri_grab(struct sig_pri_chan *p, struct sig_pri_span *pri)
00357 {
00358 int res;
00359
00360
00361 do {
00362 res = ast_mutex_trylock(&pri->lock);
00363 if (res) {
00364 sig_pri_deadlock_avoidance_private(p);
00365 }
00366 } while (res);
00367
00368 pthread_kill(pri->master, SIGURG);
00369 }
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 static enum AST_REDIRECTING_REASON pri_to_ast_reason(int pri_reason)
00381 {
00382 enum AST_REDIRECTING_REASON ast_reason;
00383
00384 switch (pri_reason) {
00385 case PRI_REDIR_FORWARD_ON_BUSY:
00386 ast_reason = AST_REDIRECTING_REASON_USER_BUSY;
00387 break;
00388 case PRI_REDIR_FORWARD_ON_NO_REPLY:
00389 ast_reason = AST_REDIRECTING_REASON_NO_ANSWER;
00390 break;
00391 case PRI_REDIR_DEFLECTION:
00392 ast_reason = AST_REDIRECTING_REASON_DEFLECTION;
00393 break;
00394 case PRI_REDIR_UNCONDITIONAL:
00395 ast_reason = AST_REDIRECTING_REASON_UNCONDITIONAL;
00396 break;
00397 case PRI_REDIR_UNKNOWN:
00398 default:
00399 ast_reason = AST_REDIRECTING_REASON_UNKNOWN;
00400 break;
00401 }
00402
00403 return ast_reason;
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 static int ast_to_pri_reason(enum AST_REDIRECTING_REASON ast_reason)
00416 {
00417 int pri_reason;
00418
00419 switch (ast_reason) {
00420 case AST_REDIRECTING_REASON_USER_BUSY:
00421 pri_reason = PRI_REDIR_FORWARD_ON_BUSY;
00422 break;
00423 case AST_REDIRECTING_REASON_NO_ANSWER:
00424 pri_reason = PRI_REDIR_FORWARD_ON_NO_REPLY;
00425 break;
00426 case AST_REDIRECTING_REASON_UNCONDITIONAL:
00427 pri_reason = PRI_REDIR_UNCONDITIONAL;
00428 break;
00429 case AST_REDIRECTING_REASON_DEFLECTION:
00430 pri_reason = PRI_REDIR_DEFLECTION;
00431 break;
00432 case AST_REDIRECTING_REASON_UNKNOWN:
00433 default:
00434 pri_reason = PRI_REDIR_UNKNOWN;
00435 break;
00436 }
00437
00438 return pri_reason;
00439 }
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 static int pri_to_ast_presentation(int pri_presentation)
00451 {
00452 int ast_presentation;
00453
00454 switch (pri_presentation) {
00455 case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED:
00456 ast_presentation = AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_UNSCREENED;
00457 break;
00458 case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
00459 ast_presentation = AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_PASSED_SCREEN;
00460 break;
00461 case PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
00462 ast_presentation = AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_FAILED_SCREEN;
00463 break;
00464 case PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER:
00465 ast_presentation = AST_PRES_ALLOWED | AST_PRES_NETWORK_NUMBER;
00466 break;
00467
00468 case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED:
00469 ast_presentation = AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED;
00470 break;
00471 case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
00472 ast_presentation = AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_PASSED_SCREEN;
00473 break;
00474 case PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
00475 ast_presentation = AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_FAILED_SCREEN;
00476 break;
00477 case PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER:
00478 ast_presentation = AST_PRES_RESTRICTED | AST_PRES_NETWORK_NUMBER;
00479 break;
00480
00481 case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_UNSCREENED:
00482 case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_PASSED_SCREEN:
00483 case PRI_PRES_UNAVAILABLE | PRI_PRES_USER_NUMBER_FAILED_SCREEN:
00484 case PRI_PRES_UNAVAILABLE | PRI_PRES_NETWORK_NUMBER:
00485 ast_presentation = AST_PRES_NUMBER_NOT_AVAILABLE;
00486 break;
00487
00488 default:
00489 ast_presentation = AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED;
00490 break;
00491 }
00492
00493 return ast_presentation;
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 static int ast_to_pri_presentation(int ast_presentation)
00506 {
00507 int pri_presentation;
00508
00509 switch (ast_presentation) {
00510 case AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_UNSCREENED:
00511 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_UNSCREENED;
00512 break;
00513 case AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_PASSED_SCREEN:
00514 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_PASSED_SCREEN;
00515 break;
00516 case AST_PRES_ALLOWED | AST_PRES_USER_NUMBER_FAILED_SCREEN:
00517 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_USER_NUMBER_FAILED_SCREEN;
00518 break;
00519 case AST_PRES_ALLOWED | AST_PRES_NETWORK_NUMBER:
00520 pri_presentation = PRI_PRES_ALLOWED | PRI_PRES_NETWORK_NUMBER;
00521 break;
00522
00523 case AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_UNSCREENED:
00524 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
00525 break;
00526 case AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_PASSED_SCREEN:
00527 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_PASSED_SCREEN;
00528 break;
00529 case AST_PRES_RESTRICTED | AST_PRES_USER_NUMBER_FAILED_SCREEN:
00530 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_FAILED_SCREEN;
00531 break;
00532 case AST_PRES_RESTRICTED | AST_PRES_NETWORK_NUMBER:
00533 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_NETWORK_NUMBER;
00534 break;
00535
00536 case AST_PRES_UNAVAILABLE | AST_PRES_USER_NUMBER_UNSCREENED:
00537 case AST_PRES_UNAVAILABLE | AST_PRES_USER_NUMBER_PASSED_SCREEN:
00538 case AST_PRES_UNAVAILABLE | AST_PRES_USER_NUMBER_FAILED_SCREEN:
00539 case AST_PRES_UNAVAILABLE | AST_PRES_NETWORK_NUMBER:
00540 pri_presentation = PRES_NUMBER_NOT_AVAILABLE;
00541 break;
00542
00543 default:
00544 pri_presentation = PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
00545 break;
00546 }
00547
00548 return pri_presentation;
00549 }
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 static enum AST_PARTY_CHAR_SET pri_to_ast_char_set(int pri_char_set)
00561 {
00562 enum AST_PARTY_CHAR_SET ast_char_set;
00563
00564 switch (pri_char_set) {
00565 default:
00566 case PRI_CHAR_SET_UNKNOWN:
00567 ast_char_set = AST_PARTY_CHAR_SET_UNKNOWN;
00568 break;
00569 case PRI_CHAR_SET_ISO8859_1:
00570 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_1;
00571 break;
00572 case PRI_CHAR_SET_WITHDRAWN:
00573 ast_char_set = AST_PARTY_CHAR_SET_WITHDRAWN;
00574 break;
00575 case PRI_CHAR_SET_ISO8859_2:
00576 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_2;
00577 break;
00578 case PRI_CHAR_SET_ISO8859_3:
00579 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_3;
00580 break;
00581 case PRI_CHAR_SET_ISO8859_4:
00582 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_4;
00583 break;
00584 case PRI_CHAR_SET_ISO8859_5:
00585 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_5;
00586 break;
00587 case PRI_CHAR_SET_ISO8859_7:
00588 ast_char_set = AST_PARTY_CHAR_SET_ISO8859_7;
00589 break;
00590 case PRI_CHAR_SET_ISO10646_BMPSTRING:
00591 ast_char_set = AST_PARTY_CHAR_SET_ISO10646_BMPSTRING;
00592 break;
00593 case PRI_CHAR_SET_ISO10646_UTF_8STRING:
00594 ast_char_set = AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING;
00595 break;
00596 }
00597
00598 return ast_char_set;
00599 }
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610 static int ast_to_pri_char_set(enum AST_PARTY_CHAR_SET ast_char_set)
00611 {
00612 int pri_char_set;
00613
00614 switch (ast_char_set) {
00615 default:
00616 case AST_PARTY_CHAR_SET_UNKNOWN:
00617 pri_char_set = PRI_CHAR_SET_UNKNOWN;
00618 break;
00619 case AST_PARTY_CHAR_SET_ISO8859_1:
00620 pri_char_set = PRI_CHAR_SET_ISO8859_1;
00621 break;
00622 case AST_PARTY_CHAR_SET_WITHDRAWN:
00623 pri_char_set = PRI_CHAR_SET_WITHDRAWN;
00624 break;
00625 case AST_PARTY_CHAR_SET_ISO8859_2:
00626 pri_char_set = PRI_CHAR_SET_ISO8859_2;
00627 break;
00628 case AST_PARTY_CHAR_SET_ISO8859_3:
00629 pri_char_set = PRI_CHAR_SET_ISO8859_3;
00630 break;
00631 case AST_PARTY_CHAR_SET_ISO8859_4:
00632 pri_char_set = PRI_CHAR_SET_ISO8859_4;
00633 break;
00634 case AST_PARTY_CHAR_SET_ISO8859_5:
00635 pri_char_set = PRI_CHAR_SET_ISO8859_5;
00636 break;
00637 case AST_PARTY_CHAR_SET_ISO8859_7:
00638 pri_char_set = PRI_CHAR_SET_ISO8859_7;
00639 break;
00640 case AST_PARTY_CHAR_SET_ISO10646_BMPSTRING:
00641 pri_char_set = PRI_CHAR_SET_ISO10646_BMPSTRING;
00642 break;
00643 case AST_PARTY_CHAR_SET_ISO10646_UTF_8STRING:
00644 pri_char_set = PRI_CHAR_SET_ISO10646_UTF_8STRING;
00645 break;
00646 }
00647
00648 return pri_char_set;
00649 }
00650
00651 #if defined(HAVE_PRI_SUBADDR)
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663 static void sig_pri_set_subaddress(struct ast_party_subaddress *ast_subaddress, const struct pri_party_subaddress *pri_subaddress)
00664 {
00665 char *cnum, *ptr;
00666 int x, len;
00667
00668 if (ast_subaddress->str) {
00669 ast_free(ast_subaddress->str);
00670 }
00671 if (pri_subaddress->length <= 0) {
00672 ast_party_subaddress_init(ast_subaddress);
00673 return;
00674 }
00675
00676 if (!pri_subaddress->type) {
00677
00678 ast_subaddress->str = ast_strdup((char *) pri_subaddress->data);
00679 } else {
00680
00681 if (!(cnum = ast_malloc(2 * pri_subaddress->length + 1))) {
00682 ast_party_subaddress_init(ast_subaddress);
00683 return;
00684 }
00685
00686 ptr = cnum;
00687 len = pri_subaddress->length - 1;
00688 for (x = 0; x < len; ++x) {
00689 ptr += sprintf(ptr, "%02x", pri_subaddress->data[x]);
00690 }
00691
00692 if (pri_subaddress->odd_even_indicator) {
00693
00694 sprintf(ptr, "%01x", (pri_subaddress->data[len]) >> 4);
00695 } else {
00696
00697 sprintf(ptr, "%02x", pri_subaddress->data[len]);
00698 }
00699 ast_subaddress->str = cnum;
00700 }
00701 ast_subaddress->type = pri_subaddress->type;
00702 ast_subaddress->odd_even_indicator = pri_subaddress->odd_even_indicator;
00703 ast_subaddress->valid = 1;
00704 }
00705 #endif
00706
00707 #if defined(HAVE_PRI_SUBADDR)
00708 static unsigned char ast_pri_pack_hex_char(char c)
00709 {
00710 unsigned char res;
00711
00712 if (c < '0') {
00713 res = 0;
00714 } else if (c < ('9' + 1)) {
00715 res = c - '0';
00716 } else if (c < 'A') {
00717 res = 0;
00718 } else if (c < ('F' + 1)) {
00719 res = c - 'A' + 10;
00720 } else if (c < 'a') {
00721 res = 0;
00722 } else if (c < ('f' + 1)) {
00723 res = c - 'a' + 10;
00724 } else {
00725 res = 0;
00726 }
00727 return res;
00728 }
00729 #endif
00730
00731 #if defined(HAVE_PRI_SUBADDR)
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747 static int ast_pri_pack_hex_string(unsigned char *dst, char *src, int maxlen)
00748 {
00749 int res = 0;
00750 int len = strlen(src);
00751
00752 if (len > (2 * maxlen)) {
00753 len = 2 * maxlen;
00754 }
00755
00756 res = len / 2 + len % 2;
00757
00758 while (len > 1) {
00759 *dst = ast_pri_pack_hex_char(*src) << 4;
00760 src++;
00761 *dst |= ast_pri_pack_hex_char(*src);
00762 dst++, src++;
00763 len -= 2;
00764 }
00765 if (len) {
00766 *dst = ast_pri_pack_hex_char(*src) << 4;
00767 }
00768 return res;
00769 }
00770 #endif
00771
00772 #if defined(HAVE_PRI_SUBADDR)
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785 static void sig_pri_party_subaddress_from_ast(struct pri_party_subaddress *pri_subaddress, const struct ast_party_subaddress *ast_subaddress)
00786 {
00787 if (ast_subaddress->valid && !ast_strlen_zero(ast_subaddress->str)) {
00788 pri_subaddress->type = ast_subaddress->type;
00789 if (!ast_subaddress->type) {
00790
00791 ast_copy_string((char *) pri_subaddress->data, ast_subaddress->str,
00792 sizeof(pri_subaddress->data));
00793 pri_subaddress->length = strlen((char *) pri_subaddress->data);
00794 pri_subaddress->odd_even_indicator = 0;
00795 pri_subaddress->valid = 1;
00796 } else {
00797
00798
00799
00800
00801
00802 int length = ast_pri_pack_hex_string(pri_subaddress->data,
00803 ast_subaddress->str, sizeof(pri_subaddress->data));
00804
00805 pri_subaddress->length = length;
00806
00807 length = strlen(ast_subaddress->str);
00808 if (length > 2 * sizeof(pri_subaddress->data)) {
00809 pri_subaddress->odd_even_indicator = 0;
00810 } else {
00811 pri_subaddress->odd_even_indicator = (length & 1);
00812 }
00813 pri_subaddress->valid = 1;
00814 }
00815 }
00816 }
00817 #endif
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831 static void sig_pri_party_name_from_ast(struct pri_party_name *pri_name, const struct ast_party_name *ast_name)
00832 {
00833 if (!ast_name->valid) {
00834 return;
00835 }
00836 pri_name->valid = 1;
00837 pri_name->presentation = ast_to_pri_presentation(ast_name->presentation);
00838 pri_name->char_set = ast_to_pri_char_set(ast_name->char_set);
00839 if (!ast_strlen_zero(ast_name->str)) {
00840 ast_copy_string(pri_name->str, ast_name->str, sizeof(pri_name->str));
00841 }
00842 }
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856 static void sig_pri_party_number_from_ast(struct pri_party_number *pri_number, const struct ast_party_number *ast_number)
00857 {
00858 if (!ast_number->valid) {
00859 return;
00860 }
00861 pri_number->valid = 1;
00862 pri_number->presentation = ast_to_pri_presentation(ast_number->presentation);
00863 pri_number->plan = ast_number->plan;
00864 if (!ast_strlen_zero(ast_number->str)) {
00865 ast_copy_string(pri_number->str, ast_number->str, sizeof(pri_number->str));
00866 }
00867 }
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881 static void sig_pri_party_id_from_ast(struct pri_party_id *pri_id, const struct ast_party_id *ast_id)
00882 {
00883 sig_pri_party_name_from_ast(&pri_id->name, &ast_id->name);
00884 sig_pri_party_number_from_ast(&pri_id->number, &ast_id->number);
00885 #if defined(HAVE_PRI_SUBADDR)
00886 sig_pri_party_subaddress_from_ast(&pri_id->subaddress, &ast_id->subaddress);
00887 #endif
00888 }
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902 static void sig_pri_redirecting_update(struct sig_pri_chan *pvt, struct ast_channel *ast)
00903 {
00904 struct pri_party_redirecting pri_redirecting;
00905 const struct ast_party_redirecting *ast_redirecting;
00906
00907 memset(&pri_redirecting, 0, sizeof(pri_redirecting));
00908 ast_redirecting = ast_channel_redirecting(ast);
00909 sig_pri_party_id_from_ast(&pri_redirecting.from, &ast_redirecting->from);
00910 sig_pri_party_id_from_ast(&pri_redirecting.to, &ast_redirecting->to);
00911 sig_pri_party_id_from_ast(&pri_redirecting.orig_called, &ast_redirecting->orig);
00912 pri_redirecting.count = ast_redirecting->count;
00913 pri_redirecting.orig_reason = ast_to_pri_reason(ast_redirecting->orig_reason);
00914 pri_redirecting.reason = ast_to_pri_reason(ast_redirecting->reason);
00915
00916 pri_redirecting_update(pvt->pri->pri, pvt->call, &pri_redirecting);
00917 }
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928 static void sig_pri_dsp_reset_and_flush_digits(struct sig_pri_chan *p)
00929 {
00930 if (p->calls->dsp_reset_and_flush_digits) {
00931 p->calls->dsp_reset_and_flush_digits(p->chan_pvt);
00932 }
00933 }
00934
00935 static int sig_pri_set_echocanceller(struct sig_pri_chan *p, int enable)
00936 {
00937 if (p->calls->set_echocanceller)
00938 return p->calls->set_echocanceller(p->chan_pvt, enable);
00939 else
00940 return -1;
00941 }
00942
00943 static void sig_pri_fixup_chans(struct sig_pri_chan *old_chan, struct sig_pri_chan *new_chan)
00944 {
00945 if (old_chan->calls->fixup_chans)
00946 old_chan->calls->fixup_chans(old_chan->chan_pvt, new_chan->chan_pvt);
00947 }
00948
00949 static int sig_pri_play_tone(struct sig_pri_chan *p, enum sig_pri_tone tone)
00950 {
00951 if (p->calls->play_tone)
00952 return p->calls->play_tone(p->chan_pvt, tone);
00953 else
00954 return -1;
00955 }
00956
00957 static struct ast_channel *sig_pri_new_ast_channel(struct sig_pri_chan *p, int state, int ulaw, int transfercapability, char *exten, const struct ast_channel *requestor)
00958 {
00959 struct ast_channel *c;
00960
00961 if (p->calls->new_ast_channel) {
00962 c = p->calls->new_ast_channel(p->chan_pvt, state, ulaw, exten, requestor);
00963 } else {
00964 return NULL;
00965 }
00966 if (!c) {
00967 return NULL;
00968 }
00969
00970 if (!p->owner)
00971 p->owner = c;
00972 p->isidlecall = 0;
00973 p->alreadyhungup = 0;
00974 ast_channel_transfercapability_set(c, transfercapability);
00975 pbx_builtin_setvar_helper(c, "TRANSFERCAPABILITY",
00976 ast_transfercapability2str(transfercapability));
00977 if (transfercapability & AST_TRANS_CAP_DIGITAL) {
00978 sig_pri_set_digital(p, 1);
00979 }
00980 if (p->pri) {
00981 ast_mutex_lock(&p->pri->lock);
00982 sig_pri_span_devstate_changed(p->pri);
00983 ast_mutex_unlock(&p->pri->lock);
00984 }
00985
00986 return c;
00987 }
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998 static void sig_pri_open_media(struct sig_pri_chan *p)
00999 {
01000 if (p->no_b_channel) {
01001 return;
01002 }
01003
01004 if (p->calls->open_media) {
01005 p->calls->open_media(p->chan_pvt);
01006 }
01007 }
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020 static void sig_pri_ami_channel_event(struct sig_pri_chan *p)
01021 {
01022 if (p->calls->ami_channel_event) {
01023 p->calls->ami_channel_event(p->chan_pvt, p->owner);
01024 }
01025 }
01026
01027 struct ast_channel *sig_pri_request(struct sig_pri_chan *p, enum sig_pri_law law, const struct ast_channel *requestor, int transfercapability)
01028 {
01029 struct ast_channel *ast;
01030
01031 ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
01032
01033 sig_pri_set_outgoing(p, 1);
01034 ast = sig_pri_new_ast_channel(p, AST_STATE_RESERVED, law, transfercapability, p->exten, requestor);
01035 if (!ast) {
01036 sig_pri_set_outgoing(p, 0);
01037 }
01038 return ast;
01039 }
01040
01041 int pri_is_up(struct sig_pri_span *pri)
01042 {
01043 int x;
01044 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
01045 if (pri->dchanavail[x] == DCHAN_AVAILABLE)
01046 return 1;
01047 }
01048 return 0;
01049 }
01050
01051 static const char *pri_order(int level)
01052 {
01053 switch (level) {
01054 case 0:
01055 return "Primary";
01056 case 1:
01057 return "Secondary";
01058 case 2:
01059 return "Tertiary";
01060 case 3:
01061 return "Quaternary";
01062 default:
01063 return "<Unknown>";
01064 }
01065 }
01066
01067
01068 static int pri_active_dchan_index(struct sig_pri_span *pri)
01069 {
01070 int x;
01071
01072 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
01073 if ((pri->dchans[x] == pri->pri))
01074 return x;
01075 }
01076
01077 ast_log(LOG_WARNING, "No active dchan found!\n");
01078 return -1;
01079 }
01080
01081 static void pri_find_dchan(struct sig_pri_span *pri)
01082 {
01083 struct pri *old;
01084 int oldslot = -1;
01085 int newslot = -1;
01086 int idx;
01087
01088 old = pri->pri;
01089 for (idx = 0; idx < SIG_PRI_NUM_DCHANS; ++idx) {
01090 if (!pri->dchans[idx]) {
01091
01092 break;
01093 }
01094 if (pri->dchans[idx] == old) {
01095 oldslot = idx;
01096 }
01097 if (newslot < 0 && pri->dchanavail[idx] == DCHAN_AVAILABLE) {
01098 newslot = idx;
01099 }
01100 }
01101
01102
01103 if (1 < idx) {
01104
01105 if (newslot < 0) {
01106
01107 newslot = 0;
01108
01109 if (!pri->no_d_channels) {
01110 pri->no_d_channels = 1;
01111 if (old && oldslot != newslot) {
01112 ast_log(LOG_WARNING,
01113 "Span %d: No D-channels up! Switching selected D-channel from %s to %s.\n",
01114 pri->span, pri_order(oldslot), pri_order(newslot));
01115 } else {
01116 ast_log(LOG_WARNING, "Span %d: No D-channels up!\n", pri->span);
01117 }
01118 }
01119 } else {
01120 pri->no_d_channels = 0;
01121 }
01122 if (old && oldslot != newslot) {
01123 ast_log(LOG_NOTICE,
01124 "Switching selected D-channel from %s (fd %d) to %s (fd %d)!\n",
01125 pri_order(oldslot), pri->fds[oldslot],
01126 pri_order(newslot), pri->fds[newslot]);
01127 }
01128 } else {
01129 if (newslot < 0) {
01130
01131 newslot = 0;
01132
01133 if (!pri->no_d_channels) {
01134 pri->no_d_channels = 1;
01135
01136
01137
01138
01139
01140 if (pri->sig != SIG_BRI_PTMP) {
01141 ast_log(LOG_WARNING, "Span %d: D-channel is down!\n", pri->span);
01142 }
01143 }
01144 } else {
01145 pri->no_d_channels = 0;
01146 }
01147 }
01148 pri->pri = pri->dchans[newslot];
01149 }
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160 static int sig_pri_is_chan_in_use(struct sig_pri_chan *pvt)
01161 {
01162 return pvt->owner || pvt->call || pvt->allocated || pvt->inalarm
01163 || pvt->resetting != SIG_PRI_RESET_IDLE;
01164 }
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174 int sig_pri_is_chan_available(struct sig_pri_chan *pvt)
01175 {
01176 return !sig_pri_is_chan_in_use(pvt)
01177 #if defined(HAVE_PRI_SERVICE_MESSAGES)
01178
01179 && !pvt->service_status
01180 #endif
01181 ;
01182 }
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197 static void sig_pri_lock_owner(struct sig_pri_span *pri, int chanpos)
01198 {
01199 for (;;) {
01200 if (!pri->pvts[chanpos]->owner) {
01201
01202 break;
01203 }
01204 if (!ast_channel_trylock(pri->pvts[chanpos]->owner)) {
01205
01206 break;
01207 }
01208
01209 ast_mutex_unlock(&pri->lock);
01210 sig_pri_deadlock_avoidance_private(pri->pvts[chanpos]);
01211 ast_mutex_lock(&pri->lock);
01212 }
01213 }
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229 static void pri_queue_frame(struct sig_pri_span *pri, int chanpos, struct ast_frame *frame)
01230 {
01231 sig_pri_lock_owner(pri, chanpos);
01232 if (pri->pvts[chanpos]->owner) {
01233 ast_queue_frame(pri->pvts[chanpos]->owner, frame);
01234 ast_channel_unlock(pri->pvts[chanpos]->owner);
01235 }
01236 }
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252 static void pri_queue_control(struct sig_pri_span *pri, int chanpos, int subclass)
01253 {
01254 struct ast_frame f = {AST_FRAME_CONTROL, };
01255 struct sig_pri_chan *p = pri->pvts[chanpos];
01256
01257 if (p->calls->queue_control) {
01258 p->calls->queue_control(p->chan_pvt, subclass);
01259 }
01260
01261 f.subclass.integer = subclass;
01262 pri_queue_frame(pri, chanpos, &f);
01263 }
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278 static int pri_find_principle_by_call(struct sig_pri_span *pri, q931_call *call)
01279 {
01280 int idx;
01281
01282 if (!call) {
01283
01284 return -1;
01285 }
01286 for (idx = 0; idx < pri->numchans; ++idx) {
01287 if (pri->pvts[idx] && pri->pvts[idx]->call == call) {
01288
01289 return idx;
01290 }
01291 }
01292 return -1;
01293 }
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308 static void sig_pri_kill_call(struct sig_pri_span *pri, q931_call *call, int cause)
01309 {
01310 int chanpos;
01311
01312 chanpos = pri_find_principle_by_call(pri, call);
01313 if (chanpos < 0) {
01314 pri_hangup(pri->pri, call, cause);
01315 return;
01316 }
01317 sig_pri_lock_private(pri->pvts[chanpos]);
01318 if (!pri->pvts[chanpos]->owner) {
01319 pri_hangup(pri->pri, call, cause);
01320 pri->pvts[chanpos]->call = NULL;
01321 sig_pri_unlock_private(pri->pvts[chanpos]);
01322 sig_pri_span_devstate_changed(pri);
01323 return;
01324 }
01325 ast_channel_hangupcause_set(pri->pvts[chanpos]->owner, cause);
01326 pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP);
01327 sig_pri_unlock_private(pri->pvts[chanpos]);
01328 }
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343 static int pri_find_principle(struct sig_pri_span *pri, int channel, q931_call *call)
01344 {
01345 int x;
01346 int span;
01347 int principle;
01348 int prioffset;
01349
01350 if (channel < 0) {
01351
01352 return -1;
01353 }
01354
01355 prioffset = PRI_CHANNEL(channel);
01356 if (!prioffset || (channel & PRI_HELD_CALL)) {
01357
01358 return pri_find_principle_by_call(pri, call);
01359 }
01360
01361 span = PRI_SPAN(channel);
01362 if (!(channel & PRI_EXPLICIT)) {
01363 int index;
01364
01365 index = pri_active_dchan_index(pri);
01366 if (index == -1) {
01367 return -1;
01368 }
01369 span = pri->dchan_logical_span[index];
01370 }
01371
01372 principle = -1;
01373 for (x = 0; x < pri->numchans; x++) {
01374 if (pri->pvts[x]
01375 && pri->pvts[x]->prioffset == prioffset
01376 && pri->pvts[x]->logicalspan == span
01377 && !pri->pvts[x]->no_b_channel) {
01378 principle = x;
01379 break;
01380 }
01381 }
01382
01383 return principle;
01384 }
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399 static int pri_fixup_principle(struct sig_pri_span *pri, int principle, q931_call *call)
01400 {
01401 int x;
01402
01403 if (principle < 0 || pri->numchans <= principle) {
01404
01405 return -1;
01406 }
01407 if (!call) {
01408
01409 return principle;
01410 }
01411 if (pri->pvts[principle] && pri->pvts[principle]->call == call) {
01412
01413 return principle;
01414 }
01415
01416
01417 for (x = 0; x < pri->numchans; x++) {
01418 struct sig_pri_chan *new_chan;
01419 struct sig_pri_chan *old_chan;
01420
01421 if (!pri->pvts[x] || pri->pvts[x]->call != call) {
01422 continue;
01423 }
01424
01425
01426 new_chan = pri->pvts[principle];
01427 old_chan = pri->pvts[x];
01428
01429
01430 sig_pri_lock_private(old_chan);
01431 sig_pri_lock_owner(pri, x);
01432 sig_pri_lock_private(new_chan);
01433
01434 ast_verb(3, "Moving call (%s) from channel %d to %d.\n",
01435 old_chan->owner ? ast_channel_name(old_chan->owner) : "",
01436 old_chan->channel, new_chan->channel);
01437 if (!sig_pri_is_chan_available(new_chan)) {
01438 ast_log(LOG_WARNING,
01439 "Can't move call (%s) from channel %d to %d. It is already in use.\n",
01440 old_chan->owner ? ast_channel_name(old_chan->owner) : "",
01441 old_chan->channel, new_chan->channel);
01442 sig_pri_unlock_private(new_chan);
01443 if (old_chan->owner) {
01444 ast_channel_unlock(old_chan->owner);
01445 }
01446 sig_pri_unlock_private(old_chan);
01447 return -1;
01448 }
01449
01450 sig_pri_fixup_chans(old_chan, new_chan);
01451
01452
01453 new_chan->owner = old_chan->owner;
01454 old_chan->owner = NULL;
01455
01456 new_chan->call = old_chan->call;
01457 old_chan->call = NULL;
01458
01459
01460 #if defined(HAVE_PRI_AOC_EVENTS)
01461 new_chan->aoc_s_request_invoke_id_valid = old_chan->aoc_s_request_invoke_id_valid;
01462 new_chan->waiting_for_aoce = old_chan->waiting_for_aoce;
01463 new_chan->holding_aoce = old_chan->holding_aoce;
01464 #endif
01465 new_chan->alreadyhungup = old_chan->alreadyhungup;
01466 new_chan->isidlecall = old_chan->isidlecall;
01467 new_chan->progress = old_chan->progress;
01468 new_chan->allocated = old_chan->allocated;
01469 new_chan->outgoing = old_chan->outgoing;
01470 new_chan->digital = old_chan->digital;
01471 #if defined(HAVE_PRI_CALL_WAITING)
01472 new_chan->is_call_waiting = old_chan->is_call_waiting;
01473 #endif
01474
01475 #if defined(HAVE_PRI_AOC_EVENTS)
01476 old_chan->aoc_s_request_invoke_id_valid = 0;
01477 old_chan->waiting_for_aoce = 0;
01478 old_chan->holding_aoce = 0;
01479 #endif
01480 old_chan->alreadyhungup = 0;
01481 old_chan->isidlecall = 0;
01482 old_chan->progress = 0;
01483 old_chan->allocated = 0;
01484 old_chan->outgoing = 0;
01485 old_chan->digital = 0;
01486 #if defined(HAVE_PRI_CALL_WAITING)
01487 old_chan->is_call_waiting = 0;
01488 #endif
01489
01490
01491 new_chan->call_level = old_chan->call_level;
01492 old_chan->call_level = SIG_PRI_CALL_LEVEL_IDLE;
01493 #if defined(HAVE_PRI_REVERSE_CHARGE)
01494 new_chan->reverse_charging_indication = old_chan->reverse_charging_indication;
01495 #endif
01496 #if defined(HAVE_PRI_SETUP_KEYPAD)
01497 strcpy(new_chan->keypad_digits, old_chan->keypad_digits);
01498 #endif
01499 strcpy(new_chan->deferred_digits, old_chan->deferred_digits);
01500 strcpy(new_chan->moh_suggested, old_chan->moh_suggested);
01501 new_chan->moh_state = old_chan->moh_state;
01502 old_chan->moh_state = SIG_PRI_MOH_STATE_IDLE;
01503
01504 #if defined(HAVE_PRI_AOC_EVENTS)
01505 new_chan->aoc_s_request_invoke_id = old_chan->aoc_s_request_invoke_id;
01506 new_chan->aoc_e = old_chan->aoc_e;
01507 #endif
01508 strcpy(new_chan->user_tag, old_chan->user_tag);
01509
01510 if (new_chan->no_b_channel) {
01511
01512 new_chan->hidecallerid = old_chan->hidecallerid;
01513 new_chan->hidecalleridname = old_chan->hidecalleridname;
01514 new_chan->immediate = old_chan->immediate;
01515 new_chan->priexclusive = old_chan->priexclusive;
01516 new_chan->priindication_oob = old_chan->priindication_oob;
01517 new_chan->use_callerid = old_chan->use_callerid;
01518 new_chan->use_callingpres = old_chan->use_callingpres;
01519 new_chan->stripmsd = old_chan->stripmsd;
01520 strcpy(new_chan->context, old_chan->context);
01521 strcpy(new_chan->mohinterpret, old_chan->mohinterpret);
01522
01523
01524 new_chan->logicalspan = old_chan->logicalspan;
01525 new_chan->mastertrunkgroup = old_chan->mastertrunkgroup;
01526 } else if (old_chan->no_b_channel) {
01527
01528
01529
01530
01531
01532
01533 sig_pri_open_media(new_chan);
01534 }
01535
01536 if (new_chan->owner) {
01537 sig_pri_ami_channel_event(new_chan);
01538 }
01539
01540 sig_pri_unlock_private(old_chan);
01541 if (new_chan->owner) {
01542 ast_channel_unlock(new_chan->owner);
01543 }
01544 sig_pri_unlock_private(new_chan);
01545
01546 return principle;
01547 }
01548 ast_verb(3, "Call specified, but not found.\n");
01549 return -1;
01550 }
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565
01566
01567
01568
01569
01570 static int pri_find_fixup_principle(struct sig_pri_span *pri, int channel, q931_call *call)
01571 {
01572 int chanpos;
01573
01574 chanpos = pri_find_principle(pri, channel, call);
01575 if (chanpos < 0) {
01576 ast_log(LOG_WARNING, "Span %d: PRI requested channel %d/%d is unconfigured.\n",
01577 pri->span, PRI_SPAN(channel), PRI_CHANNEL(channel));
01578 sig_pri_kill_call(pri, call, PRI_CAUSE_IDENTIFIED_CHANNEL_NOTEXIST);
01579 return -1;
01580 }
01581 chanpos = pri_fixup_principle(pri, chanpos, call);
01582 if (chanpos < 0) {
01583 ast_log(LOG_WARNING, "Span %d: PRI requested channel %d/%d is not available.\n",
01584 pri->span, PRI_SPAN(channel), PRI_CHANNEL(channel));
01585
01586
01587
01588
01589
01590
01591
01592 sig_pri_kill_call(pri, call, PRI_CAUSE_CHANNEL_UNACCEPTABLE);
01593 return -1;
01594 }
01595 return chanpos;
01596 }
01597
01598 static char * redirectingreason2str(int redirectingreason)
01599 {
01600 switch (redirectingreason) {
01601 case 0:
01602 return "UNKNOWN";
01603 case 1:
01604 return "BUSY";
01605 case 2:
01606 return "NO_REPLY";
01607 case 0xF:
01608 return "UNCONDITIONAL";
01609 default:
01610 return "NOREDIRECT";
01611 }
01612 }
01613
01614 static char *dialplan2str(int dialplan)
01615 {
01616 if (dialplan == -1) {
01617 return("Dynamically set dialplan in ISDN");
01618 }
01619 return (pri_plan2str(dialplan));
01620 }
01621
01622
01623
01624
01625
01626
01627
01628
01629
01630
01631
01632
01633
01634 static void apply_plan_to_number(char *buf, size_t size, const struct sig_pri_span *pri, const char *number, int plan)
01635 {
01636 switch (plan) {
01637 case PRI_INTERNATIONAL_ISDN:
01638 snprintf(buf, size, "%s%s", pri->internationalprefix, number);
01639 break;
01640 case PRI_NATIONAL_ISDN:
01641 snprintf(buf, size, "%s%s", pri->nationalprefix, number);
01642 break;
01643 case PRI_LOCAL_ISDN:
01644 snprintf(buf, size, "%s%s", pri->localprefix, number);
01645 break;
01646 case PRI_PRIVATE:
01647 snprintf(buf, size, "%s%s", pri->privateprefix, number);
01648 break;
01649 case PRI_UNKNOWN:
01650 snprintf(buf, size, "%s%s", pri->unknownprefix, number);
01651 break;
01652 default:
01653 snprintf(buf, size, "%s", number);
01654 break;
01655 }
01656 }
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670 static void apply_plan_to_existing_number(char *buf, size_t size, const struct sig_pri_span *pri, const char *number, int plan)
01671 {
01672
01673 if (ast_strlen_zero(number)) {
01674 if (size) {
01675 *buf = '\0';
01676 }
01677 return;
01678 }
01679 apply_plan_to_number(buf, size, pri, number, plan);
01680 }
01681
01682
01683
01684
01685
01686
01687
01688
01689
01690
01691
01692 static void pri_check_restart(struct sig_pri_span *pri)
01693 {
01694 #if defined(HAVE_PRI_SERVICE_MESSAGES)
01695 unsigned why;
01696 #endif
01697
01698 for (++pri->resetpos; pri->resetpos < pri->numchans; ++pri->resetpos) {
01699 if (!pri->pvts[pri->resetpos]
01700 || pri->pvts[pri->resetpos]->no_b_channel
01701 || sig_pri_is_chan_in_use(pri->pvts[pri->resetpos])) {
01702 continue;
01703 }
01704 #if defined(HAVE_PRI_SERVICE_MESSAGES)
01705 why = pri->pvts[pri->resetpos]->service_status;
01706 if (why) {
01707 ast_log(LOG_NOTICE,
01708 "Span %d: channel %d out-of-service (reason: %s), not sending RESTART\n",
01709 pri->span, pri->pvts[pri->resetpos]->channel,
01710 (why & SRVST_FAREND) ? (why & SRVST_NEAREND) ? "both ends" : "far end" : "near end");
01711 continue;
01712 }
01713 #endif
01714 break;
01715 }
01716 if (pri->resetpos < pri->numchans) {
01717
01718 pri->pvts[pri->resetpos]->resetting = SIG_PRI_RESET_ACTIVE;
01719 pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[pri->resetpos]));
01720 } else {
01721 pri->resetting = 0;
01722 time(&pri->lastreset);
01723 sig_pri_span_devstate_changed(pri);
01724 }
01725 }
01726
01727 #if defined(HAVE_PRI_CALL_WAITING)
01728
01729
01730
01731
01732
01733
01734
01735
01736
01737
01738
01739
01740 static void sig_pri_init_config(struct sig_pri_chan *pvt, struct sig_pri_span *pri)
01741 {
01742 pvt->stripmsd = pri->ch_cfg.stripmsd;
01743 pvt->hidecallerid = pri->ch_cfg.hidecallerid;
01744 pvt->hidecalleridname = pri->ch_cfg.hidecalleridname;
01745 pvt->immediate = pri->ch_cfg.immediate;
01746 pvt->priexclusive = pri->ch_cfg.priexclusive;
01747 pvt->priindication_oob = pri->ch_cfg.priindication_oob;
01748 pvt->use_callerid = pri->ch_cfg.use_callerid;
01749 pvt->use_callingpres = pri->ch_cfg.use_callingpres;
01750 ast_copy_string(pvt->context, pri->ch_cfg.context, sizeof(pvt->context));
01751 ast_copy_string(pvt->mohinterpret, pri->ch_cfg.mohinterpret, sizeof(pvt->mohinterpret));
01752
01753 if (pri->calls->init_config) {
01754 pri->calls->init_config(pvt->chan_pvt, pri);
01755 }
01756 }
01757 #endif
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771 static int pri_find_empty_chan(struct sig_pri_span *pri, int backwards)
01772 {
01773 int x;
01774 if (backwards)
01775 x = pri->numchans;
01776 else
01777 x = 0;
01778 for (;;) {
01779 if (backwards && (x < 0))
01780 break;
01781 if (!backwards && (x >= pri->numchans))
01782 break;
01783 if (pri->pvts[x]
01784 && !pri->pvts[x]->no_b_channel
01785 && sig_pri_is_chan_available(pri->pvts[x])) {
01786 ast_debug(1, "Found empty available channel %d/%d\n",
01787 pri->pvts[x]->logicalspan, pri->pvts[x]->prioffset);
01788 return x;
01789 }
01790 if (backwards)
01791 x--;
01792 else
01793 x++;
01794 }
01795 return -1;
01796 }
01797
01798 #if defined(HAVE_PRI_CALL_HOLD)
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808
01809
01810
01811 static int pri_find_empty_nobch(struct sig_pri_span *pri)
01812 {
01813 int idx;
01814
01815 for (idx = 0; idx < pri->numchans; ++idx) {
01816 if (pri->pvts[idx]
01817 && pri->pvts[idx]->no_b_channel
01818 && sig_pri_is_chan_available(pri->pvts[idx])) {
01819 ast_debug(1, "Found empty available no B channel interface\n");
01820 return idx;
01821 }
01822 }
01823
01824
01825 if (pri->calls->new_nobch_intf) {
01826 idx = pri->calls->new_nobch_intf(pri);
01827 } else {
01828 idx = -1;
01829 }
01830 return idx;
01831 }
01832 #endif
01833
01834 static void *do_idle_thread(void *v_pvt)
01835 {
01836 struct sig_pri_chan *pvt = v_pvt;
01837 struct ast_channel *chan = pvt->owner;
01838 struct ast_frame *f;
01839 char ex[80];
01840
01841 int newms, ms = 30000;
01842
01843 ast_verb(3, "Initiating idle call on channel %s\n", ast_channel_name(chan));
01844 snprintf(ex, sizeof(ex), "%d/%s", pvt->channel, pvt->pri->idledial);
01845 if (ast_call(chan, ex, 0)) {
01846 ast_log(LOG_WARNING, "Idle dial failed on '%s' to '%s'\n", ast_channel_name(chan), ex);
01847 ast_hangup(chan);
01848 return NULL;
01849 }
01850 while ((newms = ast_waitfor(chan, ms)) > 0) {
01851 f = ast_read(chan);
01852 if (!f) {
01853
01854 break;
01855 }
01856 if (f->frametype == AST_FRAME_CONTROL) {
01857 switch (f->subclass.integer) {
01858 case AST_CONTROL_ANSWER:
01859
01860 ast_channel_exten_set(chan, pvt->pri->idleext);
01861 ast_channel_context_set(chan, pvt->pri->idlecontext);
01862 ast_channel_priority_set(chan, 1);
01863 ast_verb(4, "Idle channel '%s' answered, sending to %s@%s\n", ast_channel_name(chan), ast_channel_exten(chan), ast_channel_context(chan));
01864 ast_pbx_run(chan);
01865
01866 return NULL;
01867 case AST_CONTROL_BUSY:
01868 ast_verb(4, "Idle channel '%s' busy, waiting...\n", ast_channel_name(chan));
01869 break;
01870 case AST_CONTROL_CONGESTION:
01871 ast_verb(4, "Idle channel '%s' congested, waiting...\n", ast_channel_name(chan));
01872 break;
01873 };
01874 }
01875 ast_frfree(f);
01876 ms = newms;
01877 }
01878
01879 ast_hangup(chan);
01880 return NULL;
01881 }
01882
01883 static void *pri_ss_thread(void *data)
01884 {
01885 struct sig_pri_chan *p = data;
01886 struct ast_channel *chan = p->owner;
01887 char exten[AST_MAX_EXTENSION];
01888 int res;
01889 int len;
01890 int timeout;
01891
01892 if (!chan) {
01893
01894 return NULL;
01895 }
01896
01897
01898
01899
01900
01901 if (!ast_channel_tech_pvt(chan)) {
01902 ast_log(LOG_WARNING, "Channel became a zombie before simple switch could be started (%s)\n", ast_channel_name(chan));
01903 ast_hangup(chan);
01904 return NULL;
01905 }
01906
01907 ast_verb(3, "Starting simple switch on '%s'\n", ast_channel_name(chan));
01908
01909 sig_pri_dsp_reset_and_flush_digits(p);
01910
01911
01912 ast_copy_string(exten, p->exten, sizeof(exten));
01913 len = strlen(exten);
01914 res = 0;
01915 while ((len < AST_MAX_EXTENSION-1) && ast_matchmore_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num)) {
01916 if (len && !ast_ignore_pattern(ast_channel_context(chan), exten))
01917 sig_pri_play_tone(p, -1);
01918 else
01919 sig_pri_play_tone(p, SIG_PRI_TONE_DIALTONE);
01920 if (ast_exists_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num))
01921 timeout = pri_matchdigittimeout;
01922 else
01923 timeout = pri_gendigittimeout;
01924 res = ast_waitfordigit(chan, timeout);
01925 if (res < 0) {
01926 ast_debug(1, "waitfordigit returned < 0...\n");
01927 ast_hangup(chan);
01928 return NULL;
01929 } else if (res) {
01930 exten[len++] = res;
01931 exten[len] = '\0';
01932 } else
01933 break;
01934 }
01935
01936 if (ast_strlen_zero(exten)) {
01937 ast_verb(3, "Going to extension s|1 because of empty extension received on overlap call\n");
01938 exten[0] = 's';
01939 exten[1] = '\0';
01940 } else {
01941 ast_free(ast_channel_dialed(chan)->number.str);
01942 ast_channel_dialed(chan)->number.str = ast_strdup(exten);
01943
01944 if (p->pri->append_msn_to_user_tag && p->pri->nodetype != PRI_NETWORK) {
01945
01946
01947
01948
01949 snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag,
01950 exten);
01951 ast_free(ast_channel_caller(chan)->id.tag);
01952 ast_channel_caller(chan)->id.tag = ast_strdup(p->user_tag);
01953 }
01954 }
01955 sig_pri_play_tone(p, -1);
01956 if (ast_exists_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num)) {
01957
01958 ast_channel_exten_set(chan, exten);
01959 sig_pri_dsp_reset_and_flush_digits(p);
01960 #if defined(ISSUE_16789)
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973 if ((p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
01974 && !ast_matchmore_extension(chan, ast_channel_context(chan), exten, 1, p->cid_num)) {
01975 sig_pri_lock_private(p);
01976 if (p->pri->pri) {
01977 pri_grab(p, p->pri);
01978 if (p->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING) {
01979 p->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING;
01980 }
01981 pri_proceeding(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 0);
01982 pri_rel(p->pri);
01983 }
01984 sig_pri_unlock_private(p);
01985 }
01986 #endif
01987
01988 sig_pri_set_echocanceller(p, 1);
01989 ast_setstate(chan, AST_STATE_RING);
01990 res = ast_pbx_run(chan);
01991 if (res) {
01992 ast_log(LOG_WARNING, "PBX exited non-zero!\n");
01993 }
01994 } else {
01995 ast_debug(1, "No such possible extension '%s' in context '%s'\n", exten, ast_channel_context(chan));
01996 ast_channel_hangupcause_set(chan, AST_CAUSE_UNALLOCATED);
01997 ast_hangup(chan);
01998 p->exten[0] = '\0';
01999
02000 p->call = NULL;
02001 ast_mutex_lock(&p->pri->lock);
02002 sig_pri_span_devstate_changed(p->pri);
02003 ast_mutex_unlock(&p->pri->lock);
02004 }
02005 return NULL;
02006 }
02007
02008 void pri_event_alarm(struct sig_pri_span *pri, int index, int before_start_pri)
02009 {
02010 pri->dchanavail[index] &= ~(DCHAN_NOTINALARM | DCHAN_UP);
02011 if (!before_start_pri) {
02012 pri_find_dchan(pri);
02013 }
02014 }
02015
02016 void pri_event_noalarm(struct sig_pri_span *pri, int index, int before_start_pri)
02017 {
02018 pri->dchanavail[index] |= DCHAN_NOTINALARM;
02019 if (!before_start_pri)
02020 pri_restart(pri->dchans[index]);
02021 }
02022
02023
02024
02025
02026
02027
02028
02029
02030
02031
02032
02033
02034
02035
02036 static void sig_pri_party_name_convert(struct ast_party_name *ast_name, const struct pri_party_name *pri_name)
02037 {
02038 ast_name->str = ast_strdup(pri_name->str);
02039 ast_name->char_set = pri_to_ast_char_set(pri_name->char_set);
02040 ast_name->presentation = pri_to_ast_presentation(pri_name->presentation);
02041 ast_name->valid = 1;
02042 }
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
02058 static void sig_pri_party_number_convert(struct ast_party_number *ast_number, const struct pri_party_number *pri_number, struct sig_pri_span *pri)
02059 {
02060 char number[AST_MAX_EXTENSION];
02061
02062 apply_plan_to_existing_number(number, sizeof(number), pri, pri_number->str,
02063 pri_number->plan);
02064 ast_number->str = ast_strdup(number);
02065 ast_number->plan = pri_number->plan;
02066 ast_number->presentation = pri_to_ast_presentation(pri_number->presentation);
02067 ast_number->valid = 1;
02068 }
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084 static void sig_pri_party_id_convert(struct ast_party_id *ast_id, const struct pri_party_id *pri_id, struct sig_pri_span *pri)
02085 {
02086 if (pri_id->name.valid) {
02087 sig_pri_party_name_convert(&ast_id->name, &pri_id->name);
02088 }
02089 if (pri_id->number.valid) {
02090 sig_pri_party_number_convert(&ast_id->number, &pri_id->number, pri);
02091 }
02092 #if defined(HAVE_PRI_SUBADDR)
02093 if (pri_id->subaddress.valid) {
02094 sig_pri_set_subaddress(&ast_id->subaddress, &pri_id->subaddress);
02095 }
02096 #endif
02097 }
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114 static void sig_pri_redirecting_convert(struct ast_party_redirecting *ast_redirecting,
02115 const struct pri_party_redirecting *pri_redirecting,
02116 const struct ast_party_redirecting *ast_guide,
02117 struct sig_pri_span *pri)
02118 {
02119 ast_party_redirecting_set_init(ast_redirecting, ast_guide);
02120
02121 sig_pri_party_id_convert(&ast_redirecting->orig, &pri_redirecting->orig_called, pri);
02122 sig_pri_party_id_convert(&ast_redirecting->from, &pri_redirecting->from, pri);
02123 sig_pri_party_id_convert(&ast_redirecting->to, &pri_redirecting->to, pri);
02124 ast_redirecting->count = pri_redirecting->count;
02125 ast_redirecting->reason = pri_to_ast_reason(pri_redirecting->reason);
02126 ast_redirecting->orig_reason = pri_to_ast_reason(pri_redirecting->orig_reason);
02127 }
02128
02129
02130
02131
02132
02133
02134
02135
02136
02137
02138
02139
02140 static int sig_pri_msn_match(const char *msn_patterns, const char *exten)
02141 {
02142 char *pattern;
02143 char *msn_list;
02144 char *list_tail;
02145
02146 msn_list = ast_strdupa(msn_patterns);
02147
02148 list_tail = NULL;
02149 pattern = strtok_r(msn_list, ",", &list_tail);
02150 while (pattern) {
02151 pattern = ast_strip(pattern);
02152 if (!ast_strlen_zero(pattern) && ast_extension_match(pattern, exten)) {
02153
02154 return 1;
02155 }
02156 pattern = strtok_r(NULL, ",", &list_tail);
02157 }
02158
02159 return 0;
02160 }
02161
02162 #if defined(HAVE_PRI_MCID)
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174 static void sig_pri_event_party_id(struct ast_str **msg, const char *prefix, struct ast_party_id *party)
02175 {
02176 int pres;
02177
02178
02179 pres = ast_party_id_presentation(party);
02180 ast_str_append(msg, 0, "%sPres: %d (%s)\r\n", prefix, pres,
02181 ast_describe_caller_presentation(pres));
02182
02183
02184 ast_str_append(msg, 0, "%sNumValid: %d\r\n", prefix,
02185 (unsigned) party->number.valid);
02186 ast_str_append(msg, 0, "%sNum: %s\r\n", prefix,
02187 S_COR(party->number.valid, party->number.str, ""));
02188 ast_str_append(msg, 0, "%ston: %d\r\n", prefix, party->number.plan);
02189 if (party->number.valid) {
02190 ast_str_append(msg, 0, "%sNumPlan: %d\r\n", prefix, party->number.plan);
02191 ast_str_append(msg, 0, "%sNumPres: %d (%s)\r\n", prefix,
02192 party->number.presentation,
02193 ast_describe_caller_presentation(party->number.presentation));
02194 }
02195
02196
02197 ast_str_append(msg, 0, "%sNameValid: %d\r\n", prefix,
02198 (unsigned) party->name.valid);
02199 ast_str_append(msg, 0, "%sName: %s\r\n", prefix,
02200 S_COR(party->name.valid, party->name.str, ""));
02201 if (party->name.valid) {
02202 ast_str_append(msg, 0, "%sNameCharSet: %s\r\n", prefix,
02203 ast_party_name_charset_describe(party->name.char_set));
02204 ast_str_append(msg, 0, "%sNamePres: %d (%s)\r\n", prefix,
02205 party->name.presentation,
02206 ast_describe_caller_presentation(party->name.presentation));
02207 }
02208
02209 #if defined(HAVE_PRI_SUBADDR)
02210
02211 if (party->subaddress.valid) {
02212 static const char subaddress[] = "Subaddr";
02213
02214 ast_str_append(msg, 0, "%s%s: %s\r\n", prefix, subaddress,
02215 S_OR(party->subaddress.str, ""));
02216 ast_str_append(msg, 0, "%s%sType: %d\r\n", prefix, subaddress,
02217 party->subaddress.type);
02218 ast_str_append(msg, 0, "%s%sOdd: %d\r\n", prefix, subaddress,
02219 party->subaddress.odd_even_indicator);
02220 }
02221 #endif
02222 }
02223 #endif
02224
02225 #if defined(HAVE_PRI_MCID)
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241 static void sig_pri_mcid_event(struct sig_pri_span *pri, const struct pri_subcmd_mcid_req *mcid, struct ast_channel *owner)
02242 {
02243 struct ast_channel *chans[1];
02244 struct ast_str *msg;
02245 struct ast_party_id party;
02246
02247 msg = ast_str_create(4096);
02248 if (!msg) {
02249 return;
02250 }
02251
02252 if (owner) {
02253
02254
02255
02256
02257 ast_queue_control(owner, AST_CONTROL_MCID);
02258
02259 ast_str_append(&msg, 0, "Channel: %s\r\n", ast_channel_name(owner));
02260 ast_str_append(&msg, 0, "UniqueID: %s\r\n", ast_channel_uniqueid(owner));
02261
02262 sig_pri_event_party_id(&msg, "CallerID", &ast_channel_connected(owner)->id);
02263 } else {
02264
02265
02266
02267
02268 ast_party_id_init(&party);
02269 sig_pri_party_id_convert(&party, &mcid->originator, pri);
02270 sig_pri_event_party_id(&msg, "CallerID", &party);
02271 ast_party_id_free(&party);
02272 }
02273
02274
02275 ast_party_id_init(&party);
02276 sig_pri_party_id_convert(&party, &mcid->answerer, pri);
02277 sig_pri_event_party_id(&msg, "ConnectedID", &party);
02278 ast_party_id_free(&party);
02279
02280 chans[0] = owner;
02281 ast_manager_event_multichan(EVENT_FLAG_CALL, "MCID", owner ? 1 : 0, chans, "%s",
02282 ast_str_buffer(msg));
02283 ast_free(msg);
02284 }
02285 #endif
02286
02287 #if defined(HAVE_PRI_TRANSFER)
02288 struct xfer_rsp_data {
02289 struct sig_pri_span *pri;
02290
02291 q931_call *call;
02292
02293 int invoke_id;
02294 };
02295 #endif
02296
02297 #if defined(HAVE_PRI_TRANSFER)
02298
02299
02300
02301
02302
02303
02304
02305
02306
02307
02308 static void sig_pri_transfer_rsp(void *data, int is_successful)
02309 {
02310 struct xfer_rsp_data *rsp = data;
02311
02312 pri_transfer_rsp(rsp->pri->pri, rsp->call, rsp->invoke_id, is_successful);
02313 }
02314 #endif
02315
02316 #if defined(HAVE_PRI_CALL_HOLD) || defined(HAVE_PRI_TRANSFER)
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326 typedef void (*xfer_rsp_callback)(void *data, int is_successful);
02327 #endif
02328
02329 #if defined(HAVE_PRI_CALL_HOLD) || defined(HAVE_PRI_TRANSFER)
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348 static int sig_pri_attempt_transfer(struct sig_pri_span *pri, q931_call *call_1_pri, int call_1_held, q931_call *call_2_pri, int call_2_held, xfer_rsp_callback rsp_callback, void *data)
02349 {
02350 struct attempt_xfer_call {
02351 q931_call *pri;
02352 struct ast_channel *ast;
02353 int held;
02354 int chanpos;
02355 };
02356 int retval;
02357 struct ast_channel *transferee;
02358 struct attempt_xfer_call *call_1;
02359 struct attempt_xfer_call *call_2;
02360 struct attempt_xfer_call *swap_call;
02361 struct attempt_xfer_call c1;
02362 struct attempt_xfer_call c2;
02363
02364 c1.pri = call_1_pri;
02365 c1.held = call_1_held;
02366 call_1 = &c1;
02367
02368 c2.pri = call_2_pri;
02369 c2.held = call_2_held;
02370 call_2 = &c2;
02371
02372 call_1->chanpos = pri_find_principle_by_call(pri, call_1->pri);
02373 call_2->chanpos = pri_find_principle_by_call(pri, call_2->pri);
02374 if (call_1->chanpos < 0 || call_2->chanpos < 0) {
02375
02376 if (rsp_callback) {
02377
02378 rsp_callback(data, 0);
02379 }
02380 return -1;
02381 }
02382
02383
02384 if (!call_1->held && call_2->held) {
02385
02386
02387
02388
02389 swap_call = call_1;
02390 call_1 = call_2;
02391 call_2 = swap_call;
02392 }
02393
02394
02395 sig_pri_lock_private(pri->pvts[call_1->chanpos]);
02396 sig_pri_lock_owner(pri, call_1->chanpos);
02397 sig_pri_lock_private(pri->pvts[call_2->chanpos]);
02398 sig_pri_lock_owner(pri, call_2->chanpos);
02399
02400 call_1->ast = pri->pvts[call_1->chanpos]->owner;
02401 call_2->ast = pri->pvts[call_2->chanpos]->owner;
02402 if (!call_1->ast || !call_2->ast) {
02403
02404 if (call_1->ast) {
02405 ast_channel_unlock(call_1->ast);
02406 }
02407 if (call_2->ast) {
02408 ast_channel_unlock(call_2->ast);
02409 }
02410 sig_pri_unlock_private(pri->pvts[call_1->chanpos]);
02411 sig_pri_unlock_private(pri->pvts[call_2->chanpos]);
02412 if (rsp_callback) {
02413
02414 rsp_callback(data, 0);
02415 }
02416 return -1;
02417 }
02418
02419 for (;;) {
02420 transferee = ast_bridged_channel(call_1->ast);
02421 if (transferee) {
02422 break;
02423 }
02424
02425
02426 swap_call = call_1;
02427 call_1 = call_2;
02428 call_2 = swap_call;
02429
02430 transferee = ast_bridged_channel(call_1->ast);
02431 if (transferee) {
02432 break;
02433 }
02434
02435
02436 ast_channel_unlock(call_1->ast);
02437 ast_channel_unlock(call_2->ast);
02438 sig_pri_unlock_private(pri->pvts[call_1->chanpos]);
02439 sig_pri_unlock_private(pri->pvts[call_2->chanpos]);
02440
02441 if (rsp_callback) {
02442
02443 rsp_callback(data, 0);
02444 }
02445 return -1;
02446 }
02447
02448 ast_verb(3, "TRANSFERRING %s to %s\n", ast_channel_name(call_1->ast), ast_channel_name(call_2->ast));
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459
02460
02461 ast_mutex_unlock(&pri->lock);
02462 retval = ast_channel_transfer_masquerade(
02463 call_2->ast,
02464 ast_channel_connected(call_2->ast),
02465 call_2->held,
02466 transferee,
02467 ast_channel_connected(call_1->ast),
02468 call_1->held);
02469
02470
02471 ast_mutex_lock(&pri->lock);
02472
02473 ast_channel_unlock(call_1->ast);
02474 ast_channel_unlock(call_2->ast);
02475 sig_pri_unlock_private(pri->pvts[call_1->chanpos]);
02476 sig_pri_unlock_private(pri->pvts[call_2->chanpos]);
02477
02478 if (rsp_callback) {
02479
02480
02481
02482
02483
02484
02485
02486 rsp_callback(data, retval ? 0 : 1);
02487 }
02488 return retval;
02489 }
02490 #endif
02491
02492 #if defined(HAVE_PRI_CCSS)
02493
02494
02495
02496
02497
02498
02499
02500
02501
02502
02503
02504 static int sig_pri_cc_agent_cmp_cc_id(void *obj, void *arg, int flags)
02505 {
02506 struct ast_cc_agent *agent_1 = obj;
02507 struct sig_pri_cc_agent_prv *agent_prv_1 = agent_1->private_data;
02508 struct sig_pri_cc_agent_prv *agent_prv_2 = arg;
02509
02510 return (agent_prv_1 && agent_prv_1->pri == agent_prv_2->pri
02511 && agent_prv_1->cc_id == agent_prv_2->cc_id) ? CMP_MATCH | CMP_STOP : 0;
02512 }
02513 #endif
02514
02515 #if defined(HAVE_PRI_CCSS)
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531
02532 static struct ast_cc_agent *sig_pri_find_cc_agent_by_cc_id(struct sig_pri_span *pri, long cc_id)
02533 {
02534 struct sig_pri_cc_agent_prv finder = {
02535 .pri = pri,
02536 .cc_id = cc_id,
02537 };
02538
02539 return ast_cc_agent_callback(0, sig_pri_cc_agent_cmp_cc_id, &finder,
02540 sig_pri_cc_type_name);
02541 }
02542 #endif
02543
02544 #if defined(HAVE_PRI_CCSS)
02545
02546
02547
02548
02549
02550
02551
02552
02553
02554
02555
02556 static int sig_pri_cc_monitor_cmp_cc_id(void *obj, void *arg, int flags)
02557 {
02558 struct sig_pri_cc_monitor_instance *monitor_1 = obj;
02559 struct sig_pri_cc_monitor_instance *monitor_2 = arg;
02560
02561 return (monitor_1->pri == monitor_2->pri
02562 && monitor_1->cc_id == monitor_2->cc_id) ? CMP_MATCH | CMP_STOP : 0;
02563 }
02564 #endif
02565
02566 #if defined(HAVE_PRI_CCSS)
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583 static struct sig_pri_cc_monitor_instance *sig_pri_find_cc_monitor_by_cc_id(struct sig_pri_span *pri, long cc_id)
02584 {
02585 struct sig_pri_cc_monitor_instance finder = {
02586 .pri = pri,
02587 .cc_id = cc_id,
02588 };
02589
02590 return ao2_callback(sig_pri_cc_monitors, 0, sig_pri_cc_monitor_cmp_cc_id, &finder);
02591 }
02592 #endif
02593
02594 #if defined(HAVE_PRI_CCSS)
02595
02596
02597
02598
02599
02600
02601
02602
02603
02604 static void sig_pri_cc_monitor_instance_destroy(void *data)
02605 {
02606 struct sig_pri_cc_monitor_instance *monitor_instance = data;
02607
02608 if (monitor_instance->cc_id != -1) {
02609 ast_mutex_lock(&monitor_instance->pri->lock);
02610 pri_cc_cancel(monitor_instance->pri->pri, monitor_instance->cc_id);
02611 ast_mutex_unlock(&monitor_instance->pri->lock);
02612 }
02613 monitor_instance->pri->calls->module_unref();
02614 }
02615 #endif
02616
02617 #if defined(HAVE_PRI_CCSS)
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635
02636 static struct sig_pri_cc_monitor_instance *sig_pri_cc_monitor_instance_init(int core_id, struct sig_pri_span *pri, long cc_id, const char *device_name)
02637 {
02638 struct sig_pri_cc_monitor_instance *monitor_instance;
02639
02640 if (!pri->calls->module_ref || !pri->calls->module_unref) {
02641 return NULL;
02642 }
02643
02644 monitor_instance = ao2_alloc(sizeof(*monitor_instance) + strlen(device_name),
02645 sig_pri_cc_monitor_instance_destroy);
02646 if (!monitor_instance) {
02647 return NULL;
02648 }
02649
02650 monitor_instance->cc_id = cc_id;
02651 monitor_instance->pri = pri;
02652 monitor_instance->core_id = core_id;
02653 strcpy(monitor_instance->name, device_name);
02654
02655 pri->calls->module_ref();
02656
02657 ao2_link(sig_pri_cc_monitors, monitor_instance);
02658 return monitor_instance;
02659 }
02660 #endif
02661
02662 #if defined(HAVE_PRI_CCSS)
02663
02664
02665
02666
02667
02668
02669
02670
02671
02672
02673
02674
02675
02676
02677
02678
02679
02680 static int sig_pri_cc_available(struct sig_pri_span *pri, int chanpos, long cc_id, enum ast_cc_service_type service)
02681 {
02682 struct sig_pri_chan *pvt;
02683 struct ast_cc_config_params *cc_params;
02684 struct sig_pri_cc_monitor_instance *monitor;
02685 enum ast_cc_monitor_policies monitor_policy;
02686 int core_id;
02687 int res;
02688 char device_name[AST_CHANNEL_NAME];
02689 char dialstring[AST_CHANNEL_NAME];
02690
02691 pvt = pri->pvts[chanpos];
02692
02693 core_id = ast_cc_get_current_core_id(pvt->owner);
02694 if (core_id == -1) {
02695 return -1;
02696 }
02697
02698 cc_params = ast_channel_get_cc_config_params(pvt->owner);
02699 if (!cc_params) {
02700 return -1;
02701 }
02702
02703 res = -1;
02704 monitor_policy = ast_get_cc_monitor_policy(cc_params);
02705 switch (monitor_policy) {
02706 case AST_CC_MONITOR_NEVER:
02707
02708 break;
02709 case AST_CC_MONITOR_NATIVE:
02710 case AST_CC_MONITOR_ALWAYS:
02711
02712
02713
02714
02715 ast_channel_get_device_name(pvt->owner, device_name, sizeof(device_name));
02716 sig_pri_make_cc_dialstring(pvt, dialstring, sizeof(dialstring));
02717 monitor = sig_pri_cc_monitor_instance_init(core_id, pri, cc_id, device_name);
02718 if (!monitor) {
02719 break;
02720 }
02721 res = ast_queue_cc_frame(pvt->owner, sig_pri_cc_type_name, dialstring, service,
02722 monitor);
02723 if (res) {
02724 monitor->cc_id = -1;
02725 ao2_unlink(sig_pri_cc_monitors, monitor);
02726 ao2_ref(monitor, -1);
02727 }
02728 break;
02729 case AST_CC_MONITOR_GENERIC:
02730 ast_queue_cc_frame(pvt->owner, AST_CC_GENERIC_MONITOR_TYPE,
02731 sig_pri_get_orig_dialstring(pvt), service, NULL);
02732
02733 break;
02734 }
02735 return res;
02736 }
02737 #endif
02738
02739
02740
02741
02742
02743
02744
02745
02746
02747
02748
02749
02750
02751
02752
02753 static void sig_pri_cc_generic_check(struct sig_pri_span *pri, int chanpos, enum ast_cc_service_type service)
02754 {
02755 struct ast_channel *owner;
02756 struct ast_cc_config_params *cc_params;
02757 #if defined(HAVE_PRI_CCSS)
02758 struct ast_cc_monitor *monitor;
02759 char device_name[AST_CHANNEL_NAME];
02760 #endif
02761 enum ast_cc_monitor_policies monitor_policy;
02762 int core_id;
02763
02764 if (!pri->pvts[chanpos]->outgoing) {
02765
02766 return;
02767 }
02768
02769 sig_pri_lock_owner(pri, chanpos);
02770 owner = pri->pvts[chanpos]->owner;
02771 if (!owner) {
02772 return;
02773 }
02774 core_id = ast_cc_get_current_core_id(owner);
02775 if (core_id == -1) {
02776
02777 goto done;
02778 }
02779
02780 cc_params = ast_channel_get_cc_config_params(owner);
02781 if (!cc_params) {
02782
02783 goto done;
02784 }
02785
02786 #if defined(HAVE_PRI_CCSS)
02787 ast_channel_get_device_name(owner, device_name, sizeof(device_name));
02788 monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name);
02789 if (monitor) {
02790
02791 ao2_ref(monitor, -1);
02792 goto done;
02793 }
02794 #endif
02795
02796 monitor_policy = ast_get_cc_monitor_policy(cc_params);
02797 switch (monitor_policy) {
02798 case AST_CC_MONITOR_NEVER:
02799
02800 break;
02801 case AST_CC_MONITOR_NATIVE:
02802 if (pri->sig == SIG_BRI_PTMP && pri->nodetype == PRI_NETWORK) {
02803
02804 ast_queue_cc_frame(owner, AST_CC_GENERIC_MONITOR_TYPE,
02805 sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL);
02806 }
02807 break;
02808 case AST_CC_MONITOR_ALWAYS:
02809 if (pri->sig == SIG_BRI_PTMP && pri->nodetype != PRI_NETWORK) {
02810
02811
02812
02813
02814
02815
02816 break;
02817 }
02818
02819
02820
02821
02822 ast_queue_cc_frame(owner, AST_CC_GENERIC_MONITOR_TYPE,
02823 sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL);
02824 break;
02825 case AST_CC_MONITOR_GENERIC:
02826 if (pri->sig == SIG_BRI_PTMP && pri->nodetype == PRI_NETWORK) {
02827
02828 ast_queue_cc_frame(owner, AST_CC_GENERIC_MONITOR_TYPE,
02829 sig_pri_get_orig_dialstring(pri->pvts[chanpos]), service, NULL);
02830 }
02831 break;
02832 }
02833
02834 done:
02835 ast_channel_unlock(owner);
02836 }
02837
02838 #if defined(HAVE_PRI_CCSS)
02839
02840
02841
02842
02843
02844
02845
02846
02847
02848
02849
02850 static void sig_pri_cc_link_canceled(struct sig_pri_span *pri, long cc_id, int is_agent)
02851 {
02852 if (is_agent) {
02853 struct ast_cc_agent *agent;
02854
02855 agent = sig_pri_find_cc_agent_by_cc_id(pri, cc_id);
02856 if (!agent) {
02857 return;
02858 }
02859 ast_cc_failed(agent->core_id, "%s agent got canceled by link",
02860 sig_pri_cc_type_name);
02861 ao2_ref(agent, -1);
02862 } else {
02863 struct sig_pri_cc_monitor_instance *monitor;
02864
02865 monitor = sig_pri_find_cc_monitor_by_cc_id(pri, cc_id);
02866 if (!monitor) {
02867 return;
02868 }
02869 monitor->cc_id = -1;
02870 ast_cc_monitor_failed(monitor->core_id, monitor->name,
02871 "%s monitor got canceled by link", sig_pri_cc_type_name);
02872 ao2_ref(monitor, -1);
02873 }
02874 }
02875 #endif
02876
02877 #if defined(HAVE_PRI_AOC_EVENTS)
02878
02879
02880
02881
02882
02883
02884
02885
02886
02887 static enum PRI_AOC_CHARGED_ITEM sig_pri_aoc_charged_item_to_pri(enum PRI_AOC_CHARGED_ITEM value)
02888 {
02889 switch (value) {
02890 case AST_AOC_CHARGED_ITEM_NA:
02891 return PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE;
02892 case AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT:
02893 return PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT;
02894 case AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION:
02895 return PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION;
02896 case AST_AOC_CHARGED_ITEM_CALL_ATTEMPT:
02897 return PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT;
02898 case AST_AOC_CHARGED_ITEM_CALL_SETUP:
02899 return PRI_AOC_CHARGED_ITEM_CALL_SETUP;
02900 case AST_AOC_CHARGED_ITEM_USER_USER_INFO:
02901 return PRI_AOC_CHARGED_ITEM_USER_USER_INFO;
02902 case AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE:
02903 return PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE;
02904 }
02905 return PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE;
02906 }
02907 #endif
02908
02909 #if defined(HAVE_PRI_AOC_EVENTS)
02910
02911
02912
02913
02914
02915
02916
02917
02918
02919 static enum ast_aoc_s_charged_item sig_pri_aoc_charged_item_to_ast(enum PRI_AOC_CHARGED_ITEM value)
02920 {
02921 switch (value) {
02922 case PRI_AOC_CHARGED_ITEM_NOT_AVAILABLE:
02923 return AST_AOC_CHARGED_ITEM_NA;
02924 case PRI_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT:
02925 return AST_AOC_CHARGED_ITEM_SPECIAL_ARRANGEMENT;
02926 case PRI_AOC_CHARGED_ITEM_BASIC_COMMUNICATION:
02927 return AST_AOC_CHARGED_ITEM_BASIC_COMMUNICATION;
02928 case PRI_AOC_CHARGED_ITEM_CALL_ATTEMPT:
02929 return AST_AOC_CHARGED_ITEM_CALL_ATTEMPT;
02930 case PRI_AOC_CHARGED_ITEM_CALL_SETUP:
02931 return AST_AOC_CHARGED_ITEM_CALL_SETUP;
02932 case PRI_AOC_CHARGED_ITEM_USER_USER_INFO:
02933 return AST_AOC_CHARGED_ITEM_USER_USER_INFO;
02934 case PRI_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE:
02935 return AST_AOC_CHARGED_ITEM_SUPPLEMENTARY_SERVICE;
02936 }
02937 return AST_AOC_CHARGED_ITEM_NA;
02938 }
02939 #endif
02940
02941 #if defined(HAVE_PRI_AOC_EVENTS)
02942
02943
02944
02945
02946
02947
02948
02949 static int sig_pri_aoc_multiplier_from_ast(enum ast_aoc_currency_multiplier mult)
02950 {
02951 switch (mult) {
02952 case AST_AOC_MULT_ONETHOUSANDTH:
02953 return PRI_AOC_MULTIPLIER_THOUSANDTH;
02954 case AST_AOC_MULT_ONEHUNDREDTH:
02955 return PRI_AOC_MULTIPLIER_HUNDREDTH;
02956 case AST_AOC_MULT_ONETENTH:
02957 return PRI_AOC_MULTIPLIER_TENTH;
02958 case AST_AOC_MULT_ONE:
02959 return PRI_AOC_MULTIPLIER_ONE;
02960 case AST_AOC_MULT_TEN:
02961 return PRI_AOC_MULTIPLIER_TEN;
02962 case AST_AOC_MULT_HUNDRED:
02963 return PRI_AOC_MULTIPLIER_HUNDRED;
02964 case AST_AOC_MULT_THOUSAND:
02965 return PRI_AOC_MULTIPLIER_THOUSAND;
02966 default:
02967 return PRI_AOC_MULTIPLIER_ONE;
02968 }
02969 }
02970 #endif
02971
02972 #if defined(HAVE_PRI_AOC_EVENTS)
02973
02974
02975
02976
02977
02978
02979
02980 static int sig_pri_aoc_multiplier_from_pri(const int mult)
02981 {
02982 switch (mult) {
02983 case PRI_AOC_MULTIPLIER_THOUSANDTH:
02984 return AST_AOC_MULT_ONETHOUSANDTH;
02985 case PRI_AOC_MULTIPLIER_HUNDREDTH:
02986 return AST_AOC_MULT_ONEHUNDREDTH;
02987 case PRI_AOC_MULTIPLIER_TENTH:
02988 return AST_AOC_MULT_ONETENTH;
02989 case PRI_AOC_MULTIPLIER_ONE:
02990 return AST_AOC_MULT_ONE;
02991 case PRI_AOC_MULTIPLIER_TEN:
02992 return AST_AOC_MULT_TEN;
02993 case PRI_AOC_MULTIPLIER_HUNDRED:
02994 return AST_AOC_MULT_HUNDRED;
02995 case PRI_AOC_MULTIPLIER_THOUSAND:
02996 return AST_AOC_MULT_THOUSAND;
02997 default:
02998 return AST_AOC_MULT_ONE;
02999 }
03000 }
03001 #endif
03002
03003 #if defined(HAVE_PRI_AOC_EVENTS)
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013 static enum PRI_AOC_TIME_SCALE sig_pri_aoc_scale_to_pri(enum ast_aoc_time_scale value)
03014 {
03015 switch (value) {
03016 default:
03017 case AST_AOC_TIME_SCALE_HUNDREDTH_SECOND:
03018 return PRI_AOC_TIME_SCALE_HUNDREDTH_SECOND;
03019 case AST_AOC_TIME_SCALE_TENTH_SECOND:
03020 return PRI_AOC_TIME_SCALE_TENTH_SECOND;
03021 case AST_AOC_TIME_SCALE_SECOND:
03022 return PRI_AOC_TIME_SCALE_SECOND;
03023 case AST_AOC_TIME_SCALE_TEN_SECOND:
03024 return PRI_AOC_TIME_SCALE_TEN_SECOND;
03025 case AST_AOC_TIME_SCALE_MINUTE:
03026 return PRI_AOC_TIME_SCALE_MINUTE;
03027 case AST_AOC_TIME_SCALE_HOUR:
03028 return PRI_AOC_TIME_SCALE_HOUR;
03029 case AST_AOC_TIME_SCALE_DAY:
03030 return PRI_AOC_TIME_SCALE_DAY;
03031 }
03032 }
03033 #endif
03034
03035 #if defined(HAVE_PRI_AOC_EVENTS)
03036
03037
03038
03039
03040
03041
03042
03043
03044
03045 static enum ast_aoc_time_scale sig_pri_aoc_scale_to_ast(enum PRI_AOC_TIME_SCALE value)
03046 {
03047 switch (value) {
03048 default:
03049 case PRI_AOC_TIME_SCALE_HUNDREDTH_SECOND:
03050 return AST_AOC_TIME_SCALE_HUNDREDTH_SECOND;
03051 case PRI_AOC_TIME_SCALE_TENTH_SECOND:
03052 return AST_AOC_TIME_SCALE_TENTH_SECOND;
03053 case PRI_AOC_TIME_SCALE_SECOND:
03054 return AST_AOC_TIME_SCALE_SECOND;
03055 case PRI_AOC_TIME_SCALE_TEN_SECOND:
03056 return AST_AOC_TIME_SCALE_TEN_SECOND;
03057 case PRI_AOC_TIME_SCALE_MINUTE:
03058 return AST_AOC_TIME_SCALE_MINUTE;
03059 case PRI_AOC_TIME_SCALE_HOUR:
03060 return AST_AOC_TIME_SCALE_HOUR;
03061 case PRI_AOC_TIME_SCALE_DAY:
03062 return AST_AOC_TIME_SCALE_DAY;
03063 }
03064 return AST_AOC_TIME_SCALE_HUNDREDTH_SECOND;
03065 }
03066 #endif
03067
03068 #if defined(HAVE_PRI_AOC_EVENTS)
03069
03070
03071
03072
03073
03074
03075
03076
03077
03078
03079
03080
03081
03082
03083
03084 static void sig_pri_aoc_s_from_pri(const struct pri_subcmd_aoc_s *aoc_s, struct ast_channel *owner, int passthrough)
03085 {
03086 struct ast_aoc_decoded *decoded = NULL;
03087 struct ast_aoc_encoded *encoded = NULL;
03088 size_t encoded_size = 0;
03089 int idx;
03090
03091 if (!owner || !aoc_s) {
03092 return;
03093 }
03094
03095 if (!(decoded = ast_aoc_create(AST_AOC_S, 0, 0))) {
03096 return;
03097 }
03098
03099 for (idx = 0; idx < aoc_s->num_items; ++idx) {
03100 enum ast_aoc_s_charged_item charged_item;
03101
03102 charged_item = sig_pri_aoc_charged_item_to_ast(aoc_s->item[idx].chargeable);
03103 if (charged_item == AST_AOC_CHARGED_ITEM_NA) {
03104
03105 continue;
03106 }
03107 switch (aoc_s->item[idx].rate_type) {
03108 case PRI_AOC_RATE_TYPE_DURATION:
03109 ast_aoc_s_add_rate_duration(decoded,
03110 charged_item,
03111 aoc_s->item[idx].rate.duration.amount.cost,
03112 sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.duration.amount.multiplier),
03113 aoc_s->item[idx].rate.duration.currency,
03114 aoc_s->item[idx].rate.duration.time.length,
03115 sig_pri_aoc_scale_to_ast(aoc_s->item[idx].rate.duration.time.scale),
03116 aoc_s->item[idx].rate.duration.granularity.length,
03117 sig_pri_aoc_scale_to_ast(aoc_s->item[idx].rate.duration.granularity.scale),
03118 aoc_s->item[idx].rate.duration.charging_type);
03119 break;
03120 case PRI_AOC_RATE_TYPE_FLAT:
03121 ast_aoc_s_add_rate_flat(decoded,
03122 charged_item,
03123 aoc_s->item[idx].rate.flat.amount.cost,
03124 sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.flat.amount.multiplier),
03125 aoc_s->item[idx].rate.flat.currency);
03126 break;
03127 case PRI_AOC_RATE_TYPE_VOLUME:
03128 ast_aoc_s_add_rate_volume(decoded,
03129 charged_item,
03130 aoc_s->item[idx].rate.volume.unit,
03131 aoc_s->item[idx].rate.volume.amount.cost,
03132 sig_pri_aoc_multiplier_from_pri(aoc_s->item[idx].rate.volume.amount.multiplier),
03133 aoc_s->item[idx].rate.volume.currency);
03134 break;
03135 case PRI_AOC_RATE_TYPE_SPECIAL_CODE:
03136 ast_aoc_s_add_rate_special_charge_code(decoded,
03137 charged_item,
03138 aoc_s->item[idx].rate.special);
03139 break;
03140 case PRI_AOC_RATE_TYPE_FREE:
03141 ast_aoc_s_add_rate_free(decoded, charged_item, 0);
03142 break;
03143 case PRI_AOC_RATE_TYPE_FREE_FROM_BEGINNING:
03144 ast_aoc_s_add_rate_free(decoded, charged_item, 1);
03145 break;
03146 default:
03147 ast_aoc_s_add_rate_na(decoded, charged_item);
03148 break;
03149 }
03150 }
03151
03152 if (passthrough && (encoded = ast_aoc_encode(decoded, &encoded_size, owner))) {
03153 ast_queue_control_data(owner, AST_CONTROL_AOC, encoded, encoded_size);
03154 }
03155
03156 ast_aoc_manager_event(decoded, owner);
03157
03158 ast_aoc_destroy_decoded(decoded);
03159 ast_aoc_destroy_encoded(encoded);
03160 }
03161 #endif
03162
03163 #if defined(HAVE_PRI_AOC_EVENTS)
03164
03165
03166
03167
03168
03169
03170
03171
03172
03173
03174
03175
03176
03177 static void sig_pri_aoc_request_from_pri(const struct pri_subcmd_aoc_request *aoc_request, struct sig_pri_chan *pvt, q931_call *call)
03178 {
03179 int request;
03180
03181 if (!aoc_request) {
03182 return;
03183 }
03184
03185 request = aoc_request->charging_request;
03186
03187 if (request & PRI_AOC_REQUEST_S) {
03188 if (pvt->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S) {
03189
03190
03191 pvt->aoc_s_request_invoke_id = aoc_request->invoke_id;
03192 pvt->aoc_s_request_invoke_id_valid = 1;
03193
03194 } else {
03195 pri_aoc_s_request_response_send(pvt->pri->pri,
03196 call,
03197 aoc_request->invoke_id,
03198 NULL);
03199 }
03200 }
03201
03202 if (request & PRI_AOC_REQUEST_D) {
03203 if (pvt->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D) {
03204 pri_aoc_de_request_response_send(pvt->pri->pri,
03205 call,
03206 PRI_AOC_REQ_RSP_CHARGING_INFO_FOLLOWS,
03207 aoc_request->invoke_id);
03208 } else {
03209 pri_aoc_de_request_response_send(pvt->pri->pri,
03210 call,
03211 PRI_AOC_REQ_RSP_ERROR_NOT_AVAILABLE,
03212 aoc_request->invoke_id);
03213 }
03214 }
03215
03216 if (request & PRI_AOC_REQUEST_E) {
03217 if (pvt->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E) {
03218 pri_aoc_de_request_response_send(pvt->pri->pri,
03219 call,
03220 PRI_AOC_REQ_RSP_CHARGING_INFO_FOLLOWS,
03221 aoc_request->invoke_id);
03222 } else {
03223 pri_aoc_de_request_response_send(pvt->pri->pri,
03224 call,
03225 PRI_AOC_REQ_RSP_ERROR_NOT_AVAILABLE,
03226 aoc_request->invoke_id);
03227 }
03228 }
03229 }
03230 #endif
03231
03232 #if defined(HAVE_PRI_AOC_EVENTS)
03233
03234
03235
03236
03237
03238
03239
03240
03241
03242
03243
03244
03245
03246
03247
03248 static void sig_pri_aoc_d_from_pri(const struct pri_subcmd_aoc_d *aoc_d, struct ast_channel *owner, int passthrough)
03249 {
03250 struct ast_aoc_decoded *decoded = NULL;
03251 struct ast_aoc_encoded *encoded = NULL;
03252 size_t encoded_size = 0;
03253 enum ast_aoc_charge_type type;
03254
03255 if (!owner || !aoc_d) {
03256 return;
03257 }
03258
03259 switch (aoc_d->charge) {
03260 case PRI_AOC_DE_CHARGE_CURRENCY:
03261 type = AST_AOC_CHARGE_CURRENCY;
03262 break;
03263 case PRI_AOC_DE_CHARGE_UNITS:
03264 type = AST_AOC_CHARGE_UNIT;
03265 break;
03266 case PRI_AOC_DE_CHARGE_FREE:
03267 type = AST_AOC_CHARGE_FREE;
03268 break;
03269 default:
03270 type = AST_AOC_CHARGE_NA;
03271 break;
03272 }
03273
03274 if (!(decoded = ast_aoc_create(AST_AOC_D, type, 0))) {
03275 return;
03276 }
03277
03278 switch (aoc_d->billing_accumulation) {
03279 default:
03280 ast_debug(1, "AOC-D billing accumulation has unknown value: %d\n",
03281 aoc_d->billing_accumulation);
03282
03283 case 0:
03284 ast_aoc_set_total_type(decoded, AST_AOC_SUBTOTAL);
03285 break;
03286 case 1:
03287 ast_aoc_set_total_type(decoded, AST_AOC_TOTAL);
03288 break;
03289 }
03290
03291 switch (aoc_d->billing_id) {
03292 case PRI_AOC_D_BILLING_ID_NORMAL:
03293 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_NORMAL);
03294 break;
03295 case PRI_AOC_D_BILLING_ID_REVERSE:
03296 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_REVERSE_CHARGE);
03297 break;
03298 case PRI_AOC_D_BILLING_ID_CREDIT_CARD:
03299 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CREDIT_CARD);
03300 break;
03301 case PRI_AOC_D_BILLING_ID_NOT_AVAILABLE:
03302 default:
03303 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_NA);
03304 break;
03305 }
03306
03307 switch (aoc_d->charge) {
03308 case PRI_AOC_DE_CHARGE_CURRENCY:
03309 ast_aoc_set_currency_info(decoded,
03310 aoc_d->recorded.money.amount.cost,
03311 sig_pri_aoc_multiplier_from_pri(aoc_d->recorded.money.amount.multiplier),
03312 aoc_d->recorded.money.currency);
03313 break;
03314 case PRI_AOC_DE_CHARGE_UNITS:
03315 {
03316 int i;
03317 for (i = 0; i < aoc_d->recorded.unit.num_items; ++i) {
03318
03319 ast_aoc_add_unit_entry(decoded,
03320 (aoc_d->recorded.unit.item[i].number >= 0 ? 1 : 0),
03321 aoc_d->recorded.unit.item[i].number,
03322 (aoc_d->recorded.unit.item[i].type >= 0 ? 1 : 0),
03323 aoc_d->recorded.unit.item[i].type);
03324 }
03325 }
03326 break;
03327 }
03328
03329 if (passthrough && (encoded = ast_aoc_encode(decoded, &encoded_size, owner))) {
03330 ast_queue_control_data(owner, AST_CONTROL_AOC, encoded, encoded_size);
03331 }
03332
03333 ast_aoc_manager_event(decoded, owner);
03334
03335 ast_aoc_destroy_decoded(decoded);
03336 ast_aoc_destroy_encoded(encoded);
03337 }
03338 #endif
03339
03340 #if defined(HAVE_PRI_AOC_EVENTS)
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357 static void sig_pri_aoc_e_from_pri(const struct pri_subcmd_aoc_e *aoc_e, struct ast_channel *owner, int passthrough)
03358 {
03359 struct ast_aoc_decoded *decoded = NULL;
03360 struct ast_aoc_encoded *encoded = NULL;
03361 size_t encoded_size = 0;
03362 enum ast_aoc_charge_type type;
03363
03364 if (!aoc_e) {
03365 return;
03366 }
03367
03368 switch (aoc_e->charge) {
03369 case PRI_AOC_DE_CHARGE_CURRENCY:
03370 type = AST_AOC_CHARGE_CURRENCY;
03371 break;
03372 case PRI_AOC_DE_CHARGE_UNITS:
03373 type = AST_AOC_CHARGE_UNIT;
03374 break;
03375 case PRI_AOC_DE_CHARGE_FREE:
03376 type = AST_AOC_CHARGE_FREE;
03377 break;
03378 default:
03379 type = AST_AOC_CHARGE_NA;
03380 break;
03381 }
03382
03383 if (!(decoded = ast_aoc_create(AST_AOC_E, type, 0))) {
03384 return;
03385 }
03386
03387 switch (aoc_e->associated.charging_type) {
03388 case PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER:
03389 if (!aoc_e->associated.charge.number.valid) {
03390 break;
03391 }
03392 ast_aoc_set_association_number(decoded, aoc_e->associated.charge.number.str, aoc_e->associated.charge.number.plan);
03393 break;
03394 case PRI_AOC_E_CHARGING_ASSOCIATION_ID:
03395 ast_aoc_set_association_id(decoded, aoc_e->associated.charge.id);
03396 break;
03397 default:
03398 break;
03399 }
03400
03401 switch (aoc_e->billing_id) {
03402 case PRI_AOC_E_BILLING_ID_NORMAL:
03403 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_NORMAL);
03404 break;
03405 case PRI_AOC_E_BILLING_ID_REVERSE:
03406 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_REVERSE_CHARGE);
03407 break;
03408 case PRI_AOC_E_BILLING_ID_CREDIT_CARD:
03409 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CREDIT_CARD);
03410 break;
03411 case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL:
03412 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL);
03413 break;
03414 case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY:
03415 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CALL_FWD_BUSY);
03416 break;
03417 case PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY:
03418 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CALL_FWD_NO_REPLY);
03419 break;
03420 case PRI_AOC_E_BILLING_ID_CALL_DEFLECTION:
03421 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CALL_DEFLECTION);
03422 break;
03423 case PRI_AOC_E_BILLING_ID_CALL_TRANSFER:
03424 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_CALL_TRANSFER);
03425 break;
03426 case PRI_AOC_E_BILLING_ID_NOT_AVAILABLE:
03427 default:
03428 ast_aoc_set_billing_id(decoded, AST_AOC_BILLING_NA);
03429 break;
03430 }
03431
03432 switch (aoc_e->charge) {
03433 case PRI_AOC_DE_CHARGE_CURRENCY:
03434 ast_aoc_set_currency_info(decoded,
03435 aoc_e->recorded.money.amount.cost,
03436 sig_pri_aoc_multiplier_from_pri(aoc_e->recorded.money.amount.multiplier),
03437 aoc_e->recorded.money.currency);
03438 break;
03439 case PRI_AOC_DE_CHARGE_UNITS:
03440 {
03441 int i;
03442 for (i = 0; i < aoc_e->recorded.unit.num_items; ++i) {
03443
03444 ast_aoc_add_unit_entry(decoded,
03445 (aoc_e->recorded.unit.item[i].number >= 0 ? 1 : 0),
03446 aoc_e->recorded.unit.item[i].number,
03447 (aoc_e->recorded.unit.item[i].type >= 0 ? 1 : 0),
03448 aoc_e->recorded.unit.item[i].type);
03449 }
03450 }
03451 }
03452
03453 if (passthrough && owner && (encoded = ast_aoc_encode(decoded, &encoded_size, owner))) {
03454 ast_queue_control_data(owner, AST_CONTROL_AOC, encoded, encoded_size);
03455 }
03456
03457 ast_aoc_manager_event(decoded, owner);
03458
03459 ast_aoc_destroy_decoded(decoded);
03460 ast_aoc_destroy_encoded(encoded);
03461 }
03462 #endif
03463
03464 #if defined(HAVE_PRI_AOC_EVENTS)
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474
03475
03476 static void sig_pri_aoc_s_from_ast(struct sig_pri_chan *pvt, struct ast_aoc_decoded *decoded)
03477 {
03478 struct pri_subcmd_aoc_s aoc_s = { 0, };
03479 const struct ast_aoc_s_entry *entry;
03480 int idx;
03481
03482 for (idx = 0; idx < ast_aoc_s_get_count(decoded); idx++) {
03483 if (!(entry = ast_aoc_s_get_rate_info(decoded, idx))) {
03484 break;
03485 }
03486
03487 aoc_s.item[idx].chargeable = sig_pri_aoc_charged_item_to_pri(entry->charged_item);
03488
03489 switch (entry->rate_type) {
03490 case AST_AOC_RATE_TYPE_DURATION:
03491 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_DURATION;
03492 aoc_s.item[idx].rate.duration.amount.cost = entry->rate.duration.amount;
03493 aoc_s.item[idx].rate.duration.amount.multiplier =
03494 sig_pri_aoc_multiplier_from_ast(entry->rate.duration.multiplier);
03495 aoc_s.item[idx].rate.duration.time.length = entry->rate.duration.time;
03496 aoc_s.item[idx].rate.duration.time.scale =
03497 sig_pri_aoc_scale_to_pri(entry->rate.duration.time_scale);
03498 aoc_s.item[idx].rate.duration.granularity.length = entry->rate.duration.granularity_time;
03499 aoc_s.item[idx].rate.duration.granularity.scale =
03500 sig_pri_aoc_scale_to_pri(entry->rate.duration.granularity_time_scale);
03501 aoc_s.item[idx].rate.duration.charging_type = entry->rate.duration.charging_type;
03502
03503 if (!ast_strlen_zero(entry->rate.duration.currency_name)) {
03504 ast_copy_string(aoc_s.item[idx].rate.duration.currency,
03505 entry->rate.duration.currency_name,
03506 sizeof(aoc_s.item[idx].rate.duration.currency));
03507 }
03508 break;
03509 case AST_AOC_RATE_TYPE_FLAT:
03510 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FLAT;
03511 aoc_s.item[idx].rate.flat.amount.cost = entry->rate.flat.amount;
03512 aoc_s.item[idx].rate.flat.amount.multiplier =
03513 sig_pri_aoc_multiplier_from_ast(entry->rate.flat.multiplier);
03514
03515 if (!ast_strlen_zero(entry->rate.flat.currency_name)) {
03516 ast_copy_string(aoc_s.item[idx].rate.flat.currency,
03517 entry->rate.flat.currency_name,
03518 sizeof(aoc_s.item[idx].rate.flat.currency));
03519 }
03520 break;
03521 case AST_AOC_RATE_TYPE_VOLUME:
03522 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_VOLUME;
03523 aoc_s.item[idx].rate.volume.unit = entry->rate.volume.volume_unit;
03524 aoc_s.item[idx].rate.volume.amount.cost = entry->rate.volume.amount;
03525 aoc_s.item[idx].rate.volume.amount.multiplier =
03526 sig_pri_aoc_multiplier_from_ast(entry->rate.volume.multiplier);
03527
03528 if (!ast_strlen_zero(entry->rate.volume.currency_name)) {
03529 ast_copy_string(aoc_s.item[idx].rate.volume.currency,
03530 entry->rate.volume.currency_name,
03531 sizeof(aoc_s.item[idx].rate.volume.currency));
03532 }
03533 break;
03534 case AST_AOC_RATE_TYPE_SPECIAL_CODE:
03535 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_SPECIAL_CODE;
03536 aoc_s.item[idx].rate.special = entry->rate.special_code;
03537 break;
03538 case AST_AOC_RATE_TYPE_FREE:
03539 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FREE;
03540 break;
03541 case AST_AOC_RATE_TYPE_FREE_FROM_BEGINNING:
03542 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_FREE_FROM_BEGINNING;
03543 break;
03544 default:
03545 case AST_AOC_RATE_TYPE_NA:
03546 aoc_s.item[idx].rate_type = PRI_AOC_RATE_TYPE_NOT_AVAILABLE;
03547 break;
03548 }
03549 }
03550 aoc_s.num_items = idx;
03551
03552
03553
03554 if (pvt->aoc_s_request_invoke_id_valid) {
03555 pri_aoc_s_request_response_send(pvt->pri->pri, pvt->call, pvt->aoc_s_request_invoke_id, &aoc_s);
03556 pvt->aoc_s_request_invoke_id_valid = 0;
03557 } else {
03558 pri_aoc_s_send(pvt->pri->pri, pvt->call, &aoc_s);
03559 }
03560 }
03561 #endif
03562
03563 #if defined(HAVE_PRI_AOC_EVENTS)
03564
03565
03566
03567
03568
03569
03570
03571
03572
03573
03574
03575 static void sig_pri_aoc_d_from_ast(struct sig_pri_chan *pvt, struct ast_aoc_decoded *decoded)
03576 {
03577 struct pri_subcmd_aoc_d aoc_d = { 0, };
03578
03579 aoc_d.billing_accumulation = (ast_aoc_get_total_type(decoded) == AST_AOC_TOTAL) ? 1 : 0;
03580
03581 switch (ast_aoc_get_billing_id(decoded)) {
03582 case AST_AOC_BILLING_NORMAL:
03583 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_NORMAL;
03584 break;
03585 case AST_AOC_BILLING_REVERSE_CHARGE:
03586 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_REVERSE;
03587 break;
03588 case AST_AOC_BILLING_CREDIT_CARD:
03589 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_CREDIT_CARD;
03590 break;
03591 case AST_AOC_BILLING_NA:
03592 default:
03593 aoc_d.billing_id = PRI_AOC_D_BILLING_ID_NOT_AVAILABLE;
03594 break;
03595 }
03596
03597 switch (ast_aoc_get_charge_type(decoded)) {
03598 case AST_AOC_CHARGE_FREE:
03599 aoc_d.charge = PRI_AOC_DE_CHARGE_FREE;
03600 break;
03601 case AST_AOC_CHARGE_CURRENCY:
03602 {
03603 const char *currency_name = ast_aoc_get_currency_name(decoded);
03604 aoc_d.charge = PRI_AOC_DE_CHARGE_CURRENCY;
03605 aoc_d.recorded.money.amount.cost = ast_aoc_get_currency_amount(decoded);
03606 aoc_d.recorded.money.amount.multiplier = sig_pri_aoc_multiplier_from_ast(ast_aoc_get_currency_multiplier(decoded));
03607 if (!ast_strlen_zero(currency_name)) {
03608 ast_copy_string(aoc_d.recorded.money.currency, currency_name, sizeof(aoc_d.recorded.money.currency));
03609 }
03610 }
03611 break;
03612 case AST_AOC_CHARGE_UNIT:
03613 {
03614 const struct ast_aoc_unit_entry *entry;
03615 int i;
03616 aoc_d.charge = PRI_AOC_DE_CHARGE_UNITS;
03617 for (i = 0; i < ast_aoc_get_unit_count(decoded); i++) {
03618 if ((entry = ast_aoc_get_unit_info(decoded, i)) && i < ARRAY_LEN(aoc_d.recorded.unit.item)) {
03619 if (entry->valid_amount) {
03620 aoc_d.recorded.unit.item[i].number = entry->amount;
03621 } else {
03622 aoc_d.recorded.unit.item[i].number = -1;
03623 }
03624 if (entry->valid_type) {
03625 aoc_d.recorded.unit.item[i].type = entry->type;
03626 } else {
03627 aoc_d.recorded.unit.item[i].type = -1;
03628 }
03629 aoc_d.recorded.unit.num_items++;
03630 } else {
03631 break;
03632 }
03633 }
03634 }
03635 break;
03636 case AST_AOC_CHARGE_NA:
03637 default:
03638 aoc_d.charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE;
03639 break;
03640 }
03641
03642 pri_aoc_d_send(pvt->pri->pri, pvt->call, &aoc_d);
03643 }
03644 #endif
03645
03646 #if defined(HAVE_PRI_AOC_EVENTS)
03647
03648
03649
03650
03651
03652
03653
03654
03655
03656
03657
03658 static void sig_pri_aoc_e_from_ast(struct sig_pri_chan *pvt, struct ast_aoc_decoded *decoded)
03659 {
03660 struct pri_subcmd_aoc_e *aoc_e = &pvt->aoc_e;
03661 const struct ast_aoc_charging_association *ca = ast_aoc_get_association_info(decoded);
03662
03663 memset(aoc_e, 0, sizeof(*aoc_e));
03664 pvt->holding_aoce = 1;
03665
03666 switch (ca->charging_type) {
03667 case AST_AOC_CHARGING_ASSOCIATION_NUMBER:
03668 aoc_e->associated.charge.number.valid = 1;
03669 ast_copy_string(aoc_e->associated.charge.number.str,
03670 ca->charge.number.number,
03671 sizeof(aoc_e->associated.charge.number.str));
03672 aoc_e->associated.charge.number.plan = ca->charge.number.plan;
03673 aoc_e->associated.charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_NUMBER;
03674 break;
03675 case AST_AOC_CHARGING_ASSOCIATION_ID:
03676 aoc_e->associated.charge.id = ca->charge.id;
03677 aoc_e->associated.charging_type = PRI_AOC_E_CHARGING_ASSOCIATION_ID;
03678 break;
03679 case AST_AOC_CHARGING_ASSOCIATION_NA:
03680 default:
03681 break;
03682 }
03683
03684 switch (ast_aoc_get_billing_id(decoded)) {
03685 case AST_AOC_BILLING_NORMAL:
03686 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_NORMAL;
03687 break;
03688 case AST_AOC_BILLING_REVERSE_CHARGE:
03689 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_REVERSE;
03690 break;
03691 case AST_AOC_BILLING_CREDIT_CARD:
03692 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CREDIT_CARD;
03693 break;
03694 case AST_AOC_BILLING_CALL_FWD_UNCONDITIONAL:
03695 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_UNCONDITIONAL;
03696 break;
03697 case AST_AOC_BILLING_CALL_FWD_BUSY:
03698 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_BUSY;
03699 break;
03700 case AST_AOC_BILLING_CALL_FWD_NO_REPLY:
03701 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_FORWARDING_NO_REPLY;
03702 break;
03703 case AST_AOC_BILLING_CALL_DEFLECTION:
03704 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_DEFLECTION;
03705 break;
03706 case AST_AOC_BILLING_CALL_TRANSFER:
03707 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_CALL_TRANSFER;
03708 break;
03709 case AST_AOC_BILLING_NA:
03710 default:
03711 aoc_e->billing_id = PRI_AOC_E_BILLING_ID_NOT_AVAILABLE;
03712 break;
03713 }
03714
03715 switch (ast_aoc_get_charge_type(decoded)) {
03716 case AST_AOC_CHARGE_FREE:
03717 aoc_e->charge = PRI_AOC_DE_CHARGE_FREE;
03718 break;
03719 case AST_AOC_CHARGE_CURRENCY:
03720 {
03721 const char *currency_name = ast_aoc_get_currency_name(decoded);
03722 aoc_e->charge = PRI_AOC_DE_CHARGE_CURRENCY;
03723 aoc_e->recorded.money.amount.cost = ast_aoc_get_currency_amount(decoded);
03724 aoc_e->recorded.money.amount.multiplier = sig_pri_aoc_multiplier_from_ast(ast_aoc_get_currency_multiplier(decoded));
03725 if (!ast_strlen_zero(currency_name)) {
03726 ast_copy_string(aoc_e->recorded.money.currency, currency_name, sizeof(aoc_e->recorded.money.currency));
03727 }
03728 }
03729 break;
03730 case AST_AOC_CHARGE_UNIT:
03731 {
03732 const struct ast_aoc_unit_entry *entry;
03733 int i;
03734 aoc_e->charge = PRI_AOC_DE_CHARGE_UNITS;
03735 for (i = 0; i < ast_aoc_get_unit_count(decoded); i++) {
03736 if ((entry = ast_aoc_get_unit_info(decoded, i)) && i < ARRAY_LEN(aoc_e->recorded.unit.item)) {
03737 if (entry->valid_amount) {
03738 aoc_e->recorded.unit.item[i].number = entry->amount;
03739 } else {
03740 aoc_e->recorded.unit.item[i].number = -1;
03741 }
03742 if (entry->valid_type) {
03743 aoc_e->recorded.unit.item[i].type = entry->type;
03744 } else {
03745 aoc_e->recorded.unit.item[i].type = -1;
03746 }
03747 aoc_e->recorded.unit.num_items++;
03748 }
03749 }
03750 }
03751 break;
03752 case AST_AOC_CHARGE_NA:
03753 default:
03754 aoc_e->charge = PRI_AOC_DE_CHARGE_NOT_AVAILABLE;
03755 break;
03756 }
03757 }
03758 #endif
03759
03760 #if defined(HAVE_PRI_AOC_EVENTS)
03761
03762
03763
03764
03765
03766
03767
03768
03769
03770
03771
03772
03773
03774
03775 static void sig_pri_send_aoce_termination_request(struct sig_pri_span *pri, int chanpos, unsigned int ms)
03776 {
03777 struct sig_pri_chan *pvt;
03778 struct ast_aoc_decoded *decoded = NULL;
03779 struct ast_aoc_encoded *encoded = NULL;
03780 size_t encoded_size;
03781 struct timeval whentohangup = { 0, };
03782
03783 sig_pri_lock_owner(pri, chanpos);
03784 pvt = pri->pvts[chanpos];
03785 if (!pvt->owner) {
03786 return;
03787 }
03788
03789 if (!(decoded = ast_aoc_create(AST_AOC_REQUEST, 0, AST_AOC_REQUEST_E))) {
03790 ast_softhangup_nolock(pvt->owner, AST_SOFTHANGUP_DEV);
03791 goto cleanup_termination_request;
03792 }
03793
03794 ast_aoc_set_termination_request(decoded);
03795
03796 if (!(encoded = ast_aoc_encode(decoded, &encoded_size, pvt->owner))) {
03797 ast_softhangup_nolock(pvt->owner, AST_SOFTHANGUP_DEV);
03798 goto cleanup_termination_request;
03799 }
03800
03801
03802 whentohangup.tv_usec = (ms % 1000) * 1000;
03803 whentohangup.tv_sec = ms / 1000;
03804
03805 if (ast_queue_control_data(pvt->owner, AST_CONTROL_AOC, encoded, encoded_size)) {
03806 ast_softhangup_nolock(pvt->owner, AST_SOFTHANGUP_DEV);
03807 goto cleanup_termination_request;
03808 }
03809
03810 pvt->waiting_for_aoce = 1;
03811 ast_channel_setwhentohangup_tv(pvt->owner, whentohangup);
03812 ast_debug(1, "Delaying hangup on %s for aoc-e msg\n", ast_channel_name(pvt->owner));
03813
03814 cleanup_termination_request:
03815 ast_channel_unlock(pvt->owner);
03816 ast_aoc_destroy_decoded(decoded);
03817 ast_aoc_destroy_encoded(encoded);
03818 }
03819 #endif
03820
03821
03822
03823
03824
03825
03826
03827
03828
03829
03830 static int sig_pri_is_cis_call(int channel)
03831 {
03832 return channel != -1 && (channel & PRI_CIS_CALL);
03833 }
03834
03835
03836
03837
03838
03839
03840
03841
03842
03843
03844
03845
03846
03847
03848
03849
03850
03851
03852 static void sig_pri_handle_cis_subcmds(struct sig_pri_span *pri, int event_id,
03853 const struct pri_subcommands *subcmds, q931_call *call_rsp)
03854 {
03855 int index;
03856 #if defined(HAVE_PRI_CCSS)
03857 struct ast_cc_agent *agent;
03858 struct sig_pri_cc_agent_prv *agent_prv;
03859 struct sig_pri_cc_monitor_instance *monitor;
03860 #endif
03861
03862 if (!subcmds) {
03863 return;
03864 }
03865 for (index = 0; index < subcmds->counter_subcmd; ++index) {
03866 const struct pri_subcommand *subcmd = &subcmds->subcmd[index];
03867
03868 switch (subcmd->cmd) {
03869 #if defined(STATUS_REQUEST_PLACE_HOLDER)
03870 case PRI_SUBCMD_STATUS_REQ:
03871 case PRI_SUBCMD_STATUS_REQ_RSP:
03872
03873 break;
03874 #endif
03875 #if defined(HAVE_PRI_CCSS)
03876 case PRI_SUBCMD_CC_REQ:
03877 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_request.cc_id);
03878 if (!agent) {
03879 pri_cc_cancel(pri->pri, subcmd->u.cc_request.cc_id);
03880 break;
03881 }
03882 if (!ast_cc_request_is_within_limits()) {
03883 if (pri_cc_req_rsp(pri->pri, subcmd->u.cc_request.cc_id,
03884 5)) {
03885 pri_cc_cancel(pri->pri, subcmd->u.cc_request.cc_id);
03886 }
03887 ast_cc_failed(agent->core_id, "%s agent system CC queue full",
03888 sig_pri_cc_type_name);
03889 ao2_ref(agent, -1);
03890 break;
03891 }
03892 agent_prv = agent->private_data;
03893 agent_prv->cc_request_response_pending = 1;
03894 if (ast_cc_agent_accept_request(agent->core_id,
03895 "%s caller accepted CC offer.", sig_pri_cc_type_name)) {
03896 agent_prv->cc_request_response_pending = 0;
03897 if (pri_cc_req_rsp(pri->pri, subcmd->u.cc_request.cc_id,
03898 2)) {
03899 pri_cc_cancel(pri->pri, subcmd->u.cc_request.cc_id);
03900 }
03901 ast_cc_failed(agent->core_id, "%s agent CC core request accept failed",
03902 sig_pri_cc_type_name);
03903 }
03904 ao2_ref(agent, -1);
03905 break;
03906 #endif
03907 #if defined(HAVE_PRI_CCSS)
03908 case PRI_SUBCMD_CC_REQ_RSP:
03909 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
03910 subcmd->u.cc_request_rsp.cc_id);
03911 if (!monitor) {
03912 pri_cc_cancel(pri->pri, subcmd->u.cc_request_rsp.cc_id);
03913 break;
03914 }
03915 switch (subcmd->u.cc_request_rsp.status) {
03916 case 0:
03917 ast_cc_monitor_request_acked(monitor->core_id,
03918 "%s far end accepted CC request", sig_pri_cc_type_name);
03919 break;
03920 case 1:
03921 ast_verb(2, "core_id:%d %s CC request timeout\n", monitor->core_id,
03922 sig_pri_cc_type_name);
03923 ast_cc_monitor_failed(monitor->core_id, monitor->name,
03924 "%s CC request timeout", sig_pri_cc_type_name);
03925 break;
03926 case 2:
03927 ast_verb(2, "core_id:%d %s CC request error: %s\n", monitor->core_id,
03928 sig_pri_cc_type_name,
03929 pri_facility_error2str(subcmd->u.cc_request_rsp.fail_code));
03930 ast_cc_monitor_failed(monitor->core_id, monitor->name,
03931 "%s CC request error", sig_pri_cc_type_name);
03932 break;
03933 case 3:
03934 ast_verb(2, "core_id:%d %s CC request reject: %s\n", monitor->core_id,
03935 sig_pri_cc_type_name,
03936 pri_facility_reject2str(subcmd->u.cc_request_rsp.fail_code));
03937 ast_cc_monitor_failed(monitor->core_id, monitor->name,
03938 "%s CC request reject", sig_pri_cc_type_name);
03939 break;
03940 default:
03941 ast_verb(2, "core_id:%d %s CC request unknown status %d\n",
03942 monitor->core_id, sig_pri_cc_type_name,
03943 subcmd->u.cc_request_rsp.status);
03944 ast_cc_monitor_failed(monitor->core_id, monitor->name,
03945 "%s CC request unknown status", sig_pri_cc_type_name);
03946 break;
03947 }
03948 ao2_ref(monitor, -1);
03949 break;
03950 #endif
03951 #if defined(HAVE_PRI_CCSS)
03952 case PRI_SUBCMD_CC_REMOTE_USER_FREE:
03953 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
03954 subcmd->u.cc_remote_user_free.cc_id);
03955 if (!monitor) {
03956 pri_cc_cancel(pri->pri, subcmd->u.cc_remote_user_free.cc_id);
03957 break;
03958 }
03959 ast_cc_monitor_callee_available(monitor->core_id,
03960 "%s callee has become available", sig_pri_cc_type_name);
03961 ao2_ref(monitor, -1);
03962 break;
03963 #endif
03964 #if defined(HAVE_PRI_CCSS)
03965 case PRI_SUBCMD_CC_B_FREE:
03966 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
03967 subcmd->u.cc_b_free.cc_id);
03968 if (!monitor) {
03969 pri_cc_cancel(pri->pri, subcmd->u.cc_b_free.cc_id);
03970 break;
03971 }
03972 ast_cc_monitor_party_b_free(monitor->core_id);
03973 ao2_ref(monitor, -1);
03974 break;
03975 #endif
03976 #if defined(HAVE_PRI_CCSS)
03977 case PRI_SUBCMD_CC_STATUS_REQ:
03978 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
03979 subcmd->u.cc_status_req.cc_id);
03980 if (!monitor) {
03981 pri_cc_cancel(pri->pri, subcmd->u.cc_status_req.cc_id);
03982 break;
03983 }
03984 ast_cc_monitor_status_request(monitor->core_id);
03985 ao2_ref(monitor, -1);
03986 break;
03987 #endif
03988 #if defined(HAVE_PRI_CCSS)
03989 case PRI_SUBCMD_CC_STATUS_REQ_RSP:
03990 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status_req_rsp.cc_id);
03991 if (!agent) {
03992 pri_cc_cancel(pri->pri, subcmd->u.cc_status_req_rsp.cc_id);
03993 break;
03994 }
03995 ast_cc_agent_status_response(agent->core_id,
03996 subcmd->u.cc_status_req_rsp.status ? AST_DEVICE_INUSE
03997 : AST_DEVICE_NOT_INUSE);
03998 ao2_ref(agent, -1);
03999 break;
04000 #endif
04001 #if defined(HAVE_PRI_CCSS)
04002 case PRI_SUBCMD_CC_STATUS:
04003 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_status.cc_id);
04004 if (!agent) {
04005 pri_cc_cancel(pri->pri, subcmd->u.cc_status.cc_id);
04006 break;
04007 }
04008 if (subcmd->u.cc_status.status) {
04009 ast_cc_agent_caller_busy(agent->core_id, "%s agent caller is busy",
04010 sig_pri_cc_type_name);
04011 } else {
04012 ast_cc_agent_caller_available(agent->core_id,
04013 "%s agent caller is available", sig_pri_cc_type_name);
04014 }
04015 ao2_ref(agent, -1);
04016 break;
04017 #endif
04018 #if defined(HAVE_PRI_CCSS)
04019 case PRI_SUBCMD_CC_CANCEL:
04020 sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id,
04021 subcmd->u.cc_cancel.is_agent);
04022 break;
04023 #endif
04024 #if defined(HAVE_PRI_CCSS)
04025 case PRI_SUBCMD_CC_STOP_ALERTING:
04026 monitor = sig_pri_find_cc_monitor_by_cc_id(pri,
04027 subcmd->u.cc_stop_alerting.cc_id);
04028 if (!monitor) {
04029 pri_cc_cancel(pri->pri, subcmd->u.cc_stop_alerting.cc_id);
04030 break;
04031 }
04032 ast_cc_monitor_stop_ringing(monitor->core_id);
04033 ao2_ref(monitor, -1);
04034 break;
04035 #endif
04036 #if defined(HAVE_PRI_AOC_EVENTS)
04037 case PRI_SUBCMD_AOC_E:
04038
04039 sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, NULL, 0);
04040 break;
04041 #endif
04042 default:
04043 ast_debug(2, "Span %d: Unknown CIS subcommand(%d) in %s event.\n", pri->span,
04044 subcmd->cmd, pri_event2str(event_id));
04045 break;
04046 }
04047 }
04048 }
04049
04050 #if defined(HAVE_PRI_AOC_EVENTS)
04051
04052
04053
04054
04055
04056
04057
04058
04059
04060
04061
04062
04063
04064
04065
04066
04067
04068
04069
04070 static int detect_aoc_e_subcmd(const struct pri_subcommands *subcmds)
04071 {
04072 int i;
04073
04074 if (!subcmds) {
04075 return 0;
04076 }
04077 for (i = 0; i < subcmds->counter_subcmd; ++i) {
04078 const struct pri_subcommand *subcmd = &subcmds->subcmd[i];
04079 if (subcmd->cmd == PRI_SUBCMD_AOC_E) {
04080 return 1;
04081 }
04082 }
04083 return 0;
04084 }
04085 #endif
04086
04087
04088
04089
04090
04091
04092
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103
04104
04105
04106 static void sig_pri_handle_subcmds(struct sig_pri_span *pri, int chanpos, int event_id,
04107 const struct pri_subcommands *subcmds, q931_call *call_rsp)
04108 {
04109 int index;
04110 struct ast_channel *owner;
04111 struct ast_party_redirecting ast_redirecting;
04112 #if defined(HAVE_PRI_TRANSFER)
04113 struct xfer_rsp_data xfer_rsp;
04114 #endif
04115
04116 if (!subcmds) {
04117 return;
04118 }
04119 for (index = 0; index < subcmds->counter_subcmd; ++index) {
04120 const struct pri_subcommand *subcmd = &subcmds->subcmd[index];
04121
04122 switch (subcmd->cmd) {
04123 case PRI_SUBCMD_CONNECTED_LINE:
04124 sig_pri_lock_owner(pri, chanpos);
04125 owner = pri->pvts[chanpos]->owner;
04126 if (owner) {
04127 struct ast_party_connected_line ast_connected;
04128 int caller_id_update;
04129
04130
04131 ast_party_connected_line_init(&ast_connected);
04132 sig_pri_party_id_convert(&ast_connected.id, &subcmd->u.connected_line.id,
04133 pri);
04134 ast_connected.id.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
04135
04136 caller_id_update = 0;
04137 if (ast_connected.id.name.str) {
04138
04139 ast_copy_string(pri->pvts[chanpos]->cid_name,
04140 ast_connected.id.name.str, sizeof(pri->pvts[chanpos]->cid_name));
04141 caller_id_update = 1;
04142 }
04143 if (ast_connected.id.number.str) {
04144
04145 ast_copy_string(pri->pvts[chanpos]->cid_num,
04146 ast_connected.id.number.str, sizeof(pri->pvts[chanpos]->cid_num));
04147 pri->pvts[chanpos]->cid_ton = ast_connected.id.number.plan;
04148 caller_id_update = 1;
04149 }
04150 ast_connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
04151
04152 pri->pvts[chanpos]->cid_subaddr[0] = '\0';
04153 #if defined(HAVE_PRI_SUBADDR)
04154 if (ast_connected.id.subaddress.valid) {
04155 ast_party_subaddress_set(&ast_channel_caller(owner)->id.subaddress,
04156 &ast_connected.id.subaddress);
04157 if (ast_connected.id.subaddress.str) {
04158 ast_copy_string(pri->pvts[chanpos]->cid_subaddr,
04159 ast_connected.id.subaddress.str,
04160 sizeof(pri->pvts[chanpos]->cid_subaddr));
04161 }
04162 }
04163 #endif
04164 if (caller_id_update) {
04165 struct ast_party_caller ast_caller;
04166
04167 pri->pvts[chanpos]->callingpres =
04168 ast_party_id_presentation(&ast_connected.id);
04169 sig_pri_set_caller_id(pri->pvts[chanpos]);
04170
04171 ast_party_caller_set_init(&ast_caller, ast_channel_caller(owner));
04172 ast_caller.id = ast_connected.id;
04173 ast_caller.ani = ast_connected.id;
04174 ast_channel_set_caller_event(owner, &ast_caller, NULL);
04175 }
04176
04177
04178 if (event_id != PRI_EVENT_RING) {
04179
04180 ast_channel_queue_connected_line_update(owner, &ast_connected, NULL);
04181 }
04182
04183 ast_party_connected_line_free(&ast_connected);
04184 ast_channel_unlock(owner);
04185 }
04186 break;
04187 case PRI_SUBCMD_REDIRECTING:
04188 sig_pri_lock_owner(pri, chanpos);
04189 owner = pri->pvts[chanpos]->owner;
04190 if (owner) {
04191 sig_pri_redirecting_convert(&ast_redirecting, &subcmd->u.redirecting,
04192 ast_channel_redirecting(owner), pri);
04193 ast_redirecting.orig.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
04194 ast_redirecting.from.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
04195 ast_redirecting.to.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
04196 ast_channel_set_redirecting(owner, &ast_redirecting, NULL);
04197 if (event_id != PRI_EVENT_RING) {
04198
04199 ast_channel_queue_redirecting_update(owner, &ast_redirecting, NULL);
04200 }
04201 ast_party_redirecting_free(&ast_redirecting);
04202
04203 ast_channel_unlock(owner);
04204 }
04205 break;
04206 #if defined(HAVE_PRI_CALL_REROUTING)
04207 case PRI_SUBCMD_REROUTING:
04208 sig_pri_lock_owner(pri, chanpos);
04209 owner = pri->pvts[chanpos]->owner;
04210 if (owner) {
04211 struct pri_party_redirecting pri_deflection;
04212
04213 if (!call_rsp) {
04214 ast_log(LOG_WARNING,
04215 "Span %d: %s tried CallRerouting/CallDeflection to '%s' without call!\n",
04216 pri->span, ast_channel_name(owner), subcmd->u.rerouting.deflection.to.number.str);
04217 ast_channel_unlock(owner);
04218 break;
04219 }
04220 if (ast_strlen_zero(subcmd->u.rerouting.deflection.to.number.str)) {
04221 ast_log(LOG_WARNING,
04222 "Span %d: %s tried CallRerouting/CallDeflection to empty number!\n",
04223 pri->span, ast_channel_name(owner));
04224 pri_rerouting_rsp(pri->pri, call_rsp, subcmd->u.rerouting.invoke_id,
04225 PRI_REROUTING_RSP_INVALID_NUMBER);
04226 ast_channel_unlock(owner);
04227 break;
04228 }
04229
04230 ast_verb(3, "Span %d: %s is CallRerouting/CallDeflection to '%s'.\n",
04231 pri->span, ast_channel_name(owner), subcmd->u.rerouting.deflection.to.number.str);
04232
04233
04234
04235
04236
04237
04238
04239 pri_rerouting_rsp(pri->pri, call_rsp, subcmd->u.rerouting.invoke_id,
04240 PRI_REROUTING_RSP_OK_CLEAR);
04241
04242 pri_deflection = subcmd->u.rerouting.deflection;
04243
04244
04245 switch (subcmd->u.rerouting.subscription_option) {
04246 case 0:
04247 case 1:
04248
04249 pri_deflection.to.number.presentation =
04250 PRI_PRES_RESTRICTED | PRI_PRES_USER_NUMBER_UNSCREENED;
04251 pri_deflection.to.number.plan =
04252 (PRI_TON_UNKNOWN << 4) | PRI_NPI_E163_E164;
04253 pri_deflection.to.number.str[0] = '\0';
04254 break;
04255 case 2:
04256 break;
04257 case 3:
04258 default:
04259 break;
04260 }
04261 sig_pri_redirecting_convert(&ast_redirecting, &pri_deflection,
04262 ast_channel_redirecting(owner), pri);
04263 ast_redirecting.orig.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
04264 ast_redirecting.from.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
04265 ast_redirecting.to.tag = ast_strdup(pri->pvts[chanpos]->user_tag);
04266 ast_channel_set_redirecting(owner, &ast_redirecting, NULL);
04267 ast_party_redirecting_free(&ast_redirecting);
04268
04269
04270 ast_channel_call_forward_set(owner, subcmd->u.rerouting.deflection.to.number.str);
04271
04272
04273 ast_queue_frame(owner, &ast_null_frame);
04274
04275 ast_channel_unlock(owner);
04276 }
04277 break;
04278 #endif
04279 #if defined(HAVE_PRI_CCSS)
04280 case PRI_SUBCMD_CC_AVAILABLE:
04281 sig_pri_lock_owner(pri, chanpos);
04282 owner = pri->pvts[chanpos]->owner;
04283 if (owner) {
04284 enum ast_cc_service_type service;
04285
04286 switch (event_id) {
04287 case PRI_EVENT_RINGING:
04288 service = AST_CC_CCNR;
04289 break;
04290 case PRI_EVENT_HANGUP_REQ:
04291
04292 service = AST_CC_CCBS;
04293 break;
04294 default:
04295 service = AST_CC_NONE;
04296 break;
04297 }
04298 if (service == AST_CC_NONE
04299 || sig_pri_cc_available(pri, chanpos, subcmd->u.cc_available.cc_id,
04300 service)) {
04301 pri_cc_cancel(pri->pri, subcmd->u.cc_available.cc_id);
04302 }
04303 ast_channel_unlock(owner);
04304 } else {
04305
04306 pri_cc_cancel(pri->pri, subcmd->u.cc_available.cc_id);
04307 }
04308 break;
04309 #endif
04310 #if defined(HAVE_PRI_CCSS)
04311 case PRI_SUBCMD_CC_CALL:
04312 sig_pri_lock_owner(pri, chanpos);
04313 owner = pri->pvts[chanpos]->owner;
04314 if (owner) {
04315 struct ast_cc_agent *agent;
04316
04317 agent = sig_pri_find_cc_agent_by_cc_id(pri, subcmd->u.cc_call.cc_id);
04318 if (agent) {
04319 ast_setup_cc_recall_datastore(owner, agent->core_id);
04320 ast_cc_agent_set_interfaces_chanvar(owner);
04321 ast_cc_agent_recalling(agent->core_id,
04322 "%s caller is attempting recall", sig_pri_cc_type_name);
04323 ao2_ref(agent, -1);
04324 }
04325
04326 ast_channel_unlock(owner);
04327 }
04328 break;
04329 #endif
04330 #if defined(HAVE_PRI_CCSS)
04331 case PRI_SUBCMD_CC_CANCEL:
04332 sig_pri_cc_link_canceled(pri, subcmd->u.cc_cancel.cc_id,
04333 subcmd->u.cc_cancel.is_agent);
04334 break;
04335 #endif
04336 #if defined(HAVE_PRI_TRANSFER)
04337 case PRI_SUBCMD_TRANSFER_CALL:
04338 if (!call_rsp) {
04339
04340 ast_log(LOG_ERROR,
04341 "Call transfer subcommand without call to send response!\n");
04342 break;
04343 }
04344
04345 sig_pri_unlock_private(pri->pvts[chanpos]);
04346 xfer_rsp.pri = pri;
04347 xfer_rsp.call = call_rsp;
04348 xfer_rsp.invoke_id = subcmd->u.transfer.invoke_id;
04349 sig_pri_attempt_transfer(pri,
04350 subcmd->u.transfer.call_1, subcmd->u.transfer.is_call_1_held,
04351 subcmd->u.transfer.call_2, subcmd->u.transfer.is_call_2_held,
04352 sig_pri_transfer_rsp, &xfer_rsp);
04353 sig_pri_lock_private(pri->pvts[chanpos]);
04354 break;
04355 #endif
04356 #if defined(HAVE_PRI_AOC_EVENTS)
04357 case PRI_SUBCMD_AOC_S:
04358 sig_pri_lock_owner(pri, chanpos);
04359 owner = pri->pvts[chanpos]->owner;
04360 if (owner) {
04361 sig_pri_aoc_s_from_pri(&subcmd->u.aoc_s, owner,
04362 (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S));
04363 ast_channel_unlock(owner);
04364 }
04365 break;
04366 #endif
04367 #if defined(HAVE_PRI_AOC_EVENTS)
04368 case PRI_SUBCMD_AOC_D:
04369 sig_pri_lock_owner(pri, chanpos);
04370 owner = pri->pvts[chanpos]->owner;
04371 if (owner) {
04372
04373 sig_pri_aoc_d_from_pri(&subcmd->u.aoc_d, owner,
04374 (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D));
04375 ast_channel_unlock(owner);
04376 }
04377 break;
04378 #endif
04379 #if defined(HAVE_PRI_AOC_EVENTS)
04380 case PRI_SUBCMD_AOC_E:
04381 sig_pri_lock_owner(pri, chanpos);
04382 owner = pri->pvts[chanpos]->owner;
04383
04384 sig_pri_aoc_e_from_pri(&subcmd->u.aoc_e, owner,
04385 (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E));
04386 if (owner) {
04387 ast_channel_unlock(owner);
04388 }
04389 break;
04390 #endif
04391 #if defined(HAVE_PRI_AOC_EVENTS)
04392 case PRI_SUBCMD_AOC_CHARGING_REQ:
04393 sig_pri_lock_owner(pri, chanpos);
04394 owner = pri->pvts[chanpos]->owner;
04395 if (owner) {
04396 sig_pri_aoc_request_from_pri(&subcmd->u.aoc_request, pri->pvts[chanpos],
04397 call_rsp);
04398 ast_channel_unlock(owner);
04399 }
04400 break;
04401 #endif
04402 #if defined(HAVE_PRI_AOC_EVENTS)
04403 case PRI_SUBCMD_AOC_CHARGING_REQ_RSP:
04404
04405
04406
04407
04408
04409 if (subcmd->u.aoc_request_response.valid_aoc_s) {
04410 sig_pri_lock_owner(pri, chanpos);
04411 owner = pri->pvts[chanpos]->owner;
04412 if (owner) {
04413 sig_pri_aoc_s_from_pri(&subcmd->u.aoc_request_response.aoc_s, owner,
04414 (pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S));
04415 ast_channel_unlock(owner);
04416 }
04417 }
04418 break;
04419 #endif
04420 #if defined(HAVE_PRI_MCID)
04421 case PRI_SUBCMD_MCID_REQ:
04422 sig_pri_lock_owner(pri, chanpos);
04423 owner = pri->pvts[chanpos]->owner;
04424 sig_pri_mcid_event(pri, &subcmd->u.mcid_req, owner);
04425 if (owner) {
04426 ast_channel_unlock(owner);
04427 }
04428 break;
04429 #endif
04430 #if defined(HAVE_PRI_MCID)
04431 case PRI_SUBCMD_MCID_RSP:
04432
04433 break;
04434 #endif
04435 #if defined(HAVE_PRI_DISPLAY_TEXT)
04436 case PRI_SUBCMD_DISPLAY_TEXT:
04437 if (event_id != PRI_EVENT_RING) {
04438
04439
04440
04441
04442 sig_pri_lock_owner(pri, chanpos);
04443 owner = pri->pvts[chanpos]->owner;
04444 if (owner) {
04445 struct ast_frame f;
04446
04447
04448 memset(&f, 0, sizeof(f));
04449 f.frametype = AST_FRAME_TEXT;
04450 f.subclass.integer = 0;
04451 f.offset = 0;
04452 f.data.ptr = &subcmd->u.display.text;
04453 f.datalen = subcmd->u.display.length + 1;
04454 ast_queue_frame(owner, &f);
04455 ast_channel_unlock(owner);
04456 }
04457 }
04458 break;
04459 #endif
04460 default:
04461 ast_debug(2, "Span %d: Unknown call subcommand(%d) in %s event.\n",
04462 pri->span, subcmd->cmd, pri_event2str(event_id));
04463 break;
04464 }
04465 }
04466 }
04467
04468
04469
04470
04471
04472
04473
04474
04475
04476
04477 static const char *sig_pri_moh_state_str(enum sig_pri_moh_state state)
04478 {
04479 const char *str;
04480
04481 str = "Unknown";
04482 switch (state) {
04483 case SIG_PRI_MOH_STATE_IDLE:
04484 str = "SIG_PRI_MOH_STATE_IDLE";
04485 break;
04486 case SIG_PRI_MOH_STATE_NOTIFY:
04487 str = "SIG_PRI_MOH_STATE_NOTIFY";
04488 break;
04489 case SIG_PRI_MOH_STATE_MOH:
04490 str = "SIG_PRI_MOH_STATE_MOH";
04491 break;
04492 #if defined(HAVE_PRI_CALL_HOLD)
04493 case SIG_PRI_MOH_STATE_HOLD_REQ:
04494 str = "SIG_PRI_MOH_STATE_HOLD_REQ";
04495 break;
04496 case SIG_PRI_MOH_STATE_PEND_UNHOLD:
04497 str = "SIG_PRI_MOH_STATE_PEND_UNHOLD";
04498 break;
04499 case SIG_PRI_MOH_STATE_HOLD:
04500 str = "SIG_PRI_MOH_STATE_HOLD";
04501 break;
04502 case SIG_PRI_MOH_STATE_RETRIEVE_REQ:
04503 str = "SIG_PRI_MOH_STATE_RETRIEVE_REQ";
04504 break;
04505 case SIG_PRI_MOH_STATE_PEND_HOLD:
04506 str = "SIG_PRI_MOH_STATE_PEND_HOLD";
04507 break;
04508 case SIG_PRI_MOH_STATE_RETRIEVE_FAIL:
04509 str = "SIG_PRI_MOH_STATE_RETRIEVE_FAIL";
04510 break;
04511 #endif
04512 case SIG_PRI_MOH_STATE_NUM:
04513
04514 break;
04515 }
04516 return str;
04517 }
04518
04519
04520
04521
04522
04523
04524
04525
04526
04527
04528 static const char *sig_pri_moh_event_str(enum sig_pri_moh_event event)
04529 {
04530 const char *str;
04531
04532 str = "Unknown";
04533 switch (event) {
04534 case SIG_PRI_MOH_EVENT_RESET:
04535 str = "SIG_PRI_MOH_EVENT_RESET";
04536 break;
04537 case SIG_PRI_MOH_EVENT_HOLD:
04538 str = "SIG_PRI_MOH_EVENT_HOLD";
04539 break;
04540 case SIG_PRI_MOH_EVENT_UNHOLD:
04541 str = "SIG_PRI_MOH_EVENT_UNHOLD";
04542 break;
04543 #if defined(HAVE_PRI_CALL_HOLD)
04544 case SIG_PRI_MOH_EVENT_HOLD_ACK:
04545 str = "SIG_PRI_MOH_EVENT_HOLD_ACK";
04546 break;
04547 case SIG_PRI_MOH_EVENT_HOLD_REJ:
04548 str = "SIG_PRI_MOH_EVENT_HOLD_REJ";
04549 break;
04550 case SIG_PRI_MOH_EVENT_RETRIEVE_ACK:
04551 str = "SIG_PRI_MOH_EVENT_RETRIEVE_ACK";
04552 break;
04553 case SIG_PRI_MOH_EVENT_RETRIEVE_REJ:
04554 str = "SIG_PRI_MOH_EVENT_RETRIEVE_REJ";
04555 break;
04556 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
04557 str = "SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK";
04558 break;
04559 #endif
04560 case SIG_PRI_MOH_EVENT_NUM:
04561
04562 break;
04563 }
04564 return str;
04565 }
04566
04567 #if defined(HAVE_PRI_CALL_HOLD)
04568
04569
04570
04571
04572
04573
04574
04575
04576
04577
04578
04579
04580 static enum sig_pri_moh_state sig_pri_moh_retrieve_call(struct sig_pri_chan *pvt)
04581 {
04582 int chanpos;
04583 int channel;
04584
04585 if (pvt->pri->nodetype == PRI_NETWORK) {
04586
04587 chanpos = pri_find_empty_chan(pvt->pri, 1);
04588 if (chanpos < 0) {
04589
04590 return SIG_PRI_MOH_STATE_RETRIEVE_FAIL;
04591 }
04592 channel = PVT_TO_CHANNEL(pvt->pri->pvts[chanpos]);
04593
04594
04595
04596
04597
04598 } else {
04599
04600 channel = 0;
04601 }
04602
04603 if (pri_retrieve(pvt->pri->pri, pvt->call, channel)) {
04604 return SIG_PRI_MOH_STATE_RETRIEVE_FAIL;
04605 }
04606 return SIG_PRI_MOH_STATE_RETRIEVE_REQ;
04607 }
04608 #endif
04609
04610
04611
04612
04613
04614
04615
04616
04617
04618
04619
04620
04621
04622
04623
04624 static enum sig_pri_moh_state sig_pri_moh_fsm_idle(struct ast_channel *chan, struct sig_pri_chan *pvt, enum sig_pri_moh_event event)
04625 {
04626 enum sig_pri_moh_state next_state;
04627
04628 next_state = pvt->moh_state;
04629 switch (event) {
04630 case SIG_PRI_MOH_EVENT_HOLD:
04631 if (!strcasecmp(pvt->mohinterpret, "passthrough")) {
04632
04633
04634
04635
04636 pri_notify(pvt->pri->pri, pvt->call, pvt->prioffset, PRI_NOTIFY_REMOTE_HOLD);
04637 next_state = SIG_PRI_MOH_STATE_NOTIFY;
04638 break;
04639 }
04640
04641 switch (pvt->pri->moh_signaling) {
04642 default:
04643 case SIG_PRI_MOH_SIGNALING_MOH:
04644 ast_moh_start(chan, pvt->moh_suggested, pvt->mohinterpret);
04645 next_state = SIG_PRI_MOH_STATE_MOH;
04646 break;
04647 case SIG_PRI_MOH_SIGNALING_NOTIFY:
04648
04649 ast_moh_start(chan, pvt->moh_suggested, pvt->mohinterpret);
04650
04651 pri_notify(pvt->pri->pri, pvt->call, pvt->prioffset, PRI_NOTIFY_REMOTE_HOLD);
04652 next_state = SIG_PRI_MOH_STATE_NOTIFY;
04653 break;
04654 #if defined(HAVE_PRI_CALL_HOLD)
04655 case SIG_PRI_MOH_SIGNALING_HOLD:
04656 if (pri_hold(pvt->pri->pri, pvt->call)) {
04657
04658 ast_moh_start(chan, pvt->moh_suggested, pvt->mohinterpret);
04659 next_state = SIG_PRI_MOH_STATE_MOH;
04660 } else {
04661 next_state = SIG_PRI_MOH_STATE_HOLD_REQ;
04662 }
04663 break;
04664 #endif
04665 }
04666 break;
04667 default:
04668 break;
04669 }
04670 pvt->moh_state = next_state;
04671 return next_state;
04672 }
04673
04674
04675
04676
04677
04678
04679
04680
04681
04682
04683
04684
04685
04686
04687
04688 static enum sig_pri_moh_state sig_pri_moh_fsm_notify(struct ast_channel *chan, struct sig_pri_chan *pvt, enum sig_pri_moh_event event)
04689 {
04690 enum sig_pri_moh_state next_state;
04691
04692 next_state = pvt->moh_state;
04693 switch (event) {
04694 case SIG_PRI_MOH_EVENT_UNHOLD:
04695 pri_notify(pvt->pri->pri, pvt->call, pvt->prioffset, PRI_NOTIFY_REMOTE_RETRIEVAL);
04696
04697 case SIG_PRI_MOH_EVENT_RESET:
04698 ast_moh_stop(chan);
04699 next_state = SIG_PRI_MOH_STATE_IDLE;
04700 break;
04701 default:
04702 break;
04703 }
04704 pvt->moh_state = next_state;
04705 return next_state;
04706 }
04707
04708
04709
04710
04711
04712
04713
04714
04715
04716
04717
04718
04719
04720
04721
04722 static enum sig_pri_moh_state sig_pri_moh_fsm_moh(struct ast_channel *chan, struct sig_pri_chan *pvt, enum sig_pri_moh_event event)
04723 {
04724 enum sig_pri_moh_state next_state;
04725
04726 next_state = pvt->moh_state;
04727 switch (event) {
04728 case SIG_PRI_MOH_EVENT_RESET:
04729 case SIG_PRI_MOH_EVENT_UNHOLD:
04730 ast_moh_stop(chan);
04731 next_state = SIG_PRI_MOH_STATE_IDLE;
04732 break;
04733 default:
04734 break;
04735 }
04736 pvt->moh_state = next_state;
04737 return next_state;
04738 }
04739
04740 #if defined(HAVE_PRI_CALL_HOLD)
04741
04742
04743
04744
04745
04746
04747
04748
04749
04750
04751
04752
04753
04754
04755 static enum sig_pri_moh_state sig_pri_moh_fsm_hold_req(struct ast_channel *chan, struct sig_pri_chan *pvt, enum sig_pri_moh_event event)
04756 {
04757 enum sig_pri_moh_state next_state;
04758
04759 next_state = pvt->moh_state;
04760 switch (event) {
04761 case SIG_PRI_MOH_EVENT_RESET:
04762 next_state = SIG_PRI_MOH_STATE_IDLE;
04763 break;
04764 case SIG_PRI_MOH_EVENT_UNHOLD:
04765 next_state = SIG_PRI_MOH_STATE_PEND_UNHOLD;
04766 break;
04767 case SIG_PRI_MOH_EVENT_HOLD_REJ:
04768
04769 if (chan) {
04770 ast_moh_start(chan, pvt->moh_suggested, pvt->mohinterpret);
04771 }
04772 next_state = SIG_PRI_MOH_STATE_MOH;
04773 break;
04774 case SIG_PRI_MOH_EVENT_HOLD_ACK:
04775 next_state = SIG_PRI_MOH_STATE_HOLD;
04776 break;
04777 default:
04778 break;
04779 }
04780 pvt->moh_state = next_state;
04781 return next_state;
04782 }
04783 #endif
04784
04785 #if defined(HAVE_PRI_CALL_HOLD)
04786
04787
04788
04789
04790
04791
04792
04793
04794
04795
04796
04797
04798
04799
04800 static enum sig_pri_moh_state sig_pri_moh_fsm_pend_unhold(struct ast_channel *chan, struct sig_pri_chan *pvt, enum sig_pri_moh_event event)
04801 {
04802 enum sig_pri_moh_state next_state;
04803
04804 next_state = pvt->moh_state;
04805 switch (event) {
04806 case SIG_PRI_MOH_EVENT_RESET:
04807 next_state = SIG_PRI_MOH_STATE_IDLE;
04808 break;
04809 case SIG_PRI_MOH_EVENT_HOLD:
04810 next_state = SIG_PRI_MOH_STATE_HOLD_REQ;
04811 break;
04812 case SIG_PRI_MOH_EVENT_HOLD_REJ:
04813 next_state = SIG_PRI_MOH_STATE_IDLE;
04814 break;
04815 case SIG_PRI_MOH_EVENT_HOLD_ACK:
04816 next_state = sig_pri_moh_retrieve_call(pvt);
04817 break;
04818 default:
04819 break;
04820 }
04821 pvt->moh_state = next_state;
04822 return next_state;
04823 }
04824 #endif
04825
04826 #if defined(HAVE_PRI_CALL_HOLD)
04827
04828
04829
04830
04831
04832
04833
04834
04835
04836
04837
04838
04839
04840
04841 static enum sig_pri_moh_state sig_pri_moh_fsm_hold(struct ast_channel *chan, struct sig_pri_chan *pvt, enum sig_pri_moh_event event)
04842 {
04843 enum sig_pri_moh_state next_state;
04844
04845 next_state = pvt->moh_state;
04846 switch (event) {
04847 case SIG_PRI_MOH_EVENT_RESET:
04848 next_state = SIG_PRI_MOH_STATE_IDLE;
04849 break;
04850 case SIG_PRI_MOH_EVENT_UNHOLD:
04851 next_state = sig_pri_moh_retrieve_call(pvt);
04852 break;
04853 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
04854
04855 if (chan) {
04856 ast_moh_start(chan, pvt->moh_suggested, pvt->mohinterpret);
04857 }
04858 next_state = SIG_PRI_MOH_STATE_MOH;
04859 break;
04860 default:
04861 break;
04862 }
04863 pvt->moh_state = next_state;
04864 return next_state;
04865 }
04866 #endif
04867
04868 #if defined(HAVE_PRI_CALL_HOLD)
04869
04870
04871
04872
04873
04874
04875
04876
04877
04878
04879
04880
04881
04882
04883 static enum sig_pri_moh_state sig_pri_moh_fsm_retrieve_req(struct ast_channel *chan, struct sig_pri_chan *pvt, enum sig_pri_moh_event event)
04884 {
04885 enum sig_pri_moh_state next_state;
04886
04887 next_state = pvt->moh_state;
04888 switch (event) {
04889 case SIG_PRI_MOH_EVENT_RESET:
04890 next_state = SIG_PRI_MOH_STATE_IDLE;
04891 break;
04892 case SIG_PRI_MOH_EVENT_HOLD:
04893 next_state = SIG_PRI_MOH_STATE_PEND_HOLD;
04894 break;
04895 case SIG_PRI_MOH_EVENT_RETRIEVE_ACK:
04896 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
04897 next_state = SIG_PRI_MOH_STATE_IDLE;
04898 break;
04899 case SIG_PRI_MOH_EVENT_RETRIEVE_REJ:
04900 next_state = SIG_PRI_MOH_STATE_RETRIEVE_FAIL;
04901 break;
04902 default:
04903 break;
04904 }
04905 pvt->moh_state = next_state;
04906 return next_state;
04907 }
04908 #endif
04909
04910 #if defined(HAVE_PRI_CALL_HOLD)
04911
04912
04913
04914
04915
04916
04917
04918
04919
04920
04921
04922
04923
04924
04925 static enum sig_pri_moh_state sig_pri_moh_fsm_pend_hold(struct ast_channel *chan, struct sig_pri_chan *pvt, enum sig_pri_moh_event event)
04926 {
04927 enum sig_pri_moh_state next_state;
04928
04929 next_state = pvt->moh_state;
04930 switch (event) {
04931 case SIG_PRI_MOH_EVENT_RESET:
04932 next_state = SIG_PRI_MOH_STATE_IDLE;
04933 break;
04934 case SIG_PRI_MOH_EVENT_UNHOLD:
04935 next_state = SIG_PRI_MOH_STATE_RETRIEVE_REQ;
04936 break;
04937 case SIG_PRI_MOH_EVENT_RETRIEVE_ACK:
04938 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
04939
04940
04941
04942
04943 switch (pvt->pri->moh_signaling) {
04944 default:
04945 case SIG_PRI_MOH_SIGNALING_MOH:
04946 if (chan) {
04947 ast_moh_start(chan, pvt->moh_suggested, pvt->mohinterpret);
04948 }
04949 next_state = SIG_PRI_MOH_STATE_MOH;
04950 break;
04951 case SIG_PRI_MOH_SIGNALING_NOTIFY:
04952
04953 if (chan) {
04954 ast_moh_start(chan, pvt->moh_suggested, pvt->mohinterpret);
04955 }
04956
04957 pri_notify(pvt->pri->pri, pvt->call, pvt->prioffset, PRI_NOTIFY_REMOTE_HOLD);
04958 next_state = SIG_PRI_MOH_STATE_NOTIFY;
04959 break;
04960 case SIG_PRI_MOH_SIGNALING_HOLD:
04961 if (pri_hold(pvt->pri->pri, pvt->call)) {
04962
04963 if (chan) {
04964 ast_moh_start(chan, pvt->moh_suggested, pvt->mohinterpret);
04965 }
04966 next_state = SIG_PRI_MOH_STATE_MOH;
04967 } else {
04968 next_state = SIG_PRI_MOH_STATE_HOLD_REQ;
04969 }
04970 break;
04971 }
04972 break;
04973 case SIG_PRI_MOH_EVENT_RETRIEVE_REJ:
04974
04975
04976
04977
04978 next_state = SIG_PRI_MOH_STATE_HOLD;
04979 break;
04980 default:
04981 break;
04982 }
04983 pvt->moh_state = next_state;
04984 return next_state;
04985 }
04986 #endif
04987
04988 #if defined(HAVE_PRI_CALL_HOLD)
04989
04990
04991
04992
04993
04994
04995
04996
04997
04998
04999
05000
05001
05002
05003 static enum sig_pri_moh_state sig_pri_moh_fsm_retrieve_fail(struct ast_channel *chan, struct sig_pri_chan *pvt, enum sig_pri_moh_event event)
05004 {
05005 enum sig_pri_moh_state next_state;
05006
05007 next_state = pvt->moh_state;
05008 switch (event) {
05009 case SIG_PRI_MOH_EVENT_RESET:
05010 next_state = SIG_PRI_MOH_STATE_IDLE;
05011 break;
05012 case SIG_PRI_MOH_EVENT_HOLD:
05013 next_state = SIG_PRI_MOH_STATE_HOLD;
05014 break;
05015 case SIG_PRI_MOH_EVENT_UNHOLD:
05016 next_state = sig_pri_moh_retrieve_call(pvt);
05017 break;
05018 case SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK:
05019 next_state = SIG_PRI_MOH_STATE_IDLE;
05020 break;
05021 default:
05022 break;
05023 }
05024 pvt->moh_state = next_state;
05025 return next_state;
05026 }
05027 #endif
05028
05029
05030
05031
05032
05033
05034
05035
05036
05037
05038
05039
05040
05041
05042
05043 typedef enum sig_pri_moh_state (*sig_pri_moh_fsm_state)(struct ast_channel *chan, struct sig_pri_chan *pvt, enum sig_pri_moh_event event);
05044
05045
05046 static const sig_pri_moh_fsm_state sig_pri_moh_fsm[SIG_PRI_MOH_STATE_NUM] = {
05047
05048 [SIG_PRI_MOH_STATE_IDLE] = sig_pri_moh_fsm_idle,
05049 [SIG_PRI_MOH_STATE_NOTIFY] = sig_pri_moh_fsm_notify,
05050 [SIG_PRI_MOH_STATE_MOH] = sig_pri_moh_fsm_moh,
05051 #if defined(HAVE_PRI_CALL_HOLD)
05052 [SIG_PRI_MOH_STATE_HOLD_REQ] = sig_pri_moh_fsm_hold_req,
05053 [SIG_PRI_MOH_STATE_PEND_UNHOLD] = sig_pri_moh_fsm_pend_unhold,
05054 [SIG_PRI_MOH_STATE_HOLD] = sig_pri_moh_fsm_hold,
05055 [SIG_PRI_MOH_STATE_RETRIEVE_REQ] = sig_pri_moh_fsm_retrieve_req,
05056 [SIG_PRI_MOH_STATE_PEND_HOLD] = sig_pri_moh_fsm_pend_hold,
05057 [SIG_PRI_MOH_STATE_RETRIEVE_FAIL] = sig_pri_moh_fsm_retrieve_fail,
05058 #endif
05059
05060 };
05061
05062
05063
05064
05065
05066
05067
05068
05069
05070
05071
05072
05073
05074
05075
05076 static void sig_pri_moh_fsm_event(struct ast_channel *chan, struct sig_pri_chan *pvt, enum sig_pri_moh_event event)
05077 {
05078 enum sig_pri_moh_state orig_state;
05079 enum sig_pri_moh_state next_state;
05080 const char *chan_name;
05081
05082 if (chan) {
05083 chan_name = ast_strdupa(ast_channel_name(chan));
05084 } else {
05085 chan_name = "Unknown";
05086 }
05087 orig_state = pvt->moh_state;
05088 ast_debug(2, "Channel '%s' MOH-Event: %s in state %s\n", chan_name,
05089 sig_pri_moh_event_str(event), sig_pri_moh_state_str(orig_state));
05090 if (orig_state < SIG_PRI_MOH_STATE_IDLE || SIG_PRI_MOH_STATE_NUM <= orig_state
05091 || !sig_pri_moh_fsm[orig_state]) {
05092
05093 ast_log(LOG_ERROR, "MOH state not implemented: %s(%d)\n",
05094 sig_pri_moh_state_str(orig_state), orig_state);
05095 return;
05096 }
05097
05098 next_state = sig_pri_moh_fsm[orig_state](chan, pvt, event);
05099 ast_debug(2, "Channel '%s' MOH-Next-State: %s\n", chan_name,
05100 (orig_state == next_state) ? "$" : sig_pri_moh_state_str(next_state));
05101 }
05102
05103 #if defined(HAVE_PRI_CALL_HOLD)
05104
05105
05106
05107
05108
05109
05110
05111
05112
05113
05114 static void sig_pri_ami_hold_event(struct ast_channel *chan, int is_held)
05115 {
05116 ast_manager_event(chan, EVENT_FLAG_CALL, "Hold",
05117 "Status: %s\r\n"
05118 "Channel: %s\r\n"
05119 "Uniqueid: %s\r\n",
05120 is_held ? "On" : "Off",
05121 ast_channel_name(chan),
05122 ast_channel_uniqueid(chan));
05123 }
05124 #endif
05125
05126 #if defined(HAVE_PRI_CALL_HOLD)
05127
05128
05129
05130
05131
05132
05133
05134
05135
05136
05137
05138
05139
05140 static int sig_pri_handle_hold(struct sig_pri_span *pri, pri_event *ev)
05141 {
05142 int retval;
05143 int chanpos_old;
05144 int chanpos_new;
05145 struct ast_channel *owner;
05146
05147 chanpos_old = pri_find_principle_by_call(pri, ev->hold.call);
05148 if (chanpos_old < 0) {
05149 ast_log(LOG_WARNING, "Span %d: Received HOLD for unknown call.\n", pri->span);
05150 return -1;
05151 }
05152 if (pri->pvts[chanpos_old]->no_b_channel) {
05153
05154 return -1;
05155 }
05156
05157 chanpos_new = -1;
05158
05159 sig_pri_lock_private(pri->pvts[chanpos_old]);
05160 sig_pri_lock_owner(pri, chanpos_old);
05161 owner = pri->pvts[chanpos_old]->owner;
05162 if (!owner) {
05163 goto done_with_private;
05164 }
05165 if (pri->pvts[chanpos_old]->call_level != SIG_PRI_CALL_LEVEL_CONNECT) {
05166
05167
05168
05169
05170 goto done_with_owner;
05171 }
05172 chanpos_new = pri_find_empty_nobch(pri);
05173 if (chanpos_new < 0) {
05174
05175 goto done_with_owner;
05176 }
05177 sig_pri_handle_subcmds(pri, chanpos_old, ev->e, ev->hold.subcmds, ev->hold.call);
05178 pri_queue_control(pri, chanpos_old, AST_CONTROL_HOLD);
05179 chanpos_new = pri_fixup_principle(pri, chanpos_new, ev->hold.call);
05180 if (chanpos_new < 0) {
05181
05182 pri_queue_control(pri, chanpos_old, AST_CONTROL_UNHOLD);
05183 } else {
05184 sig_pri_ami_hold_event(owner, 1);
05185 }
05186
05187 done_with_owner:;
05188 ast_channel_unlock(owner);
05189 done_with_private:;
05190 sig_pri_unlock_private(pri->pvts[chanpos_old]);
05191
05192 if (chanpos_new < 0) {
05193 retval = -1;
05194 } else {
05195 sig_pri_span_devstate_changed(pri);
05196 retval = 0;
05197 }
05198
05199 return retval;
05200 }
05201 #endif
05202
05203 #if defined(HAVE_PRI_CALL_HOLD)
05204
05205
05206
05207
05208
05209
05210
05211
05212
05213
05214
05215
05216 static void sig_pri_handle_hold_ack(struct sig_pri_span *pri, pri_event *ev)
05217 {
05218 int chanpos;
05219
05220
05221
05222
05223
05224 chanpos = pri_find_empty_nobch(pri);
05225 if (chanpos < 0) {
05226
05227 ast_log(LOG_ERROR,
05228 "Span %d: No hold channel available for held call that is on %d/%d\n",
05229 pri->span, PRI_SPAN(ev->hold_ack.channel), PRI_CHANNEL(ev->hold_ack.channel));
05230 sig_pri_kill_call(pri, ev->hold_ack.call, PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
05231 return;
05232 }
05233 chanpos = pri_fixup_principle(pri, chanpos, ev->hold_ack.call);
05234 if (chanpos < 0) {
05235
05236 sig_pri_kill_call(pri, ev->hold_ack.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
05237 return;
05238 }
05239
05240 sig_pri_lock_private(pri->pvts[chanpos]);
05241 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->hold_ack.subcmds, ev->hold_ack.call);
05242 sig_pri_moh_fsm_event(pri->pvts[chanpos]->owner, pri->pvts[chanpos],
05243 SIG_PRI_MOH_EVENT_HOLD_ACK);
05244 sig_pri_unlock_private(pri->pvts[chanpos]);
05245 sig_pri_span_devstate_changed(pri);
05246 }
05247 #endif
05248
05249 #if defined(HAVE_PRI_CALL_HOLD)
05250
05251
05252
05253
05254
05255
05256
05257
05258
05259
05260
05261
05262 static void sig_pri_handle_hold_rej(struct sig_pri_span *pri, pri_event *ev)
05263 {
05264 int chanpos;
05265
05266 chanpos = pri_find_principle(pri, ev->hold_rej.channel, ev->hold_rej.call);
05267 if (chanpos < 0) {
05268 ast_log(LOG_WARNING, "Span %d: Could not find principle for HOLD_REJECT\n",
05269 pri->span);
05270 sig_pri_kill_call(pri, ev->hold_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
05271 return;
05272 }
05273 chanpos = pri_fixup_principle(pri, chanpos, ev->hold_rej.call);
05274 if (chanpos < 0) {
05275
05276 sig_pri_kill_call(pri, ev->hold_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
05277 return;
05278 }
05279
05280 ast_debug(1, "Span %d: HOLD_REJECT cause: %d(%s)\n", pri->span,
05281 ev->hold_rej.cause, pri_cause2str(ev->hold_rej.cause));
05282
05283 sig_pri_lock_private(pri->pvts[chanpos]);
05284 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->hold_rej.subcmds, ev->hold_rej.call);
05285 sig_pri_moh_fsm_event(pri->pvts[chanpos]->owner, pri->pvts[chanpos],
05286 SIG_PRI_MOH_EVENT_HOLD_REJ);
05287 sig_pri_unlock_private(pri->pvts[chanpos]);
05288 }
05289 #endif
05290
05291 #if defined(HAVE_PRI_CALL_HOLD)
05292
05293
05294
05295
05296
05297
05298
05299
05300
05301
05302
05303
05304 static void sig_pri_handle_retrieve(struct sig_pri_span *pri, pri_event *ev)
05305 {
05306 int chanpos;
05307
05308 if (!(ev->retrieve.channel & PRI_HELD_CALL)) {
05309
05310 pri_retrieve_rej(pri->pri, ev->retrieve.call,
05311 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
05312 return;
05313 }
05314 if (pri_find_principle_by_call(pri, ev->retrieve.call) < 0) {
05315 ast_log(LOG_WARNING, "Span %d: Received RETRIEVE for unknown call.\n", pri->span);
05316 pri_retrieve_rej(pri->pri, ev->retrieve.call,
05317 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
05318 return;
05319 }
05320 if (PRI_CHANNEL(ev->retrieve.channel) == 0xFF) {
05321 chanpos = pri_find_empty_chan(pri, 1);
05322 } else {
05323 chanpos = pri_find_principle(pri,
05324 ev->retrieve.channel & ~PRI_HELD_CALL, ev->retrieve.call);
05325 if (ev->retrieve.flexible
05326 && (chanpos < 0 || !sig_pri_is_chan_available(pri->pvts[chanpos]))) {
05327
05328
05329
05330
05331 chanpos = pri_find_empty_chan(pri, 1);
05332 }
05333 }
05334 if (chanpos < 0) {
05335 pri_retrieve_rej(pri->pri, ev->retrieve.call,
05336 ev->retrieve.flexible ? PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION
05337 : PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
05338 return;
05339 }
05340 chanpos = pri_fixup_principle(pri, chanpos, ev->retrieve.call);
05341 if (chanpos < 0) {
05342
05343 pri_retrieve_rej(pri->pri, ev->retrieve.call,
05344 PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
05345 return;
05346 }
05347 sig_pri_lock_private(pri->pvts[chanpos]);
05348 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve.subcmds, ev->retrieve.call);
05349 sig_pri_lock_owner(pri, chanpos);
05350 pri_queue_control(pri, chanpos, AST_CONTROL_UNHOLD);
05351 if (pri->pvts[chanpos]->owner) {
05352 sig_pri_ami_hold_event(pri->pvts[chanpos]->owner, 0);
05353 ast_channel_unlock(pri->pvts[chanpos]->owner);
05354 }
05355 pri_retrieve_ack(pri->pri, ev->retrieve.call,
05356 PVT_TO_CHANNEL(pri->pvts[chanpos]));
05357 sig_pri_moh_fsm_event(pri->pvts[chanpos]->owner, pri->pvts[chanpos],
05358 SIG_PRI_MOH_EVENT_REMOTE_RETRIEVE_ACK);
05359 sig_pri_unlock_private(pri->pvts[chanpos]);
05360 sig_pri_span_devstate_changed(pri);
05361 }
05362 #endif
05363
05364 #if defined(HAVE_PRI_CALL_HOLD)
05365
05366
05367
05368
05369
05370
05371
05372
05373
05374
05375
05376
05377 static void sig_pri_handle_retrieve_ack(struct sig_pri_span *pri, pri_event *ev)
05378 {
05379 int chanpos;
05380
05381 chanpos = pri_find_fixup_principle(pri, ev->retrieve_ack.channel,
05382 ev->retrieve_ack.call);
05383 if (chanpos < 0) {
05384 return;
05385 }
05386
05387 sig_pri_lock_private(pri->pvts[chanpos]);
05388 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve_ack.subcmds,
05389 ev->retrieve_ack.call);
05390 sig_pri_moh_fsm_event(pri->pvts[chanpos]->owner, pri->pvts[chanpos],
05391 SIG_PRI_MOH_EVENT_RETRIEVE_ACK);
05392 sig_pri_unlock_private(pri->pvts[chanpos]);
05393 sig_pri_span_devstate_changed(pri);
05394 }
05395 #endif
05396
05397 #if defined(HAVE_PRI_CALL_HOLD)
05398
05399
05400
05401
05402
05403
05404
05405
05406
05407
05408
05409
05410 static void sig_pri_handle_retrieve_rej(struct sig_pri_span *pri, pri_event *ev)
05411 {
05412 int chanpos;
05413
05414 chanpos = pri_find_principle(pri, ev->retrieve_rej.channel, ev->retrieve_rej.call);
05415 if (chanpos < 0) {
05416 ast_log(LOG_WARNING, "Span %d: Could not find principle for RETRIEVE_REJECT\n",
05417 pri->span);
05418 sig_pri_kill_call(pri, ev->retrieve_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
05419 return;
05420 }
05421 chanpos = pri_fixup_principle(pri, chanpos, ev->retrieve_rej.call);
05422 if (chanpos < 0) {
05423
05424 sig_pri_kill_call(pri, ev->retrieve_rej.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
05425 return;
05426 }
05427
05428 ast_debug(1, "Span %d: RETRIEVE_REJECT cause: %d(%s)\n", pri->span,
05429 ev->retrieve_rej.cause, pri_cause2str(ev->retrieve_rej.cause));
05430
05431 sig_pri_lock_private(pri->pvts[chanpos]);
05432 sig_pri_handle_subcmds(pri, chanpos, ev->e, ev->retrieve_rej.subcmds,
05433 ev->retrieve_rej.call);
05434 sig_pri_moh_fsm_event(pri->pvts[chanpos]->owner, pri->pvts[chanpos],
05435 SIG_PRI_MOH_EVENT_RETRIEVE_REJ);
05436 sig_pri_unlock_private(pri->pvts[chanpos]);
05437 }
05438 #endif
05439
05440 static void *pri_dchannel(void *vpri)
05441 {
05442 struct sig_pri_span *pri = vpri;
05443 pri_event *e;
05444 struct pollfd fds[SIG_PRI_NUM_DCHANS];
05445 int res;
05446 int chanpos = 0;
05447 int x;
05448 int law;
05449 struct ast_channel *c;
05450 struct timeval tv, lowest, *next;
05451 int doidling=0;
05452 char *cc;
05453 time_t t;
05454 int i, which=-1;
05455 int numdchans;
05456 pthread_t threadid;
05457 char ani2str[6];
05458 char plancallingnum[AST_MAX_EXTENSION];
05459 char plancallingani[AST_MAX_EXTENSION];
05460 char calledtonstr[10];
05461 struct timeval lastidle = { 0, 0 };
05462 pthread_t p;
05463 struct ast_channel *idle;
05464 char idlen[80];
05465 int nextidle = -1;
05466 int haveidles;
05467 int activeidles;
05468 unsigned int len;
05469
05470 gettimeofday(&lastidle, NULL);
05471 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
05472
05473 if (!ast_strlen_zero(pri->idledial) && !ast_strlen_zero(pri->idleext)) {
05474
05475 cc = strchr(pri->idleext, '@');
05476 if (cc) {
05477 *cc = '\0';
05478 cc++;
05479 ast_copy_string(pri->idlecontext, cc, sizeof(pri->idlecontext));
05480 #if 0
05481
05482 if (!ast_exists_extension(NULL, pri->idlecontext, pri->idleext, 1, NULL))
05483 ast_log(LOG_WARNING, "Extension '%s @ %s' does not exist\n", pri->idleext, pri->idlecontext);
05484 else
05485 #endif
05486 doidling = 1;
05487 } else
05488 ast_log(LOG_WARNING, "Idle dial string '%s' lacks '@context'\n", pri->idleext);
05489 }
05490 for (;;) {
05491 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
05492 if (!pri->dchans[i])
05493 break;
05494 fds[i].fd = pri->fds[i];
05495 fds[i].events = POLLIN | POLLPRI;
05496 fds[i].revents = 0;
05497 }
05498 numdchans = i;
05499 time(&t);
05500 ast_mutex_lock(&pri->lock);
05501 if (pri->switchtype != PRI_SWITCH_GR303_TMC && (pri->sig != SIG_BRI_PTMP) && (pri->resetinterval > 0)) {
05502 if (pri->resetting && pri_is_up(pri)) {
05503 if (pri->resetpos < 0) {
05504 pri_check_restart(pri);
05505 if (pri->resetting) {
05506 sig_pri_span_devstate_changed(pri);
05507 }
05508 }
05509 } else {
05510 if (!pri->resetting && (t - pri->lastreset) >= pri->resetinterval) {
05511 pri->resetting = 1;
05512 pri->resetpos = -1;
05513 }
05514 }
05515 }
05516
05517 if (doidling && pri_is_up(pri)) {
05518 nextidle = -1;
05519 haveidles = 0;
05520 activeidles = 0;
05521 for (x = pri->numchans; x >= 0; x--) {
05522 if (pri->pvts[x] && !pri->pvts[x]->no_b_channel) {
05523 if (sig_pri_is_chan_available(pri->pvts[x])) {
05524 if (haveidles < pri->minunused) {
05525 haveidles++;
05526 } else {
05527 nextidle = x;
05528 break;
05529 }
05530 } else if (pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
05531 activeidles++;
05532 }
05533 }
05534 }
05535 if (nextidle > -1) {
05536 if (ast_tvdiff_ms(ast_tvnow(), lastidle) > 1000) {
05537
05538 snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
05539 pri->pvts[nextidle]->allocated = 1;
05540
05541
05542
05543
05544 ast_mutex_unlock(&pri->lock);
05545
05546
05547
05548
05549
05550 sig_pri_lock_private(pri->pvts[nextidle]);
05551 sig_pri_unlock_private(pri->pvts[nextidle]);
05552 idle = sig_pri_request(pri->pvts[nextidle], AST_FORMAT_ULAW, NULL, 0);
05553 ast_mutex_lock(&pri->lock);
05554 if (idle) {
05555 pri->pvts[nextidle]->isidlecall = 1;
05556 if (ast_pthread_create_background(&p, NULL, do_idle_thread, pri->pvts[nextidle])) {
05557 ast_log(LOG_WARNING, "Unable to start new thread for idle channel '%s'\n", ast_channel_name(idle));
05558 ast_mutex_unlock(&pri->lock);
05559 ast_hangup(idle);
05560 ast_mutex_lock(&pri->lock);
05561 }
05562 } else {
05563 pri->pvts[nextidle]->allocated = 0;
05564 ast_log(LOG_WARNING, "Unable to request channel 'DAHDI/%s' for idle call\n", idlen);
05565 }
05566 gettimeofday(&lastidle, NULL);
05567 }
05568 } else if ((haveidles < pri->minunused) &&
05569 (activeidles > pri->minidle)) {
05570
05571
05572 for (x = pri->numchans; x >= 0; x--) {
05573
05574 if (pri->pvts[x] && pri->pvts[x]->owner && pri->pvts[x]->isidlecall) {
05575 ast_channel_softhangup_internal_flag_add(pri->pvts[x]->owner, AST_SOFTHANGUP_DEV);
05576 haveidles++;
05577
05578
05579 if ((haveidles >= pri->minunused) ||
05580 (activeidles <= pri->minidle))
05581 break;
05582 }
05583 }
05584 }
05585 }
05586
05587 if (doidling || pri->resetting) {
05588
05589
05590
05591
05592 lowest = ast_tv(1, 0);
05593 } else {
05594
05595 lowest = ast_tv(60, 0);
05596 }
05597 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
05598 if (!pri->dchans[i]) {
05599
05600 break;
05601 }
05602 next = pri_schedule_next(pri->dchans[i]);
05603 if (next) {
05604
05605 tv = ast_tvsub(*next, ast_tvnow());
05606 if (tv.tv_sec < 0) {
05607
05608
05609
05610
05611 lowest = ast_tv(0, 0);
05612 break;
05613 }
05614 if (ast_tvcmp(tv, lowest) < 0) {
05615 lowest = tv;
05616 }
05617 }
05618 }
05619 ast_mutex_unlock(&pri->lock);
05620
05621 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
05622 pthread_testcancel();
05623 e = NULL;
05624 res = poll(fds, numdchans, lowest.tv_sec * 1000 + lowest.tv_usec / 1000);
05625 pthread_testcancel();
05626 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
05627
05628 ast_mutex_lock(&pri->lock);
05629 if (!res) {
05630 for (which = 0; which < SIG_PRI_NUM_DCHANS; which++) {
05631 if (!pri->dchans[which])
05632 break;
05633
05634 e = pri_schedule_run(pri->dchans[which]);
05635 if (e)
05636 break;
05637 }
05638 } else if (res > -1) {
05639 for (which = 0; which < SIG_PRI_NUM_DCHANS; which++) {
05640 if (!pri->dchans[which])
05641 break;
05642 if (fds[which].revents & POLLPRI) {
05643 sig_pri_handle_dchan_exception(pri, which);
05644 } else if (fds[which].revents & POLLIN) {
05645 e = pri_check_event(pri->dchans[which]);
05646 }
05647 if (e)
05648 break;
05649 }
05650 } else if (errno != EINTR)
05651 ast_log(LOG_WARNING, "pri_event returned error %d (%s)\n", errno, strerror(errno));
05652
05653 if (e) {
05654 if (pri->debug) {
05655 ast_verbose("Span %d: Processing event %s(%d)\n",
05656 pri->span, pri_event2str(e->e), e->e);
05657 }
05658
05659 if (e->e != PRI_EVENT_DCHAN_DOWN) {
05660 if (!(pri->dchanavail[which] & DCHAN_UP)) {
05661 ast_verb(2, "%s D-Channel on span %d up\n", pri_order(which), pri->span);
05662 }
05663 pri->dchanavail[which] |= DCHAN_UP;
05664 } else {
05665 if (pri->dchanavail[which] & DCHAN_UP) {
05666 ast_verb(2, "%s D-Channel on span %d down\n", pri_order(which), pri->span);
05667 }
05668 pri->dchanavail[which] &= ~DCHAN_UP;
05669 }
05670
05671 if ((e->e != PRI_EVENT_DCHAN_UP) && (e->e != PRI_EVENT_DCHAN_DOWN) && (pri->pri != pri->dchans[which]))
05672
05673 pri->pri = pri->dchans[which];
05674
05675 switch (e->e) {
05676 case PRI_EVENT_DCHAN_UP:
05677 pri->no_d_channels = 0;
05678 if (!pri->pri) {
05679 pri_find_dchan(pri);
05680 }
05681
05682
05683 time(&pri->lastreset);
05684
05685
05686 if (pri->resetinterval > -1) {
05687 pri->lastreset -= pri->resetinterval;
05688 pri->lastreset += 5;
05689 }
05690
05691 pri->resetting = 0;
05692 for (i = 0; i < pri->numchans; i++) {
05693 if (pri->pvts[i]) {
05694 sig_pri_set_alarm(pri->pvts[i], 0);
05695 }
05696 }
05697 sig_pri_span_devstate_changed(pri);
05698 break;
05699 case PRI_EVENT_DCHAN_DOWN:
05700 pri_find_dchan(pri);
05701 if (!pri_is_up(pri)) {
05702 if (pri->sig == SIG_BRI_PTMP) {
05703
05704
05705
05706
05707 break;
05708 }
05709
05710 pri->resetting = 0;
05711 for (i = 0; i < pri->numchans; i++) {
05712 struct sig_pri_chan *p = pri->pvts[i];
05713
05714 if (p) {
05715 if (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
05716
05717 if (p->call) {
05718 pri_destroycall(p->pri->pri, p->call);
05719 p->call = NULL;
05720 }
05721 if (p->owner)
05722 ast_channel_softhangup_internal_flag_add(p->owner, AST_SOFTHANGUP_DEV);
05723 }
05724 sig_pri_set_alarm(p, 1);
05725 }
05726 }
05727 sig_pri_span_devstate_changed(pri);
05728 }
05729 break;
05730 case PRI_EVENT_RESTART:
05731 if (e->restart.channel > -1 && PRI_CHANNEL(e->restart.channel) != 0xFF) {
05732 chanpos = pri_find_principle(pri, e->restart.channel, NULL);
05733 if (chanpos < 0)
05734 ast_log(LOG_WARNING,
05735 "Span %d: Restart requested on odd/unavailable channel number %d/%d\n",
05736 pri->span, PRI_SPAN(e->restart.channel),
05737 PRI_CHANNEL(e->restart.channel));
05738 else {
05739 int skipit = 0;
05740 #if defined(HAVE_PRI_SERVICE_MESSAGES)
05741 unsigned why;
05742
05743 why = pri->pvts[chanpos]->service_status;
05744 if (why) {
05745 ast_log(LOG_NOTICE,
05746 "Span %d: Channel %d/%d out-of-service (reason: %s), ignoring RESTART\n",
05747 pri->span, PRI_SPAN(e->restart.channel),
05748 PRI_CHANNEL(e->restart.channel),
05749 (why & SRVST_FAREND) ? (why & SRVST_NEAREND) ? "both ends" : "far end" : "near end");
05750 skipit = 1;
05751 }
05752 #endif
05753 sig_pri_lock_private(pri->pvts[chanpos]);
05754 if (!skipit) {
05755 ast_verb(3, "Span %d: Channel %d/%d restarted\n", pri->span,
05756 PRI_SPAN(e->restart.channel),
05757 PRI_CHANNEL(e->restart.channel));
05758 if (pri->pvts[chanpos]->call) {
05759 pri_destroycall(pri->pri, pri->pvts[chanpos]->call);
05760 pri->pvts[chanpos]->call = NULL;
05761 }
05762 }
05763
05764 if (pri->pvts[chanpos]->owner)
05765 ast_channel_softhangup_internal_flag_add(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
05766 sig_pri_unlock_private(pri->pvts[chanpos]);
05767 }
05768 } else {
05769 ast_verb(3, "Restart requested on entire span %d\n", pri->span);
05770 for (x = 0; x < pri->numchans; x++)
05771 if (pri->pvts[x]) {
05772 sig_pri_lock_private(pri->pvts[x]);
05773 if (pri->pvts[x]->call) {
05774 pri_destroycall(pri->pri, pri->pvts[x]->call);
05775 pri->pvts[x]->call = NULL;
05776 }
05777 if (pri->pvts[x]->owner)
05778 ast_channel_softhangup_internal_flag_add(pri->pvts[x]->owner, AST_SOFTHANGUP_DEV);
05779 sig_pri_unlock_private(pri->pvts[x]);
05780 }
05781 }
05782 sig_pri_span_devstate_changed(pri);
05783 break;
05784 case PRI_EVENT_KEYPAD_DIGIT:
05785 if (sig_pri_is_cis_call(e->digit.channel)) {
05786 sig_pri_handle_cis_subcmds(pri, e->e, e->digit.subcmds,
05787 e->digit.call);
05788 break;
05789 }
05790 chanpos = pri_find_principle_by_call(pri, e->digit.call);
05791 if (chanpos < 0) {
05792 ast_log(LOG_WARNING,
05793 "Span %d: Received keypad digits for unknown call.\n", pri->span);
05794 break;
05795 }
05796 sig_pri_lock_private(pri->pvts[chanpos]);
05797 sig_pri_handle_subcmds(pri, chanpos, e->e, e->digit.subcmds,
05798 e->digit.call);
05799
05800 if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
05801 && pri->pvts[chanpos]->owner) {
05802
05803 int digitlen = strlen(e->digit.digits);
05804 int i;
05805
05806 for (i = 0; i < digitlen; i++) {
05807 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = e->digit.digits[i], };
05808
05809 pri_queue_frame(pri, chanpos, &f);
05810 }
05811 }
05812 sig_pri_unlock_private(pri->pvts[chanpos]);
05813 break;
05814
05815 case PRI_EVENT_INFO_RECEIVED:
05816 if (sig_pri_is_cis_call(e->ring.channel)) {
05817 sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds,
05818 e->ring.call);
05819 break;
05820 }
05821 chanpos = pri_find_principle_by_call(pri, e->ring.call);
05822 if (chanpos < 0) {
05823 ast_log(LOG_WARNING,
05824 "Span %d: Received INFORMATION for unknown call.\n", pri->span);
05825 break;
05826 }
05827 sig_pri_lock_private(pri->pvts[chanpos]);
05828 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.subcmds, e->ring.call);
05829
05830 if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
05831 && pri->pvts[chanpos]->owner) {
05832
05833 int digitlen = strlen(e->ring.callednum);
05834 int i;
05835
05836 for (i = 0; i < digitlen; i++) {
05837 struct ast_frame f = { AST_FRAME_DTMF, .subclass.integer = e->ring.callednum[i], };
05838
05839 pri_queue_frame(pri, chanpos, &f);
05840 }
05841 }
05842 sig_pri_unlock_private(pri->pvts[chanpos]);
05843 break;
05844 #if defined(HAVE_PRI_SERVICE_MESSAGES)
05845 case PRI_EVENT_SERVICE:
05846 chanpos = pri_find_principle(pri, e->service.channel, NULL);
05847 if (chanpos < 0) {
05848 ast_log(LOG_WARNING, "Received service change status %d on unconfigured channel %d/%d span %d\n",
05849 e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span);
05850 } else {
05851 char db_chan_name[20];
05852 char db_answer[5];
05853 int ch;
05854 unsigned *why;
05855
05856 ch = pri->pvts[chanpos]->channel;
05857 snprintf(db_chan_name, sizeof(db_chan_name), "%s/%d:%d", dahdi_db, pri->span, ch);
05858 why = &pri->pvts[chanpos]->service_status;
05859 switch (e->service.changestatus) {
05860 case 0:
05861
05862 ast_db_del(db_chan_name, SRVST_DBKEY);
05863 *why &= ~SRVST_FAREND;
05864 if (*why) {
05865 snprintf(db_answer, sizeof(db_answer), "%s:%u",
05866 SRVST_TYPE_OOS, *why);
05867 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
05868 } else {
05869 sig_pri_span_devstate_changed(pri);
05870 }
05871 break;
05872 case 2:
05873
05874 ast_db_del(db_chan_name, SRVST_DBKEY);
05875 *why |= SRVST_FAREND;
05876 snprintf(db_answer, sizeof(db_answer), "%s:%u", SRVST_TYPE_OOS,
05877 *why);
05878 ast_db_put(db_chan_name, SRVST_DBKEY, db_answer);
05879 sig_pri_span_devstate_changed(pri);
05880 break;
05881 default:
05882 ast_log(LOG_ERROR, "Huh? changestatus is: %d\n", e->service.changestatus);
05883 break;
05884 }
05885 ast_log(LOG_NOTICE, "Channel %d/%d span %d (logical: %d) received a change of service message, status '%d'\n",
05886 PRI_SPAN(e->service.channel), PRI_CHANNEL(e->service.channel), pri->span, ch, e->service.changestatus);
05887 }
05888 break;
05889 case PRI_EVENT_SERVICE_ACK:
05890 chanpos = pri_find_principle(pri, e->service_ack.channel, NULL);
05891 if (chanpos < 0) {
05892 ast_log(LOG_WARNING, "Received service acknowledge change status '%d' on unconfigured channel %d/%d span %d\n",
05893 e->service_ack.changestatus, PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span);
05894 } else {
05895 ast_debug(2, "Channel %d/%d span %d received a change os service acknowledgement message, status '%d'\n",
05896 PRI_SPAN(e->service_ack.channel), PRI_CHANNEL(e->service_ack.channel), pri->span, e->service_ack.changestatus);
05897 }
05898 break;
05899 #endif
05900 case PRI_EVENT_RING:
05901 if (!ast_strlen_zero(pri->msn_list)
05902 && !sig_pri_msn_match(pri->msn_list, e->ring.callednum)) {
05903
05904 ast_verb(3,
05905 "Ignoring call to '%s' on span %d. Its not in the MSN list: %s\n",
05906 e->ring.callednum, pri->span, pri->msn_list);
05907 pri_destroycall(pri->pri, e->ring.call);
05908 break;
05909 }
05910 if (sig_pri_is_cis_call(e->ring.channel)) {
05911 sig_pri_handle_cis_subcmds(pri, e->e, e->ring.subcmds,
05912 e->ring.call);
05913 break;
05914 }
05915 chanpos = pri_find_principle_by_call(pri, e->ring.call);
05916 if (-1 < chanpos) {
05917
05918 ast_log(LOG_WARNING,
05919 "Span %d: Got SETUP with duplicate call ptr (%p). Dropping call.\n",
05920 pri->span, e->ring.call);
05921 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_TEMPORARY_FAILURE);
05922 break;
05923 }
05924 if (e->ring.channel == -1 || PRI_CHANNEL(e->ring.channel) == 0xFF) {
05925
05926 chanpos = pri_find_empty_chan(pri, 1);
05927 } else if (PRI_CHANNEL(e->ring.channel) == 0x00) {
05928
05929 #if defined(HAVE_PRI_CALL_WAITING)
05930 if (!pri->allow_call_waiting_calls)
05931 #endif
05932 {
05933
05934 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
05935 break;
05936 }
05937 #if defined(HAVE_PRI_CALL_WAITING)
05938 chanpos = pri_find_empty_nobch(pri);
05939 if (chanpos < 0) {
05940
05941 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
05942 break;
05943 }
05944
05945 sig_pri_init_config(pri->pvts[chanpos], pri);
05946 #endif
05947 } else {
05948
05949 chanpos = pri_find_principle(pri, e->ring.channel, e->ring.call);
05950 if (chanpos < 0) {
05951 ast_log(LOG_WARNING,
05952 "Span %d: SETUP on unconfigured channel %d/%d\n",
05953 pri->span, PRI_SPAN(e->ring.channel),
05954 PRI_CHANNEL(e->ring.channel));
05955 } else {
05956 switch (pri->pvts[chanpos]->resetting) {
05957 case SIG_PRI_RESET_IDLE:
05958 break;
05959 case SIG_PRI_RESET_ACTIVE:
05960
05961
05962
05963
05964 pri->pvts[chanpos]->resetting = SIG_PRI_RESET_NO_ACK;
05965 break;
05966 case SIG_PRI_RESET_NO_ACK:
05967
05968 ast_debug(1,
05969 "Span %d: Second SETUP while waiting for RESTART ACKNOWLEDGE on channel %d/%d\n",
05970 pri->span, PRI_SPAN(e->ring.channel),
05971 PRI_CHANNEL(e->ring.channel));
05972
05973
05974 pri->pvts[chanpos]->resetting = SIG_PRI_RESET_IDLE;
05975 if (pri->resetting) {
05976
05977 pri_check_restart(pri);
05978 }
05979 break;
05980 }
05981 if (!sig_pri_is_chan_available(pri->pvts[chanpos])) {
05982
05983 ast_debug(1,
05984 "Span %d: SETUP requested unavailable channel %d/%d. Attempting to renegotiate.\n",
05985 pri->span, PRI_SPAN(e->ring.channel),
05986 PRI_CHANNEL(e->ring.channel));
05987 chanpos = -1;
05988 }
05989 }
05990 #if defined(ALWAYS_PICK_CHANNEL)
05991 if (e->ring.flexible) {
05992 chanpos = -1;
05993 }
05994 #endif
05995 if (chanpos < 0 && e->ring.flexible) {
05996
05997 chanpos = pri_find_empty_chan(pri, 1);
05998 }
05999 }
06000 if (chanpos < 0) {
06001 if (e->ring.flexible) {
06002 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
06003 } else {
06004 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_REQUESTED_CHAN_UNAVAIL);
06005 }
06006 break;
06007 }
06008
06009 sig_pri_lock_private(pri->pvts[chanpos]);
06010
06011
06012 pri->pvts[chanpos]->call = e->ring.call;
06013
06014
06015 apply_plan_to_existing_number(plancallingnum, sizeof(plancallingnum), pri,
06016 e->ring.redirectingnum, e->ring.callingplanrdnis);
06017 sig_pri_set_rdnis(pri->pvts[chanpos], plancallingnum);
06018
06019
06020 apply_plan_to_existing_number(plancallingnum, sizeof(plancallingnum), pri,
06021 e->ring.callingnum, e->ring.callingplan);
06022 pri->pvts[chanpos]->cid_ani2 = 0;
06023 if (pri->pvts[chanpos]->use_callerid) {
06024 ast_shrink_phone_number(plancallingnum);
06025 ast_copy_string(pri->pvts[chanpos]->cid_num, plancallingnum, sizeof(pri->pvts[chanpos]->cid_num));
06026 #ifdef PRI_ANI
06027 apply_plan_to_existing_number(plancallingani, sizeof(plancallingani),
06028 pri, e->ring.callingani, e->ring.callingplanani);
06029 ast_shrink_phone_number(plancallingani);
06030 ast_copy_string(pri->pvts[chanpos]->cid_ani, plancallingani,
06031 sizeof(pri->pvts[chanpos]->cid_ani));
06032 #endif
06033 pri->pvts[chanpos]->cid_subaddr[0] = '\0';
06034 #if defined(HAVE_PRI_SUBADDR)
06035 if (e->ring.calling.subaddress.valid) {
06036 struct ast_party_subaddress calling_subaddress;
06037
06038 ast_party_subaddress_init(&calling_subaddress);
06039 sig_pri_set_subaddress(&calling_subaddress,
06040 &e->ring.calling.subaddress);
06041 if (calling_subaddress.str) {
06042 ast_copy_string(pri->pvts[chanpos]->cid_subaddr,
06043 calling_subaddress.str,
06044 sizeof(pri->pvts[chanpos]->cid_subaddr));
06045 }
06046 ast_party_subaddress_free(&calling_subaddress);
06047 }
06048 #endif
06049 ast_copy_string(pri->pvts[chanpos]->cid_name, e->ring.callingname, sizeof(pri->pvts[chanpos]->cid_name));
06050 pri->pvts[chanpos]->cid_ton = e->ring.callingplan;
06051 pri->pvts[chanpos]->callingpres = e->ring.callingpres;
06052 if (e->ring.ani2 >= 0) {
06053 pri->pvts[chanpos]->cid_ani2 = e->ring.ani2;
06054 }
06055 } else {
06056 pri->pvts[chanpos]->cid_num[0] = '\0';
06057 pri->pvts[chanpos]->cid_subaddr[0] = '\0';
06058 pri->pvts[chanpos]->cid_ani[0] = '\0';
06059 pri->pvts[chanpos]->cid_name[0] = '\0';
06060 pri->pvts[chanpos]->cid_ton = 0;
06061 pri->pvts[chanpos]->callingpres = 0;
06062 }
06063
06064
06065 if (pri->append_msn_to_user_tag) {
06066 snprintf(pri->pvts[chanpos]->user_tag,
06067 sizeof(pri->pvts[chanpos]->user_tag), "%s_%s",
06068 pri->initial_user_tag,
06069 pri->nodetype == PRI_NETWORK
06070 ? plancallingnum : e->ring.callednum);
06071 } else {
06072 ast_copy_string(pri->pvts[chanpos]->user_tag,
06073 pri->initial_user_tag, sizeof(pri->pvts[chanpos]->user_tag));
06074 }
06075
06076 sig_pri_set_caller_id(pri->pvts[chanpos]);
06077
06078
06079 sig_pri_set_dnid(pri->pvts[chanpos], e->ring.callednum);
06080
06081
06082 if (pri->pvts[chanpos]->immediate) {
06083 ast_verb(3, "Going to extension s|1 because of immediate=yes\n");
06084 pri->pvts[chanpos]->exten[0] = 's';
06085 pri->pvts[chanpos]->exten[1] = '\0';
06086 }
06087
06088 else if (!ast_strlen_zero(e->ring.callednum)) {
06089 ast_copy_string(pri->pvts[chanpos]->exten, e->ring.callednum, sizeof(pri->pvts[chanpos]->exten));
06090 } else if (pri->overlapdial)
06091 pri->pvts[chanpos]->exten[0] = '\0';
06092 else {
06093
06094 pri->pvts[chanpos]->exten[0] = 's';
06095 pri->pvts[chanpos]->exten[1] = '\0';
06096 }
06097
06098 if (e->ring.complete && (ast_strlen_zero(e->ring.callednum))) {
06099 ast_verb(3, "Going to extension s|1 because of Complete received\n");
06100 pri->pvts[chanpos]->exten[0] = 's';
06101 pri->pvts[chanpos]->exten[1] = '\0';
06102 }
06103
06104
06105 if (((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) && ast_canmatch_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) ||
06106 ast_exists_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
06107
06108 switch (e->ring.layer1) {
06109 case PRI_LAYER_1_ALAW:
06110 law = SIG_PRI_ALAW;
06111 break;
06112 case PRI_LAYER_1_ULAW:
06113 law = SIG_PRI_ULAW;
06114 break;
06115 default:
06116
06117 law = SIG_PRI_DEFLAW;
06118 break;
06119 }
06120
06121 if (e->ring.complete || !(pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
06122
06123 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING;
06124 pri_proceeding(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 0);
06125 } else if (pri->switchtype == PRI_SWITCH_GR303_TMC) {
06126 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_CONNECT;
06127 pri_answer(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
06128 } else {
06129 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_OVERLAP;
06130 pri_need_more_info(pri->pri, e->ring.call, PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
06131 }
06132
06133
06134 if (!e->ring.complete
06135 && (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)
06136 && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) {
06137
06138
06139
06140
06141
06142
06143 sig_pri_unlock_private(pri->pvts[chanpos]);
06144 ast_mutex_unlock(&pri->lock);
06145 c = sig_pri_new_ast_channel(pri->pvts[chanpos],
06146 AST_STATE_RESERVED, law, e->ring.ctype,
06147 pri->pvts[chanpos]->exten, NULL);
06148 ast_mutex_lock(&pri->lock);
06149 sig_pri_lock_private(pri->pvts[chanpos]);
06150 if (c) {
06151 #if defined(HAVE_PRI_SUBADDR)
06152 if (e->ring.calling.subaddress.valid) {
06153
06154 sig_pri_lock_owner(pri, chanpos);
06155 sig_pri_set_subaddress(
06156 &ast_channel_caller(pri->pvts[chanpos]->owner)->id.subaddress,
06157 &e->ring.calling.subaddress);
06158 if (!e->ring.calling.subaddress.type
06159 && !ast_strlen_zero(
06160 (char *) e->ring.calling.subaddress.data)) {
06161
06162 pbx_builtin_setvar_helper(c, "CALLINGSUBADDR",
06163 (char *) e->ring.calling.subaddress.data);
06164 }
06165 ast_channel_unlock(c);
06166 }
06167 if (e->ring.called_subaddress.valid) {
06168
06169 sig_pri_lock_owner(pri, chanpos);
06170 sig_pri_set_subaddress(
06171 &ast_channel_dialed(pri->pvts[chanpos]->owner)->subaddress,
06172 &e->ring.called_subaddress);
06173 if (!e->ring.called_subaddress.type
06174 && !ast_strlen_zero(
06175 (char *) e->ring.called_subaddress.data)) {
06176
06177 pbx_builtin_setvar_helper(c, "CALLEDSUBADDR",
06178 (char *) e->ring.called_subaddress.data);
06179 }
06180 ast_channel_unlock(c);
06181 }
06182 #else
06183 if (!ast_strlen_zero(e->ring.callingsubaddr)) {
06184 pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
06185 }
06186 #endif
06187 if (e->ring.ani2 >= 0) {
06188 snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2);
06189 pbx_builtin_setvar_helper(c, "ANI2", ani2str);
06190 }
06191
06192 #ifdef SUPPORT_USERUSER
06193 if (!ast_strlen_zero(e->ring.useruserinfo)) {
06194 pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
06195 }
06196 #endif
06197
06198 snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan);
06199 pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
06200 if (e->ring.redirectingreason >= 0) {
06201
06202 pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
06203 }
06204 #if defined(HAVE_PRI_REVERSE_CHARGE)
06205 pri->pvts[chanpos]->reverse_charging_indication = e->ring.reversecharge;
06206 #endif
06207 #if defined(HAVE_PRI_SETUP_KEYPAD)
06208 ast_copy_string(pri->pvts[chanpos]->keypad_digits,
06209 e->ring.keypad_digits,
06210 sizeof(pri->pvts[chanpos]->keypad_digits));
06211 #endif
06212
06213 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.subcmds,
06214 e->ring.call);
06215
06216 if (!pri->pvts[chanpos]->digital
06217 && !pri->pvts[chanpos]->no_b_channel) {
06218
06219
06220
06221
06222 pri->pvts[chanpos]->progress = 1;
06223 #ifdef HAVE_PRI_PROG_W_CAUSE
06224 pri_progress_with_cause(pri->pri, e->ring.call,
06225 PVT_TO_CHANNEL(pri->pvts[chanpos]), 1, -1);
06226 #else
06227 pri_progress(pri->pri, e->ring.call,
06228 PVT_TO_CHANNEL(pri->pvts[chanpos]), 1);
06229 #endif
06230 }
06231 }
06232 if (c && !ast_pthread_create_detached(&threadid, NULL, pri_ss_thread, pri->pvts[chanpos])) {
06233 ast_verb(3, "Accepting overlap call from '%s' to '%s' on channel %d/%d, span %d\n",
06234 plancallingnum, S_OR(pri->pvts[chanpos]->exten, "<unspecified>"),
06235 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
06236 } else {
06237 ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n",
06238 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
06239 if (c) {
06240
06241 sig_pri_unlock_private(pri->pvts[chanpos]);
06242 ast_mutex_unlock(&pri->lock);
06243 ast_hangup(c);
06244 ast_mutex_lock(&pri->lock);
06245 } else {
06246 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
06247 pri->pvts[chanpos]->call = NULL;
06248 sig_pri_unlock_private(pri->pvts[chanpos]);
06249 sig_pri_span_devstate_changed(pri);
06250 }
06251 break;
06252 }
06253 } else {
06254
06255
06256
06257
06258
06259
06260 sig_pri_unlock_private(pri->pvts[chanpos]);
06261 ast_mutex_unlock(&pri->lock);
06262 c = sig_pri_new_ast_channel(pri->pvts[chanpos],
06263 AST_STATE_RING, law, e->ring.ctype,
06264 pri->pvts[chanpos]->exten, NULL);
06265 ast_mutex_lock(&pri->lock);
06266 sig_pri_lock_private(pri->pvts[chanpos]);
06267 if (c) {
06268
06269
06270
06271
06272
06273
06274
06275
06276 #if defined(HAVE_PRI_SUBADDR)
06277 if (e->ring.calling.subaddress.valid) {
06278
06279 sig_pri_lock_owner(pri, chanpos);
06280 sig_pri_set_subaddress(
06281 &ast_channel_caller(pri->pvts[chanpos]->owner)->id.subaddress,
06282 &e->ring.calling.subaddress);
06283 if (!e->ring.calling.subaddress.type
06284 && !ast_strlen_zero(
06285 (char *) e->ring.calling.subaddress.data)) {
06286
06287 pbx_builtin_setvar_helper(c, "CALLINGSUBADDR",
06288 (char *) e->ring.calling.subaddress.data);
06289 }
06290 ast_channel_unlock(c);
06291 }
06292 if (e->ring.called_subaddress.valid) {
06293
06294 sig_pri_lock_owner(pri, chanpos);
06295 sig_pri_set_subaddress(
06296 &ast_channel_dialed(pri->pvts[chanpos]->owner)->subaddress,
06297 &e->ring.called_subaddress);
06298 if (!e->ring.called_subaddress.type
06299 && !ast_strlen_zero(
06300 (char *) e->ring.called_subaddress.data)) {
06301
06302 pbx_builtin_setvar_helper(c, "CALLEDSUBADDR",
06303 (char *) e->ring.called_subaddress.data);
06304 }
06305 ast_channel_unlock(c);
06306 }
06307 #else
06308 if (!ast_strlen_zero(e->ring.callingsubaddr)) {
06309 pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr);
06310 }
06311 #endif
06312 if (e->ring.ani2 >= 0) {
06313 snprintf(ani2str, sizeof(ani2str), "%d", e->ring.ani2);
06314 pbx_builtin_setvar_helper(c, "ANI2", ani2str);
06315 }
06316
06317 #ifdef SUPPORT_USERUSER
06318 if (!ast_strlen_zero(e->ring.useruserinfo)) {
06319 pbx_builtin_setvar_helper(c, "USERUSERINFO", e->ring.useruserinfo);
06320 }
06321 #endif
06322
06323 if (e->ring.redirectingreason >= 0) {
06324
06325 pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason));
06326 }
06327 #if defined(HAVE_PRI_REVERSE_CHARGE)
06328 pri->pvts[chanpos]->reverse_charging_indication = e->ring.reversecharge;
06329 #endif
06330 #if defined(HAVE_PRI_SETUP_KEYPAD)
06331 ast_copy_string(pri->pvts[chanpos]->keypad_digits,
06332 e->ring.keypad_digits,
06333 sizeof(pri->pvts[chanpos]->keypad_digits));
06334 #endif
06335
06336 snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan);
06337 pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr);
06338
06339 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ring.subcmds,
06340 e->ring.call);
06341 }
06342 if (c && !ast_pbx_start(c)) {
06343 ast_verb(3, "Accepting call from '%s' to '%s' on channel %d/%d, span %d\n",
06344 plancallingnum, pri->pvts[chanpos]->exten,
06345 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
06346 sig_pri_set_echocanceller(pri->pvts[chanpos], 1);
06347 } else {
06348 ast_log(LOG_WARNING, "Unable to start PBX on channel %d/%d, span %d\n",
06349 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span);
06350 if (c) {
06351
06352 sig_pri_unlock_private(pri->pvts[chanpos]);
06353 ast_mutex_unlock(&pri->lock);
06354 ast_hangup(c);
06355 ast_mutex_lock(&pri->lock);
06356 } else {
06357 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_SWITCH_CONGESTION);
06358 pri->pvts[chanpos]->call = NULL;
06359 sig_pri_unlock_private(pri->pvts[chanpos]);
06360 sig_pri_span_devstate_changed(pri);
06361 }
06362 break;
06363 }
06364 }
06365 } else {
06366 ast_verb(3,
06367 "Span %d: Extension %s@%s does not exist. Rejecting call from '%s'.\n",
06368 pri->span, pri->pvts[chanpos]->exten, pri->pvts[chanpos]->context,
06369 pri->pvts[chanpos]->cid_num);
06370 pri_hangup(pri->pri, e->ring.call, PRI_CAUSE_UNALLOCATED);
06371 pri->pvts[chanpos]->call = NULL;
06372 pri->pvts[chanpos]->exten[0] = '\0';
06373 sig_pri_unlock_private(pri->pvts[chanpos]);
06374 sig_pri_span_devstate_changed(pri);
06375 break;
06376 }
06377 sig_pri_unlock_private(pri->pvts[chanpos]);
06378 break;
06379 case PRI_EVENT_RINGING:
06380 if (sig_pri_is_cis_call(e->ringing.channel)) {
06381 sig_pri_handle_cis_subcmds(pri, e->e, e->ringing.subcmds,
06382 e->ringing.call);
06383 break;
06384 }
06385 chanpos = pri_find_fixup_principle(pri, e->ringing.channel,
06386 e->ringing.call);
06387 if (chanpos < 0) {
06388 break;
06389 }
06390 sig_pri_lock_private(pri->pvts[chanpos]);
06391
06392 sig_pri_handle_subcmds(pri, chanpos, e->e, e->ringing.subcmds,
06393 e->ringing.call);
06394 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCNR);
06395 sig_pri_set_echocanceller(pri->pvts[chanpos], 1);
06396 sig_pri_lock_owner(pri, chanpos);
06397 if (pri->pvts[chanpos]->owner) {
06398 ast_setstate(pri->pvts[chanpos]->owner, AST_STATE_RINGING);
06399 ast_channel_unlock(pri->pvts[chanpos]->owner);
06400 }
06401 pri_queue_control(pri, chanpos, AST_CONTROL_RINGING);
06402 if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_ALERTING) {
06403 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_ALERTING;
06404 }
06405
06406 if (!pri->pvts[chanpos]->progress
06407 && !pri->pvts[chanpos]->no_b_channel
06408 #ifdef PRI_PROGRESS_MASK
06409 && (e->ringing.progressmask
06410 & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE))
06411 #else
06412 && e->ringing.progress == 8
06413 #endif
06414 ) {
06415
06416 pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS);
06417 pri->pvts[chanpos]->progress = 1;
06418 sig_pri_set_dialing(pri->pvts[chanpos], 0);
06419 sig_pri_open_media(pri->pvts[chanpos]);
06420 }
06421
06422 #ifdef SUPPORT_USERUSER
06423 if (!ast_strlen_zero(e->ringing.useruserinfo)) {
06424 struct ast_channel *owner;
06425
06426 sig_pri_lock_owner(pri, chanpos);
06427 owner = pri->pvts[chanpos]->owner;
06428 if (owner) {
06429 pbx_builtin_setvar_helper(owner, "USERUSERINFO",
06430 e->ringing.useruserinfo);
06431 ast_channel_unlock(owner);
06432 }
06433 }
06434 #endif
06435
06436 sig_pri_unlock_private(pri->pvts[chanpos]);
06437 break;
06438 case PRI_EVENT_PROGRESS:
06439 if (sig_pri_is_cis_call(e->proceeding.channel)) {
06440 sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds,
06441 e->proceeding.call);
06442 break;
06443 }
06444 chanpos = pri_find_fixup_principle(pri, e->proceeding.channel,
06445 e->proceeding.call);
06446 if (chanpos < 0) {
06447 break;
06448 }
06449 sig_pri_lock_private(pri->pvts[chanpos]);
06450 sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.subcmds,
06451 e->proceeding.call);
06452
06453 if (e->proceeding.cause > -1) {
06454 ast_verb(3, "PROGRESS with cause code %d received\n", e->proceeding.cause);
06455
06456
06457 if (e->proceeding.cause == AST_CAUSE_USER_BUSY) {
06458 if (pri->pvts[chanpos]->owner) {
06459 ast_verb(3, "PROGRESS with 'user busy' received, signaling AST_CONTROL_BUSY instead of AST_CONTROL_PROGRESS\n");
06460
06461 ast_channel_hangupcause_set(pri->pvts[chanpos]->owner, e->proceeding.cause);
06462 pri_queue_control(pri, chanpos, AST_CONTROL_BUSY);
06463 }
06464 }
06465 }
06466
06467 if (!pri->pvts[chanpos]->progress
06468 && !pri->pvts[chanpos]->no_b_channel
06469 #ifdef PRI_PROGRESS_MASK
06470 && (e->proceeding.progressmask
06471 & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE))
06472 #else
06473 && e->proceeding.progress == 8
06474 #endif
06475 ) {
06476
06477 ast_debug(1,
06478 "Queuing frame from PRI_EVENT_PROGRESS on channel %d/%d span %d\n",
06479 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,
06480 pri->span);
06481 pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS);
06482 pri->pvts[chanpos]->progress = 1;
06483 sig_pri_set_dialing(pri->pvts[chanpos], 0);
06484 sig_pri_open_media(pri->pvts[chanpos]);
06485 }
06486 sig_pri_unlock_private(pri->pvts[chanpos]);
06487 break;
06488 case PRI_EVENT_PROCEEDING:
06489 if (sig_pri_is_cis_call(e->proceeding.channel)) {
06490 sig_pri_handle_cis_subcmds(pri, e->e, e->proceeding.subcmds,
06491 e->proceeding.call);
06492 break;
06493 }
06494 chanpos = pri_find_fixup_principle(pri, e->proceeding.channel,
06495 e->proceeding.call);
06496 if (chanpos < 0) {
06497 break;
06498 }
06499 sig_pri_lock_private(pri->pvts[chanpos]);
06500 sig_pri_handle_subcmds(pri, chanpos, e->e, e->proceeding.subcmds,
06501 e->proceeding.call);
06502 if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING) {
06503 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING;
06504 ast_debug(1,
06505 "Queuing frame from PRI_EVENT_PROCEEDING on channel %d/%d span %d\n",
06506 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset,
06507 pri->span);
06508 pri_queue_control(pri, chanpos, AST_CONTROL_PROCEEDING);
06509 }
06510 if (!pri->pvts[chanpos]->progress
06511 && !pri->pvts[chanpos]->no_b_channel
06512 #ifdef PRI_PROGRESS_MASK
06513 && (e->proceeding.progressmask
06514 & (PRI_PROG_CALL_NOT_E2E_ISDN | PRI_PROG_INBAND_AVAILABLE))
06515 #else
06516 && e->proceeding.progress == 8
06517 #endif
06518 ) {
06519
06520 pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS);
06521 pri->pvts[chanpos]->progress = 1;
06522 sig_pri_open_media(pri->pvts[chanpos]);
06523 }
06524 sig_pri_set_dialing(pri->pvts[chanpos], 0);
06525 sig_pri_unlock_private(pri->pvts[chanpos]);
06526 break;
06527 case PRI_EVENT_FACILITY:
06528 if (!e->facility.call || sig_pri_is_cis_call(e->facility.channel)) {
06529
06530 #if defined(HAVE_PRI_CALL_REROUTING)
06531 sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds,
06532 e->facility.subcall);
06533 #else
06534 sig_pri_handle_cis_subcmds(pri, e->e, e->facility.subcmds,
06535 e->facility.call);
06536 #endif
06537 break;
06538 }
06539 chanpos = pri_find_principle_by_call(pri, e->facility.call);
06540 if (chanpos < 0) {
06541 ast_log(LOG_WARNING, "Span %d: Received facility for unknown call.\n",
06542 pri->span);
06543 break;
06544 }
06545 sig_pri_lock_private(pri->pvts[chanpos]);
06546 #if defined(HAVE_PRI_CALL_REROUTING)
06547 sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.subcmds,
06548 e->facility.subcall);
06549 #else
06550 sig_pri_handle_subcmds(pri, chanpos, e->e, e->facility.subcmds,
06551 e->facility.call);
06552 #endif
06553 sig_pri_unlock_private(pri->pvts[chanpos]);
06554 break;
06555 case PRI_EVENT_ANSWER:
06556 if (sig_pri_is_cis_call(e->answer.channel)) {
06557 #if defined(HAVE_PRI_CALL_WAITING)
06558
06559 pri_connect_ack(pri->pri, e->answer.call, 0);
06560 #endif
06561 sig_pri_handle_cis_subcmds(pri, e->e, e->answer.subcmds,
06562 e->answer.call);
06563 break;
06564 }
06565 chanpos = pri_find_fixup_principle(pri, e->answer.channel, e->answer.call);
06566 if (chanpos < 0) {
06567 break;
06568 }
06569 #if defined(HAVE_PRI_CALL_WAITING)
06570 if (pri->pvts[chanpos]->is_call_waiting) {
06571 if (pri->pvts[chanpos]->no_b_channel) {
06572 int new_chanpos;
06573
06574
06575
06576
06577
06578 new_chanpos = pri_find_empty_chan(pri, 1);
06579 if (0 <= new_chanpos) {
06580 new_chanpos = pri_fixup_principle(pri, new_chanpos,
06581 e->answer.call);
06582 }
06583 if (new_chanpos < 0) {
06584
06585
06586
06587
06588 ast_verb(3,
06589 "Span %d: Channel not available for call waiting call.\n",
06590 pri->span);
06591 sig_pri_lock_private(pri->pvts[chanpos]);
06592 sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.subcmds,
06593 e->answer.call);
06594 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS);
06595 sig_pri_lock_owner(pri, chanpos);
06596 if (pri->pvts[chanpos]->owner) {
06597 ast_channel_hangupcause_set(pri->pvts[chanpos]->owner, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
06598 switch (ast_channel_state(pri->pvts[chanpos]->owner)) {
06599 case AST_STATE_BUSY:
06600 case AST_STATE_UP:
06601 ast_softhangup_nolock(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
06602 break;
06603 default:
06604 pri_queue_control(pri, chanpos, AST_CONTROL_CONGESTION);
06605 break;
06606 }
06607 ast_channel_unlock(pri->pvts[chanpos]->owner);
06608 } else {
06609 pri->pvts[chanpos]->is_call_waiting = 0;
06610 ast_atomic_fetchadd_int(&pri->num_call_waiting_calls, -1);
06611 pri_hangup(pri->pri, e->answer.call, PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION);
06612 pri->pvts[chanpos]->call = NULL;
06613 }
06614 sig_pri_unlock_private(pri->pvts[chanpos]);
06615 sig_pri_span_devstate_changed(pri);
06616 break;
06617 }
06618 chanpos = new_chanpos;
06619 }
06620 pri_connect_ack(pri->pri, e->answer.call, PVT_TO_CHANNEL(pri->pvts[chanpos]));
06621 sig_pri_span_devstate_changed(pri);
06622 } else {
06623
06624 pri_connect_ack(pri->pri, e->answer.call, 0);
06625 }
06626 #endif
06627 sig_pri_lock_private(pri->pvts[chanpos]);
06628
06629 #if defined(HAVE_PRI_CALL_WAITING)
06630 if (pri->pvts[chanpos]->is_call_waiting) {
06631 pri->pvts[chanpos]->is_call_waiting = 0;
06632 ast_atomic_fetchadd_int(&pri->num_call_waiting_calls, -1);
06633 }
06634 #endif
06635 sig_pri_handle_subcmds(pri, chanpos, e->e, e->answer.subcmds,
06636 e->answer.call);
06637 if (!ast_strlen_zero(pri->pvts[chanpos]->deferred_digits)) {
06638
06639 ast_verb(3,
06640 "Span %d: Channel %d/%d dialing deferred digit string: %s\n",
06641 pri->span, pri->pvts[chanpos]->logicalspan,
06642 pri->pvts[chanpos]->prioffset,
06643 pri->pvts[chanpos]->deferred_digits);
06644 if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_DEFER_DIAL) {
06645 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_DEFER_DIAL;
06646 }
06647 sig_pri_dial_digits(pri->pvts[chanpos],
06648 pri->pvts[chanpos]->deferred_digits);
06649 } else {
06650 if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_CONNECT) {
06651 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_CONNECT;
06652 }
06653 sig_pri_open_media(pri->pvts[chanpos]);
06654 pri_queue_control(pri, chanpos, AST_CONTROL_ANSWER);
06655 sig_pri_set_dialing(pri->pvts[chanpos], 0);
06656
06657 sig_pri_set_echocanceller(pri->pvts[chanpos], 1);
06658 }
06659
06660 #ifdef SUPPORT_USERUSER
06661 if (!ast_strlen_zero(e->answer.useruserinfo)) {
06662 struct ast_channel *owner;
06663
06664 sig_pri_lock_owner(pri, chanpos);
06665 owner = pri->pvts[chanpos]->owner;
06666 if (owner) {
06667 pbx_builtin_setvar_helper(owner, "USERUSERINFO",
06668 e->answer.useruserinfo);
06669 ast_channel_unlock(owner);
06670 }
06671 }
06672 #endif
06673
06674 sig_pri_unlock_private(pri->pvts[chanpos]);
06675 break;
06676 #if defined(HAVE_PRI_CALL_WAITING)
06677 case PRI_EVENT_CONNECT_ACK:
06678 if (sig_pri_is_cis_call(e->connect_ack.channel)) {
06679 sig_pri_handle_cis_subcmds(pri, e->e, e->connect_ack.subcmds,
06680 e->connect_ack.call);
06681 break;
06682 }
06683 chanpos = pri_find_fixup_principle(pri, e->connect_ack.channel,
06684 e->connect_ack.call);
06685 if (chanpos < 0) {
06686 break;
06687 }
06688
06689 sig_pri_lock_private(pri->pvts[chanpos]);
06690 sig_pri_handle_subcmds(pri, chanpos, e->e, e->connect_ack.subcmds,
06691 e->connect_ack.call);
06692 sig_pri_open_media(pri->pvts[chanpos]);
06693 sig_pri_unlock_private(pri->pvts[chanpos]);
06694 sig_pri_span_devstate_changed(pri);
06695 break;
06696 #endif
06697 case PRI_EVENT_HANGUP:
06698 if (sig_pri_is_cis_call(e->hangup.channel)) {
06699 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
06700 e->hangup.call);
06701 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
06702 break;
06703 }
06704 chanpos = pri_find_principle_by_call(pri, e->hangup.call);
06705 if (chanpos < 0) {
06706
06707
06708
06709
06710 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
06711 break;
06712 }
06713 sig_pri_lock_private(pri->pvts[chanpos]);
06714 sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.subcmds,
06715 e->hangup.call);
06716 switch (e->hangup.cause) {
06717 case PRI_CAUSE_INVALID_CALL_REFERENCE:
06718
06719
06720
06721
06722 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
06723 pri->pvts[chanpos]->call = NULL;
06724 break;
06725 default:
06726 break;
06727 }
06728 if (!pri->pvts[chanpos]->alreadyhungup) {
06729
06730 pri->pvts[chanpos]->alreadyhungup = 1;
06731 switch (e->hangup.cause) {
06732 case PRI_CAUSE_USER_BUSY:
06733 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
06734 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS);
06735 break;
06736 default:
06737 break;
06738 }
06739 if (pri->pvts[chanpos]->owner) {
06740 int do_hangup = 0;
06741
06742
06743 ast_channel_hangupcause_set(pri->pvts[chanpos]->owner, e->hangup.cause);
06744 switch (ast_channel_state(pri->pvts[chanpos]->owner)) {
06745 case AST_STATE_BUSY:
06746 case AST_STATE_UP:
06747 do_hangup = 1;
06748 break;
06749 default:
06750 if (!pri->pvts[chanpos]->outgoing) {
06751
06752
06753
06754
06755 do_hangup = 1;
06756 break;
06757 }
06758 switch (e->hangup.cause) {
06759 case PRI_CAUSE_USER_BUSY:
06760 pri_queue_control(pri, chanpos, AST_CONTROL_BUSY);
06761 break;
06762 case PRI_CAUSE_CALL_REJECTED:
06763 case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
06764 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
06765 case PRI_CAUSE_SWITCH_CONGESTION:
06766 case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
06767 case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
06768 pri_queue_control(pri, chanpos, AST_CONTROL_CONGESTION);
06769 break;
06770 default:
06771 do_hangup = 1;
06772 break;
06773 }
06774 break;
06775 }
06776
06777 if (do_hangup) {
06778 #if defined(HAVE_PRI_AOC_EVENTS)
06779 if (detect_aoc_e_subcmd(e->hangup.subcmds)) {
06780
06781
06782 pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP);
06783 } else {
06784 ast_channel_softhangup_internal_flag_add(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
06785 }
06786 #else
06787 ast_channel_softhangup_internal_flag_add(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
06788 #endif
06789 }
06790 } else {
06791
06792
06793
06794
06795 pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
06796 pri->pvts[chanpos]->call = NULL;
06797 }
06798 ast_verb(3, "Span %d: Channel %d/%d got hangup, cause %d\n",
06799 pri->span, pri->pvts[chanpos]->logicalspan,
06800 pri->pvts[chanpos]->prioffset, e->hangup.cause);
06801 } else {
06802
06803 pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
06804 pri->pvts[chanpos]->call = NULL;
06805 }
06806 #if defined(FORCE_RESTART_UNAVAIL_CHANS)
06807 if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
06808 && pri->sig != SIG_BRI_PTMP && !pri->resetting
06809 && pri->pvts[chanpos]->resetting == SIG_PRI_RESET_IDLE) {
06810 ast_verb(3,
06811 "Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
06812 pri->span, pri->pvts[chanpos]->logicalspan,
06813 pri->pvts[chanpos]->prioffset);
06814 pri->pvts[chanpos]->resetting = SIG_PRI_RESET_ACTIVE;
06815 pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
06816 }
06817 #endif
06818 if (e->hangup.aoc_units > -1)
06819 ast_verb(3, "Channel %d/%d, span %d received AOC-E charging %d unit%s\n",
06820 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s");
06821
06822 #ifdef SUPPORT_USERUSER
06823 if (!ast_strlen_zero(e->hangup.useruserinfo)) {
06824 struct ast_channel *owner;
06825
06826 sig_pri_lock_owner(pri, chanpos);
06827 owner = pri->pvts[chanpos]->owner;
06828 if (owner) {
06829 pbx_builtin_setvar_helper(owner, "USERUSERINFO",
06830 e->hangup.useruserinfo);
06831 ast_channel_unlock(owner);
06832 }
06833 }
06834 #endif
06835
06836 sig_pri_unlock_private(pri->pvts[chanpos]);
06837 sig_pri_span_devstate_changed(pri);
06838 break;
06839 case PRI_EVENT_HANGUP_REQ:
06840 if (sig_pri_is_cis_call(e->hangup.channel)) {
06841 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
06842 e->hangup.call);
06843 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
06844 break;
06845 }
06846 chanpos = pri_find_principle_by_call(pri, e->hangup.call);
06847 if (chanpos < 0) {
06848
06849
06850
06851
06852 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
06853 break;
06854 }
06855 sig_pri_lock_private(pri->pvts[chanpos]);
06856 sig_pri_handle_subcmds(pri, chanpos, e->e, e->hangup.subcmds,
06857 e->hangup.call);
06858 #if defined(HAVE_PRI_CALL_HOLD)
06859 if (e->hangup.call_active && e->hangup.call_held
06860 && pri->hold_disconnect_transfer) {
06861
06862 sig_pri_unlock_private(pri->pvts[chanpos]);
06863 if (!sig_pri_attempt_transfer(pri, e->hangup.call_held, 1,
06864 e->hangup.call_active, 0, NULL, NULL)) {
06865 break;
06866 }
06867 sig_pri_lock_private(pri->pvts[chanpos]);
06868 }
06869 #endif
06870 switch (e->hangup.cause) {
06871 case PRI_CAUSE_USER_BUSY:
06872 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
06873 sig_pri_cc_generic_check(pri, chanpos, AST_CC_CCBS);
06874 break;
06875 case PRI_CAUSE_INVALID_CALL_REFERENCE:
06876
06877
06878
06879
06880
06881
06882 pri_hangup(pri->pri, e->hangup.call, e->hangup.cause);
06883 pri->pvts[chanpos]->call = NULL;
06884 break;
06885 default:
06886 break;
06887 }
06888 if (pri->pvts[chanpos]->owner) {
06889 int do_hangup = 0;
06890
06891 ast_channel_hangupcause_set(pri->pvts[chanpos]->owner, e->hangup.cause);
06892 switch (ast_channel_state(pri->pvts[chanpos]->owner)) {
06893 case AST_STATE_BUSY:
06894 case AST_STATE_UP:
06895 do_hangup = 1;
06896 break;
06897 default:
06898 if (!pri->pvts[chanpos]->outgoing) {
06899
06900
06901
06902
06903 do_hangup = 1;
06904 break;
06905 }
06906 switch (e->hangup.cause) {
06907 case PRI_CAUSE_USER_BUSY:
06908 pri_queue_control(pri, chanpos, AST_CONTROL_BUSY);
06909 break;
06910 case PRI_CAUSE_CALL_REJECTED:
06911 case PRI_CAUSE_NETWORK_OUT_OF_ORDER:
06912 case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION:
06913 case PRI_CAUSE_SWITCH_CONGESTION:
06914 case PRI_CAUSE_DESTINATION_OUT_OF_ORDER:
06915 case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE:
06916 pri_queue_control(pri, chanpos, AST_CONTROL_CONGESTION);
06917 break;
06918 default:
06919 do_hangup = 1;
06920 break;
06921 }
06922 break;
06923 }
06924
06925 if (do_hangup) {
06926 #if defined(HAVE_PRI_AOC_EVENTS)
06927 if (!pri->pvts[chanpos]->holding_aoce
06928 && pri->aoce_delayhangup
06929 && ast_bridged_channel(pri->pvts[chanpos]->owner)) {
06930 sig_pri_send_aoce_termination_request(pri, chanpos,
06931 pri_get_timer(pri->pri, PRI_TIMER_T305) / 2);
06932 } else if (detect_aoc_e_subcmd(e->hangup.subcmds)) {
06933
06934
06935 pri_queue_control(pri, chanpos, AST_CONTROL_HANGUP);
06936 } else {
06937 ast_channel_softhangup_internal_flag_add(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
06938 }
06939 #else
06940 ast_channel_softhangup_internal_flag_add(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
06941 #endif
06942 }
06943 ast_verb(3, "Span %d: Channel %d/%d got hangup request, cause %d\n",
06944 pri->span, pri->pvts[chanpos]->logicalspan,
06945 pri->pvts[chanpos]->prioffset, e->hangup.cause);
06946 } else {
06947
06948
06949
06950
06951 pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause);
06952 pri->pvts[chanpos]->call = NULL;
06953 }
06954 #if defined(FORCE_RESTART_UNAVAIL_CHANS)
06955 if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL
06956 && pri->sig != SIG_BRI_PTMP && !pri->resetting
06957 && pri->pvts[chanpos]->resetting == SIG_PRI_RESET_IDLE) {
06958 ast_verb(3,
06959 "Span %d: Forcing restart of channel %d/%d since channel reported in use\n",
06960 pri->span, pri->pvts[chanpos]->logicalspan,
06961 pri->pvts[chanpos]->prioffset);
06962 pri->pvts[chanpos]->resetting = SIG_PRI_RESET_ACTIVE;
06963 pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos]));
06964 }
06965 #endif
06966
06967 #ifdef SUPPORT_USERUSER
06968 if (!ast_strlen_zero(e->hangup.useruserinfo)) {
06969 struct ast_channel *owner;
06970
06971 sig_pri_lock_owner(pri, chanpos);
06972 owner = pri->pvts[chanpos]->owner;
06973 if (owner) {
06974 pbx_builtin_setvar_helper(owner, "USERUSERINFO",
06975 e->hangup.useruserinfo);
06976 ast_channel_unlock(owner);
06977 }
06978 }
06979 #endif
06980
06981 sig_pri_unlock_private(pri->pvts[chanpos]);
06982 sig_pri_span_devstate_changed(pri);
06983 break;
06984 case PRI_EVENT_HANGUP_ACK:
06985 if (sig_pri_is_cis_call(e->hangup.channel)) {
06986 sig_pri_handle_cis_subcmds(pri, e->e, e->hangup.subcmds,
06987 e->hangup.call);
06988 break;
06989 }
06990 chanpos = pri_find_principle_by_call(pri, e->hangup.call);
06991 if (chanpos < 0) {
06992 break;
06993 }
06994 sig_pri_lock_private(pri->pvts[chanpos]);
06995 pri->pvts[chanpos]->call = NULL;
06996 if (pri->pvts[chanpos]->owner) {
06997 ast_verb(3, "Span %d: Channel %d/%d got hangup ACK\n", pri->span,
06998 pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset);
06999 }
07000 #ifdef SUPPORT_USERUSER
07001 if (!ast_strlen_zero(e->hangup.useruserinfo)) {
07002 struct ast_channel *owner;
07003
07004 sig_pri_lock_owner(pri, chanpos);
07005 owner = pri->pvts[chanpos]->owner;
07006 if (owner) {
07007 pbx_builtin_setvar_helper(owner, "USERUSERINFO",
07008 e->hangup.useruserinfo);
07009 ast_channel_unlock(owner);
07010 }
07011 }
07012 #endif
07013 sig_pri_unlock_private(pri->pvts[chanpos]);
07014 sig_pri_span_devstate_changed(pri);
07015 break;
07016 case PRI_EVENT_CONFIG_ERR:
07017 ast_log(LOG_WARNING, "PRI Error on span %d: %s\n", pri->span, e->err.err);
07018 break;
07019 case PRI_EVENT_RESTART_ACK:
07020 chanpos = pri_find_principle(pri, e->restartack.channel, NULL);
07021 if (chanpos < 0) {
07022
07023
07024
07025 for (x = 0; x < pri->numchans; x++) {
07026 if (pri->pvts[x]
07027 && pri->pvts[x]->resetting != SIG_PRI_RESET_IDLE) {
07028 chanpos = x;
07029 sig_pri_lock_private(pri->pvts[chanpos]);
07030 ast_debug(1,
07031 "Span %d: Assuming restart ack is for channel %d/%d\n",
07032 pri->span, pri->pvts[chanpos]->logicalspan,
07033 pri->pvts[chanpos]->prioffset);
07034 if (pri->pvts[chanpos]->owner) {
07035 ast_log(LOG_WARNING,
07036 "Span %d: Got restart ack on channel %d/%d with owner\n",
07037 pri->span, pri->pvts[chanpos]->logicalspan,
07038 pri->pvts[chanpos]->prioffset);
07039 ast_channel_softhangup_internal_flag_add(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
07040 }
07041 pri->pvts[chanpos]->resetting = SIG_PRI_RESET_IDLE;
07042 ast_verb(3,
07043 "Span %d: Channel %d/%d successfully restarted\n",
07044 pri->span, pri->pvts[chanpos]->logicalspan,
07045 pri->pvts[chanpos]->prioffset);
07046 sig_pri_unlock_private(pri->pvts[chanpos]);
07047 if (pri->resetting)
07048 pri_check_restart(pri);
07049 break;
07050 }
07051 }
07052 if (chanpos < 0) {
07053 ast_log(LOG_WARNING,
07054 "Span %d: Restart ACK on strange channel %d/%d\n",
07055 pri->span, PRI_SPAN(e->restartack.channel),
07056 PRI_CHANNEL(e->restartack.channel));
07057 }
07058 } else {
07059 sig_pri_lock_private(pri->pvts[chanpos]);
07060 if (pri->pvts[chanpos]->resetting == SIG_PRI_RESET_IDLE) {
07061
07062 ast_debug(1,
07063 "Span %d: Unexpected or late restart ack on channel %d/%d (Ignoring)\n",
07064 pri->span, pri->pvts[chanpos]->logicalspan,
07065 pri->pvts[chanpos]->prioffset);
07066 sig_pri_unlock_private(pri->pvts[chanpos]);
07067 break;
07068 }
07069 if (pri->pvts[chanpos]->owner) {
07070 ast_log(LOG_WARNING,
07071 "Span %d: Got restart ack on channel %d/%d with owner\n",
07072 pri->span, pri->pvts[chanpos]->logicalspan,
07073 pri->pvts[chanpos]->prioffset);
07074 ast_channel_softhangup_internal_flag_add(pri->pvts[chanpos]->owner, AST_SOFTHANGUP_DEV);
07075 }
07076 pri->pvts[chanpos]->resetting = SIG_PRI_RESET_IDLE;
07077 ast_verb(3,
07078 "Span %d: Channel %d/%d successfully restarted\n",
07079 pri->span, pri->pvts[chanpos]->logicalspan,
07080 pri->pvts[chanpos]->prioffset);
07081 sig_pri_unlock_private(pri->pvts[chanpos]);
07082 if (pri->resetting)
07083 pri_check_restart(pri);
07084 }
07085 break;
07086 case PRI_EVENT_SETUP_ACK:
07087 if (sig_pri_is_cis_call(e->setup_ack.channel)) {
07088 sig_pri_handle_cis_subcmds(pri, e->e, e->setup_ack.subcmds,
07089 e->setup_ack.call);
07090 break;
07091 }
07092 chanpos = pri_find_fixup_principle(pri, e->setup_ack.channel,
07093 e->setup_ack.call);
07094 if (chanpos < 0) {
07095 break;
07096 }
07097 sig_pri_lock_private(pri->pvts[chanpos]);
07098 sig_pri_handle_subcmds(pri, chanpos, e->e, e->setup_ack.subcmds,
07099 e->setup_ack.call);
07100 if (pri->pvts[chanpos]->call_level < SIG_PRI_CALL_LEVEL_OVERLAP) {
07101 pri->pvts[chanpos]->call_level = SIG_PRI_CALL_LEVEL_OVERLAP;
07102 }
07103
07104
07105 len = strlen(pri->pvts[chanpos]->dialdest);
07106 for (x = 0; x < len; ++x) {
07107 ast_debug(1, "Sending pending digit '%c'\n", pri->pvts[chanpos]->dialdest[x]);
07108 pri_information(pri->pri, pri->pvts[chanpos]->call,
07109 pri->pvts[chanpos]->dialdest[x]);
07110 }
07111
07112 if (!pri->pvts[chanpos]->progress
07113 && (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING)
07114 && !pri->pvts[chanpos]->digital
07115 && !pri->pvts[chanpos]->no_b_channel) {
07116
07117
07118
07119
07120 pri_queue_control(pri, chanpos, AST_CONTROL_PROGRESS);
07121 pri->pvts[chanpos]->progress = 1;
07122 sig_pri_set_dialing(pri->pvts[chanpos], 0);
07123 sig_pri_open_media(pri->pvts[chanpos]);
07124 }
07125 sig_pri_unlock_private(pri->pvts[chanpos]);
07126 break;
07127 case PRI_EVENT_NOTIFY:
07128 if (sig_pri_is_cis_call(e->notify.channel)) {
07129 #if defined(HAVE_PRI_CALL_HOLD)
07130 sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds,
07131 e->notify.call);
07132 #else
07133 sig_pri_handle_cis_subcmds(pri, e->e, e->notify.subcmds, NULL);
07134 #endif
07135 break;
07136 }
07137 #if defined(HAVE_PRI_CALL_HOLD)
07138 chanpos = pri_find_principle_by_call(pri, e->notify.call);
07139 if (chanpos < 0) {
07140 ast_log(LOG_WARNING, "Span %d: Received NOTIFY for unknown call.\n",
07141 pri->span);
07142 break;
07143 }
07144 #else
07145
07146
07147
07148
07149
07150 chanpos = pri_find_principle(pri, e->notify.channel, NULL);
07151 if (chanpos < 0) {
07152 ast_log(LOG_WARNING, "Received NOTIFY on unconfigured channel %d/%d span %d\n",
07153 PRI_SPAN(e->notify.channel), PRI_CHANNEL(e->notify.channel), pri->span);
07154 break;
07155 }
07156 #endif
07157 sig_pri_lock_private(pri->pvts[chanpos]);
07158 #if defined(HAVE_PRI_CALL_HOLD)
07159 sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.subcmds,
07160 e->notify.call);
07161 #else
07162 sig_pri_handle_subcmds(pri, chanpos, e->e, e->notify.subcmds, NULL);
07163 #endif
07164 switch (e->notify.info) {
07165 case PRI_NOTIFY_REMOTE_HOLD:
07166 if (!pri->discardremoteholdretrieval) {
07167 pri_queue_control(pri, chanpos, AST_CONTROL_HOLD);
07168 }
07169 break;
07170 case PRI_NOTIFY_REMOTE_RETRIEVAL:
07171 if (!pri->discardremoteholdretrieval) {
07172 pri_queue_control(pri, chanpos, AST_CONTROL_UNHOLD);
07173 }
07174 break;
07175 }
07176 sig_pri_unlock_private(pri->pvts[chanpos]);
07177 break;
07178 #if defined(HAVE_PRI_CALL_HOLD)
07179 case PRI_EVENT_HOLD:
07180
07181 if (sig_pri_handle_hold(pri, e)) {
07182 pri_hold_rej(pri->pri, e->hold.call,
07183 PRI_CAUSE_RESOURCE_UNAVAIL_UNSPECIFIED);
07184 } else {
07185 pri_hold_ack(pri->pri, e->hold.call);
07186 }
07187 break;
07188 #endif
07189 #if defined(HAVE_PRI_CALL_HOLD)
07190 case PRI_EVENT_HOLD_ACK:
07191
07192 sig_pri_handle_hold_ack(pri, e);
07193 break;
07194 #endif
07195 #if defined(HAVE_PRI_CALL_HOLD)
07196 case PRI_EVENT_HOLD_REJ:
07197
07198 sig_pri_handle_hold_rej(pri, e);
07199 break;
07200 #endif
07201 #if defined(HAVE_PRI_CALL_HOLD)
07202 case PRI_EVENT_RETRIEVE:
07203
07204 sig_pri_handle_retrieve(pri, e);
07205 break;
07206 #endif
07207 #if defined(HAVE_PRI_CALL_HOLD)
07208 case PRI_EVENT_RETRIEVE_ACK:
07209
07210 sig_pri_handle_retrieve_ack(pri, e);
07211 break;
07212 #endif
07213 #if defined(HAVE_PRI_CALL_HOLD)
07214 case PRI_EVENT_RETRIEVE_REJ:
07215
07216 sig_pri_handle_retrieve_rej(pri, e);
07217 break;
07218 #endif
07219 default:
07220 ast_debug(1, "Span: %d Unhandled event: %s(%d)\n",
07221 pri->span, pri_event2str(e->e), e->e);
07222 break;
07223 }
07224 }
07225 ast_mutex_unlock(&pri->lock);
07226 }
07227
07228 return NULL;
07229 }
07230
07231
07232
07233
07234
07235
07236
07237
07238
07239
07240
07241
07242
07243 int sig_pri_ami_show_spans(struct mansession *s, const char *show_cmd, struct sig_pri_span *pri, const int *dchannels, const char *action_id)
07244 {
07245 int count;
07246 int x;
07247
07248 count = 0;
07249 for (x = 0; x < ARRAY_LEN(pri->dchans); ++x) {
07250 if (pri->dchans[x]) {
07251 ++count;
07252
07253 astman_append(s,
07254 "Event: %s\r\n"
07255 "Span: %d\r\n"
07256 "DChannel: %d\r\n"
07257 "Order: %s\r\n"
07258 "Active: %s\r\n"
07259 "Alarm: %s\r\n"
07260 "Up: %s\r\n"
07261 "%s"
07262 "\r\n",
07263 show_cmd,
07264 pri->span,
07265 dchannels[x],
07266 pri_order(x),
07267 (pri->dchans[x] == pri->pri) ? "Yes" : "No",
07268 (pri->dchanavail[x] & DCHAN_NOTINALARM) ? "No" : "Yes",
07269 (pri->dchanavail[x] & DCHAN_UP) ? "Yes" : "No",
07270 action_id
07271 );
07272 }
07273 }
07274 return count;
07275 }
07276
07277 void sig_pri_init_pri(struct sig_pri_span *pri)
07278 {
07279 int i;
07280
07281 memset(pri, 0, sizeof(*pri));
07282
07283 ast_mutex_init(&pri->lock);
07284
07285 pri->master = AST_PTHREADT_NULL;
07286 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++)
07287 pri->fds[i] = -1;
07288 }
07289
07290 int sig_pri_hangup(struct sig_pri_chan *p, struct ast_channel *ast)
07291 {
07292 ast_debug(1, "%s %d\n", __FUNCTION__, p->channel);
07293 if (!ast_channel_tech_pvt(ast)) {
07294 ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");
07295 return 0;
07296 }
07297
07298 sig_pri_set_outgoing(p, 0);
07299 sig_pri_set_digital(p, 0);
07300 #if defined(HAVE_PRI_CALL_WAITING)
07301 if (p->is_call_waiting) {
07302 p->is_call_waiting = 0;
07303 ast_atomic_fetchadd_int(&p->pri->num_call_waiting_calls, -1);
07304 }
07305 #endif
07306 p->call_level = SIG_PRI_CALL_LEVEL_IDLE;
07307 p->progress = 0;
07308 p->cid_num[0] = '\0';
07309 p->cid_subaddr[0] = '\0';
07310 p->cid_name[0] = '\0';
07311 p->user_tag[0] = '\0';
07312 p->exten[0] = '\0';
07313 sig_pri_set_dialing(p, 0);
07314
07315
07316 pri_grab(p, p->pri);
07317 sig_pri_moh_fsm_event(ast, p, SIG_PRI_MOH_EVENT_RESET);
07318 if (p->call) {
07319 #if defined(SUPPORT_USERUSER)
07320 const char *useruser = pbx_builtin_getvar_helper(ast, "USERUSERINFO");
07321
07322 if (!ast_strlen_zero(useruser)) {
07323 pri_call_set_useruser(p->call, useruser);
07324 }
07325 #endif
07326
07327 #if defined(HAVE_PRI_AOC_EVENTS)
07328 if (p->holding_aoce) {
07329 pri_aoc_e_send(p->pri->pri, p->call, &p->aoc_e);
07330 }
07331 #endif
07332
07333 if (p->alreadyhungup) {
07334 ast_debug(1, "Already hungup... Calling hangup once, and clearing call\n");
07335
07336 pri_hangup(p->pri->pri, p->call, -1);
07337 p->call = NULL;
07338 } else {
07339 const char *cause = pbx_builtin_getvar_helper(ast,"PRI_CAUSE");
07340 int icause = ast_channel_hangupcause(ast) ? ast_channel_hangupcause(ast) : -1;
07341
07342 p->alreadyhungup = 1;
07343 if (!ast_strlen_zero(cause)) {
07344 if (atoi(cause)) {
07345 icause = atoi(cause);
07346 }
07347 }
07348 ast_debug(1,
07349 "Not yet hungup... Calling hangup with cause %d, and clearing call\n",
07350 icause);
07351
07352 pri_hangup(p->pri->pri, p->call, icause);
07353 }
07354 }
07355 #if defined(HAVE_PRI_AOC_EVENTS)
07356 p->aoc_s_request_invoke_id_valid = 0;
07357 p->holding_aoce = 0;
07358 p->waiting_for_aoce = 0;
07359 #endif
07360
07361 p->allocated = 0;
07362 p->owner = NULL;
07363
07364 sig_pri_span_devstate_changed(p->pri);
07365 pri_rel(p->pri);
07366 return 0;
07367 }
07368
07369
07370
07371
07372
07373
07374
07375
07376
07377
07378
07379
07380
07381
07382 void sig_pri_extract_called_num_subaddr(struct sig_pri_chan *p, const char *rdest, char *called, size_t called_buff_size)
07383 {
07384 char *dial;
07385 char *number;
07386 char *subaddr;
07387 AST_DECLARE_APP_ARGS(args,
07388 AST_APP_ARG(group);
07389 AST_APP_ARG(ext);
07390
07391 AST_APP_ARG(other);
07392 );
07393
07394
07395 dial = ast_strdupa(rdest);
07396 AST_NONSTANDARD_APP_ARGS(args, dial, '/');
07397
07398 number = args.ext;
07399 if (!number) {
07400 number = "";
07401 }
07402
07403
07404 subaddr = strchr(number, ':');
07405 if (subaddr) {
07406 *subaddr++ = '\0';
07407
07408
07409 switch (*subaddr) {
07410 case 'U':
07411 case 'u':
07412 case 'N':
07413 case 'n':
07414 ++subaddr;
07415 break;
07416 default:
07417 break;
07418 }
07419 }
07420
07421
07422 if (strlen(number) < p->stripmsd) {
07423 number = "";
07424 } else {
07425 char *deferred;
07426
07427 number += p->stripmsd;
07428 deferred = strchr(number, 'w');
07429 if (deferred) {
07430
07431 *deferred = '\0';
07432 }
07433 while (isalpha(*number)) {
07434 ++number;
07435 }
07436 }
07437
07438
07439 if (ast_strlen_zero(subaddr)) {
07440
07441 snprintf(called, called_buff_size, "%s", number);
07442 } else {
07443
07444 snprintf(called, called_buff_size, "%s:%s", number, subaddr);
07445 }
07446 }
07447
07448 enum SIG_PRI_CALL_OPT_FLAGS {
07449 OPT_KEYPAD = (1 << 0),
07450 OPT_REVERSE_CHARGE = (1 << 1),
07451 OPT_AOC_REQUEST = (1 << 2),
07452 };
07453 enum SIG_PRI_CALL_OPT_ARGS {
07454 OPT_ARG_KEYPAD = 0,
07455 OPT_ARG_AOC_REQUEST,
07456
07457
07458 OPT_ARG_ARRAY_SIZE,
07459 };
07460
07461 AST_APP_OPTIONS(sig_pri_call_opts, BEGIN_OPTIONS
07462 AST_APP_OPTION_ARG('K', OPT_KEYPAD, OPT_ARG_KEYPAD),
07463 AST_APP_OPTION('R', OPT_REVERSE_CHARGE),
07464 AST_APP_OPTION_ARG('A', OPT_AOC_REQUEST, OPT_ARG_AOC_REQUEST),
07465 END_OPTIONS);
07466
07467
07468 int sig_pri_call(struct sig_pri_chan *p, struct ast_channel *ast, const char *rdest, int timeout, int layer1)
07469 {
07470 char dest[256];
07471 struct ast_party_subaddress dialed_subaddress;
07472 struct pri_sr *sr;
07473 char *c, *l, *n, *s;
07474 #ifdef SUPPORT_USERUSER
07475 const char *useruser;
07476 #endif
07477 int core_id;
07478 int pridialplan;
07479 int dp_strip;
07480 int prilocaldialplan;
07481 int ldp_strip;
07482 int exclusive;
07483 #if defined(HAVE_PRI_SETUP_KEYPAD)
07484 const char *keypad;
07485 #endif
07486 AST_DECLARE_APP_ARGS(args,
07487 AST_APP_ARG(group);
07488 AST_APP_ARG(ext);
07489 AST_APP_ARG(opts);
07490 AST_APP_ARG(other);
07491 );
07492 struct ast_flags opts;
07493 char *opt_args[OPT_ARG_ARRAY_SIZE];
07494
07495 ast_debug(1, "CALLER NAME: %s NUM: %s\n",
07496 S_COR(ast_channel_connected(ast)->id.name.valid, ast_channel_connected(ast)->id.name.str, ""),
07497 S_COR(ast_channel_connected(ast)->id.number.valid, ast_channel_connected(ast)->id.number.str, ""));
07498
07499 if (!p->pri) {
07500 ast_log(LOG_ERROR, "Could not find pri on channel %d\n", p->channel);
07501 return -1;
07502 }
07503
07504 if ((ast_channel_state(ast) != AST_STATE_DOWN) && (ast_channel_state(ast) != AST_STATE_RESERVED)) {
07505 ast_log(LOG_WARNING, "sig_pri_call called on %s, neither down nor reserved\n", ast_channel_name(ast));
07506 return -1;
07507 }
07508
07509 p->dialdest[0] = '\0';
07510 sig_pri_set_outgoing(p, 1);
07511
07512 ast_copy_string(dest, rdest, sizeof(dest));
07513 AST_NONSTANDARD_APP_ARGS(args, dest, '/');
07514 if (ast_app_parse_options(sig_pri_call_opts, &opts, opt_args, args.opts)) {
07515
07516 return -1;
07517 }
07518
07519 c = args.ext;
07520 if (!c) {
07521 c = "";
07522 }
07523
07524
07525 ast_party_subaddress_init(&dialed_subaddress);
07526 s = strchr(c, ':');
07527 if (s) {
07528 *s = '\0';
07529 s++;
07530
07531
07532
07533
07534 switch (*s) {
07535 case 'U':
07536 case 'u':
07537 s++;
07538 dialed_subaddress.type = 2;
07539 break;
07540 case 'N':
07541 case 'n':
07542 s++;
07543
07544 break;
07545 }
07546 dialed_subaddress.str = s;
07547 dialed_subaddress.valid = 1;
07548 }
07549
07550 l = NULL;
07551 n = NULL;
07552 if (!p->hidecallerid) {
07553 if (ast_channel_connected(ast)->id.number.valid) {
07554
07555
07556
07557
07558 for (l = ast_channel_connected(ast)->id.number.str; l && *l; l++) {
07559 if (strchr("0123456789", *l)) {
07560 l = ast_channel_connected(ast)->id.number.str;
07561 break;
07562 }
07563 }
07564 } else {
07565 l = NULL;
07566 }
07567 if (!p->hidecalleridname) {
07568 n = ast_channel_connected(ast)->id.name.valid ? ast_channel_connected(ast)->id.name.str : NULL;
07569 }
07570 }
07571
07572 if (strlen(c) < p->stripmsd) {
07573 ast_log(LOG_WARNING, "Number '%s' is shorter than stripmsd (%d)\n", c, p->stripmsd);
07574 return -1;
07575 }
07576
07577
07578 s = strchr(c + p->stripmsd, 'w');
07579 if (s) {
07580 *s++ = '\0';
07581 ast_copy_string(p->deferred_digits, s, sizeof(p->deferred_digits));
07582
07583
07584
07585
07586
07587 } else {
07588 p->deferred_digits[0] = '\0';
07589 }
07590
07591 pri_grab(p, p->pri);
07592 if (!(p->call = pri_new_call(p->pri->pri))) {
07593 ast_log(LOG_WARNING, "Unable to create call on channel %d\n", p->channel);
07594 pri_rel(p->pri);
07595 return -1;
07596 }
07597 if (!(sr = pri_sr_new())) {
07598 ast_log(LOG_WARNING, "Failed to allocate setup request on channel %d\n",
07599 p->channel);
07600 pri_destroycall(p->pri->pri, p->call);
07601 p->call = NULL;
07602 pri_rel(p->pri);
07603 return -1;
07604 }
07605
07606 sig_pri_set_digital(p, IS_DIGITAL(ast_channel_transfercapability(ast)));
07607
07608 #if defined(HAVE_PRI_CALL_WAITING)
07609 if (p->is_call_waiting) {
07610
07611
07612
07613
07614 pri_sr_set_channel(sr, 0, 0, 1);
07615 } else
07616 #endif
07617 {
07618
07619 if (p->priexclusive || p->pri->nodetype == PRI_NETWORK) {
07620 exclusive = 1;
07621 } else {
07622 exclusive = 0;
07623 }
07624 pri_sr_set_channel(sr, PVT_TO_CHANNEL(p), exclusive, 1);
07625 }
07626
07627 pri_sr_set_bearer(sr, p->digital ? PRI_TRANS_CAP_DIGITAL : ast_channel_transfercapability(ast),
07628 (p->digital ? -1 : layer1));
07629
07630 if (p->pri->facilityenable)
07631 pri_facility_enable(p->pri->pri);
07632
07633 ast_verb(3, "Requested transfer capability: 0x%.2x - %s\n", ast_channel_transfercapability(ast), ast_transfercapability2str(ast_channel_transfercapability(ast)));
07634 dp_strip = 0;
07635 pridialplan = p->pri->dialplan - 1;
07636 if (pridialplan == -2 || pridialplan == -3) {
07637 if (strncmp(c + p->stripmsd, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
07638 if (pridialplan == -2) {
07639 dp_strip = strlen(p->pri->internationalprefix);
07640 }
07641 pridialplan = PRI_INTERNATIONAL_ISDN;
07642 } else if (strncmp(c + p->stripmsd, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
07643 if (pridialplan == -2) {
07644 dp_strip = strlen(p->pri->nationalprefix);
07645 }
07646 pridialplan = PRI_NATIONAL_ISDN;
07647 } else {
07648 pridialplan = PRI_LOCAL_ISDN;
07649 }
07650 }
07651 while (c[p->stripmsd] > '9' && c[p->stripmsd] != '*' && c[p->stripmsd] != '#') {
07652 switch (c[p->stripmsd]) {
07653 case 'U':
07654 pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf);
07655 break;
07656 case 'I':
07657 pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf);
07658 break;
07659 case 'N':
07660 pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf);
07661 break;
07662 case 'L':
07663 pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf);
07664 break;
07665 case 'S':
07666 pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf);
07667 break;
07668 case 'V':
07669 pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf);
07670 break;
07671 case 'R':
07672 pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf);
07673 break;
07674 case 'u':
07675 pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0);
07676 break;
07677 case 'e':
07678 pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0);
07679 break;
07680 case 'x':
07681 pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0);
07682 break;
07683 case 'f':
07684 pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0);
07685 break;
07686 case 'n':
07687 pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0);
07688 break;
07689 case 'p':
07690 pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0);
07691 break;
07692 case 'r':
07693 pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0);
07694 break;
07695 default:
07696 if (isalpha(c[p->stripmsd])) {
07697 ast_log(LOG_WARNING, "Unrecognized pridialplan %s modifier: %c\n",
07698 c[p->stripmsd] > 'Z' ? "NPI" : "TON", c[p->stripmsd]);
07699 }
07700 break;
07701 }
07702 c++;
07703 }
07704 #if defined(HAVE_PRI_SETUP_KEYPAD)
07705 if (ast_test_flag(&opts, OPT_KEYPAD)
07706 && !ast_strlen_zero(opt_args[OPT_ARG_KEYPAD])) {
07707
07708 keypad = opt_args[OPT_ARG_KEYPAD];
07709 pri_sr_set_keypad_digits(sr, keypad);
07710 } else {
07711 keypad = NULL;
07712 }
07713 if (!keypad || !ast_strlen_zero(c + p->stripmsd + dp_strip))
07714 #endif
07715 {
07716 pri_sr_set_called(sr, c + p->stripmsd + dp_strip, pridialplan, s ? 1 : 0);
07717 }
07718
07719 #if defined(HAVE_PRI_SUBADDR)
07720 if (dialed_subaddress.valid) {
07721 struct pri_party_subaddress subaddress;
07722
07723 memset(&subaddress, 0, sizeof(subaddress));
07724 sig_pri_party_subaddress_from_ast(&subaddress, &dialed_subaddress);
07725 pri_sr_set_called_subaddress(sr, &subaddress);
07726 }
07727 #endif
07728 #if defined(HAVE_PRI_REVERSE_CHARGE)
07729 if (ast_test_flag(&opts, OPT_REVERSE_CHARGE)) {
07730 pri_sr_set_reversecharge(sr, PRI_REVERSECHARGE_REQUESTED);
07731 }
07732 #endif
07733 #if defined(HAVE_PRI_AOC_EVENTS)
07734 if (ast_test_flag(&opts, OPT_AOC_REQUEST)
07735 && !ast_strlen_zero(opt_args[OPT_ARG_AOC_REQUEST])) {
07736 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 's')) {
07737 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_S);
07738 }
07739 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'd')) {
07740 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_D);
07741 }
07742 if (strchr(opt_args[OPT_ARG_AOC_REQUEST], 'e')) {
07743 pri_sr_set_aoc_charging_request(sr, PRI_AOC_REQUEST_E);
07744 }
07745 }
07746 #endif
07747
07748
07749 if (p->pri->append_msn_to_user_tag) {
07750 snprintf(p->user_tag, sizeof(p->user_tag), "%s_%s", p->pri->initial_user_tag,
07751 p->pri->nodetype == PRI_NETWORK
07752 ? c + p->stripmsd + dp_strip
07753 : S_COR(ast_channel_connected(ast)->id.number.valid,
07754 ast_channel_connected(ast)->id.number.str, ""));
07755 } else {
07756 ast_copy_string(p->user_tag, p->pri->initial_user_tag, sizeof(p->user_tag));
07757 }
07758
07759
07760
07761
07762
07763 ast_free(ast_channel_caller(ast)->id.tag);
07764 ast_channel_caller(ast)->id.tag = ast_strdup(p->user_tag);
07765
07766 ldp_strip = 0;
07767 prilocaldialplan = p->pri->localdialplan - 1;
07768 if ((l != NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) {
07769 if (strncmp(l, p->pri->internationalprefix, strlen(p->pri->internationalprefix)) == 0) {
07770 if (prilocaldialplan == -2) {
07771 ldp_strip = strlen(p->pri->internationalprefix);
07772 }
07773 prilocaldialplan = PRI_INTERNATIONAL_ISDN;
07774 } else if (strncmp(l, p->pri->nationalprefix, strlen(p->pri->nationalprefix)) == 0) {
07775 if (prilocaldialplan == -2) {
07776 ldp_strip = strlen(p->pri->nationalprefix);
07777 }
07778 prilocaldialplan = PRI_NATIONAL_ISDN;
07779 } else {
07780 prilocaldialplan = PRI_LOCAL_ISDN;
07781 }
07782 } else if (prilocaldialplan == -1) {
07783
07784 prilocaldialplan = ast_channel_connected(ast)->id.number.plan;
07785 }
07786 if (l != NULL) {
07787 while (*l > '9' && *l != '*' && *l != '#') {
07788 switch (*l) {
07789 case 'U':
07790 prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf);
07791 break;
07792 case 'I':
07793 prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf);
07794 break;
07795 case 'N':
07796 prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf);
07797 break;
07798 case 'L':
07799 prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf);
07800 break;
07801 case 'S':
07802 prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf);
07803 break;
07804 case 'V':
07805 prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf);
07806 break;
07807 case 'R':
07808 prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf);
07809 break;
07810 case 'u':
07811 prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0);
07812 break;
07813 case 'e':
07814 prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0);
07815 break;
07816 case 'x':
07817 prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0);
07818 break;
07819 case 'f':
07820 prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0);
07821 break;
07822 case 'n':
07823 prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0);
07824 break;
07825 case 'p':
07826 prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0);
07827 break;
07828 case 'r':
07829 prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0);
07830 break;
07831 default:
07832 if (isalpha(*l)) {
07833 ast_log(LOG_WARNING,
07834 "Unrecognized prilocaldialplan %s modifier: %c\n",
07835 *l > 'Z' ? "NPI" : "TON", *l);
07836 }
07837 break;
07838 }
07839 l++;
07840 }
07841 }
07842 pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan,
07843 p->use_callingpres ? ast_channel_connected(ast)->id.number.presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE));
07844
07845 #if defined(HAVE_PRI_SUBADDR)
07846 if (ast_channel_connected(ast)->id.subaddress.valid) {
07847 struct pri_party_subaddress subaddress;
07848
07849 memset(&subaddress, 0, sizeof(subaddress));
07850 sig_pri_party_subaddress_from_ast(&subaddress, &ast_channel_connected(ast)->id.subaddress);
07851 pri_sr_set_caller_subaddress(sr, &subaddress);
07852 }
07853 #endif
07854
07855 sig_pri_redirecting_update(p, ast);
07856
07857 #ifdef SUPPORT_USERUSER
07858
07859 useruser = pbx_builtin_getvar_helper(p->owner, "USERUSERINFO");
07860 if (useruser)
07861 pri_sr_set_useruser(sr, useruser);
07862 #endif
07863
07864 #if defined(HAVE_PRI_CCSS)
07865 if (ast_cc_is_recall(ast, &core_id, sig_pri_cc_type_name)) {
07866 struct ast_cc_monitor *monitor;
07867 char device_name[AST_CHANNEL_NAME];
07868
07869
07870 ast_channel_get_device_name(ast, device_name, sizeof(device_name));
07871 monitor = ast_cc_get_monitor_by_recall_core_id(core_id, device_name);
07872 if (monitor) {
07873 struct sig_pri_cc_monitor_instance *instance;
07874
07875 instance = monitor->private_data;
07876
07877
07878 ast_assert(p->pri == instance->pri);
07879
07880 if (pri_cc_call(p->pri->pri, instance->cc_id, p->call, sr)) {
07881
07882 ast_log(LOG_WARNING, "Unable to setup CC recall call to device %s\n",
07883 device_name);
07884 ao2_ref(monitor, -1);
07885 pri_destroycall(p->pri->pri, p->call);
07886 p->call = NULL;
07887 pri_rel(p->pri);
07888 pri_sr_free(sr);
07889 return -1;
07890 }
07891 ao2_ref(monitor, -1);
07892 } else {
07893 core_id = -1;
07894 }
07895 } else
07896 #endif
07897 {
07898 core_id = -1;
07899 }
07900 if (core_id == -1 && pri_setup(p->pri->pri, p->call, sr)) {
07901 ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n",
07902 c + p->stripmsd + dp_strip, dialplan2str(p->pri->dialplan));
07903 pri_destroycall(p->pri->pri, p->call);
07904 p->call = NULL;
07905 pri_rel(p->pri);
07906 pri_sr_free(sr);
07907 return -1;
07908 }
07909 p->call_level = SIG_PRI_CALL_LEVEL_SETUP;
07910 pri_sr_free(sr);
07911 ast_setstate(ast, AST_STATE_DIALING);
07912 sig_pri_set_dialing(p, 1);
07913 pri_rel(p->pri);
07914 return 0;
07915 }
07916
07917 int sig_pri_indicate(struct sig_pri_chan *p, struct ast_channel *chan, int condition, const void *data, size_t datalen)
07918 {
07919 int res = -1;
07920
07921 switch (condition) {
07922 case AST_CONTROL_BUSY:
07923 if (p->priindication_oob || p->no_b_channel) {
07924 ast_channel_hangupcause_set(chan, AST_CAUSE_USER_BUSY);
07925 ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
07926 res = 0;
07927 break;
07928 }
07929 res = sig_pri_play_tone(p, SIG_PRI_TONE_BUSY);
07930 if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) {
07931 ast_channel_hangupcause_set(chan, AST_CAUSE_USER_BUSY);
07932 p->progress = 1;
07933 if (p->pri && p->pri->pri) {
07934 pri_grab(p, p->pri);
07935 #ifdef HAVE_PRI_PROG_W_CAUSE
07936 pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, ast_channel_hangupcause(chan));
07937 #else
07938 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
07939 #endif
07940 pri_rel(p->pri);
07941 }
07942 }
07943 break;
07944 case AST_CONTROL_RINGING:
07945 if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) {
07946 p->call_level = SIG_PRI_CALL_LEVEL_ALERTING;
07947 if (p->pri && p->pri->pri) {
07948 pri_grab(p, p->pri);
07949 pri_acknowledge(p->pri->pri,p->call, PVT_TO_CHANNEL(p),
07950 p->no_b_channel || p->digital ? 0 : 1);
07951 pri_rel(p->pri);
07952 }
07953 }
07954 res = sig_pri_play_tone(p, SIG_PRI_TONE_RINGTONE);
07955 if (ast_channel_state(chan) != AST_STATE_UP) {
07956 if (ast_channel_state(chan) != AST_STATE_RING)
07957 ast_setstate(chan, AST_STATE_RINGING);
07958 }
07959 break;
07960 case AST_CONTROL_PROCEEDING:
07961 ast_debug(1, "Received AST_CONTROL_PROCEEDING on %s\n",ast_channel_name(chan));
07962 if (p->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING && !p->outgoing) {
07963 p->call_level = SIG_PRI_CALL_LEVEL_PROCEEDING;
07964 if (p->pri && p->pri->pri) {
07965 pri_grab(p, p->pri);
07966 pri_proceeding(p->pri->pri,p->call, PVT_TO_CHANNEL(p),
07967 p->no_b_channel || p->digital ? 0 : 1);
07968 if (!p->no_b_channel && !p->digital) {
07969 sig_pri_set_dialing(p, 0);
07970 }
07971 pri_rel(p->pri);
07972 }
07973 }
07974
07975 res = 0;
07976 break;
07977 case AST_CONTROL_PROGRESS:
07978 ast_debug(1, "Received AST_CONTROL_PROGRESS on %s\n",ast_channel_name(chan));
07979 sig_pri_set_digital(p, 0);
07980 if (!p->progress && p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing
07981 && !p->no_b_channel) {
07982 p->progress = 1;
07983 if (p->pri && p->pri->pri) {
07984 pri_grab(p, p->pri);
07985 #ifdef HAVE_PRI_PROG_W_CAUSE
07986 pri_progress_with_cause(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1, -1);
07987 #else
07988 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
07989 #endif
07990 pri_rel(p->pri);
07991 }
07992 }
07993
07994 res = 0;
07995 break;
07996 case AST_CONTROL_INCOMPLETE:
07997
07998 if (p->call_level == SIG_PRI_CALL_LEVEL_CONNECT || (p->pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)) {
07999 res = 0;
08000 break;
08001 }
08002
08003 ast_channel_hangupcause_set(chan, AST_CAUSE_INVALID_NUMBER_FORMAT);
08004
08005 case AST_CONTROL_CONGESTION:
08006 if (p->priindication_oob || p->no_b_channel) {
08007
08008 switch (ast_channel_hangupcause(chan)) {
08009 case AST_CAUSE_USER_BUSY:
08010 case AST_CAUSE_NORMAL_CLEARING:
08011 case 0:
08012
08013 ast_channel_hangupcause_set(chan, AST_CAUSE_SWITCH_CONGESTION);
08014 break;
08015 default:
08016 break;
08017 }
08018 ast_channel_softhangup_internal_flag_add(chan, AST_SOFTHANGUP_DEV);
08019 res = 0;
08020 break;
08021 }
08022 res = sig_pri_play_tone(p, SIG_PRI_TONE_CONGESTION);
08023 if (p->call_level < SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) {
08024
08025 switch (ast_channel_hangupcause(chan)) {
08026 case AST_CAUSE_USER_BUSY:
08027 case AST_CAUSE_NORMAL_CLEARING:
08028 case 0:
08029
08030 ast_channel_hangupcause_set(chan, AST_CAUSE_SWITCH_CONGESTION);
08031 break;
08032 default:
08033 break;
08034 }
08035 p->progress = 1;
08036 if (p->pri && p->pri->pri) {
08037 pri_grab(p, p->pri);
08038 #ifdef HAVE_PRI_PROG_W_CAUSE
08039 pri_progress_with_cause(p->pri->pri, p->call, PVT_TO_CHANNEL(p), 1, ast_channel_hangupcause(chan));
08040 #else
08041 pri_progress(p->pri->pri,p->call, PVT_TO_CHANNEL(p), 1);
08042 #endif
08043 pri_rel(p->pri);
08044 }
08045 }
08046 break;
08047 case AST_CONTROL_HOLD:
08048 ast_copy_string(p->moh_suggested, S_OR(data, ""), sizeof(p->moh_suggested));
08049 if (p->pri) {
08050 pri_grab(p, p->pri);
08051 sig_pri_moh_fsm_event(chan, p, SIG_PRI_MOH_EVENT_HOLD);
08052 pri_rel(p->pri);
08053 } else {
08054
08055 ast_moh_start(chan, data, p->mohinterpret);
08056 }
08057 break;
08058 case AST_CONTROL_UNHOLD:
08059 if (p->pri) {
08060 pri_grab(p, p->pri);
08061 sig_pri_moh_fsm_event(chan, p, SIG_PRI_MOH_EVENT_UNHOLD);
08062 pri_rel(p->pri);
08063 } else {
08064
08065 ast_moh_stop(chan);
08066 }
08067 break;
08068 case AST_CONTROL_SRCUPDATE:
08069 res = 0;
08070 break;
08071 case -1:
08072 res = sig_pri_play_tone(p, -1);
08073 break;
08074 case AST_CONTROL_CONNECTED_LINE:
08075 ast_debug(1, "Received AST_CONTROL_CONNECTED_LINE on %s\n", ast_channel_name(chan));
08076 if (p->pri) {
08077 struct pri_party_connected_line connected;
08078 int dialplan;
08079 int prefix_strip;
08080 int colp_allowed = 0;
08081
08082 pri_grab(p, p->pri);
08083
08084
08085 switch (p->pri->colp_send) {
08086 case SIG_PRI_COLP_BLOCK:
08087 break;
08088 case SIG_PRI_COLP_CONNECT:
08089
08090
08091
08092
08093 if (p->call_level <= SIG_PRI_CALL_LEVEL_ALERTING && !p->outgoing) {
08094 colp_allowed = 1;
08095 }
08096 break;
08097 case SIG_PRI_COLP_UPDATE:
08098 colp_allowed = 1;
08099 break;
08100 }
08101 if (!colp_allowed) {
08102 pri_rel(p->pri);
08103 ast_debug(1, "Blocked AST_CONTROL_CONNECTED_LINE on %s\n",
08104 ast_channel_name(chan));
08105 break;
08106 }
08107
08108 memset(&connected, 0, sizeof(connected));
08109 sig_pri_party_id_from_ast(&connected.id, &ast_channel_connected(chan)->id);
08110
08111
08112 switch (p->pri->cpndialplan) {
08113 case -2:
08114 case -1:
08115
08116 prefix_strip = 0;
08117 if (!strncmp(connected.id.number.str, p->pri->internationalprefix,
08118 strlen(p->pri->internationalprefix))) {
08119 prefix_strip = strlen(p->pri->internationalprefix);
08120 dialplan = PRI_INTERNATIONAL_ISDN;
08121 } else if (!strncmp(connected.id.number.str, p->pri->nationalprefix,
08122 strlen(p->pri->nationalprefix))) {
08123 prefix_strip = strlen(p->pri->nationalprefix);
08124 dialplan = PRI_NATIONAL_ISDN;
08125 } else {
08126 dialplan = PRI_LOCAL_ISDN;
08127 }
08128 connected.id.number.plan = dialplan;
08129
08130 if (prefix_strip && p->pri->cpndialplan != -2) {
08131
08132 memmove(connected.id.number.str,
08133 connected.id.number.str + prefix_strip,
08134 strlen(connected.id.number.str + prefix_strip) + 1);
08135 }
08136 break;
08137 case 0:
08138
08139 break;
08140 default:
08141 connected.id.number.plan = p->pri->cpndialplan - 1;
08142 break;
08143 }
08144
08145 pri_connected_line_update(p->pri->pri, p->call, &connected);
08146 pri_rel(p->pri);
08147 }
08148 break;
08149 case AST_CONTROL_REDIRECTING:
08150 ast_debug(1, "Received AST_CONTROL_REDIRECTING on %s\n", ast_channel_name(chan));
08151 if (p->pri) {
08152 pri_grab(p, p->pri);
08153 sig_pri_redirecting_update(p, chan);
08154 pri_rel(p->pri);
08155 }
08156 break;
08157 case AST_CONTROL_AOC:
08158 #if defined(HAVE_PRI_AOC_EVENTS)
08159 {
08160 struct ast_aoc_decoded *decoded
08161 = ast_aoc_decode((struct ast_aoc_encoded *) data, datalen, chan);
08162 ast_debug(1, "Received AST_CONTROL_AOC on %s\n", ast_channel_name(chan));
08163 if (decoded && p->pri) {
08164 pri_grab(p, p->pri);
08165 switch (ast_aoc_get_msg_type(decoded)) {
08166 case AST_AOC_S:
08167 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_S) {
08168 sig_pri_aoc_s_from_ast(p, decoded);
08169 }
08170 break;
08171 case AST_AOC_D:
08172 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_D) {
08173 sig_pri_aoc_d_from_ast(p, decoded);
08174 }
08175 break;
08176 case AST_AOC_E:
08177 if (p->pri->aoc_passthrough_flag & SIG_PRI_AOC_GRANT_E) {
08178 sig_pri_aoc_e_from_ast(p, decoded);
08179 }
08180
08181
08182
08183
08184 if (p->waiting_for_aoce) {
08185 p->waiting_for_aoce = 0;
08186 ast_debug(1,
08187 "Received final AOC-E msg, continue with hangup on %s\n",
08188 ast_channel_name(chan));
08189 ast_softhangup_nolock(chan, AST_SOFTHANGUP_DEV);
08190 }
08191 break;
08192 case AST_AOC_REQUEST:
08193
08194
08195 if (ast_aoc_get_termination_request(decoded)) {
08196 pri_hangup(p->pri->pri, p->call, -1);
08197 }
08198 break;
08199 default:
08200 break;
08201 }
08202 pri_rel(p->pri);
08203 }
08204 ast_aoc_destroy_decoded(decoded);
08205 }
08206 #endif
08207 break;
08208 #if defined(HAVE_PRI_MCID)
08209 case AST_CONTROL_MCID:
08210 if (p->pri && p->pri->pri && p->pri->mcid_send) {
08211 pri_grab(p, p->pri);
08212 pri_mcid_req_send(p->pri->pri, p->call);
08213 pri_rel(p->pri);
08214 }
08215 break;
08216 #endif
08217 }
08218
08219 return res;
08220 }
08221
08222 int sig_pri_answer(struct sig_pri_chan *p, struct ast_channel *ast)
08223 {
08224 int res;
08225
08226
08227 pri_grab(p, p->pri);
08228 #if defined(HAVE_PRI_AOC_EVENTS)
08229 if (p->aoc_s_request_invoke_id_valid) {
08230
08231
08232
08233 pri_aoc_s_request_response_send(p->pri->pri, p->call,
08234 p->aoc_s_request_invoke_id, NULL);
08235 p->aoc_s_request_invoke_id_valid = 0;
08236 }
08237 #endif
08238 if (p->call_level < SIG_PRI_CALL_LEVEL_CONNECT) {
08239 p->call_level = SIG_PRI_CALL_LEVEL_CONNECT;
08240 }
08241 sig_pri_set_dialing(p, 0);
08242 sig_pri_open_media(p);
08243 res = pri_answer(p->pri->pri, p->call, 0, !p->digital);
08244 pri_rel(p->pri);
08245 ast_setstate(ast, AST_STATE_UP);
08246 return res;
08247 }
08248
08249
08250
08251
08252
08253
08254
08255
08256
08257
08258
08259 static int sig_pri_available_check(struct sig_pri_chan *pvt)
08260 {
08261
08262
08263
08264
08265 if (!pvt->no_b_channel && sig_pri_is_chan_available(pvt)) {
08266 return 1;
08267 }
08268 return 0;
08269 }
08270
08271 #if defined(HAVE_PRI_CALL_WAITING)
08272
08273
08274
08275
08276
08277
08278
08279
08280
08281
08282
08283
08284 static struct sig_pri_chan *sig_pri_cw_available(struct sig_pri_span *pri)
08285 {
08286 struct sig_pri_chan *cw;
08287 int idx;
08288
08289 cw = NULL;
08290 if (pri->num_call_waiting_calls < pri->max_call_waiting_calls) {
08291 if (!pri->num_call_waiting_calls) {
08292
08293
08294
08295
08296
08297 for (idx = 0; idx < pri->numchans; ++idx) {
08298 if (pri->pvts[idx] && sig_pri_available_check(pri->pvts[idx])) {
08299
08300 return cw;
08301 }
08302 }
08303 }
08304 idx = pri_find_empty_nobch(pri);
08305 if (0 <= idx) {
08306
08307 cw = pri->pvts[idx];
08308 cw->is_call_waiting = 1;
08309 sig_pri_init_config(cw, pri);
08310 ast_atomic_fetchadd_int(&pri->num_call_waiting_calls, 1);
08311 }
08312 }
08313 return cw;
08314 }
08315 #endif
08316
08317 int sig_pri_available(struct sig_pri_chan **pvt, int is_specific_channel)
08318 {
08319 struct sig_pri_chan *p = *pvt;
08320 struct sig_pri_span *pri;
08321
08322 if (!p->pri) {
08323
08324 return 0;
08325 }
08326 pri = p->pri;
08327
08328 ast_mutex_lock(&pri->lock);
08329 if (
08330 #if defined(HAVE_PRI_CALL_WAITING)
08331
08332
08333
08334
08335
08336
08337 !pri->num_call_waiting_calls &&
08338 #endif
08339 sig_pri_available_check(p)) {
08340 p->allocated = 1;
08341 ast_mutex_unlock(&pri->lock);
08342 return 1;
08343 }
08344
08345 #if defined(HAVE_PRI_CALL_WAITING)
08346 if (!is_specific_channel) {
08347 struct sig_pri_chan *cw;
08348
08349 cw = sig_pri_cw_available(pri);
08350 if (cw) {
08351
08352 cw->allocated = 1;
08353 *pvt = cw;
08354 ast_mutex_unlock(&pri->lock);
08355 return 1;
08356 }
08357 }
08358 #endif
08359 ast_mutex_unlock(&pri->lock);
08360 return 0;
08361 }
08362
08363
08364
08365 int sig_pri_digit_begin(struct sig_pri_chan *pvt, struct ast_channel *ast, char digit)
08366 {
08367 if (ast_channel_state(ast) == AST_STATE_DIALING) {
08368 if (pvt->call_level < SIG_PRI_CALL_LEVEL_OVERLAP) {
08369 unsigned int len;
08370
08371 len = strlen(pvt->dialdest);
08372 if (len < sizeof(pvt->dialdest) - 1) {
08373 ast_debug(1, "Queueing digit '%c' since setup_ack not yet received\n",
08374 digit);
08375 pvt->dialdest[len++] = digit;
08376 pvt->dialdest[len] = '\0';
08377 } else {
08378 ast_log(LOG_WARNING,
08379 "Span %d: Deferred digit buffer overflow for digit '%c'.\n",
08380 pvt->pri->span, digit);
08381 }
08382 return 0;
08383 }
08384 if (pvt->call_level < SIG_PRI_CALL_LEVEL_PROCEEDING) {
08385 pri_grab(pvt, pvt->pri);
08386 pri_information(pvt->pri->pri, pvt->call, digit);
08387 pri_rel(pvt->pri);
08388 return 0;
08389 }
08390 if (pvt->call_level < SIG_PRI_CALL_LEVEL_CONNECT) {
08391 ast_log(LOG_WARNING,
08392 "Span %d: Digit '%c' may be ignored by peer. (Call level:%d(%s))\n",
08393 pvt->pri->span, digit, pvt->call_level,
08394 sig_pri_call_level2str(pvt->call_level));
08395 }
08396 }
08397 return 1;
08398 }
08399
08400
08401
08402
08403
08404
08405
08406
08407
08408
08409
08410
08411 void sig_pri_dial_complete(struct sig_pri_chan *pvt, struct ast_channel *ast)
08412 {
08413
08414 if (pvt->call_level == SIG_PRI_CALL_LEVEL_DEFER_DIAL) {
08415 pvt->call_level = SIG_PRI_CALL_LEVEL_CONNECT;
08416
08417 sig_pri_open_media(pvt);
08418 {
08419 struct ast_frame f = {AST_FRAME_CONTROL, };
08420
08421 if (pvt->calls->queue_control) {
08422 pvt->calls->queue_control(pvt->chan_pvt, AST_CONTROL_ANSWER);
08423 }
08424
08425 f.subclass.integer = AST_CONTROL_ANSWER;
08426 ast_queue_frame(ast, &f);
08427 }
08428 sig_pri_set_dialing(pvt, 0);
08429
08430 sig_pri_set_echocanceller(pvt, 1);
08431 }
08432 }
08433
08434 #if defined(HAVE_PRI_MWI)
08435
08436
08437
08438
08439
08440
08441
08442
08443
08444
08445
08446
08447
08448 static void sig_pri_send_mwi_indication(struct sig_pri_span *pri, const char *vm_number, const char *mbox_number, const char *mbox_context, int num_messages)
08449 {
08450 struct pri_party_id voicemail;
08451 struct pri_party_id mailbox;
08452
08453 ast_debug(1, "Send MWI indication for %s@%s vm_number:%s num_messages:%d\n",
08454 mbox_number, mbox_context, S_OR(vm_number, "<not-present>"), num_messages);
08455
08456 memset(&mailbox, 0, sizeof(mailbox));
08457 mailbox.number.valid = 1;
08458 mailbox.number.presentation = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
08459 mailbox.number.plan = (PRI_TON_UNKNOWN << 4) | PRI_NPI_UNKNOWN;
08460 ast_copy_string(mailbox.number.str, mbox_number, sizeof(mailbox.number.str));
08461
08462 memset(&voicemail, 0, sizeof(voicemail));
08463 voicemail.number.valid = 1;
08464 voicemail.number.presentation = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
08465 voicemail.number.plan = (PRI_TON_UNKNOWN << 4) | PRI_NPI_UNKNOWN;
08466 if (vm_number) {
08467 ast_copy_string(voicemail.number.str, vm_number, sizeof(voicemail.number.str));
08468 }
08469
08470 ast_mutex_lock(&pri->lock);
08471 #if defined(HAVE_PRI_MWI_V2)
08472 pri_mwi_indicate_v2(pri->pri, &mailbox, &voicemail, 1 , num_messages,
08473 NULL, NULL, -1, 0);
08474 #else
08475 pri_mwi_indicate(pri->pri, &mailbox, 1 , num_messages, NULL, NULL, -1, 0);
08476 #endif
08477 ast_mutex_unlock(&pri->lock);
08478 }
08479 #endif
08480
08481 #if defined(HAVE_PRI_MWI)
08482
08483
08484
08485
08486
08487
08488
08489
08490
08491
08492 static void sig_pri_mwi_event_cb(const struct ast_event *event, void *userdata)
08493 {
08494 struct sig_pri_span *pri = userdata;
08495 const char *mbox_context;
08496 const char *mbox_number;
08497 int num_messages;
08498 int idx;
08499
08500 mbox_number = ast_event_get_ie_str(event, AST_EVENT_IE_MAILBOX);
08501 if (ast_strlen_zero(mbox_number)) {
08502 return;
08503 }
08504 mbox_context = ast_event_get_ie_str(event, AST_EVENT_IE_CONTEXT);
08505 if (ast_strlen_zero(mbox_context)) {
08506 return;
08507 }
08508 num_messages = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08509
08510 for (idx = 0; idx < ARRAY_LEN(pri->mbox); ++idx) {
08511 if (!pri->mbox[idx].sub) {
08512
08513 continue;
08514 }
08515 if (!strcmp(pri->mbox[idx].number, mbox_number)
08516 && !strcmp(pri->mbox[idx].context, mbox_context)) {
08517
08518 sig_pri_send_mwi_indication(pri, pri->mbox[idx].vm_number, mbox_number,
08519 mbox_context, num_messages);
08520 break;
08521 }
08522 }
08523 }
08524 #endif
08525
08526 #if defined(HAVE_PRI_MWI)
08527
08528
08529
08530
08531
08532
08533
08534
08535
08536 static void sig_pri_mwi_cache_update(struct sig_pri_span *pri)
08537 {
08538 int idx;
08539 int num_messages;
08540 struct ast_event *event;
08541
08542 for (idx = 0; idx < ARRAY_LEN(pri->mbox); ++idx) {
08543 if (!pri->mbox[idx].sub) {
08544
08545 continue;
08546 }
08547
08548 event = ast_event_get_cached(AST_EVENT_MWI,
08549 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, pri->mbox[idx].number,
08550 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, pri->mbox[idx].context,
08551 AST_EVENT_IE_END);
08552 if (!event) {
08553
08554 continue;
08555 }
08556 num_messages = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
08557 sig_pri_send_mwi_indication(pri, pri->mbox[idx].vm_number, pri->mbox[idx].number,
08558 pri->mbox[idx].context, num_messages);
08559 ast_event_destroy(event);
08560 }
08561 }
08562 #endif
08563
08564
08565
08566
08567
08568
08569
08570
08571
08572 void sig_pri_stop_pri(struct sig_pri_span *pri)
08573 {
08574 #if defined(HAVE_PRI_MWI)
08575 int idx;
08576 #endif
08577
08578 #if defined(HAVE_PRI_MWI)
08579 for (idx = 0; idx < ARRAY_LEN(pri->mbox); ++idx) {
08580 if (pri->mbox[idx].sub) {
08581 pri->mbox[idx].sub = ast_event_unsubscribe(pri->mbox[idx].sub);
08582 }
08583 }
08584 #endif
08585 }
08586
08587
08588
08589
08590
08591
08592
08593
08594
08595
08596
08597
08598
08599 static int sig_pri_cmp_pri_chans(const void *left, const void *right)
08600 {
08601 const struct sig_pri_chan *pvt_left;
08602 const struct sig_pri_chan *pvt_right;
08603
08604 pvt_left = *(struct sig_pri_chan **) left;
08605 pvt_right = *(struct sig_pri_chan **) right;
08606 if (!pvt_left) {
08607 if (!pvt_right) {
08608 return 0;
08609 }
08610 return 1;
08611 }
08612 if (!pvt_right) {
08613 return -1;
08614 }
08615
08616 return pvt_left->channel - pvt_right->channel;
08617 }
08618
08619
08620
08621
08622
08623
08624
08625
08626
08627
08628
08629
08630
08631
08632 static void sig_pri_sort_pri_chans(struct sig_pri_span *pri)
08633 {
08634 qsort(&pri->pvts, pri->numchans, sizeof(pri->pvts[0]), sig_pri_cmp_pri_chans);
08635 }
08636
08637 int sig_pri_start_pri(struct sig_pri_span *pri)
08638 {
08639 int x;
08640 int i;
08641 #if defined(HAVE_PRI_MWI)
08642 char *saveptr;
08643 char *prev_vm_number;
08644 struct ast_str *mwi_description = ast_str_alloca(64);
08645 #endif
08646
08647 #if defined(HAVE_PRI_MWI)
08648
08649 for (i = 0; i < ARRAY_LEN(pri->mbox); ++i) {
08650 if (pri->mbox[i].sub) {
08651 pri->mbox[i].sub = ast_event_unsubscribe(pri->mbox[i].sub);
08652 }
08653 }
08654 #endif
08655
08656 ast_mutex_init(&pri->lock);
08657 sig_pri_sort_pri_chans(pri);
08658
08659 #if defined(HAVE_PRI_MWI)
08660
08661
08662
08663
08664 prev_vm_number = NULL;
08665 saveptr = pri->mwi_vm_numbers;
08666 for (i = 0; i < ARRAY_LEN(pri->mbox); ++i) {
08667 char *vm_number;
08668
08669 vm_number = strsep(&saveptr, ",");
08670 if (vm_number) {
08671 vm_number = ast_strip(vm_number);
08672 }
08673 if (ast_strlen_zero(vm_number)) {
08674
08675 vm_number = prev_vm_number;
08676 } else {
08677
08678 prev_vm_number = vm_number;
08679 }
08680 pri->mbox[i].vm_number = vm_number;
08681 }
08682
08683
08684
08685
08686
08687 saveptr = pri->mwi_mailboxes;
08688 for (i = 0; i < ARRAY_LEN(pri->mbox); ++i) {
08689 char *mbox_number;
08690 char *mbox_context;
08691
08692 mbox_number = strsep(&saveptr, ",");
08693 if (!mbox_number) {
08694
08695 break;
08696 }
08697
08698 mbox_context = strchr(mbox_number, '@');
08699 if (mbox_context) {
08700 *mbox_context++ = '\0';
08701 mbox_context = ast_strip(mbox_context);
08702 }
08703 mbox_number = ast_strip(mbox_number);
08704 if (ast_strlen_zero(mbox_number)) {
08705
08706 continue;
08707 }
08708 if (ast_strlen_zero(mbox_context)) {
08709
08710 mbox_context = "default";
08711 }
08712
08713
08714 pri->mbox[i].number = mbox_number;
08715 pri->mbox[i].context = mbox_context;
08716 ast_str_set(&mwi_description, -1, "%s span %d[%d] MWI mailbox %s@%s",
08717 sig_pri_cc_type_name, pri->span, i, mbox_number, mbox_context);
08718 pri->mbox[i].sub = ast_event_subscribe(AST_EVENT_MWI, sig_pri_mwi_event_cb,
08719 ast_str_buffer(mwi_description), pri,
08720 AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mbox_number,
08721 AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, mbox_context,
08722 AST_EVENT_IE_END);
08723 if (!pri->mbox[i].sub) {
08724 ast_log(LOG_ERROR, "%s span %d could not subscribe to MWI events for %s@%s.",
08725 sig_pri_cc_type_name, pri->span, mbox_number, mbox_context);
08726 }
08727 #if defined(HAVE_PRI_MWI_V2)
08728 if (ast_strlen_zero(pri->mbox[i].vm_number)) {
08729 ast_log(LOG_WARNING, "%s span %d MWI voicemail number for %s@%s is empty.\n",
08730 sig_pri_cc_type_name, pri->span, mbox_number, mbox_context);
08731 }
08732 #endif
08733 }
08734 #endif
08735
08736 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
08737 if (pri->fds[i] == -1) {
08738 break;
08739 }
08740
08741 switch (pri->sig) {
08742 case SIG_BRI:
08743 pri->dchans[i] = pri_new_bri(pri->fds[i], 1, pri->nodetype, pri->switchtype);
08744 break;
08745 case SIG_BRI_PTMP:
08746 pri->dchans[i] = pri_new_bri(pri->fds[i], 0, pri->nodetype, pri->switchtype);
08747 break;
08748 default:
08749 pri->dchans[i] = pri_new(pri->fds[i], pri->nodetype, pri->switchtype);
08750 #if defined(HAVE_PRI_SERVICE_MESSAGES)
08751 if (pri->enable_service_message_support) {
08752 pri_set_service_message_support(pri->dchans[i], 1);
08753 }
08754 #endif
08755 break;
08756 }
08757
08758 pri_set_overlapdial(pri->dchans[i], (pri->overlapdial & DAHDI_OVERLAPDIAL_OUTGOING) ? 1 : 0);
08759 #ifdef HAVE_PRI_PROG_W_CAUSE
08760 pri_set_chan_mapping_logical(pri->dchans[i], pri->qsigchannelmapping == DAHDI_CHAN_MAPPING_LOGICAL);
08761 #endif
08762 #ifdef HAVE_PRI_INBANDDISCONNECT
08763 pri_set_inbanddisconnect(pri->dchans[i], pri->inbanddisconnect);
08764 #endif
08765
08766 if (i)
08767 pri_enslave(pri->dchans[0], pri->dchans[i]);
08768 if (!pri->dchans[i]) {
08769 if (pri->fds[i] > 0)
08770 close(pri->fds[i]);
08771 pri->fds[i] = -1;
08772 ast_log(LOG_ERROR, "Unable to create PRI structure\n");
08773 return -1;
08774 }
08775 pri_set_debug(pri->dchans[i], SIG_PRI_DEBUG_DEFAULT);
08776 pri_set_nsf(pri->dchans[i], pri->nsf);
08777 #ifdef PRI_GETSET_TIMERS
08778 for (x = 0; x < PRI_MAX_TIMERS; x++) {
08779 if (pri->pritimers[x] != 0)
08780 pri_set_timer(pri->dchans[i], x, pri->pritimers[x]);
08781 }
08782 #endif
08783 }
08784
08785
08786 pri->pri = pri->dchans[0];
08787
08788 #if defined(HAVE_PRI_CALL_HOLD)
08789 pri_hold_enable(pri->pri, 1);
08790 #endif
08791 #if defined(HAVE_PRI_CALL_REROUTING)
08792 pri_reroute_enable(pri->pri, 1);
08793 #endif
08794 #if defined(HAVE_PRI_HANGUP_FIX)
08795 pri_hangup_fix_enable(pri->pri, 1);
08796 #endif
08797 #if defined(HAVE_PRI_CCSS)
08798 pri_cc_enable(pri->pri, 1);
08799 pri_cc_recall_mode(pri->pri, pri->cc_ptmp_recall_mode);
08800 pri_cc_retain_signaling_req(pri->pri, pri->cc_qsig_signaling_link_req);
08801 pri_cc_retain_signaling_rsp(pri->pri, pri->cc_qsig_signaling_link_rsp);
08802 #endif
08803 #if defined(HAVE_PRI_TRANSFER)
08804 pri_transfer_enable(pri->pri, 1);
08805 #endif
08806 #if defined(HAVE_PRI_AOC_EVENTS)
08807 pri_aoc_events_enable(pri->pri, 1);
08808 #endif
08809 #if defined(HAVE_PRI_CALL_WAITING)
08810 pri_connect_ack_enable(pri->pri, 1);
08811 #endif
08812 #if defined(HAVE_PRI_MCID)
08813 pri_mcid_enable(pri->pri, 1);
08814 #endif
08815 #if defined(HAVE_PRI_DISPLAY_TEXT)
08816 pri_display_options_send(pri->pri, pri->display_flags_send);
08817 pri_display_options_receive(pri->pri, pri->display_flags_receive);
08818 #endif
08819 #if defined(HAVE_PRI_DATETIME_SEND)
08820 pri_date_time_send_option(pri->pri, pri->datetime_send);
08821 #endif
08822 #if defined(HAVE_PRI_L2_PERSISTENCE)
08823 pri_persistent_layer2_option(pri->pri, pri->l2_persistence);
08824 #endif
08825
08826 pri->resetpos = -1;
08827 if (ast_pthread_create_background(&pri->master, NULL, pri_dchannel, pri)) {
08828 for (i = 0; i < SIG_PRI_NUM_DCHANS; i++) {
08829 if (!pri->dchans[i])
08830 break;
08831 if (pri->fds[i] > 0)
08832 close(pri->fds[i]);
08833 pri->fds[i] = -1;
08834 }
08835 ast_log(LOG_ERROR, "Unable to spawn D-channel: %s\n", strerror(errno));
08836 return -1;
08837 }
08838
08839 #if defined(HAVE_PRI_MWI)
08840
08841
08842
08843
08844
08845
08846
08847
08848 sig_pri_mwi_cache_update(pri);
08849 #endif
08850
08851 return 0;
08852 }
08853
08854
08855
08856
08857
08858
08859
08860
08861
08862
08863
08864 void sig_pri_chan_alarm_notify(struct sig_pri_chan *p, int noalarm)
08865 {
08866 pri_grab(p, p->pri);
08867 sig_pri_set_alarm(p, !noalarm);
08868 if (!noalarm) {
08869 if (pri_get_timer(p->pri->pri, PRI_TIMER_T309) < 0) {
08870
08871 if (p->call) {
08872 pri_destroycall(p->pri->pri, p->call);
08873 p->call = NULL;
08874 }
08875 if (p->owner)
08876 ast_channel_softhangup_internal_flag_add(p->owner, AST_SOFTHANGUP_DEV);
08877 }
08878 }
08879 sig_pri_span_devstate_changed(p->pri);
08880 pri_rel(p->pri);
08881 }
08882
08883
08884
08885
08886
08887
08888
08889
08890 int sig_pri_is_alarm_ignored(struct sig_pri_span *pri)
08891 {
08892 return pri->layer1_ignored;
08893 }
08894
08895 struct sig_pri_chan *sig_pri_chan_new(void *pvt_data, struct sig_pri_callback *callback, struct sig_pri_span *pri, int logicalspan, int channo, int trunkgroup)
08896 {
08897 struct sig_pri_chan *p;
08898
08899 p = ast_calloc(1, sizeof(*p));
08900 if (!p)
08901 return p;
08902
08903 p->logicalspan = logicalspan;
08904 p->prioffset = channo;
08905 p->mastertrunkgroup = trunkgroup;
08906
08907 p->calls = callback;
08908 p->chan_pvt = pvt_data;
08909
08910 p->pri = pri;
08911
08912 return p;
08913 }
08914
08915
08916
08917
08918
08919
08920
08921
08922
08923 void sig_pri_chan_delete(struct sig_pri_chan *doomed)
08924 {
08925 ast_free(doomed);
08926 }
08927
08928 #define SIG_PRI_SC_HEADER "%-4s %4s %-4s %-4s %-10s %-4s %s\n"
08929 #define SIG_PRI_SC_LINE "%4d %4d %-4s %-4s %-10s %-4s %s"
08930 void sig_pri_cli_show_channels_header(int fd)
08931 {
08932 ast_cli(fd, SIG_PRI_SC_HEADER, "PRI", "", "B", "Chan", "Call", "PRI", "Channel");
08933 ast_cli(fd, SIG_PRI_SC_HEADER, "Span", "Chan", "Chan", "Idle", "Level", "Call", "Name");
08934 }
08935
08936 void sig_pri_cli_show_channels(int fd, struct sig_pri_span *pri)
08937 {
08938 char line[256];
08939 int idx;
08940 struct sig_pri_chan *pvt;
08941
08942 ast_mutex_lock(&pri->lock);
08943 for (idx = 0; idx < pri->numchans; ++idx) {
08944 if (!pri->pvts[idx]) {
08945 continue;
08946 }
08947 pvt = pri->pvts[idx];
08948 sig_pri_lock_private(pvt);
08949 sig_pri_lock_owner(pri, idx);
08950 if (pvt->no_b_channel && sig_pri_is_chan_available(pvt)) {
08951
08952 sig_pri_unlock_private(pvt);
08953 continue;
08954 }
08955
08956 snprintf(line, sizeof(line), SIG_PRI_SC_LINE,
08957 pri->span,
08958 pvt->channel,
08959 pvt->no_b_channel ? "No" : "Yes",
08960 sig_pri_is_chan_available(pvt) ? "Yes" : "No",
08961 sig_pri_call_level2str(pvt->call_level),
08962 pvt->call ? "Yes" : "No",
08963 pvt->owner ? ast_channel_name(pvt->owner) : "");
08964
08965 if (pvt->owner) {
08966 ast_channel_unlock(pvt->owner);
08967 }
08968 sig_pri_unlock_private(pvt);
08969
08970 ast_mutex_unlock(&pri->lock);
08971 ast_cli(fd, "%s\n", line);
08972 ast_mutex_lock(&pri->lock);
08973 }
08974 ast_mutex_unlock(&pri->lock);
08975 }
08976
08977 static void build_status(char *s, size_t len, int status, int active)
08978 {
08979 if (!s || len < 1) {
08980 return;
08981 }
08982 snprintf(s, len, "%s%s, %s",
08983 (status & DCHAN_NOTINALARM) ? "" : "In Alarm, ",
08984 (status & DCHAN_UP) ? "Up" : "Down",
08985 (active) ? "Active" : "Standby");
08986 }
08987
08988 void sig_pri_cli_show_spans(int fd, int span, struct sig_pri_span *pri)
08989 {
08990 char status[256];
08991 int x;
08992 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
08993 if (pri->dchans[x]) {
08994 build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri);
08995 ast_cli(fd, "PRI span %d/%d: %s\n", span, x, status);
08996 }
08997 }
08998 }
08999
09000 void sig_pri_cli_show_span(int fd, int *dchannels, struct sig_pri_span *pri)
09001 {
09002 int x;
09003 char status[256];
09004
09005 for (x = 0; x < SIG_PRI_NUM_DCHANS; x++) {
09006 if (pri->dchans[x]) {
09007 #ifdef PRI_DUMP_INFO_STR
09008 char *info_str = NULL;
09009 #endif
09010 ast_cli(fd, "%s D-channel: %d\n", pri_order(x), dchannels[x]);
09011 build_status(status, sizeof(status), pri->dchanavail[x], pri->dchans[x] == pri->pri);
09012 ast_cli(fd, "Status: %s\n", status);
09013 ast_mutex_lock(&pri->lock);
09014 #ifdef PRI_DUMP_INFO_STR
09015 info_str = pri_dump_info_str(pri->pri);
09016 if (info_str) {
09017 ast_cli(fd, "%s", info_str);
09018 free(info_str);
09019 }
09020 #else
09021 pri_dump_info(pri->pri);
09022 #endif
09023 ast_mutex_unlock(&pri->lock);
09024 ast_cli(fd, "Overlap Recv: %s\n\n", (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING)?"Yes":"No");
09025 ast_cli(fd, "\n");
09026 }
09027 }
09028 }
09029
09030 int pri_send_keypad_facility_exec(struct sig_pri_chan *p, const char *digits)
09031 {
09032 sig_pri_lock_private(p);
09033
09034 if (!p->pri || !p->call) {
09035 ast_debug(1, "Unable to find pri or call on channel!\n");
09036 sig_pri_unlock_private(p);
09037 return -1;
09038 }
09039
09040 pri_grab(p, p->pri);
09041 pri_keypad_facility(p->pri->pri, p->call, digits);
09042 pri_rel(p->pri);
09043
09044 sig_pri_unlock_private(p);
09045
09046 return 0;
09047 }
09048
09049 int pri_send_callrerouting_facility_exec(struct sig_pri_chan *p, enum ast_channel_state chanstate, const char *destination, const char *original, const char *reason)
09050 {
09051 int res;
09052
09053 sig_pri_lock_private(p);
09054
09055 if (!p->pri || !p->call) {
09056 ast_debug(1, "Unable to find pri or call on channel!\n");
09057 sig_pri_unlock_private(p);
09058 return -1;
09059 }
09060
09061 pri_grab(p, p->pri);
09062 res = pri_callrerouting_facility(p->pri->pri, p->call, destination, original, reason);
09063 pri_rel(p->pri);
09064
09065 sig_pri_unlock_private(p);
09066
09067 return res;
09068 }
09069
09070 #if defined(HAVE_PRI_SERVICE_MESSAGES)
09071 int pri_maintenance_bservice(struct pri *pri, struct sig_pri_chan *p, int changestatus)
09072 {
09073 int channel = PVT_TO_CHANNEL(p);
09074 int span = PRI_SPAN(channel);
09075
09076 return pri_maintenance_service(pri, span, channel, changestatus);
09077 }
09078 #endif
09079
09080 void sig_pri_fixup(struct ast_channel *oldchan, struct ast_channel *newchan, struct sig_pri_chan *pchan)
09081 {
09082 if (pchan->owner == oldchan) {
09083 pchan->owner = newchan;
09084 }
09085 }
09086
09087 #if defined(HAVE_PRI_DISPLAY_TEXT)
09088
09089
09090
09091
09092
09093
09094
09095
09096
09097 void sig_pri_sendtext(struct sig_pri_chan *p, const char *text)
09098 {
09099 struct pri_subcmd_display_txt display;
09100
09101 if (p->pri && p->pri->pri) {
09102 ast_copy_string(display.text, text, sizeof(display.text));
09103 display.length = strlen(display.text);
09104 display.char_set = 0;
09105 pri_grab(p, p->pri);
09106 pri_display_text(p->pri->pri, p->call, &display);
09107 pri_rel(p->pri);
09108 }
09109 }
09110 #endif
09111
09112 #if defined(HAVE_PRI_CCSS)
09113
09114
09115
09116
09117
09118
09119
09120
09121
09122
09123
09124
09125
09126
09127
09128
09129 int sig_pri_cc_agent_init(struct ast_cc_agent *agent, struct sig_pri_chan *pvt_chan)
09130 {
09131 struct sig_pri_cc_agent_prv *cc_pvt;
09132
09133 cc_pvt = ast_calloc(1, sizeof(*cc_pvt));
09134 if (!cc_pvt) {
09135 return -1;
09136 }
09137
09138 ast_mutex_lock(&pvt_chan->pri->lock);
09139 cc_pvt->pri = pvt_chan->pri;
09140 cc_pvt->cc_id = pri_cc_available(pvt_chan->pri->pri, pvt_chan->call);
09141 ast_mutex_unlock(&pvt_chan->pri->lock);
09142 if (cc_pvt->cc_id == -1) {
09143 ast_free(cc_pvt);
09144 return -1;
09145 }
09146 agent->private_data = cc_pvt;
09147 return 0;
09148 }
09149 #endif
09150
09151 #if defined(HAVE_PRI_CCSS)
09152
09153
09154
09155
09156
09157
09158
09159
09160
09161
09162
09163
09164
09165
09166
09167
09168
09169
09170
09171
09172
09173 int sig_pri_cc_agent_start_offer_timer(struct ast_cc_agent *agent)
09174 {
09175
09176 return 0;
09177 }
09178 #endif
09179
09180 #if defined(HAVE_PRI_CCSS)
09181
09182
09183
09184
09185
09186
09187
09188
09189
09190
09191
09192
09193
09194 int sig_pri_cc_agent_stop_offer_timer(struct ast_cc_agent *agent)
09195 {
09196
09197 return 0;
09198 }
09199 #endif
09200
09201 #if defined(HAVE_PRI_CCSS)
09202
09203
09204
09205
09206
09207
09208
09209
09210
09211
09212
09213
09214
09215
09216
09217
09218
09219
09220
09221
09222 void sig_pri_cc_agent_req_rsp(struct ast_cc_agent *agent, enum ast_cc_agent_response_reason reason)
09223 {
09224 struct sig_pri_cc_agent_prv *cc_pvt;
09225 int res;
09226 int status;
09227 const char *failed_msg;
09228 static const char *failed_to_send = "Failed to send the CC request response.";
09229 static const char *not_accepted = "The core declined the CC request.";
09230
09231 cc_pvt = agent->private_data;
09232 ast_mutex_lock(&cc_pvt->pri->lock);
09233 if (cc_pvt->cc_request_response_pending) {
09234 cc_pvt->cc_request_response_pending = 0;
09235
09236
09237 status = 2;
09238 switch (reason) {
09239 case AST_CC_AGENT_RESPONSE_SUCCESS:
09240 status = 0;
09241 break;
09242 case AST_CC_AGENT_RESPONSE_FAILURE_INVALID:
09243 status = 2;
09244 break;
09245 case AST_CC_AGENT_RESPONSE_FAILURE_TOO_MANY:
09246 status = 5;
09247 break;
09248 }
09249
09250 res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id, status);
09251 if (!status) {
09252
09253 if (res) {
09254 failed_msg = failed_to_send;
09255 } else {
09256 failed_msg = NULL;
09257 }
09258 } else {
09259
09260 if (res) {
09261 failed_msg = failed_to_send;
09262 } else {
09263 failed_msg = not_accepted;
09264 }
09265 }
09266 } else {
09267 failed_msg = NULL;
09268 }
09269 ast_mutex_unlock(&cc_pvt->pri->lock);
09270 if (failed_msg) {
09271 ast_cc_failed(agent->core_id, "%s agent: %s", sig_pri_cc_type_name, failed_msg);
09272 }
09273 }
09274 #endif
09275
09276 #if defined(HAVE_PRI_CCSS)
09277
09278
09279
09280
09281
09282
09283
09284
09285
09286
09287
09288
09289
09290
09291
09292 int sig_pri_cc_agent_status_req(struct ast_cc_agent *agent)
09293 {
09294 struct sig_pri_cc_agent_prv *cc_pvt;
09295
09296 cc_pvt = agent->private_data;
09297 ast_mutex_lock(&cc_pvt->pri->lock);
09298 pri_cc_status_req(cc_pvt->pri->pri, cc_pvt->cc_id);
09299 ast_mutex_unlock(&cc_pvt->pri->lock);
09300 return 0;
09301 }
09302 #endif
09303
09304 #if defined(HAVE_PRI_CCSS)
09305
09306
09307
09308
09309
09310
09311
09312
09313
09314
09315
09316
09317
09318
09319
09320
09321
09322
09323
09324
09325
09326
09327 int sig_pri_cc_agent_stop_ringing(struct ast_cc_agent *agent)
09328 {
09329 struct sig_pri_cc_agent_prv *cc_pvt;
09330
09331 cc_pvt = agent->private_data;
09332 ast_mutex_lock(&cc_pvt->pri->lock);
09333 pri_cc_stop_alerting(cc_pvt->pri->pri, cc_pvt->cc_id);
09334 ast_mutex_unlock(&cc_pvt->pri->lock);
09335 return 0;
09336 }
09337 #endif
09338
09339 #if defined(HAVE_PRI_CCSS)
09340
09341
09342
09343
09344
09345
09346
09347
09348
09349
09350
09351
09352
09353
09354
09355
09356
09357
09358
09359
09360
09361 int sig_pri_cc_agent_party_b_free(struct ast_cc_agent *agent)
09362 {
09363 struct sig_pri_cc_agent_prv *cc_pvt;
09364
09365 cc_pvt = agent->private_data;
09366 ast_mutex_lock(&cc_pvt->pri->lock);
09367 pri_cc_b_free(cc_pvt->pri->pri, cc_pvt->cc_id);
09368 ast_mutex_unlock(&cc_pvt->pri->lock);
09369 return 0;
09370 }
09371 #endif
09372
09373 #if defined(HAVE_PRI_CCSS)
09374
09375
09376
09377
09378
09379
09380
09381
09382
09383
09384
09385
09386
09387
09388
09389
09390 int sig_pri_cc_agent_start_monitoring(struct ast_cc_agent *agent)
09391 {
09392
09393 return 0;
09394 }
09395 #endif
09396
09397 #if defined(HAVE_PRI_CCSS)
09398
09399
09400
09401
09402
09403
09404
09405
09406
09407
09408
09409
09410
09411
09412
09413
09414
09415
09416
09417 int sig_pri_cc_agent_callee_available(struct ast_cc_agent *agent)
09418 {
09419 struct sig_pri_cc_agent_prv *cc_pvt;
09420
09421 cc_pvt = agent->private_data;
09422 ast_mutex_lock(&cc_pvt->pri->lock);
09423 pri_cc_remote_user_free(cc_pvt->pri->pri, cc_pvt->cc_id);
09424 ast_mutex_unlock(&cc_pvt->pri->lock);
09425 return 0;
09426 }
09427 #endif
09428
09429 #if defined(HAVE_PRI_CCSS)
09430
09431
09432
09433
09434
09435
09436
09437
09438
09439
09440
09441
09442
09443
09444
09445
09446 void sig_pri_cc_agent_destructor(struct ast_cc_agent *agent)
09447 {
09448 struct sig_pri_cc_agent_prv *cc_pvt;
09449 int res;
09450
09451 cc_pvt = agent->private_data;
09452 if (!cc_pvt) {
09453
09454 return;
09455 }
09456 ast_mutex_lock(&cc_pvt->pri->lock);
09457 res = -1;
09458 if (cc_pvt->cc_request_response_pending) {
09459 res = pri_cc_req_rsp(cc_pvt->pri->pri, cc_pvt->cc_id, 2);
09460 }
09461 if (res) {
09462 pri_cc_cancel(cc_pvt->pri->pri, cc_pvt->cc_id);
09463 }
09464 ast_mutex_unlock(&cc_pvt->pri->lock);
09465 ast_free(cc_pvt);
09466 }
09467 #endif
09468
09469 #if defined(HAVE_PRI_CCSS)
09470
09471
09472
09473
09474
09475
09476
09477
09478
09479
09480 static int sig_pri_cc_monitor_instance_hash_fn(const void *obj, const int flags)
09481 {
09482 const struct sig_pri_cc_monitor_instance *monitor_instance = obj;
09483
09484 return monitor_instance->core_id;
09485 }
09486 #endif
09487
09488 #if defined(HAVE_PRI_CCSS)
09489
09490
09491
09492
09493
09494
09495
09496
09497
09498
09499
09500 static int sig_pri_cc_monitor_instance_cmp_fn(void *obj, void *arg, int flags)
09501 {
09502 struct sig_pri_cc_monitor_instance *monitor_1 = obj;
09503 struct sig_pri_cc_monitor_instance *monitor_2 = arg;
09504
09505 return monitor_1->core_id == monitor_2->core_id ? CMP_MATCH | CMP_STOP : 0;
09506 }
09507 #endif
09508
09509 #if defined(HAVE_PRI_CCSS)
09510
09511
09512
09513
09514
09515
09516
09517
09518
09519
09520
09521
09522
09523
09524
09525
09526
09527
09528 int sig_pri_cc_monitor_req_cc(struct ast_cc_monitor *monitor, int *available_timer_id)
09529 {
09530 struct sig_pri_cc_monitor_instance *instance;
09531 int cc_mode;
09532 int res;
09533
09534 switch (monitor->service_offered) {
09535 case AST_CC_CCBS:
09536 cc_mode = 0;
09537 break;
09538 case AST_CC_CCNR:
09539 cc_mode = 1;
09540 break;
09541 default:
09542
09543 return -1;
09544 }
09545
09546 instance = monitor->private_data;
09547
09548
09549 ast_mutex_lock(&instance->pri->lock);
09550 res = pri_cc_req(instance->pri->pri, instance->cc_id, cc_mode);
09551 ast_mutex_unlock(&instance->pri->lock);
09552
09553 return res;
09554 }
09555 #endif
09556
09557 #if defined(HAVE_PRI_CCSS)
09558
09559
09560
09561
09562
09563
09564
09565
09566
09567
09568
09569
09570
09571 int sig_pri_cc_monitor_suspend(struct ast_cc_monitor *monitor)
09572 {
09573 struct sig_pri_cc_monitor_instance *instance;
09574
09575 instance = monitor->private_data;
09576 ast_mutex_lock(&instance->pri->lock);
09577 pri_cc_status(instance->pri->pri, instance->cc_id, 1);
09578 ast_mutex_unlock(&instance->pri->lock);
09579
09580 return 0;
09581 }
09582 #endif
09583
09584 #if defined(HAVE_PRI_CCSS)
09585
09586
09587
09588
09589
09590
09591
09592
09593
09594
09595
09596
09597 int sig_pri_cc_monitor_unsuspend(struct ast_cc_monitor *monitor)
09598 {
09599 struct sig_pri_cc_monitor_instance *instance;
09600
09601 instance = monitor->private_data;
09602 ast_mutex_lock(&instance->pri->lock);
09603 pri_cc_status(instance->pri->pri, instance->cc_id, 0);
09604 ast_mutex_unlock(&instance->pri->lock);
09605
09606 return 0;
09607 }
09608 #endif
09609
09610 #if defined(HAVE_PRI_CCSS)
09611
09612
09613
09614
09615
09616
09617
09618
09619
09620
09621
09622
09623
09624
09625
09626
09627 int sig_pri_cc_monitor_status_rsp(struct ast_cc_monitor *monitor, enum ast_device_state devstate)
09628 {
09629 struct sig_pri_cc_monitor_instance *instance;
09630 int cc_status;
09631
09632 switch (devstate) {
09633 case AST_DEVICE_UNKNOWN:
09634 case AST_DEVICE_NOT_INUSE:
09635 cc_status = 0;
09636 break;
09637 case AST_DEVICE_BUSY:
09638 case AST_DEVICE_INUSE:
09639 cc_status = 1;
09640 break;
09641 default:
09642
09643 return 0;
09644 }
09645 instance = monitor->private_data;
09646 ast_mutex_lock(&instance->pri->lock);
09647 pri_cc_status_req_rsp(instance->pri->pri, instance->cc_id, cc_status);
09648 ast_mutex_unlock(&instance->pri->lock);
09649
09650 return 0;
09651 }
09652 #endif
09653
09654 #if defined(HAVE_PRI_CCSS)
09655
09656
09657
09658
09659
09660
09661
09662
09663
09664
09665
09666
09667
09668
09669
09670
09671
09672 int sig_pri_cc_monitor_cancel_available_timer(struct ast_cc_monitor *monitor, int *sched_id)
09673 {
09674
09675
09676
09677
09678
09679 return 0;
09680 }
09681 #endif
09682
09683 #if defined(HAVE_PRI_CCSS)
09684
09685
09686
09687
09688
09689
09690
09691
09692
09693
09694
09695 void sig_pri_cc_monitor_destructor(void *monitor_pvt)
09696 {
09697 struct sig_pri_cc_monitor_instance *instance;
09698
09699 instance = monitor_pvt;
09700 if (!instance) {
09701 return;
09702 }
09703 ao2_unlink(sig_pri_cc_monitors, instance);
09704 ao2_ref(instance, -1);
09705 }
09706 #endif
09707
09708
09709
09710
09711
09712
09713
09714
09715
09716
09717 int sig_pri_load(const char *cc_type_name)
09718 {
09719 #if defined(HAVE_PRI_CCSS)
09720 sig_pri_cc_type_name = cc_type_name;
09721 sig_pri_cc_monitors = ao2_container_alloc(37, sig_pri_cc_monitor_instance_hash_fn,
09722 sig_pri_cc_monitor_instance_cmp_fn);
09723 if (!sig_pri_cc_monitors) {
09724 return -1;
09725 }
09726 #endif
09727 return 0;
09728 }
09729
09730
09731
09732
09733
09734
09735
09736 void sig_pri_unload(void)
09737 {
09738 #if defined(HAVE_PRI_CCSS)
09739 if (sig_pri_cc_monitors) {
09740 ao2_ref(sig_pri_cc_monitors, -1);
09741 sig_pri_cc_monitors = NULL;
09742 }
09743 #endif
09744 }
09745
09746 #endif