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