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