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