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