diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 6bdc988471..36c384fed9 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -7051,10 +7051,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); - p->owner = 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); + p->owner = 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; } @@ -7083,7 +7085,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); @@ -7585,7 +7587,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. @@ -12506,9 +12510,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; @@ -12519,22 +12523,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); @@ -17897,13 +17899,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); @@ -17957,14 +17961,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); @@ -25455,12 +25463,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); @@ -29953,7 +29955,7 @@ static struct ast_channel *sip_request_call(const char *type, struct ast_format_ if (sip_cfg.callevents) manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate", "Channel: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n", - p->owner? ast_channel_name(p->owner) : "", "SIP", p->callid, p->fullcontact, p->peername); + p->owner ? ast_channel_name(p->owner) : "", "SIP", p->callid, p->fullcontact, p->peername); sip_pvt_unlock(p); if (!tmpc) { dialog_unlink_all(p);