Index: channels/chan_dahdi.c =================================================================== --- a/channels/chan_dahdi.c (.../trunk) (revision 186562) +++ b/channels/chan_dahdi.c (.../team/group/issue14068) (revision 186562) @@ -3096,6 +3096,196 @@ } #endif /* defined(HAVE_SS7) */ +#if defined(HAVE_PRI) +static enum AST_REDIRECTING_REASON pri_to_ast_reason(int pri_reason) +{ + enum AST_REDIRECTING_REASON ast_reason; + + switch (pri_reason) { + case PRI_REDIR_FORWARD_ON_BUSY: + ast_reason = AST_REDIRECTING_REASON_USER_BUSY; + break; + case PRI_REDIR_FORWARD_ON_NO_REPLY: + ast_reason = AST_REDIRECTING_REASON_NO_ANSWER; + break; + case PRI_REDIR_DEFLECTION: + ast_reason = AST_REDIRECTING_REASON_DEFLECTION; + break; + case PRI_REDIR_UNCONDITIONAL: + ast_reason = AST_REDIRECTING_REASON_UNCONDITIONAL; + break; + case PRI_REDIR_UNKNOWN: + default: + ast_reason = AST_REDIRECTING_REASON_UNKNOWN; + break; + } /* end switch */ + + return ast_reason; +} +#endif /* defined(HAVE_PRI) */ + +#if defined(HAVE_PRI) +static int ast_to_pri_reason(enum AST_REDIRECTING_REASON ast_reason) +{ + int pri_reason; + + switch (ast_reason) { + case AST_REDIRECTING_REASON_USER_BUSY: + pri_reason = PRI_REDIR_FORWARD_ON_BUSY; + break; + case AST_REDIRECTING_REASON_NO_ANSWER: + pri_reason = PRI_REDIR_FORWARD_ON_NO_REPLY; + break; + case AST_REDIRECTING_REASON_UNCONDITIONAL: + pri_reason = PRI_REDIR_UNCONDITIONAL; + break; + case AST_REDIRECTING_REASON_DEFLECTION: + pri_reason = PRI_REDIR_DEFLECTION; + break; + case AST_REDIRECTING_REASON_UNKNOWN: + default: + pri_reason = PRI_REDIR_UNKNOWN; + break; + } /* end switch */ + + return pri_reason; +} +#endif /* defined(HAVE_PRI) */ + +#if defined(HAVE_PRI) +static int pri_to_ast_presentation(int pri_presentation) +{ + int ast_presentation; + + switch (pri_presentation) { + case PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: + ast_presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; + break; + case PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: + ast_presentation = AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; + break; + case PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: + ast_presentation = AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN; + break; + case PRES_ALLOWED_NETWORK_NUMBER: + ast_presentation = AST_PRES_ALLOWED_NETWORK_NUMBER; + break; + case PRES_PROHIB_USER_NUMBER_NOT_SCREENED: + ast_presentation = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; + break; + case PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: + ast_presentation = AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN; + break; + case PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: + ast_presentation = AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN; + break; + case PRES_PROHIB_NETWORK_NUMBER: + ast_presentation = AST_PRES_PROHIB_NETWORK_NUMBER; + break; + case PRES_NUMBER_NOT_AVAILABLE: + ast_presentation = AST_PRES_NUMBER_NOT_AVAILABLE; + break; + default: + ast_presentation = AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED; /* ?? */ + break; + } /* end switch */ + + return ast_presentation; +} +#endif /* defined(HAVE_PRI) */ + +#if defined(HAVE_PRI) +static int ast_to_pri_presentation(int ast_presentation) +{ + int pri_presentation; + + switch (ast_presentation) { + case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED: + pri_presentation = PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; + break; + case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN: + pri_presentation = PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN; + break; + case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN: + pri_presentation = PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN; + break; + case AST_PRES_ALLOWED_NETWORK_NUMBER: + pri_presentation = PRES_ALLOWED_NETWORK_NUMBER; + break; + case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED: + pri_presentation = PRES_PROHIB_USER_NUMBER_NOT_SCREENED; + break; + case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN: + pri_presentation = PRES_PROHIB_USER_NUMBER_PASSED_SCREEN; + break; + case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN: + pri_presentation = PRES_PROHIB_USER_NUMBER_FAILED_SCREEN; + break; + case AST_PRES_PROHIB_NETWORK_NUMBER: + pri_presentation = PRES_PROHIB_NETWORK_NUMBER; + break; + case AST_PRES_NUMBER_NOT_AVAILABLE: + pri_presentation = PRES_NUMBER_NOT_AVAILABLE; + break; + default: + pri_presentation = PRES_PROHIB_USER_NUMBER_NOT_SCREENED; /* ?? */ + break; + } /* end switch */ + + return pri_presentation; +} +#endif /* defined(HAVE_PRI) */ + +#if defined(HAVE_PRI) +static enum AST_CONNECTED_LINE_UPDATE_SOURCE pri_to_ast_connected_line_update_source(enum PRI_CONNECTED_LINE_UPDATE_SOURCE pri_source) +{ + enum AST_CONNECTED_LINE_UPDATE_SOURCE ast_source; + + switch (pri_source) { + case PRI_CONNECTED_LINE_UPDATE_SOURCE_ANSWER: + ast_source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; + break; + case PRI_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER: + ast_source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; + break; + case PRI_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING: + ast_source = AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING; + break; + case PRI_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN: + default: + ast_source = AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN; + break; + } /* end switch */ + + return ast_source; +} +#endif /* defined(HAVE_PRI) */ + +#if defined(HAVE_PRI) +static enum PRI_CONNECTED_LINE_UPDATE_SOURCE ast_to_pri_connected_line_update_source(enum AST_CONNECTED_LINE_UPDATE_SOURCE ast_source) +{ + enum PRI_CONNECTED_LINE_UPDATE_SOURCE pri_source; + + switch (ast_source) { + case AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER: + pri_source = PRI_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; + break; + case AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER: + pri_source = PRI_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER; + break; + case AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING: + pri_source = PRI_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER_ALERTING; + break; + case AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN: + default: + pri_source = PRI_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN; + break; + } /* end switch */ + + return pri_source; +} +#endif /* defined(HAVE_PRI) */ + static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout) { struct dahdi_pvt *p = ast->tech_pvt; @@ -3391,7 +3581,8 @@ ast_mutex_unlock(&p->lock); return -1; } -#ifdef HAVE_SS7 + +#if defined(HAVE_SS7) if (p->ss7) { char ss7_called_nai; int called_nai_strip; @@ -3528,7 +3719,8 @@ ast_setstate(ast, AST_STATE_DIALING); ss7_rel(p->ss7); } -#endif /* HAVE_SS7 */ +#endif /* defined(HAVE_SS7) */ + #ifdef HAVE_OPENR2 if (p->mfcr2) { openr2_calling_party_category_t chancat; @@ -3563,7 +3755,8 @@ ast_setstate(ast, AST_STATE_DIALING); } #endif /* HAVE_OPENR2 */ -#ifdef HAVE_PRI + +#if defined(HAVE_PRI) if (p->pri) { struct pri_sr *sr; #ifdef SUPPORT_USERUSER @@ -3574,8 +3767,6 @@ int prilocaldialplan; int ldp_strip; int exclusive; - const char *rr_str; - int redirect_reason; c = strchr(dest, '/'); if (c) { @@ -3804,20 +3995,10 @@ } pri_sr_set_caller(sr, l ? (l + ldp_strip) : NULL, n, prilocaldialplan, p->use_callingpres ? ast->connected.id.number_presentation : (l ? PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN : PRES_NUMBER_NOT_AVAILABLE)); - if ((rr_str = pbx_builtin_getvar_helper(ast, "PRIREDIRECTREASON"))) { - if (!strcasecmp(rr_str, "UNKNOWN")) - redirect_reason = 0; - else if (!strcasecmp(rr_str, "BUSY")) - redirect_reason = 1; - else if (!strcasecmp(rr_str, "NO_REPLY")) - redirect_reason = 2; - else if (!strcasecmp(rr_str, "UNCONDITIONAL")) - redirect_reason = 15; - else - redirect_reason = PRI_REDIR_UNCONDITIONAL; - } else - redirect_reason = PRI_REDIR_UNCONDITIONAL; - pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, p->pri->localdialplan - 1, PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, redirect_reason); + pri_sr_set_redirecting(sr, ast->cid.cid_rdnis, ast->redirecting.from.number_type, + ast->redirecting.from.number_presentation, + ast_to_pri_reason(ast->redirecting.reason)); + pri_sr_set_redirecting_name(sr, ast->redirecting.from.name); #ifdef SUPPORT_USERUSER /* User-user info */ @@ -3838,7 +4019,8 @@ ast_setstate(ast, AST_STATE_DIALING); pri_rel(p->pri); } -#endif +#endif /* defined(HAVE_PRI) */ + ast_mutex_unlock(&p->lock); return 0; } @@ -7111,6 +7293,7 @@ int res=-1; int idx; int func = DAHDI_FLASH; + ast_mutex_lock(&p->lock); idx = dahdi_get_index(chan, p, 0); ast_debug(1, "Requested indication %d on channel %s\n", condition, chan->name); @@ -7345,6 +7528,65 @@ case -1: res = tone_zone_play_tone(p->subs[idx].dfd, -1); break; + case AST_CONTROL_CONNECTED_LINE: + ast_debug(1, "Received AST_CONTROL_CONNECTED_LINE on %s\n", chan->name); +#if defined(HAVE_PRI) + if (p->pri) { + struct pri_party_connected_line connected; + + if (chan->connected.id.number) { + ast_copy_string(connected.id.number, chan->connected.id.number, sizeof(connected.id.number)); + } else { + connected.id.number[0] = '\0'; + } + if (chan->connected.id.name) { + ast_copy_string(connected.id.name, chan->connected.id.name, sizeof(connected.id.name)); + } else { + connected.id.name[0] = '\0'; + } + connected.id.number_type = chan->connected.id.number_type; + connected.id.number_presentation = ast_to_pri_presentation(chan->connected.id.number_presentation); + connected.source = ast_to_pri_connected_line_update_source(chan->connected.source); + pri_connected_line_update(p->pri->pri, p->call, &connected); + } +#endif /* defined(HAVE_PRI) */ + break; + case AST_CONTROL_REDIRECTING: + ast_debug(1, "Received AST_CONTROL_REDIRECTING on %s\n", chan->name); +#if defined(HAVE_PRI) + if (p->pri) { + struct pri_party_redirecting redirecting; + + if (chan->cid.cid_rdnis) { + ast_copy_string(redirecting.from.number, chan->cid.cid_rdnis, sizeof(redirecting.from.number)); + } else { + redirecting.from.number[0] = '\0'; + } + if (chan->redirecting.from.name) { + ast_copy_string(redirecting.from.name, chan->redirecting.from.name, sizeof(redirecting.from.name)); + } else { + redirecting.from.name[0] = '\0'; + } + redirecting.from.number_type = chan->redirecting.from.number_type; + redirecting.from.number_presentation = ast_to_pri_presentation(chan->redirecting.from.number_presentation); + if (chan->redirecting.to.number) { + ast_copy_string(redirecting.to.number, chan->redirecting.to.number, sizeof(redirecting.to.number)); + } else { + redirecting.to.number[0] = '\0'; + } + if (chan->redirecting.to.name) { + ast_copy_string(redirecting.to.name, chan->redirecting.to.name, sizeof(redirecting.to.name)); + } else { + redirecting.to.name[0] = '\0'; + } + redirecting.to.number_type = chan->redirecting.to.number_type; + redirecting.to.number_presentation = ast_to_pri_presentation(chan->redirecting.to.number_presentation); + redirecting.count = chan->redirecting.count; + redirecting.reason = ast_to_pri_reason(chan->redirecting.reason); + pri_redirecting_update(p->pri->pri, p->call, &redirecting); + } +#endif /* defined(HAVE_PRI) */ + break; } } else res = 0; @@ -12607,17 +12849,17 @@ if (chanpos > -1) { ast_mutex_lock(&pri->pvts[chanpos]->lock); /* queue DTMF frame if the PBX for this call was already started (we're forwarding KEYPAD_DIGITs further on */ - if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) && pri->pvts[chanpos]->call==e->digit.call && pri->pvts[chanpos]->owner) { + if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) + && pri->pvts[chanpos]->call == e->digit.call + && pri->pvts[chanpos]->owner) { /* how to do that */ int digitlen = strlen(e->digit.digits); - char digit; int i; + for (i = 0; i < digitlen; i++) { - digit = e->digit.digits[i]; - { - struct ast_frame f = { AST_FRAME_DTMF, digit, }; - dahdi_queue_frame(pri->pvts[chanpos], &f, pri); - } + struct ast_frame f = { AST_FRAME_DTMF, e->digit.digits[i], }; + + dahdi_queue_frame(pri->pvts[chanpos], &f, pri); } } ast_mutex_unlock(&pri->pvts[chanpos]->lock); @@ -12635,17 +12877,40 @@ if (chanpos > -1) { ast_mutex_lock(&pri->pvts[chanpos]->lock); /* queue DTMF frame if the PBX for this call was already started (we're forwarding INFORMATION further on */ - if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) && pri->pvts[chanpos]->call==e->ring.call && pri->pvts[chanpos]->owner) { + if ((pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) + && pri->pvts[chanpos]->call == e->ring.call + && pri->pvts[chanpos]->owner) { /* how to do that */ int digitlen = strlen(e->ring.callednum); - char digit; int i; + for (i = 0; i < digitlen; i++) { - digit = e->ring.callednum[i]; - { - struct ast_frame f = { AST_FRAME_DTMF, digit, }; - dahdi_queue_frame(pri->pvts[chanpos], &f, pri); + struct ast_frame f = { AST_FRAME_DTMF, e->ring.callednum[i], }; + + dahdi_queue_frame(pri->pvts[chanpos], &f, pri); + } + if (pri->pvts[chanpos]->owner) { + char dnid[AST_MAX_EXTENSION]; + + /* + * Append the received info digits to the end of + * the exten and dnid strings + */ + strncat(pri->pvts[chanpos]->owner->exten, + e->ring.callednum, + sizeof(pri->pvts[chanpos]->owner->exten) - 1 + - strlen(pri->pvts[chanpos]->owner->exten)); + if (pri->pvts[chanpos]->owner->cid.cid_dnid) { + ast_copy_string(dnid, + pri->pvts[chanpos]->owner->cid.cid_dnid, + sizeof(dnid)); + ast_free(pri->pvts[chanpos]->owner->cid.cid_dnid); + } else { + dnid[0] = 0; } + strncat(dnid, e->ring.callednum, + sizeof(dnid) - 1 - strlen(dnid)); + pri->pvts[chanpos]->owner->cid.cid_dnid = ast_strdup(dnid); } } ast_mutex_unlock(&pri->pvts[chanpos]->lock); @@ -12683,6 +12948,7 @@ if ((chanpos < 0) && (e->ring.flexible)) chanpos = pri_find_empty_chan(pri, 1); if (chanpos > -1) { + struct ast_party_redirecting redirecting = {{0,},}; ast_mutex_lock(&pri->pvts[chanpos]->lock); if (pri->switchtype == PRI_SWITCH_GR303_TMC) { /* Should be safe to lock CRV AFAIK while bearer is still locked */ @@ -12704,6 +12970,17 @@ break; } } + if (e->ring.redirectingnum[0] || e->ring.redirectingname[0]) { + redirecting.to.number = e->ring.callednum; + redirecting.to.number_type = e->ring.calledplan; + redirecting.to.number_presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED; + redirecting.from.name = e->ring.redirectingname; + redirecting.from.number = e->ring.redirectingnum; + redirecting.from.number_presentation = e->ring.redirectingpres; + redirecting.from.number_type = e->ring.callingplanrdnis; + redirecting.reason = pri_to_ast_reason(e->ring.redirectingreason); + redirecting.count = e->ring.redirectingcount; + } pri->pvts[chanpos]->call = e->ring.call; apply_plan_to_number(plancallingnum, sizeof(plancallingnum), pri, e->ring.callingnum, e->ring.callingplan); if (pri->pvts[chanpos]->use_callerid) { @@ -12789,7 +13066,9 @@ pri->pvts[chanpos]->callingpres = e->ring.callingpres; /* Start PBX */ - if (!e->ring.complete && (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) { + if (!e->ring.complete + && (pri->overlapdial & DAHDI_OVERLAPDIAL_INCOMING) + && ast_matchmore_extension(NULL, pri->pvts[chanpos]->context, pri->pvts[chanpos]->exten, 1, pri->pvts[chanpos]->cid_num)) { /* Release the PRI lock while we create the channel */ ast_mutex_unlock(&pri->lock); if (crv) { @@ -12804,6 +13083,9 @@ ast_mutex_unlock(&pri->pvts[chanpos]->lock); + if (c && (redirecting.from.number || redirecting.from.name)) { + ast_channel_update_redirecting(c, &redirecting); + } if (!ast_strlen_zero(e->ring.callingsubaddr)) { pbx_builtin_setvar_helper(c, "CALLINGSUBADDR", e->ring.callingsubaddr); } @@ -12821,8 +13103,10 @@ snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan); pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr); - if (e->ring.redirectingreason >= 0) + if (e->ring.redirectingreason >= 0) { + /* This is now just a status variable. Use REDIRECTING() dialplan function. */ pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason)); + } ast_mutex_lock(&pri->pvts[chanpos]->lock); ast_mutex_lock(&pri->lock); @@ -12849,6 +13133,9 @@ ast_mutex_unlock(&pri->pvts[chanpos]->lock); + if (redirecting.from.number || redirecting.from.name) { + ast_channel_update_redirecting(c, &redirecting); + } if (e->ring.ani2 >= 0) { snprintf(ani2str, 5, "%d", e->ring.ani2); pbx_builtin_setvar_helper(c, "ANI2", ani2str); @@ -12861,8 +13148,10 @@ } #endif - if (e->ring.redirectingreason >= 0) + if (e->ring.redirectingreason >= 0) { + /* This is now just a status variable. Use REDIRECTING() dialplan function. */ pbx_builtin_setvar_helper(c, "PRIREDIRECTREASON", redirectingreason2str(e->ring.redirectingreason)); + } snprintf(calledtonstr, sizeof(calledtonstr), "%d", e->ring.calledplan); pbx_builtin_setvar_helper(c, "CALLEDTON", calledtonstr); @@ -12946,6 +13235,19 @@ } #endif + if ((e->ringing.calledname[0] || e->ringing.callednum[0]) && pri->pvts[chanpos]->owner) { + struct ast_party_connected_line connected; + + /* Update the connected line information on the other channel */ + ast_party_connected_line_init(&connected); + connected.id.name = e->ringing.calledname; + connected.id.number = e->ringing.callednum; + connected.id.number_type = e->ringing.calledplan; + connected.id.number_presentation = pri_to_ast_presentation(e->ringing.calledpres); + connected.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER; + ast_channel_queue_connected_line_update(pri->pvts[chanpos]->owner, &connected); + } + ast_mutex_unlock(&pri->pvts[chanpos]->lock); } } @@ -13050,12 +13352,85 @@ ast_mutex_lock(&pri->pvts[chanpos]->lock); ast_copy_string(pri->pvts[chanpos]->lastcid_num, e->facname.callingnum, sizeof(pri->pvts[chanpos]->lastcid_num)); ast_copy_string(pri->pvts[chanpos]->lastcid_name, e->facname.callingname, sizeof(pri->pvts[chanpos]->lastcid_name)); - pri->pvts[chanpos]->subs[SUB_REAL].needcallerid =1; + pri->pvts[chanpos]->subs[SUB_REAL].needcallerid = 1; dahdi_enable_ec(pri->pvts[chanpos]); ast_mutex_unlock(&pri->pvts[chanpos]->lock); } } break; + case PRI_EVENT_FACILITY: + 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++) { + struct subcommand *subcmd = &e->facility.subcmds.subcmd[i]; + struct ast_channel *owner; + + switch (subcmd->cmd) { + case CMD_CONNECTEDLINE: + owner = pri->pvts[chanpos]->owner; + if (owner) { + struct ast_party_connected_line connected; + struct cmd_connectedline *cmdcl; + + /* 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_channel_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)); + + pri->pvts[chanpos]->subs[SUB_REAL].needcallerid = 1; + //dahdi_enable_ec(pri->pvts[chanpos]); + } + break; + case CMD_REDIRECTING: + owner = pri->pvts[chanpos]->owner; + if (owner) { + struct ast_party_redirecting redirecting = {{0,},}; + struct cmd_redirecting *cmdr; + + 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_channel_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: chanpos = pri_find_principle(pri, e->answer.channel); if (chanpos < 0) { @@ -13067,6 +13442,9 @@ 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; + ast_mutex_lock(&pri->pvts[chanpos]->lock); /* Now we can do call progress detection */ @@ -13105,15 +13483,26 @@ dahdi_enable_ec(pri->pvts[chanpos]); } + owner = pri->pvts[chanpos]->owner; #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); } #endif + if (owner) { + /* 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_channel_queue_connected_line_update(owner, &connected); + } + ast_mutex_unlock(&pri->pvts[chanpos]->lock); } } @@ -13152,6 +13541,7 @@ break; default: pri->pvts[chanpos]->owner->_softhangup |= AST_SOFTHANGUP_DEV; + break; } } } Index: CHANGES =================================================================== --- a/CHANGES (.../trunk) (revision 186562) +++ b/CHANGES (.../team/group/issue14068) (revision 186562) @@ -55,6 +55,10 @@ received number from the ISDN link if that number has the corresponding Type-Of-Number. +libpri channel driver (chan_dahdi) changes +------------------------------------------- + * The channel variable PRIREDIRECTREASON is now just a status variable. + Use the REDIRECTING(reason) dialplan function to alter the reason. SIP channel driver (chan_sip) changes -------------------------------------------