|
|
|
@ -7167,10 +7167,12 @@ static int sip_hangup(struct ast_channel *ast)
|
|
|
|
|
ast_debug(4, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid);
|
|
|
|
|
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
|
|
|
|
|
ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */
|
|
|
|
|
ast_channel_tech_pvt_set(p->owner, dialog_unref(ast_channel_tech_pvt(p->owner), "unref p->owner->tech_pvt"));
|
|
|
|
|
sip_pvt_lock(p);
|
|
|
|
|
sip_set_owner(p, NULL); /* Owner will be gone after we return, so take it away */
|
|
|
|
|
sip_pvt_unlock(p);
|
|
|
|
|
if (p->owner) {
|
|
|
|
|
ast_channel_tech_pvt_set(p->owner, dialog_unref(ast_channel_tech_pvt(p->owner), "unref p->owner->tech_pvt"));
|
|
|
|
|
sip_pvt_lock(p);
|
|
|
|
|
sip_set_owner(p, NULL); /* Owner will be gone after we return, so take it away */
|
|
|
|
|
sip_pvt_unlock(p);
|
|
|
|
|
}
|
|
|
|
|
ast_module_unref(ast_module_info->self);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -7199,7 +7201,7 @@ static int sip_hangup(struct ast_channel *ast)
|
|
|
|
|
|
|
|
|
|
stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
|
|
|
|
|
|
|
|
|
|
append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->hangupcause) : "Unknown");
|
|
|
|
|
append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", ast_cause2str(p->hangupcause));
|
|
|
|
|
|
|
|
|
|
/* Disconnect */
|
|
|
|
|
disable_dsp_detect(p);
|
|
|
|
@ -7729,7 +7731,9 @@ static int interpret_t38_parameters(struct sip_pvt *p, const struct ast_control_
|
|
|
|
|
AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr"));
|
|
|
|
|
parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
|
|
|
|
|
parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
|
|
|
|
|
ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters));
|
|
|
|
|
if (p->owner) {
|
|
|
|
|
ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters));
|
|
|
|
|
}
|
|
|
|
|
/* we need to return a positive value here, so that applications that
|
|
|
|
|
* send this request can determine conclusively whether it was accepted or not...
|
|
|
|
|
* older versions of chan_sip would just silently accept it and return zero.
|
|
|
|
@ -12634,9 +12638,9 @@ static int add_rpid(struct sip_request *req, struct sip_pvt *p)
|
|
|
|
|
{
|
|
|
|
|
struct ast_str *tmp = ast_str_alloca(256);
|
|
|
|
|
char tmp2[256];
|
|
|
|
|
char *lid_num = NULL;
|
|
|
|
|
char *lid_name = NULL;
|
|
|
|
|
int lid_pres = AST_PRES_NUMBER_NOT_AVAILABLE;
|
|
|
|
|
char *lid_num;
|
|
|
|
|
char *lid_name;
|
|
|
|
|
int lid_pres;
|
|
|
|
|
const char *fromdomain;
|
|
|
|
|
const char *privacy = NULL;
|
|
|
|
|
const char *screen = NULL;
|
|
|
|
@ -12647,22 +12651,20 @@ static int add_rpid(struct sip_request *req, struct sip_pvt *p)
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (p->owner) {
|
|
|
|
|
connected_id = ast_channel_connected_effective_id(p->owner);
|
|
|
|
|
|
|
|
|
|
if (connected_id.number.valid) {
|
|
|
|
|
lid_num = connected_id.number.str;
|
|
|
|
|
}
|
|
|
|
|
if (connected_id.name.valid) {
|
|
|
|
|
lid_name = connected_id.name.str;
|
|
|
|
|
}
|
|
|
|
|
lid_pres = ast_party_id_presentation(&connected_id);
|
|
|
|
|
if (!p->owner) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ast_strlen_zero(lid_num))
|
|
|
|
|
connected_id = ast_channel_connected_effective_id(p->owner);
|
|
|
|
|
lid_num = S_COR(connected_id.number.valid, connected_id.number.str, NULL);
|
|
|
|
|
if (!lid_num) {
|
|
|
|
|
return 0;
|
|
|
|
|
if (ast_strlen_zero(lid_name))
|
|
|
|
|
}
|
|
|
|
|
lid_name = S_COR(connected_id.name.valid, connected_id.name.str, NULL);
|
|
|
|
|
if (!lid_name) {
|
|
|
|
|
lid_name = lid_num;
|
|
|
|
|
}
|
|
|
|
|
lid_pres = ast_party_id_presentation(&connected_id);
|
|
|
|
|
|
|
|
|
|
fromdomain = S_OR(p->fromdomain, ast_sockaddr_stringify_host_remote(&p->ourip));
|
|
|
|
|
|
|
|
|
|
lid_num = ast_uri_encode(lid_num, tmp2, sizeof(tmp2), ast_uri_sip_user);
|
|
|
|
@ -18124,13 +18126,15 @@ static int get_refer_info(struct sip_pvt *transferer, struct sip_request *outgoi
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Determine transfer context */
|
|
|
|
|
if (transferer->owner) /* Mimic behaviour in res_features.c */
|
|
|
|
|
if (transferer->owner) {
|
|
|
|
|
/* By default, use the context in the channel sending the REFER */
|
|
|
|
|
transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT");
|
|
|
|
|
|
|
|
|
|
/* By default, use the context in the channel sending the REFER */
|
|
|
|
|
if (ast_strlen_zero(transfer_context)) {
|
|
|
|
|
transfer_context = ast_channel_macrocontext(transferer->owner);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (ast_strlen_zero(transfer_context)) {
|
|
|
|
|
transfer_context = S_OR(ast_channel_macrocontext(transferer->owner),
|
|
|
|
|
S_OR(transferer->context, sip_cfg.default_context));
|
|
|
|
|
transfer_context = S_OR(transferer->context, sip_cfg.default_context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ast_string_field_set(refer, refer_to_context, transfer_context);
|
|
|
|
@ -18184,14 +18188,18 @@ static int get_also_info(struct sip_pvt *p, struct sip_request *oreq)
|
|
|
|
|
if (sip_debug_test_pvt(p))
|
|
|
|
|
ast_verbose("Looking for %s in %s\n", c, p->context);
|
|
|
|
|
|
|
|
|
|
if (p->owner) /* Mimic behaviour in res_features.c */
|
|
|
|
|
/* Determine transfer context */
|
|
|
|
|
if (p->owner) {
|
|
|
|
|
/* By default, use the context in the channel sending the REFER */
|
|
|
|
|
transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT");
|
|
|
|
|
|
|
|
|
|
/* By default, use the context in the channel sending the REFER */
|
|
|
|
|
if (ast_strlen_zero(transfer_context)) {
|
|
|
|
|
transfer_context = ast_channel_macrocontext(p->owner);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (ast_strlen_zero(transfer_context)) {
|
|
|
|
|
transfer_context = S_OR(ast_channel_macrocontext(p->owner),
|
|
|
|
|
S_OR(p->context, sip_cfg.default_context));
|
|
|
|
|
transfer_context = S_OR(p->context, sip_cfg.default_context);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) {
|
|
|
|
|
/* This is a blind transfer */
|
|
|
|
|
ast_debug(1, "SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
|
|
|
|
@ -25397,12 +25405,6 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str
|
|
|
|
|
ast_debug(2, "No SDP in Invite, third party call control\n");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Queue NULL frame to prod ast_rtp_bridge if appropriate */
|
|
|
|
|
/* This seems redundant ... see !p-owner above */
|
|
|
|
|
if (p->owner)
|
|
|
|
|
ast_queue_frame(p->owner, &ast_null_frame);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Initialize the context if it hasn't been already */
|
|
|
|
|
if (ast_strlen_zero(p->context))
|
|
|
|
|
ast_string_field_set(p, context, sip_cfg.default_context);
|
|
|
|
|