diff -Naur asterisk-issue8824-2008-12-10/channels/chan_dahdi.c asterisk-issue8824-2008-12-10.new/channels/chan_dahdi.c --- asterisk-issue8824-2008-12-10/channels/chan_dahdi.c 2008-12-11 16:37:52.000000000 +0100 +++ asterisk-issue8824-2008-12-10.new/channels/chan_dahdi.c 2008-12-11 16:06:35.000000000 +0100 @@ -335,296 +335,6 @@ * event cache instead of checking the mailbox directly. */ } -#ifdef HAVE_PRI -#define CC_TIMEOUT_PEERLINKCHANNELS 60 -#define CC_MAX_PEERLINKCHANNELS 20*CC_TIMEOUT_PEERLINKCHANNELS -AST_MUTEX_DEFINE_STATIC(peerlink_lock); -static struct peerlink_s { - struct ast_channel *channel; - time_t age; -} peerlinkchannel[CC_MAX_PEERLINKCHANNELS+1]; - - -#define CC_IDLE 1 -#define CC_WAIT_ACK 2 -#define CC_INVOKED_A_RET 3 -#define CC_WAIT_USER_A_ANSWER_N 4 - -#define CCBS_SPAN(h) ((h) & 0xff) -#define CCBS_CR(h) (((h) >> 16) & 0xffff) -#define CCBS_HANDLE(s,r) ((s & 0xff) | ((r & 0xffff) << 16)) - -struct ccbsnr_link { - unsigned int handle; - char type; - unsigned int state; - char callingnum[AST_MAX_EXTENSION]; - char callernum[AST_MAX_EXTENSION]; - char callername[AST_MAX_EXTENSION]; - char context[AST_MAX_CONTEXT]; - int priority; - q931_call *call; - struct ast_channel *peer; - time_t age; - struct ccbsnr_link *next; -}; - -static struct ccbsnr_link *ccbsnr_list = NULL; -AST_MUTEX_DEFINE_STATIC(ccbsnr_lock); - -/* - * remove too old CCBS/CCNR entries - * (must be called with ccbsnr_lock held) - */ -static void del_old_ccbsnr(void) -{ - struct ccbsnr_link *ccbsnr; - struct ccbsnr_link *tmp = NULL; - - ccbsnr = ccbsnr_list; - while (ccbsnr) { - if ((ccbsnr->age + 86400) < time(NULL)) { - ast_verbose(VERBOSE_PREFIX_3 "DAHDI: CCBS/CCNR handle=%d timeout.\n", ccbsnr->handle); - if (!tmp) { - ccbsnr_list = ccbsnr->next; - } else { - tmp->next = ccbsnr->next; - } - ast_free(ccbsnr); - break; - } - tmp = ccbsnr; - ccbsnr = ccbsnr->next; - } -} - - -/* - * return the pointer to ccbsnr structure by handle - */ -static struct ccbsnr_link *ccbsnr_get_link(unsigned int handle, unsigned int *state) -{ - struct ccbsnr_link *ret; - - if (state) { - *state = CC_IDLE; - } - - if (handle) - ast_verbose(VERBOSE_PREFIX_3 "DAHDI: ccbsnr_get_link: handle=%x\n", handle); - - ast_mutex_lock(&ccbsnr_lock); - - ret = ccbsnr_list; - while (ret) { - if ((handle) && (ret->handle == handle)) { - if (state) { - *state = ret->state; - } - break; - } - ret = ret->next; - } - ast_mutex_unlock(&ccbsnr_lock); - - return ret; -} - - -static struct ccbsnr_link *ccbsnr_get_link_by_number(const char *callingnum, const char *callernum, unsigned int *state) -{ - struct ccbsnr_link *ret; - - if (state) { - *state = CC_IDLE; - } - - if (callingnum && callernum) { - if (strlen(callingnum) && strlen(callernum)) - ast_verbose(VERBOSE_PREFIX_3 "DAHDI: ccbsnr_get_link_by_number: callingnum=%s callernum=%s\n", callingnum, callernum); - } else { - return NULL; - } - - ast_mutex_lock(&ccbsnr_lock); - - ret = ccbsnr_list; - while (ret) { - if (!strcmp(ret->callingnum, callingnum) && !strcmp(ret->callernum, callernum)) { - if (state) { - *state = ret->state; - } - break; - } - ret = ret->next; - } - ast_mutex_unlock(&ccbsnr_lock); - - return ret; -} - - -/* - * select CCBS/CCNR id - */ -static struct ccbsnr_link *ccbsnr_select_link(unsigned int handle) { - - struct ccbsnr_link *ccbsnr; - struct ccbsnr_link * ret = NULL; - int ccbsnronprispan; - int cr; - - ast_verbose(VERBOSE_PREFIX_3 "DAHDI: ccbsnr_select_link: handle=%x\n", handle); - - ast_mutex_lock(&ccbsnr_lock); - - ccbsnr = ccbsnr_list; - while (ccbsnr) { - if ((ccbsnr->handle == handle) && (ccbsnr->state == CC_WAIT_ACK)) { - ccbsnr->state = CC_INVOKED_A_RET; - ret = ccbsnr; - - ccbsnronprispan = CCBS_SPAN(handle); - cr = CCBS_CR(handle); - ast_verbose(VERBOSE_PREFIX_3 "DAHDI: request CCBS/NR span=%d type=%d cr =%x handle=%x state=%d (%s, %s, %s, %s, %d)\n", - ccbsnronprispan, ccbsnr->type, cr, handle, ccbsnr->state, ccbsnr->callingnum, ccbsnr->callernum, ccbsnr->callername, ccbsnr->context, ccbsnr->priority); - break; - } - ccbsnr = ccbsnr->next; - } - ast_mutex_unlock(&ccbsnr_lock); - - return ret; -} - - -/* - * a CCBS/CCNR link was removed - */ -static void ccbsnr_del_link(unsigned int handle) -{ - struct ccbsnr_link *ccbsnr; - struct ccbsnr_link *tmp = NULL; - int ccbsnronprispan; - int cr; - - ast_verbose(VERBOSE_PREFIX_3 "DAHDI: ccbsnr_del_link: handle=%x\n", handle); - - ast_mutex_lock(&ccbsnr_lock); - - ccbsnr = ccbsnr_list; - while (ccbsnr) { - if (ccbsnr->handle == handle) { - if (!tmp) { - ccbsnr_list = ccbsnr->next; - } else { - tmp->next = ccbsnr->next; - } - ccbsnronprispan = CCBS_SPAN(handle); - cr = CCBS_CR(handle); - - ast_verbose(VERBOSE_PREFIX_3 "DAHDI: destroy CCBS/NR span=%d type=%d cr=%x handle=%x state=%d (%s, %s, %s, %s, %d)\n", - ccbsnronprispan, ccbsnr->type, cr, handle, ccbsnr->state, ccbsnr->callingnum, ccbsnr->callernum, ccbsnr->callername, ccbsnr->context, ccbsnr->priority); - - if (ccbsnr->call ) - ast_log(LOG_NOTICE, "call(%x) must be 'NULL'. Memory leak!\n", (int)ccbsnr->call); - - ast_free(ccbsnr); - break; - } - tmp = ccbsnr; - ccbsnr = ccbsnr->next; - } - ast_mutex_unlock(&ccbsnr_lock); -} - - -/* - * return the counter of ccbsnrlinks to callingnumber - */ -static int ccbsnr_count_callingnum(const char *callingnum) -{ - int count = 0; - struct ccbsnr_link *ccbsnr; - - ast_mutex_lock(&ccbsnr_lock); - ccbsnr = ccbsnr_list; - while (ccbsnr) { - if (!strcmp(ccbsnr->callingnum, callingnum)) { - count++; - } - ccbsnr = ccbsnr->next; - } - ast_mutex_unlock(&ccbsnr_lock); - - return count; -} - - -/* - * Add a new peer link id - */ -static int cc_add_peer_link_id(struct ast_channel *ast) -{ - int i; - - ast_mutex_lock(&peerlink_lock); - for (i = 1; i <= CC_MAX_PEERLINKCHANNELS; i++) { - if (peerlinkchannel[i].channel == NULL) { - peerlinkchannel[i].channel = ast; - peerlinkchannel[i].age = time(NULL); - break; - } else { - /* remove too old entries */ - if ((peerlinkchannel[i].age + CC_TIMEOUT_PEERLINKCHANNELS) < time(NULL)) { - peerlinkchannel[i].channel = NULL; - ast_verbose(VERBOSE_PREFIX_4 "DAHDI: peerlink %d timeout-erase\n", i); - } - } - } - ast_mutex_unlock(&peerlink_lock); - if (i > CC_MAX_PEERLINKCHANNELS) { - return -1; - } - return i; -} - -/* - * Get and remove peer link id - */ -static struct ast_channel *cc_get_peer_link_id(const char *p) -{ - int id = -1; - struct ast_channel *ast = NULL; - - if (p) { - id = (int)strtol(p, NULL, 0); - } - - ast_mutex_lock(&peerlink_lock); - if ((id >= 1) && (id <= CC_MAX_PEERLINKCHANNELS)) { - ast = peerlinkchannel[id].channel; - peerlinkchannel[id].channel = NULL; - } - ast_verbose(VERBOSE_PREFIX_4 "DAHDI: peerlink %d allocated, peer is %s\n", id, (ast)?ast->name:"unlinked"); - ast_mutex_unlock(&peerlink_lock); - return ast; -} - -static void cc_destroy_all_peer_link_id(void) -{ - int i; - - ast_mutex_lock(&peerlink_lock); - for (i = 1; i <= CC_MAX_PEERLINKCHANNELS; i++) { - /* remove entries */ - peerlinkchannel[i].channel = NULL; - } - ast_mutex_unlock(&peerlink_lock); -} -#endif - - /*! \brief Avoid the silly dahdi_getevent which ignores a bunch of events */ static inline int dahdi_get_event(int fd) { @@ -756,7 +466,6 @@ time_t lastreset; /*!< time when unused channels were last reset */ long resetinterval; /*!< Interval (in seconds) for resetting unused channels */ int sig; - unsigned int use_callingpres:1; /*!< used for no channel call */ struct dahdi_pvt *pvts[MAX_CHANNELS]; /*!< Member channel pvt structs */ struct dahdi_pvt *crvs; /*!< Member CRV structs */ struct dahdi_pvt *crvend; /*!< Pointer to end of CRV structs */ @@ -854,9 +563,6 @@ ast_mutex_t lock; struct ast_channel *owner; /*!< Our current active owner (if applicable) */ /*!< Up to three channels can be associated with this call */ -#ifdef HAVE_PRI - int dummychannel; /*!< Flag for dummy Channel. used for ccbsnr (shellscript) */ -#endif struct dahdi_subchannel sub_unused; /*!< Just a safety precaution */ struct dahdi_subchannel subs[3]; /*!< Sub-channels */ @@ -944,9 +650,6 @@ unsigned int resetting:1; unsigned int setup_ack:1; #endif -#ifdef HAVE_PRI - unsigned int ccringout:1; /*!< Append CC-Ringout facility */ -#endif unsigned int use_smdi:1; /* Whether to use SMDI on this channel */ struct mwisend_info mwisend_data; struct ast_smdi_interface *smdi_iface; /* The serial port to listen for SMDI data on */ @@ -1233,282 +936,6 @@ #define GET_CHANNEL(p) ((p)->channel) #endif -#ifdef HAVE_PRI -static inline int pri_nochannel_grab(struct dahdi_pri *pri) -{ - int res; - /* Grab the lock first */ - do { - res = ast_mutex_trylock(&pri->lock); - if (res) { - /* Release the lock and try again */ - usleep(1); - } - } while (res); - /* Then break the poll */ - pthread_kill(pri->master, SIGURG); - return 0; -} - - -/* - * a new CCBS/CCNR id was received - */ -static struct ccbsnr_link *ccbsnr_new_id(int callreference, int ccbsnronprispan, q931_call *call, int type, char* callingnum, char *callernum, - char *callername, char *context, int priority, struct ast_channel *peer) { - struct ccbsnr_link *ccbsnr; - - ccbsnr = ast_calloc(1, sizeof(*ccbsnr)); - if (!ccbsnr) { - ast_log(LOG_ERROR, "Unable to allocate CCBS/CCNR struct.\n"); - return NULL; - } - - ccbsnr->age = time(NULL); - ccbsnr->type = type; - ccbsnr->call = call; - ccbsnr->handle = CCBS_HANDLE(ccbsnronprispan,callreference); - ccbsnr->peer = peer; - ccbsnr->priority = priority; - ccbsnr->state = CC_WAIT_ACK; - ast_copy_string(ccbsnr->callingnum, callingnum, sizeof(ccbsnr->callingnum)); - ast_copy_string(ccbsnr->callernum, callernum, sizeof(ccbsnr->callernum)); - ast_copy_string(ccbsnr->callername, callername, sizeof(ccbsnr->callername)); - ast_copy_string(ccbsnr->context, context, sizeof(ccbsnr->context)); - - ast_mutex_lock(&ccbsnr_lock); - del_old_ccbsnr(); - ccbsnr->next = ccbsnr_list; - ccbsnr_list = ccbsnr; - ast_mutex_unlock(&ccbsnr_lock); - - return ccbsnr; -} - - -/* - * Clear CCBS/CCNR links - */ -static void ccbsnr_clear_all(void) -{ - struct ccbsnr_link *ccbsnr; - struct ccbsnr_link *tmp = NULL; - unsigned int span; - int cr; - - ast_mutex_lock(&ccbsnr_lock); - ccbsnr = ccbsnr_list; - while (ccbsnr) { - tmp = ccbsnr; - ccbsnr = ccbsnr->next; - span = CCBS_SPAN(tmp->handle); - cr = CCBS_CR(tmp->handle); - ast_log(LOG_NOTICE, "ccbsnr_clear_all: ccbsnr found(%x) span %d\n", (int)tmp, span); - ast_free(tmp); - } - - ccbsnr_list = NULL; - ast_mutex_unlock(&ccbsnr_lock); -} - - -static void ccbsnr_destroy_all_of_span(struct dahdi_pri *pri) -{ - int span = pri->span; - struct ccbsnr_link *ccbsnr; - struct ccbsnr_link *prev = NULL; - struct ccbsnr_link *tmp = NULL; - q931_call *call; - unsigned int ccbs_span; - int cr; - - ast_mutex_lock(&ccbsnr_lock); - ccbsnr = ccbsnr_list; - while (ccbsnr) { - ccbs_span = CCBS_SPAN(ccbsnr->handle); - cr = CCBS_CR(ccbsnr->handle); - if (ccbs_span == span) { - ast_log(LOG_NOTICE, "ccbsnr found(%x) ccbs_span %d\n", (int)ccbsnr, ccbs_span); - - tmp = ccbsnr; - if (!prev) { - ccbsnr_list = ccbsnr->next; - } else { - prev->next = ccbsnr->next; - } - ccbsnr = ccbsnr->next; - - if (tmp->call) { - call = pri_find_call(pri->pri, cr); - ast_log(LOG_NOTICE, "call found(%x)\n", (int)call); - - if (call == tmp->call) { - ast_log(LOG_WARNING, "Q931Call(%x) cr(%x) found, hang it up it.\n", (int)call, cr); - - pri_call_set_cc_operation(call, PRI_CC_CANCEL); - pri_hangup(pri->pri, call, -1); - pri_destroycall(pri->pri, call); - } - } - ast_free(tmp); - ast_log(LOG_WARNING, "Free ccbsnr-link (%x) ccbs_span %d\n", (int)tmp, ccbs_span); - } else { - prev = ccbsnr; - ccbsnr = ccbsnr->next; - } - } - - ast_mutex_unlock(&ccbsnr_lock); -} - - -/* - * Destroy CCBS/CCNR links - */ -static void ccbsnr_destroy_all(void) -{ - struct ccbsnr_link *ccbsnr; - struct ccbsnr_link *tmp = NULL; - q931_call *call; - struct dahdi_pri *pri; - unsigned int span; - int cr; - - ast_mutex_lock(&ccbsnr_lock); - ccbsnr = ccbsnr_list; - while (ccbsnr) { - tmp = ccbsnr; - ccbsnr = ccbsnr->next; - span = CCBS_SPAN(tmp->handle); - cr = CCBS_CR(tmp->handle); - ast_log(LOG_NOTICE, "ccbsnr_destroy_all: ccbsnr found(%x) span %d\n", (int)tmp, span); - - if (tmp->call) { - pri = &pris[span - 1]; - - if (pri_nochannel_grab(pri)) { - ast_log(LOG_ERROR, "Failed to grab PRI!\n"); - return; - } - - call = pri_find_call(pri->pri, cr); - ast_log(LOG_NOTICE, "ccbsnr_destroy_all: call found(%x)\n", (int)call); - - if (call == tmp->call) { - ast_log(LOG_WARNING, "ccbsnr_destroy_all(%x) cr(%x):Q931_call found, hang it up it.\n", (int)call, cr); - - pri_call_set_cc_operation(call, PRI_CC_CANCEL); - pri_hangup(pri->pri, call, -1); - } - - pri_rel(pri); - } - ast_free(tmp); - } - - ccbsnr_list = NULL; - ast_mutex_unlock(&ccbsnr_lock); -} - - -/* - * on an activated CCBS, the remote party is now free - */ -static void ccbsnr_remote_user_free(unsigned int handle) -{ - - struct ast_channel *ast; - struct ccbsnr_link *ccbsnr; - int state = AST_STATE_DOWN; - struct dahdi_pvt *dummy; - - ast_verbose(VERBOSE_PREFIX_3 "ccbsnr_remote_user_free: handle %x\n", handle); - - ast_mutex_lock(&ccbsnr_lock); - - ccbsnr = ccbsnr_list; - while (ccbsnr) { - if (ccbsnr->handle == handle) { - break; - } - ccbsnr = ccbsnr->next; - } - ast_mutex_unlock(&ccbsnr_lock); - - if (!(ccbsnr)) { - ast_log(LOG_ERROR, "DAHDI: CCBS/CCBR reference not found!\n"); - return; - } - - ast = ast_channel_alloc(0, state, 0, 0, "", "", "", 0, 0); - if (!ast) { - ast_log(LOG_ERROR, "Unable to allocate channel!\n"); - return; - } - - ast->tech = &dahdi_tech; - dummy = ast_calloc(1,sizeof(*dummy)); - if (!dummy) { - ast_log(LOG_ERROR, "Unable to allocate dummy:struct dahdi_pvt!\n"); - return; - } - ast_mutex_init(&dummy->lock); - dummy->dummychannel = 1; - ast->tech_pvt = dummy; - ast_string_field_build(ast, name, "CCBSNR/%x", ccbsnr->handle); - - ast_verbose(VERBOSE_PREFIX_3 "ccbsnr_remote_user_free: ast=%x name=%s ast->_softhangup=%x ast->tech%x\n", - (int)ast, ast->name, ast->_softhangup, (int)ast->tech); - - ast->_softhangup = 0; - memset(&ast->whentohangup, 0, sizeof(ast->whentohangup)); - - ast->priority = ccbsnr->priority; - - if (ast->cid.cid_num) { - ast_free(ast->cid.cid_num); - } - ast->cid.cid_num = ast_strdup(ccbsnr->callernum); - - if (ast->cid.cid_dnid) { - ast_free(ast->cid.cid_dnid); - } - ast->cid.cid_name = ast_strdup(ccbsnr->callername); - - ast_copy_string(ast->context, ccbsnr->context, sizeof(ast->context)); - ast_copy_string(ast->exten, ccbsnr->callingnum, sizeof(ast->exten)); - - ast_setstate(ast, state); - ast_verbose(VERBOSE_PREFIX_3 "ccbsnr_remote_user_free: ast_pbx_start:ast %x cc-req(%d)\n", (int)ast, ccbsnr->type); - - if (ast_pbx_start(ast)) { - pri_call_set_cc_operation(ccbsnr->call, PRI_CC_CANCEL); - - int ccbs_span = CCBS_SPAN(ccbsnr->handle); - struct dahdi_pri *ccbs_pri = &pris[ccbs_span - 1]; - - if (pri_nochannel_grab(ccbs_pri)) { - ast_log(LOG_WARNING, "Failed to grab PRI!\n"); - return; - } - pri_hangup(ccbs_pri->pri, ccbsnr->call, -1); - pri_rel(ccbs_pri); - ccbsnr->call = NULL; - ccbsnr_del_link(ccbsnr->handle); - - ast_log(LOG_ERROR, "DAHDI: CCBS/CCNR: Unable to start pbx!\n"); - - return; - } else { - ast_verbose(VERBOSE_PREFIX_3 "DAHDI-span%d: started PBX for CCBS/CCNR callback (context:%s/callingnum:%s/prio:%d)callernum:%s callername:%s peer=%x\n", - CCBS_SPAN(ccbsnr->handle), ccbsnr->context, ccbsnr->callingnum, ccbsnr->priority, ccbsnr->callernum, ccbsnr->callername, (int)ccbsnr->peer); - ccbsnr->state = CC_WAIT_USER_A_ANSWER_N; - } - - ast_module_ref(ast_module_info->self); -} -#endif - struct dahdi_pvt *round_robin[32]; #ifdef HAVE_PRI @@ -3322,11 +2749,6 @@ #ifdef HAVE_PRI if (p->pri) { struct pri_sr *sr; - struct ast_channel *peer; - struct ccbsnr_link *cclink; - unsigned int state = 0; - char *callingnum; - char *callernum; #ifdef SUPPORT_USERUSER const char *useruser; #endif @@ -3580,57 +3002,6 @@ if (useruser) pri_sr_set_useruser(sr, useruser); #endif - callingnum = c + p->stripmsd + dp_strip; - callernum = l ? (l + ldp_strip) : NULL; - - /* search ccbs-list */ - cclink = ccbsnr_get_link_by_number(callingnum, callernum, &state); - - if (p->ccringout) { - if (cclink) { - pri_sr_set_ccringout(sr, p->ccringout); - } else { - ast_verbose(VERBOSE_PREFIX_3 "DAHDI-Call: ccbsnr-link found. state(%d). Change to Dial without CC-Ringout\n", state); - p->ccringout = 0; - } - } else { - /* Normal Call */ - if (cclink) { - int span = CCBS_SPAN(cclink->handle); - struct dahdi_pri *ccbs_pri; - - switch (state) { - case CC_WAIT_ACK: - case CC_WAIT_USER_A_ANSWER_N: - case CC_INVOKED_A_RET: - ast_verbose(VERBOSE_PREFIX_4 "DAHDI-Call: CCBS-List-Obj 0x%x: handle %x span(%d) peer=%x\n", \ - (int)cclink, cclink->handle, span, (int)cclink->peer); - - if (cclink->call) { - pri_call_set_cc_operation(cclink->call, PRI_CC_CANCEL); - - ccbs_pri = &pris[span - 1]; - if (ccbs_pri != p->pri) { - if (pri_nochannel_grab(ccbs_pri)) { - ast_log(LOG_WARNING, "Failed to grab PRI!\n"); - return -1; - } - - pri_hangup(ccbs_pri->pri, cclink->call, -1); - - pri_rel(ccbs_pri); - } else { - pri_hangup(p->pri->pri, cclink->call, -1); - } - } - cclink->call = NULL; - ccbsnr_del_link(cclink->handle); - break; - default: - ast_verbose(VERBOSE_PREFIX_3 "DAHDI-Call:wrong ccbsnr-link-state '%d'\n", state); - } - } - } if (pri_setup(p->pri->pri, p->call, sr)) { ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", @@ -3643,17 +3014,6 @@ pri_sr_free(sr); ast_setstate(ast, AST_STATE_DIALING); pri_rel(p->pri); - peer = cc_get_peer_link_id(pbx_builtin_getvar_helper(ast, "CCPEERLINKID")); - if (peer) { - char tmp[32]; - - pbx_builtin_setvar_helper(peer, "CCPEERLINKID", "0"); - - ast_verbose(VERBOSE_PREFIX_3 "DAHDI peer link is %x %s.\n", (int)peer, peer->name); - - snprintf(tmp, sizeof(tmp) - 1, "%d", p->pri->span); - pbx_builtin_setvar_helper(peer, "CCBSNRONPRISPAN", tmp); - } } #endif ast_mutex_unlock(&p->lock); @@ -3708,564 +3068,61 @@ iflist = cur->next; if (iflist) iflist->prev = NULL; - else - ifend = NULL; - } - destroy_dahdi_pvt(&cur); - } - } else { - if (prev) { - prev->next = cur->next; - if (prev->next) - prev->next->prev = prev; - else - ifend = prev; - } else { - iflist = cur->next; - if (iflist) - iflist->prev = NULL; - else - ifend = NULL; - } - destroy_dahdi_pvt(&cur); - } - return 0; -} - -static void destroy_all_channels(void) -{ - int x; - struct dahdi_pvt *p, *pl; - - while (num_restart_pending) { - usleep(1); - } - - ast_mutex_lock(&iflock); - /* Destroy all the interfaces and free their memory */ - p = iflist; - while (p) { - /* Free any callerid */ - if (p->cidspill) - ast_free(p->cidspill); - pl = p; - p = p->next; - x = pl->channel; - /* Free associated memory */ - if (pl) - destroy_dahdi_pvt(&pl); - if (option_verbose > 2) - ast_verbose(VERBOSE_PREFIX_2 "Unregistered channel %d\n", x); - } - iflist = NULL; - ifcount = 0; - ast_mutex_unlock(&iflock); -} - -#ifdef HAVE_PRI -static char *dahdi_qsig_ccbsnr_initialize_app = "DAHDIQsigCcbsnrInitialize"; - -/* - * store the peer for future actions - */ -static int dahdi_qsig_ccbsnr_initialize_exec(struct ast_channel *ast, void *param) -{ - char buffer[32]; - int id; - - id = cc_add_peer_link_id(ast); - - if (id >= 0) { - snprintf(buffer, sizeof(buffer) - 1, "%d", id); - pbx_builtin_setvar_helper(ast, "_CCPEERLINKID", buffer); - pbx_builtin_setvar_helper(ast, "_CCBSNRREQSTATE", "AVAILABLE"); - pbx_builtin_setvar_helper(ast, "_CCBSNRONPRISPAN", "0"); - } - - ast_verbose(VERBOSE_PREFIX_3 "Added %s as DAHDI peer link.\n", - ast->name); - - return 0; -} - -#define CC_MAX_NOCHANNELS 256 - -static char *dahdi_qsic_check_ccbsnr_app = "DAHDIQsigCheckCcbsnr"; - -static int dahdi_qsig_check_ccbsnr_exec(struct ast_channel *ast, void *param) -{ - -#define MAX_DISSALOWED 4 - - char *data = (char *) param; - char *parse, *tok, *tokb; - int maxcount = 0; - char *dissalowed_callernum[MAX_DISSALOWED] = {NULL, NULL, NULL, NULL}; - char *maxcounter = NULL; - char *callingnum = NULL; - char *callernum = NULL; - int count = 0; - int flag = 0; - char *c; - int cnt; - - if (ast_strlen_zero(param)) { - ast_debug(1, "Check command requires arguments!\n"); - return -1; - } - - parse = ast_strdupa(data); - tok = strtok_r(parse, "|", &tokb); - if (!tok) { - ast_log(LOG_WARNING, "DAHDIQsigCheckCcbsnr requires at least maxcounter argument\n"); - return -1; - } - maxcounter = tok; - if (*tokb != '|') { - tok = strtok_r(NULL, "|", &tokb); - if (!tok) { - ast_log(LOG_WARNING, "DAHDIQsigCheckCcbsnr without callingnum argument\n"); - return -1; - } - callingnum = tok; - } else { - callingnum = ""; - tokb++; - } - - if (*tokb != '|') { - tok = strtok_r(NULL, "|", &tokb); - if (!tok) { - ast_log(LOG_NOTICE, "DAHDIQsigCheckCcbsnr without callernum argument\n"); - return -1; - } - callernum = tok; - } else { - callernum = ""; - tokb++; - } - - - /* Optional args 'dissalowed_callernum'*/ - for (cnt = 0; cnt < MAX_DISSALOWED; cnt++) { - tok = strtok_r(NULL, "|", &tokb); - if (!tok) { - ast_verbose(VERBOSE_PREFIX_3 "DAHDIQsigCheckCcbsnr without dissalowed-callernum argument\n"); - } else { - dissalowed_callernum[cnt] = tok; - } - } - - ast_verbose(VERBOSE_PREFIX_3 "DAHDI ccbsnr: '%s' '%s' '%s'\n", maxcounter, callingnum, callernum); - for (cnt = 0; cnt < MAX_DISSALOWED; cnt++) { - if (dissalowed_callernum[cnt]) - ast_verbose(VERBOSE_PREFIX_3 "DAHDI ccbsnr: '%s'\n", dissalowed_callernum[cnt]); - } - - maxcount = (int)strtol(maxcounter, NULL, 0); - if (maxcount > CC_MAX_NOCHANNELS) { - ast_debug(1, "DAHDIQsigCheckCcbsnr range:(%d - %d)\n", 0, CC_MAX_NOCHANNELS); - return -1; - } else if (!maxcount) { - maxcount = CC_MAX_NOCHANNELS; - } - - if (ast_strlen_zero(callernum)) { - flag = 1; - ast_verbose(VERBOSE_PREFIX_3 "DAHDIQsigCheckCcbsnr: no caller number - |\n"); - } else if (ast_strlen_zero(callingnum)) { - flag = 1; - ast_verbose(VERBOSE_PREFIX_3 "DAHDIQsigCheckCcbsnr: no caller number - |\n"); - } else if (!strcmp(callernum, callingnum)) { - flag = 1; - ast_verbose(VERBOSE_PREFIX_3 "DAHDIQsigCheckCcbsnr: caller number(%s) and calling number are equal\n", callernum); - } else { - for (c = callernum; *c; c++) - *c = tolower(*c); - for (cnt = 0; cnt < MAX_DISSALOWED; cnt++) { - if (dissalowed_callernum[cnt]) { - if (!strcmp(callernum, dissalowed_callernum[cnt])) { - flag = 1; - ast_verbose(VERBOSE_PREFIX_4 "DAHDIQsigCheckCcbsnr: dissalowed_callernum - %s\n", dissalowed_callernum[cnt]); - break; - } - } - } - count = ccbsnr_count_callingnum(callingnum); - ast_verbose(VERBOSE_PREFIX_4 "DAHDIQsigCheckCcbsnr: maxcount(%d) count(%d)\n", maxcount, count); - if (count >= maxcount) { - flag = 1; - ast_verbose(VERBOSE_PREFIX_3 "DAHDIQsigCheckCcbsnr: count(%d) |\n", count); - } - } - - if (flag) { - ast_verbose(VERBOSE_PREFIX_3 "Set CCBSNRREQSTATE to NOTAVAILABLE\n"); - pbx_builtin_setvar_helper(ast, "CCBSNRREQSTATE", "NOTAVAILABLE"); - } - - return 0; -} - - -static char *dahdi_qsic_clear_nochannel_app = "DAHDIQsigClearNoChannel"; - -static int dahdi_qsig_clear_nochannel_exec(struct ast_channel *ast, void *param) -{ - char *callingnum, *callernum; - char *data = (char *) param; - - struct ccbsnr_link *cclink; - unsigned int state = 0; - struct dahdi_pri *pri; - unsigned int span; - int cr; - q931_call *call; - - if (ast_strlen_zero(data)) { - ast_debug(1, "Clear command requires arguments!\n"); - return -1; - } - - callingnum = strsep(&data, "|"); - callernum = data; - - if ((!callingnum) || (!callernum)) { - ast_debug(1, "DAHDIQsigClearNoChannel requires |\n"); - return -1; - } - - ast_verbose(VERBOSE_PREFIX_3 "DAHDI ccbsnr: '%s' '%s'\n", callingnum, callernum); - - cclink = ccbsnr_get_link_by_number(callingnum, callernum, &state); - if (cclink) { - ast_verbose(VERBOSE_PREFIX_3 "DAHDI ccbsnr: state(%d)\n", state); - - switch (state) { - case CC_WAIT_ACK: - case CC_WAIT_USER_A_ANSWER_N: - case CC_INVOKED_A_RET: - if (cclink->call) { - span = CCBS_SPAN(cclink->handle); - pri = &pris[span - 1]; - - if (pri_nochannel_grab(pri)) { - ast_log(LOG_WARNING, "Failed to grab PRI!\n"); - return -1; - } - cr = CCBS_CR(cclink->handle); - call = pri_find_call(pri->pri, cr); - - ast_log(LOG_NOTICE, "destroy cclink: call found(%x)\n", (int)call); - - if (call == cclink->call) { - ast_log(LOG_NOTICE, "destroy call(%x) cr(%x):Q931_call found, hang it up it.\n", (int)call, cr); - - pri_call_set_cc_operation(call, PRI_CC_CANCEL); - pri_hangup(pri->pri, call, -1); - } - pri_rel(pri); - } - ast_mutex_lock(&ccbsnr_lock); - cclink->call = NULL; - ast_mutex_unlock(&ccbsnr_lock); - ccbsnr_del_link(cclink->handle); - break; - default: - ast_verbose(VERBOSE_PREFIX_2 "PRI_EVENT_HANGUP:wrong state '%d'\n", state); - } - } else { - ast_verbose(VERBOSE_PREFIX_2 "dahdi_qsig_clear_nochannel: CCBS-List-Obj for callingnum(%s) callernum(%s) not found\n", callingnum, callernum); - return 0; - } - return 0; - -} - - -static char *dahdi_qsic_ccbsnr_request_app = "DAHDIQsigCcbsnrRequest"; - -static int dahdi_qsig_ccbsnr_request_exec(struct ast_channel *ast, void *param) -{ - int type; - char *ccbsnrtype, *callingnum, *callernum, *callername, *context, *priority; - char *data = (char *) param; - - const char *ccbsnronprispan; - unsigned int prispan; - char *c, *l, *n; - char *s = NULL; - int dp_strip; - int ldp_strip; - struct pri_sr *sr; - int pridialplan; - int prilocaldialplan; - l = NULL; - n = NULL; - - struct dahdi_pri *pri; - struct ccbsnr_link *cclink; - q931_call *call; - - /* sets for no channel call */ - int channel = 0; - int exclusive = 1; - int nonisdn = 0; - int transmode = -1; - int userl1 = ast->transfercapability; - int cref = 0; - - if (ast_strlen_zero(data)) { - ast_debug(1, "CCBScommand requires arguments!\n"); - return -1; - } - - ccbsnrtype = strsep(&data, "|"); - callingnum = strsep(&data, "|"); - callernum = strsep(&data, "|"); - callername = strsep(&data, "|"); - context = strsep(&data, "|"); - priority = data; - - if ((!ccbsnrtype) || (!callingnum) || (!callernum) || (!callername) || (!context) || (!priority)) { - ast_debug(1, "DAHDIQsigCcbsnrRequest requires |||||\n"); - return -1; - } - - ast_verbose(VERBOSE_PREFIX_3 "DAHDI ccbsnr: '%s' '%s' '%s' '%s' '%s' '%s'\n", - ccbsnrtype, callingnum, callernum, callername, context, priority); - - if (!strcmp(callernum, callingnum)) { - ast_debug(1, "DAHDIQsigCcbsnrRequest: caller number(%s) and calling number are equal\n", callernum); - return -1; - } - - if (!strcmp(ccbsnrtype, "CCBS")) - type = PRI_CC_CCBSREQUEST; - else if (!strcmp(ccbsnrtype, "CCNR")) - type = PRI_CC_CCNRREQUEST; - else { - ast_verbose(VERBOSE_PREFIX_2 "DAHDIQsigCcbsnrRequest requires |||||\n"); - return -1; - } - - ccbsnronprispan = pbx_builtin_getvar_helper(ast, "CCBSNRONPRISPAN"); - ast_verbose(VERBOSE_PREFIX_3 "DAHDI ccbsnronprispan: '%s'\n", ccbsnronprispan); - - if (ast_strlen_zero(ccbsnronprispan)) { - ast_debug(1, "DAHDIQsigCcbsnrRequest: Use initialize befor use this funktion\n"); - return -1; - } - - prispan = (int)strtol(ccbsnronprispan, NULL, 0); - - if ((prispan < 1) || (prispan > NUM_SPANS)) { - ast_verbose(VERBOSE_PREFIX_2 "DAHDI:Invalid span %d. Should be a number %d to %d\n", prispan, 1, NUM_SPANS); - return -1; - } - - pri = &pris[prispan-1]; - if (pri_nochannel_grab(pri)) { - ast_log(LOG_WARNING, "Failed to grab PRI!\n"); - return -1; - } - - if (!(call = pri_new_nochannel_call(pri->pri, &cref))) { - ast_log(LOG_WARNING, "Unable to create no channel call on span %d\n", prispan); - pri_rel(pri); - return -1; - } - - if (!(sr = pri_sr_new())) { - ast_log(LOG_WARNING, "Failed to allocate setup request for no channel on span %d\n", prispan); - pri_rel(pri); - } - pri_sr_set_no_channel_call(sr); - pri_sr_set_ccbsnr(sr, type); - - channel |= prispan << 8 | exclusive << 16; - pri_sr_set_channel(sr, channel, exclusive, nonisdn); - pri_sr_set_bearer(sr, transmode, userl1); - if (pri->facilityenable) - pri_facility_enable(pri->pri); - - ast_verbose(VERBOSE_PREFIX_4 "DAHDI:Requested transfer capability: 0x%.2x - %s\n", ast->transfercapability, ast_transfercapability2str(ast->transfercapability)); - dp_strip = 0; - pridialplan = pri->dialplan - 1; - c = callingnum; - if (pridialplan == -2 || pridialplan == -3) { /* compute dynamically */ - if (strncmp(c, pri->internationalprefix, strlen(pri->internationalprefix)) == 0) { - if (pridialplan == -2) { - dp_strip = strlen(pri->internationalprefix); - } - pridialplan = PRI_INTERNATIONAL_ISDN; - } else if (strncmp(c, pri->nationalprefix, strlen(pri->nationalprefix)) == 0) { - if (pridialplan == -2) { - dp_strip = strlen(pri->nationalprefix); - } - pridialplan = PRI_NATIONAL_ISDN; - } else { - pridialplan = PRI_LOCAL_ISDN; - } - } - while (c[0] > '9' && c[0] != '*' && c[0] != '#') { - switch (c[0]) { - case 'U': - pridialplan = (PRI_TON_UNKNOWN << 4) | (pridialplan & 0xf); - break; - case 'I': - pridialplan = (PRI_TON_INTERNATIONAL << 4) | (pridialplan & 0xf); - break; - case 'N': - pridialplan = (PRI_TON_NATIONAL << 4) | (pridialplan & 0xf); - break; - case 'L': - pridialplan = (PRI_TON_NET_SPECIFIC << 4) | (pridialplan & 0xf); - break; - case 'S': - pridialplan = (PRI_TON_SUBSCRIBER << 4) | (pridialplan & 0xf); - break; - case 'V': - pridialplan = (PRI_TON_ABBREVIATED << 4) | (pridialplan & 0xf); - break; - case 'R': - pridialplan = (PRI_TON_RESERVED << 4) | (pridialplan & 0xf); - break; - case 'u': - pridialplan = PRI_NPI_UNKNOWN | (pridialplan & 0xf0); - break; - case 'e': - pridialplan = PRI_NPI_E163_E164 | (pridialplan & 0xf0); - break; - case 'x': - pridialplan = PRI_NPI_X121 | (pridialplan & 0xf0); - break; - case 'f': - pridialplan = PRI_NPI_F69 | (pridialplan & 0xf0); - break; - case 'n': - pridialplan = PRI_NPI_NATIONAL | (pridialplan & 0xf0); - break; - case 'p': - pridialplan = PRI_NPI_PRIVATE | (pridialplan & 0xf0); - break; - case 'r': - pridialplan = PRI_NPI_RESERVED | (pridialplan & 0xf0); - break; - default: - if (isalpha(*c)) - ast_log(LOG_WARNING, "Unrecognized pridialplan %s modifier: %c\n", *c > 'Z' ? "NPI" : "TON", *c); - } - c++; - } - pri_sr_set_called(sr, c + dp_strip, pridialplan, s ? 1 : 0); - - l = callernum; - n = callername; - ldp_strip = 0; - prilocaldialplan = pri->localdialplan - 1; - if ((l != NULL) && (prilocaldialplan == -2 || prilocaldialplan == -3)) { /* compute dynamically */ - if (strncmp(l, pri->internationalprefix, strlen(pri->internationalprefix)) == 0) { - if (prilocaldialplan == -2) { - ldp_strip = strlen(pri->internationalprefix); - } - prilocaldialplan = PRI_INTERNATIONAL_ISDN; - } else if (strncmp(l, pri->nationalprefix, strlen(pri->nationalprefix)) == 0) { - if (prilocaldialplan == -2) { - ldp_strip = strlen(pri->nationalprefix); - } - prilocaldialplan = PRI_NATIONAL_ISDN; - } else { - prilocaldialplan = PRI_LOCAL_ISDN; - } - } - if (l != NULL) { - while (*l > '9' && *l != '*' && *l != '#') { - switch (*l) { - case 'U': - prilocaldialplan = (PRI_TON_UNKNOWN << 4) | (prilocaldialplan & 0xf); - break; - case 'I': - prilocaldialplan = (PRI_TON_INTERNATIONAL << 4) | (prilocaldialplan & 0xf); - break; - case 'N': - prilocaldialplan = (PRI_TON_NATIONAL << 4) | (prilocaldialplan & 0xf); - break; - case 'L': - prilocaldialplan = (PRI_TON_NET_SPECIFIC << 4) | (prilocaldialplan & 0xf); - break; - case 'S': - prilocaldialplan = (PRI_TON_SUBSCRIBER << 4) | (prilocaldialplan & 0xf); - break; - case 'V': - prilocaldialplan = (PRI_TON_ABBREVIATED << 4) | (prilocaldialplan & 0xf); - break; - case 'R': - prilocaldialplan = (PRI_TON_RESERVED << 4) | (prilocaldialplan & 0xf); - break; - case 'u': - prilocaldialplan = PRI_NPI_UNKNOWN | (prilocaldialplan & 0xf0); - break; - case 'e': - prilocaldialplan = PRI_NPI_E163_E164 | (prilocaldialplan & 0xf0); - break; - case 'x': - prilocaldialplan = PRI_NPI_X121 | (prilocaldialplan & 0xf0); - break; - case 'f': - prilocaldialplan = PRI_NPI_F69 | (prilocaldialplan & 0xf0); - break; - case 'n': - prilocaldialplan = PRI_NPI_NATIONAL | (prilocaldialplan & 0xf0); - break; - case 'p': - prilocaldialplan = PRI_NPI_PRIVATE | (prilocaldialplan & 0xf0); - break; - case 'r': - prilocaldialplan = PRI_NPI_RESERVED | (prilocaldialplan & 0xf0); - break; - default: - if (isalpha(*l)) - ast_log(LOG_WARNING, "Unrecognized prilocaldialplan %s modifier: %c\n", *c > 'Z' ? "NPI" : "TON", *c); + else + ifend = NULL; } - l++; + destroy_dahdi_pvt(&cur); + } + } else { + if (prev) { + prev->next = cur->next; + if (prev->next) + prev->next->prev = prev; + else + ifend = prev; + } else { + iflist = cur->next; + if (iflist) + iflist->prev = NULL; + else + ifend = NULL; } + destroy_dahdi_pvt(&cur); } + return 0; +} - pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan, - pri->use_callingpres ? ast->cid.cid_pres : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE)); +static void destroy_all_channels(void) +{ + int x; + struct dahdi_pvt *p, *pl; - cclink = ccbsnr_new_id(cref, prispan, call, type, callingnum, callernum, - callername, context, (int)strtol(priority, NULL, 0), ast); - if (!cclink) { - ast_log(LOG_WARNING, "Unable to allocate ccbsnr list object. Aborting!\n"); - pri_rel(pri); - pri_sr_free(sr); - return -1; + while (num_restart_pending) { + usleep(1); } - if (pri_setup(pri->pri, cclink->call, sr)) { - unsigned int handle = CCBS_HANDLE(prispan, cref); - ast_log(LOG_WARNING, "Unable to setup call to %s (using %s)\n", - c + dp_strip, dialplan2str(pri->dialplan)); - - pri_hangup(pri->pri, cclink->call, -1); - cclink->call = NULL; - ccbsnr_del_link(handle); - pri_rel(pri); - pri_sr_free(sr); - - return -1; + ast_mutex_lock(&iflock); + /* Destroy all the interfaces and free their memory */ + p = iflist; + while (p) { + /* Free any callerid */ + if (p->cidspill) + ast_free(p->cidspill); + pl = p; + p = p->next; + x = pl->channel; + /* Free associated memory */ + if (pl) + destroy_dahdi_pvt(&pl); + if (option_verbose > 2) + ast_verbose(VERBOSE_PREFIX_2 "Unregistered channel %d\n", x); } - - pri_sr_free(sr); - ast_setstate(ast, AST_STATE_DIALING); - pri_rel(pri); - - return 0; + iflist = NULL; + ifcount = 0; + ast_mutex_unlock(&iflock); } - +#ifdef HAVE_PRI static char *dahdi_send_keypad_facility_app = "DAHDISendKeypadFacility"; static int dahdi_send_keypad_facility_exec(struct ast_channel *chan, void *data) @@ -4484,21 +3341,6 @@ ast_mutex_lock(&p->lock); -#ifdef HAVE_PRI - if (p->dummychannel == 1) { - ast_verb(3, "Hangup: dummy-channel(%s)\n", ast->name); - ast_verb(3, "Hangup:tech_pvt=%x q931_call=%x\n", (int)p, (int)p->call); - - ast->tech_pvt = NULL; - ast_mutex_unlock(&p->lock); - ast_module_unref(ast_module_info->self); - ast_mutex_destroy(&p->lock); - ast_free(p); - return 0; - } - p->ccringout = 0; -#endif - idx = dahdi_get_index(ast, p, 1); if ((p->sig == SIG_PRI) || (p->sig == SIG_SS7) || (p->sig == SIG_BRI) || (p->sig == SIG_BRI_PTMP)) { @@ -10101,9 +8943,6 @@ ast_copy_string(pris[span].privateprefix, conf->pri.privateprefix, sizeof(pris[span].privateprefix)); ast_copy_string(pris[span].unknownprefix, conf->pri.unknownprefix, sizeof(pris[span].unknownprefix)); pris[span].resetinterval = conf->pri.resetinterval; - if (chan_sig == SIG_PRI) { - pris[span].use_callingpres = conf->chan.use_callingpres; - } tmp->pri = &pris[span]; tmp->prioffset = offset; @@ -10776,11 +9615,6 @@ p->digital = 1; if (tmp) tmp->transfercapability = AST_TRANS_CAP_DIGITAL; -#ifdef HAVE_PRI - } else if (opt == 'q') { - /* Append CC-Ringout facility */ - p->ccringout = 1; -#endif } else { ast_log(LOG_WARNING, "Unknown option '%c' in '%s'\n", opt, (char *)data); } @@ -12274,7 +11108,6 @@ p->inalarm = 1; } } - ccbsnr_destroy_all_of_span(pri); } break; case PRI_EVENT_RESTART: @@ -12815,426 +11648,215 @@ } break; case PRI_EVENT_FACILITY: - { - unsigned int handle; - int channel = e->facility.channel; - int ccbsnronprispan = PRI_SPAN(channel); - int explicit = PRI_EXPLICIT(channel); - int i; - - channel = PRI_CHANNEL(channel); - - ast_verbose(VERBOSE_PREFIX_4 "PRI_EVENT_CC_FACILITY e->facility.channel(0x%x) span(%d) explicit(%d) channel(%d)\n", \ - e->facility.channel, ccbsnronprispan, explicit, channel); - if (channel == 0) { + chanpos = pri_find_principle(pri, e->facility.channel); + if (chanpos < 0) { + ast_log(LOG_WARNING, "Facility requested on unconfigured channel %d/%d span %d\n", + PRI_SPAN(e->facility.channel), PRI_CHANNEL(e->facility.channel), pri->span); + } else { + chanpos = pri_fixup_principle(pri, chanpos, e->facility.call); + if (chanpos < 0) { + ast_log(LOG_WARNING, "Facility requested on channel %d/%d not in use on span %d\n", + PRI_SPAN(e->facility.channel), PRI_CHANNEL(e->facility.channel), pri->span); + } else { + int i; + + ast_mutex_lock(&pri->pvts[chanpos]->lock); for (i = 0; i < e->facility.subcmds.counter_subcmd; i++) { subcommand *subcmd = &e->facility.subcmds.subcmd[i]; + switch (subcmd->cmd) { - case CMD_CC_EXECPOSIBLE_INV: + case CMD_CONNECTEDLINE: { - int cr = e->facility.cref; - ast_verbose(VERBOSE_PREFIX_4 "Facility cc-execposible INV cr %d channel %d/%d, span %d\n", - cr, ccbsnronprispan, channel, pri->span); - - handle = CCBS_HANDLE(ccbsnronprispan,cr); - unsigned int state = 0; - ast_verbose(VERBOSE_PREFIX_4 "Facility cc-execposible: handle=%x\n", handle); - if (ccbsnr_get_link(handle, &state) != NULL) { - if (state == CC_INVOKED_A_RET) { - ast_verbose(VERBOSE_PREFIX_4 "DAHDI ccbsnr_remote_user_free: state '%d'\n", state); - ccbsnr_remote_user_free(handle); - } - } else { - ast_verbose(VERBOSE_PREFIX_3 "Facility cc-execposible: List-obj not found - handle=%x state=%d\n", handle, state); - } - } - break; - default: - ast_log(LOG_WARNING, "Illegal subcommand %d in facility request on channel %d/%d span %d\n", \ - subcmd->cmd, ccbsnronprispan, channel, pri->span); - break; - } - } - } else { - chanpos = pri_find_principle(pri, e->facility.channel); - if (chanpos < 0) { - ast_log(LOG_WARNING, "Facility requested on unconfigured channel %d/%d span %d\n", - PRI_SPAN(e->facility.channel), PRI_CHANNEL(e->facility.channel), pri->span); - } else { - chanpos = pri_fixup_principle(pri, chanpos, e->facility.call); - if (chanpos < 0) { - ast_log(LOG_WARNING, "Facility requested on channel %d/%d not in use on span %d\n", - PRI_SPAN(e->facility.channel), PRI_CHANNEL(e->facility.channel), pri->span); - } else { - ast_mutex_lock(&pri->pvts[chanpos]->lock); - for (i = 0; i < e->facility.subcmds.counter_subcmd; i++) { - subcommand *subcmd = &e->facility.subcmds.subcmd[i]; + struct ast_party_connected_line connected; + cmd_connectedline *cmdcl; + struct ast_channel *owner = pri->pvts[chanpos]->owner; - switch (subcmd->cmd) { - case CMD_CONNECTEDLINE: - { - struct ast_party_connected_line connected; - cmd_connectedline *cmdcl; - struct ast_channel *owner = pri->pvts[chanpos]->owner; - - /* Update the connected line information on the other channel */ - ast_party_connected_line_init(&connected); - cmdcl = &subcmd->connectedline; - connected.id.number = cmdcl->connected.id.number; - connected.id.name = cmdcl->connected.id.name; - connected.id.number_type = cmdcl->connected.id.number_type; - connected.id.number_presentation = pri_to_ast_presentation(cmdcl->connected.id.number_presentation); - connected.source = pri_to_ast_connected_line_update_source(cmdcl->connected.source); - ast_queue_connected_line_update(owner, &connected); + /* Update the connected line information on the other channel */ + ast_party_connected_line_init(&connected); + cmdcl = &subcmd->connectedline; + connected.id.number = cmdcl->connected.id.number; + connected.id.name = cmdcl->connected.id.name; + connected.id.number_type = cmdcl->connected.id.number_type; + connected.id.number_presentation = pri_to_ast_presentation(cmdcl->connected.id.number_presentation); + connected.source = pri_to_ast_connected_line_update_source(cmdcl->connected.source); + ast_queue_connected_line_update(owner, &connected); - ast_copy_string(pri->pvts[chanpos]->lastcid_num, cmdcl->connected.id.number, sizeof(pri->pvts[chanpos]->lastcid_num)); - ast_copy_string(pri->pvts[chanpos]->lastcid_name, cmdcl->connected.id.name, sizeof(pri->pvts[chanpos]->lastcid_name)); + ast_copy_string(pri->pvts[chanpos]->lastcid_num, cmdcl->connected.id.number, sizeof(pri->pvts[chanpos]->lastcid_num)); + ast_copy_string(pri->pvts[chanpos]->lastcid_name, cmdcl->connected.id.name, sizeof(pri->pvts[chanpos]->lastcid_name)); - pri->pvts[chanpos]->subs[SUB_REAL].needcallerid =1; - } - break; - case CMD_REDIRECTING: - { - struct ast_party_redirecting redirecting = {{0,},}; - cmd_redirecting *cmdr; - struct ast_channel *owner = pri->pvts[chanpos]->owner; - - cmdr = &subcmd->redirecting; - redirecting.from.number = cmdr->redirecting.from.number; - redirecting.from.name = cmdr->redirecting.from.name; - redirecting.from.number_type = cmdr->redirecting.from.number_type; - redirecting.from.number_presentation = pri_to_ast_presentation(cmdr->redirecting.from.number_presentation); - redirecting.to.number = cmdr->redirecting.to.number; - redirecting.to.name = cmdr->redirecting.to.name; - redirecting.to.number_type = cmdr->redirecting.to.number_type; - redirecting.to.number_presentation = pri_to_ast_presentation(cmdr->redirecting.to.number_presentation); - redirecting.count = 0; - redirecting.reason = pri_to_ast_reason(cmdr->redirecting.reason); - ast_queue_redirecting_update(owner, &redirecting); - } - break; - default: - ast_log(LOG_WARNING, "Illegal subcommand %d in facility request on channel %d/%d not in use on span %d\n", \ - subcmd->cmd, PRI_SPAN(e->facility.channel), PRI_CHANNEL(e->facility.channel), pri->span); - break; - } - } - ast_mutex_unlock(&pri->pvts[chanpos]->lock); - } - } - } - } - break; - case PRI_EVENT_ANSWER: - { - int channel = e->answer.channel; - int ccbsnronprispan = PRI_SPAN(channel); - int explicit = PRI_EXPLICIT(channel); - channel = PRI_CHANNEL(channel); - int i; - - ast_verbose(VERBOSE_PREFIX_4 "PRI_EVENT_ANSWER e->answer.channel(0x%x) span(%d) explicit(%d) channel(%d)\n", \ - e->answer.channel, ccbsnronprispan, explicit, channel); - - if (channel == 0) { /* No channel Connection */ - for (i = 0; i < e->answer.subcmds.counter_subcmd; i++) { - subcommand *subcmd = &e->answer.subcmds.subcmd[i]; - switch (subcmd->cmd) { - case CMD_CC_CCBSREQUEST_RR: - { - struct ccbsnr_link *cclink; - unsigned int handle; - int cr = e->answer.cref; - int no_path_reservation = subcmd->cc_ccbs_rr.cc_request_res.no_path_reservation; - int retain_service = subcmd->cc_ccbs_rr.cc_request_res.retain_service; - - ast_verbose(VERBOSE_PREFIX_4 "Answer ccbs-request RR no-path-reservation '%d' retain-service '%d' on channel %d/%d on span %d\n", - no_path_reservation, retain_service, - PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span); - handle = CCBS_HANDLE(ccbsnronprispan,cr); - cclink = ccbsnr_select_link(handle); - if (cclink) { - struct ast_channel *peer; - peer = cclink->peer; - cclink->peer = NULL; - ast_verbose(VERBOSE_PREFIX_4 "PRI_EVENT_ANSWER: peer on CCBS-List-Obj (%x))\n", (int)peer); - - if (peer) { - ast_verbose(VERBOSE_PREFIX_4 "fac-ev:PRI_CC_CCBSREQUEST:set per peer %x state ACTIVATED\n", (int)peer); - pbx_builtin_setvar_helper(peer, "CCBSNRREQSTATE", "ACTIVATED"); - } else { - ast_verbose(VERBOSE_PREFIX_4 "PRI_EVENT_ANSWER: No peer on CCBS-List-Obj found\n"); - } - } else { - ast_verbose(VERBOSE_PREFIX_3 "PRI_EVENT_ANSWER: CCBS-List-Obj not found: e->answer.channel(0x%x) span(%d) explicit(%d) channel(%d)\n", - e->answer.channel, ccbsnronprispan, explicit, channel); - } + pri->pvts[chanpos]->subs[SUB_REAL].needcallerid =1; } break; - - case CMD_CC_CCNRREQUEST_RR: + case CMD_REDIRECTING: { - struct ccbsnr_link *cclink; - unsigned int handle; - int cr = e->answer.cref; - int no_path_reservation = subcmd->cc_ccnr_rr.cc_request_res.no_path_reservation; - int retain_service = subcmd->cc_ccnr_rr.cc_request_res.retain_service; - - ast_verbose(VERBOSE_PREFIX_3 "Answer ccnr-request RR no-path-reservation '%d' retain-service '%d' on channel %d/%d on span %d\n", - no_path_reservation, retain_service, - PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span); - handle = CCBS_HANDLE(ccbsnronprispan,cr); - cclink = ccbsnr_select_link(handle); - if (cclink) { - struct ast_channel *peer; - peer = cclink->peer; - cclink->peer = NULL; - ast_verbose(VERBOSE_PREFIX_4 "PRI_EVENT_ANSWER: peer on CCBS-List-Obj (%x))\n", (int)peer); - - if (peer) { - ast_verbose(VERBOSE_PREFIX_4 "fac-ev:PRI_CC_CCBSREQUEST:set per peer %x state ACTIVATED\n", (int)peer); - pbx_builtin_setvar_helper(peer, "CCBSNRREQSTATE", "ACTIVATED"); - } else { - ast_verbose(VERBOSE_PREFIX_3 "PRI_EVENT_ANSWER: No peer on CCBS-List-Obj found\n"); - } - } else { - ast_verbose(VERBOSE_PREFIX_3 "PRI_EVENT_ANSWER: CCBS-List-Obj not found: e->answer.channel(0x%x) span(%d) explicit(%d) channel(%d)\n", - e->answer.channel, ccbsnronprispan, explicit, channel); - } + struct ast_party_redirecting redirecting = {{0,},}; + cmd_redirecting *cmdr; + struct ast_channel *owner = pri->pvts[chanpos]->owner; + + cmdr = &subcmd->redirecting; + redirecting.from.number = cmdr->redirecting.from.number; + redirecting.from.name = cmdr->redirecting.from.name; + redirecting.from.number_type = cmdr->redirecting.from.number_type; + redirecting.from.number_presentation = pri_to_ast_presentation(cmdr->redirecting.from.number_presentation); + redirecting.to.number = cmdr->redirecting.to.number; + redirecting.to.name = cmdr->redirecting.to.name; + redirecting.to.number_type = cmdr->redirecting.to.number_type; + redirecting.to.number_presentation = pri_to_ast_presentation(cmdr->redirecting.to.number_presentation); + redirecting.count = 0; + redirecting.reason = pri_to_ast_reason(cmdr->redirecting.reason); + ast_queue_redirecting_update(owner, &redirecting); } break; - default: - ast_log(LOG_WARNING, "Illegal subcommand %d in answer on channel %d/%d span %d\n", \ - subcmd->cmd, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span); + ast_log(LOG_WARNING, "Illegal subcommand %d in facility request on channel %d/%d not in use on span %d\n", \ + subcmd->cmd, PRI_SPAN(e->facility.channel), PRI_CHANNEL(e->facility.channel), pri->span); break; - } } + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + } + } + break; + case PRI_EVENT_ANSWER: + chanpos = pri_find_principle(pri, e->answer.channel); + if (chanpos < 0) { + ast_log(LOG_WARNING, "Answer on unconfigured channel %d/%d span %d\n", + PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span); + } else { + chanpos = pri_fixup_principle(pri, chanpos, e->answer.call); + if (chanpos < 0) { + ast_log(LOG_WARNING, "Answer requested on channel %d/%d not in use on span %d\n", + PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span); } else { - chanpos = pri_find_principle(pri, e->answer.channel); - if (chanpos < 0) { - ast_log(LOG_WARNING, "Answer on unconfigured channel %d/%d span %d\n", - PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span); - } else { - chanpos = pri_fixup_principle(pri, chanpos, e->answer.call); - if (chanpos < 0) { - ast_log(LOG_WARNING, "Answer requested on channel %d/%d not in use on span %d\n", - PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), pri->span); - } else { - struct ast_party_connected_line connected; - struct ast_channel *owner = pri->pvts[chanpos]->owner; + struct ast_party_connected_line connected; + struct ast_channel *owner = pri->pvts[chanpos]->owner; - ast_mutex_lock(&pri->pvts[chanpos]->lock); - /* Now we can do call progress detection */ + ast_mutex_lock(&pri->pvts[chanpos]->lock); + /* Now we can do call progress detection */ - /* We changed this so it turns on the DSP no matter what... progress or no progress. - * By this time, we need DTMF detection and other features that were previously disabled - * -- Matt F */ - if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) { - ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features); - pri->pvts[chanpos]->dsp_features = 0; + /* We changed this so it turns on the DSP no matter what... progress or no progress. + * By this time, we need DTMF detection and other features that were previously disabled + * -- Matt F */ + if (pri->pvts[chanpos]->dsp && pri->pvts[chanpos]->dsp_features) { + ast_dsp_set_features(pri->pvts[chanpos]->dsp, pri->pvts[chanpos]->dsp_features); + pri->pvts[chanpos]->dsp_features = 0; + } + if (pri->pvts[chanpos]->realcall && (pri->pvts[chanpos]->realcall->sig == SIG_FXSKS)) { + ast_debug(1, "Starting up GR-303 trunk now that we got CONNECT...\n"); + x = DAHDI_START; + res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); + if (res < 0) { + if (errno != EINPROGRESS) { + ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno)); } - if (pri->pvts[chanpos]->realcall && (pri->pvts[chanpos]->realcall->sig == SIG_FXSKS)) { - ast_debug(1, "Starting up GR-303 trunk now that we got CONNECT...\n"); - x = DAHDI_START; - res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].dfd, DAHDI_HOOK, &x); - if (res < 0) { - if (errno != EINPROGRESS) { - ast_log(LOG_WARNING, "Unable to start channel: %s\n", strerror(errno)); - } - } - } else if (!ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) { - pri->pvts[chanpos]->dialing = 1; - /* Send any "w" waited stuff */ - res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].dfd, DAHDI_DIAL, &pri->pvts[chanpos]->dop); - if (res < 0) { - ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", pri->pvts[chanpos]->channel, strerror(errno)); - pri->pvts[chanpos]->dop.dialstr[0] = '\0'; - } else - ast_debug(1, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr); + } + } else if (!ast_strlen_zero(pri->pvts[chanpos]->dop.dialstr)) { + pri->pvts[chanpos]->dialing = 1; + /* Send any "w" waited stuff */ + res = ioctl(pri->pvts[chanpos]->subs[SUB_REAL].dfd, DAHDI_DIAL, &pri->pvts[chanpos]->dop); + if (res < 0) { + ast_log(LOG_WARNING, "Unable to initiate dialing on trunk channel %d: %s\n", pri->pvts[chanpos]->channel, strerror(errno)); + pri->pvts[chanpos]->dop.dialstr[0] = '\0'; + } else + ast_debug(1, "Sent deferred digit string: %s\n", pri->pvts[chanpos]->dop.dialstr); - pri->pvts[chanpos]->dop.dialstr[0] = '\0'; - } else if (pri->pvts[chanpos]->confirmanswer) { - ast_debug(1, "Waiting on answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel); - } else { - pri->pvts[chanpos]->subs[SUB_REAL].needanswer =1; - /* Enable echo cancellation if it's not on already */ - dahdi_enable_ec(pri->pvts[chanpos]); - } + pri->pvts[chanpos]->dop.dialstr[0] = '\0'; + } else if (pri->pvts[chanpos]->confirmanswer) { + ast_debug(1, "Waiting on answer confirmation on channel %d!\n", pri->pvts[chanpos]->channel); + } else { + pri->pvts[chanpos]->subs[SUB_REAL].needanswer =1; + /* Enable echo cancellation if it's not on already */ + dahdi_enable_ec(pri->pvts[chanpos]); + } #ifdef SUPPORT_USERUSER - if (!ast_strlen_zero(e->answer.useruserinfo)) { - struct ast_channel *owner = pri->pvts[chanpos]->owner; - ast_mutex_unlock(&pri->pvts[chanpos]->lock); - pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->answer.useruserinfo); - ast_mutex_lock(&pri->pvts[chanpos]->lock); - } + if (!ast_strlen_zero(e->answer.useruserinfo)) { + struct ast_channel *owner = pri->pvts[chanpos]->owner; + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->answer.useruserinfo); + ast_mutex_lock(&pri->pvts[chanpos]->lock); + } #endif - /* Update the connected line information on the other channel */ - ast_party_connected_line_init(&connected); - connected.id.name = e->answer.connectedname; - connected.id.number = e->answer.connectednum; - connected.id.number_type = e->answer.connectedplan; - connected.id.number_presentation = pri_to_ast_presentation(e->answer.connectedpres); - connected.source = pri_to_ast_connected_line_update_source(e->answer.source); - ast_queue_connected_line_update(owner, &connected); + /* Update the connected line information on the other channel */ + ast_party_connected_line_init(&connected); + connected.id.name = e->answer.connectedname; + connected.id.number = e->answer.connectednum; + connected.id.number_type = e->answer.connectedplan; + connected.id.number_presentation = pri_to_ast_presentation(e->answer.connectedpres); + connected.source = pri_to_ast_connected_line_update_source(e->answer.source); + ast_queue_connected_line_update(owner, &connected); - ast_mutex_unlock(&pri->pvts[chanpos]->lock); - } - } + ast_mutex_unlock(&pri->pvts[chanpos]->lock); } } break; case PRI_EVENT_HANGUP: - { - int errorvalue = 0; - int channel = e->hangup.channel; - int ccbsnronprispan = PRI_SPAN(channel); - int explicit = PRI_EXPLICIT(channel); - int i; - - channel = PRI_CHANNEL(channel); - - ast_verbose(VERBOSE_PREFIX_4 "Channel %d/%d, span %d got hangup, cause %d\n", - ccbsnronprispan, channel, pri->span, e->hangup.cause); - - if (channel == 0) { /* No channel Connection */ - for (i = 0; i < e->hangup.subcmds.counter_subcmd; i++) { - subcommand *subcmd = &e->hangup.subcmds.subcmd[i]; - switch (subcmd->cmd) { - case CMD_CC_ERROR: - errorvalue = subcmd->cc_error.error_value; - ast_verbose(VERBOSE_PREFIX_4 "Hangup cc-error RR value '%d' on channel %d/%d on span %d\n", - errorvalue, PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); - break; - case CMD_CC_CANCEL_INV: - ast_verbose(VERBOSE_PREFIX_4 "Hangup cc-cancel INV numberA '%s' numberB '%s' on channel %d/%d on span %d\n", - subcmd->cc_cancel_inv.cc_optional_arg.number_A, - subcmd->cc_cancel_inv.cc_optional_arg.number_B, - PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); - break; - default: - ast_log(LOG_WARNING, "Illegal subcommand %d in hangup on channel %d/%d span %d\n", \ - subcmd->cmd, PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); - break; - } - } - - struct ccbsnr_link *cclink; - unsigned int handle; - int cr = e->hangup.cref; - unsigned int state = 0; - - handle = CCBS_HANDLE(ccbsnronprispan,cr); - cclink = ccbsnr_get_link(handle, &state); - if (cclink) { - switch (state) { - case CC_WAIT_ACK: - case CC_WAIT_USER_A_ANSWER_N: - case CC_INVOKED_A_RET: - ast_verbose(VERBOSE_PREFIX_4 "PRI_EVENT_HANGUP: CCBS-List-Obj 0x%x: handle %x e->hangup.channel(0x%x) span(%d) explicit(%d) channel(%d) error(%d) peer=%x\n", - (int)cclink, handle, e->hangup.channel, ccbsnronprispan, explicit, channel, errorvalue, (int)cclink->peer); - - pri_hangup(pri->pri, cclink->call, e->hangup.cause); - cclink->call = NULL; - ccbsnr_del_link(handle); - break; - default: - ast_verbose(VERBOSE_PREFIX_3 "PRI_EVENT_HANGUP:wrong state '%d'\n", state); + chanpos = pri_find_principle(pri, e->hangup.channel); + if (chanpos < 0) { + ast_log(LOG_WARNING, "Hangup requested on unconfigured channel %d/%d span %d\n", + PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); + } else { + chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call); + if (chanpos > -1) { + ast_mutex_lock(&pri->pvts[chanpos]->lock); + if (!pri->pvts[chanpos]->alreadyhungup) { + /* we're calling here dahdi_hangup so once we get there we need to clear p->call after calling pri_hangup */ + pri->pvts[chanpos]->alreadyhungup = 1; + if (pri->pvts[chanpos]->realcall) + pri_hangup_all(pri->pvts[chanpos]->realcall, pri); + else if (pri->pvts[chanpos]->owner) { + /* Queue a BUSY instead of a hangup if our cause is appropriate */ + pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause; + if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP) + pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; + else { + switch (e->hangup.cause) { + case PRI_CAUSE_USER_BUSY: + pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1; + break; + case PRI_CAUSE_CALL_REJECTED: + case PRI_CAUSE_NETWORK_OUT_OF_ORDER: + case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION: + case PRI_CAUSE_SWITCH_CONGESTION: + case PRI_CAUSE_DESTINATION_OUT_OF_ORDER: + case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE: + pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1; + break; + default: + pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; + } + } } + ast_verb(3, "Channel %d/%d, span %d got hangup, cause %d\n", + pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause); } else { - ast_verbose(VERBOSE_PREFIX_4 "PRI_EVENT_HANGUP: CCBS-List-Obj not found: e->hangup.channel(0x%x) span(%d) explicit(%d) channel(%d)\n", - e->hangup.channel, ccbsnronprispan, explicit, channel); - ast_verbose(VERBOSE_PREFIX_3 "Hangup on bad channel %d/%d on span %d\n", - PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); - + pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); + pri->pvts[chanpos]->call = NULL; } - } else { - chanpos = pri_find_principle(pri, e->hangup.channel); - if (chanpos < 0) { - ast_log(LOG_WARNING, "Hangup requested on unconfigured channel %d/%d span %d\n", - PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); - } else { - chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call); - if (chanpos > -1) { - ast_mutex_lock(&pri->pvts[chanpos]->lock); - if (!pri->pvts[chanpos]->alreadyhungup) { - /* we're calling here dahdi_hangup so once we get there we need to clear p->call after calling pri_hangup */ - pri->pvts[chanpos]->alreadyhungup = 1; - if (pri->pvts[chanpos]->realcall) - pri_hangup_all(pri->pvts[chanpos]->realcall, pri); - else if (pri->pvts[chanpos]->owner) { - /* Queue a BUSY instead of a hangup if our cause is appropriate */ - pri->pvts[chanpos]->owner->hangupcause = e->hangup.cause; - if (pri->pvts[chanpos]->owner->_state == AST_STATE_UP) - pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; - else { - switch (e->hangup.cause) { - case PRI_CAUSE_USER_BUSY: - pri->pvts[chanpos]->subs[SUB_REAL].needbusy =1; - break; - case PRI_CAUSE_CALL_REJECTED: - case PRI_CAUSE_NETWORK_OUT_OF_ORDER: - case PRI_CAUSE_NORMAL_CIRCUIT_CONGESTION: - case PRI_CAUSE_SWITCH_CONGESTION: - case PRI_CAUSE_DESTINATION_OUT_OF_ORDER: - case PRI_CAUSE_NORMAL_TEMPORARY_FAILURE: - pri->pvts[chanpos]->subs[SUB_REAL].needcongestion =1; - break; - default: - pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; - } - } - } - ast_verb(3, "Channel %d/%d, span %d got hangup, cause %d\n", - pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, e->hangup.cause); - } else { - pri_hangup(pri->pri, pri->pvts[chanpos]->call, e->hangup.cause); - pri->pvts[chanpos]->call = NULL; - } - if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) { - ast_verb(3, "Forcing restart of channel %d/%d on span %d since channel reported in use\n", - PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); - pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos])); - pri->pvts[chanpos]->resetting = 1; - } - if (e->hangup.aoc_units > -1) - ast_verb(3, "Channel %d/%d, span %d received AOC-E charging %d unit%s\n", - pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s"); + if (e->hangup.cause == PRI_CAUSE_REQUESTED_CHAN_UNAVAIL) { + ast_verb(3, "Forcing restart of channel %d/%d on span %d since channel reported in use\n", + PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); + pri_reset(pri->pri, PVT_TO_CHANNEL(pri->pvts[chanpos])); + pri->pvts[chanpos]->resetting = 1; + } + if (e->hangup.aoc_units > -1) + ast_verb(3, "Channel %d/%d, span %d received AOC-E charging %d unit%s\n", + pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span, (int)e->hangup.aoc_units, (e->hangup.aoc_units == 1) ? "" : "s"); #ifdef SUPPORT_USERUSER - if (pri->pvts[chanpos]->owner && !ast_strlen_zero(e->hangup.useruserinfo)) { - struct ast_channel *owner = pri->pvts[chanpos]->owner; - ast_mutex_unlock(&pri->pvts[chanpos]->lock); - pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo); - ast_mutex_lock(&pri->pvts[chanpos]->lock); - } + if (pri->pvts[chanpos]->owner && !ast_strlen_zero(e->hangup.useruserinfo)) { + struct ast_channel *owner = pri->pvts[chanpos]->owner; + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo); + ast_mutex_lock(&pri->pvts[chanpos]->lock); + } #endif - for (i = 0; i < e->hangup.subcmds.counter_subcmd; i++) { - subcommand *subcmd = &e->hangup.subcmds.subcmd[i]; - switch (subcmd->cmd) { - case CMD_CC_RINGOUT_INV: - { - ast_verb(3, "Facility cc-suspend INV on channel %d/%d, span %d\n", - pri->pvts[chanpos]->logicalspan, pri->pvts[chanpos]->prioffset, pri->span); - } - break; - - default: - ast_log(LOG_WARNING, "Illegal subcommand %d in hangup on channel %d/%d not in use on span %d\n", \ - subcmd->cmd, PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); - } - } - - ast_mutex_unlock(&pri->pvts[chanpos]->lock); - } else { - ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n", - PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); - } - } + ast_mutex_unlock(&pri->pvts[chanpos]->lock); + } else { + ast_log(LOG_WARNING, "Hangup on bad channel %d/%d on span %d\n", + PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); } } break; @@ -13304,62 +11926,30 @@ } break; case PRI_EVENT_HANGUP_ACK: - { - int channel = e->hangup.channel; - int ccbsnronprispan = PRI_SPAN(channel); - int explicit = PRI_EXPLICIT(channel); - channel = PRI_CHANNEL(channel); - - ast_verbose(VERBOSE_PREFIX_4 "PRI_EVENT_HANGUP_ACK e->hangup.cause(%d) e->hangup.channel(0x%x) span(%d) explicit(%d) channel(%d)\n", - e->hangup.cause, e->hangup.channel, ccbsnronprispan, explicit, channel); - ast_verbose(VERBOSE_PREFIX_3 "Channel %d/%d, span %d got hangup, cause %d\n", - ccbsnronprispan, channel, pri->span, e->hangup.cause); - if (channel == 0) { /* No channel Connection */ - struct ccbsnr_link *cclink; - unsigned int handle; - int cr = e->hangup.cref; - unsigned int state = 0; - - handle = CCBS_HANDLE(ccbsnronprispan,cr); - cclink = ccbsnr_get_link(handle, &state); - if (cclink) { - ast_verbose(VERBOSE_PREFIX_4 "PRI_EVENT_HANGUP_ACK: CCBS-List-Obj 0x%x: handle %x e->hangup.channel(0x%x) span(%d) explicit(%d) channel(%d) peer=%x\n", - (int)cclink, handle, e->hangup.channel, ccbsnronprispan, explicit, channel, (int)cclink->peer); - cclink->call = NULL; - ccbsnr_del_link(handle); - } else { - ast_verbose(VERBOSE_PREFIX_4 "PRI_EVENT_HANGUP_ACK: CCBS-List-Obj 0x%x: handle %x e->hangup.channel(0x%x) span(%d) explicit(%d) channel(%d)", - (int)cclink, handle, e->hangup.channel, ccbsnronprispan, explicit, channel); + chanpos = pri_find_principle(pri, e->hangup.channel); + if (chanpos < 0) { + ast_log(LOG_WARNING, "Hangup ACK requested on unconfigured channel number %d/%d span %d\n", + PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); + } else { + chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call); + if (chanpos > -1) { + ast_mutex_lock(&pri->pvts[chanpos]->lock); + pri->pvts[chanpos]->call = NULL; + pri->pvts[chanpos]->resetting = 0; + if (pri->pvts[chanpos]->owner) { + ast_verb(3, "Channel %d/%d, span %d got hangup ACK\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); } - break; - } - - chanpos = pri_find_principle(pri, e->hangup.channel); - if (chanpos < 0) { - ast_log(LOG_WARNING, "Hangup ACK requested on unconfigured channel number %d/%d span %d\n", - PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); - } else { - chanpos = pri_fixup_principle(pri, chanpos, e->hangup.call); - if (chanpos > -1) { - ast_mutex_lock(&pri->pvts[chanpos]->lock); - pri->pvts[chanpos]->call = NULL; - pri->pvts[chanpos]->resetting = 0; - if (pri->pvts[chanpos]->owner) { - ast_verb(3, "Channel %d/%d, span %d got hangup ACK\n", PRI_SPAN(e->hangup.channel), PRI_CHANNEL(e->hangup.channel), pri->span); - } - #ifdef SUPPORT_USERUSER - if (!ast_strlen_zero(e->hangup.useruserinfo)) { - struct ast_channel *owner = pri->pvts[chanpos]->owner; - ast_mutex_unlock(&pri->pvts[chanpos]->lock); - pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo); - ast_mutex_lock(&pri->pvts[chanpos]->lock); - } -#endif - + if (!ast_strlen_zero(e->hangup.useruserinfo)) { + struct ast_channel *owner = pri->pvts[chanpos]->owner; ast_mutex_unlock(&pri->pvts[chanpos]->lock); + pbx_builtin_setvar_helper(owner, "USERUSERINFO", e->hangup.useruserinfo); + ast_mutex_lock(&pri->pvts[chanpos]->lock); } +#endif + + ast_mutex_unlock(&pri->pvts[chanpos]->lock); } } break; @@ -13749,10 +12339,6 @@ int span; int x; char status[256]; - struct ccbsnr_link *ccbsnr; - int ccbsnronprispan; - int cr; - int counter = 0; switch (cmd) { case CLI_INIT: e->command = "pri show span"; @@ -13795,24 +12381,6 @@ ast_cli(a->fd, "Overlap Recv: %s\n\n", (pris[span-1].overlapdial & DAHDI_OVERLAPDIAL_INCOMING)?"Yes":"No"); } } - - ast_mutex_lock(&ccbsnr_lock); - ccbsnr = ccbsnr_list; - if (ccbsnr) - ast_cli(a->fd, "ccbsnr-list: %x\n", (int)ccbsnr); - - while (ccbsnr) { - ccbsnronprispan = CCBS_SPAN(ccbsnr->handle); - cr = CCBS_CR(ccbsnr->handle); - ast_cli(a->fd, "%d. Active No Channel Call: Q.931 Call %x cr=%d span=%d type=%d handle=%x state=%d (%s, %s, %s, %s, %d) peer=%x\n", - ++counter, (int)ccbsnr->call, cr, ccbsnronprispan, ccbsnr->type, ccbsnr->handle, ccbsnr->state, - ccbsnr->callingnum, ccbsnr->callernum, ccbsnr->callername, - ccbsnr->context, ccbsnr->priority, (int)ccbsnr->peer ); - - ccbsnr = ccbsnr->next; - } - ast_mutex_unlock(&ccbsnr_lock); - return CLI_SUCCESS; } @@ -13948,8 +12516,6 @@ ast_verb(4, "Initial softhangup of all DAHDI channels complete.\n"); #if defined(HAVE_PRI) - cc_destroy_all_peer_link_id(); - ccbsnr_clear_all(); for (i = 0; i < NUM_SPANS; i++) { if (pris[i].master && (pris[i].master != AST_PTHREADT_NULL)) { cancel_code = pthread_cancel(pris[i].master); @@ -15409,10 +13975,6 @@ #ifdef HAVE_PRI_PROG_W_CAUSE ast_unregister_application(dahdi_send_callrerouting_facility_app); #endif - ast_unregister_application(dahdi_qsig_ccbsnr_initialize_app); - ast_unregister_application(dahdi_qsic_ccbsnr_request_app); - ast_unregister_application(dahdi_qsic_clear_nochannel_app); - ast_unregister_application(dahdi_qsic_check_ccbsnr_app); #endif #if defined(HAVE_SS7) for (i = 0; i < NUM_SPANS; i++) { @@ -15481,8 +14043,6 @@ int y; #endif #ifdef HAVE_PRI - cc_destroy_all_peer_link_id(); - ccbsnr_destroy_all(); for (y = 0; y < NUM_SPANS; y++) ast_mutex_destroy(&pris[y].lock); #endif @@ -16721,10 +15281,6 @@ #ifdef HAVE_PRI_PROG_W_CAUSE ast_register_application_xml(dahdi_send_callrerouting_facility_app, dahdi_send_callrerouting_facility_exec); #endif - ast_register_application_xml(dahdi_qsig_ccbsnr_initialize_app, dahdi_qsig_ccbsnr_initialize_exec); - ast_register_application_xml(dahdi_qsic_ccbsnr_request_app, dahdi_qsig_ccbsnr_request_exec); - ast_register_application_xml(dahdi_qsic_clear_nochannel_app, dahdi_qsig_clear_nochannel_exec); - ast_register_application_xml(dahdi_qsic_check_ccbsnr_app, dahdi_qsig_check_ccbsnr_exec); #endif #ifdef HAVE_SS7 memset(linksets, 0, sizeof(linksets)); @@ -16875,11 +15431,6 @@ { int res = 0; -#if defined(HAVE_PRI) - cc_destroy_all_peer_link_id(); - ccbsnr_destroy_all(); -#endif - res = setup_dahdi(1); if (res) { ast_log(LOG_WARNING, "Reload of chan_dahdi.so is unsuccessful!\n");