Create more accurate Contact headers for dialogs when we are the UAS.
[asterisk/asterisk.git] / res / res_pjsip_session.c
index fd13608..c6c3953 100644 (file)
@@ -947,6 +947,9 @@ int ast_sip_session_create_invite(struct ast_sip_session *session, pjsip_tx_data
 
        pjsip_inv_set_local_sdp(session->inv_session, offer);
        pjmedia_sdp_neg_set_prefer_remote_codec_order(session->inv_session->neg, PJ_FALSE);
+#ifdef PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS
+       pjmedia_sdp_neg_set_answer_multiple_codecs(session->inv_session->neg, PJ_TRUE);
+#endif
        if (pjsip_inv_invite(session->inv_session, tdata) != PJ_SUCCESS) {
                return -1;
        }
@@ -1182,7 +1185,7 @@ struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint
                return NULL;
        }
 
-       if (!(dlg = ast_sip_create_dialog(endpoint, uri, request_user))) {
+       if (!(dlg = ast_sip_create_dialog_uac(endpoint, uri, request_user))) {
                return NULL;
        }
 
@@ -1334,7 +1337,8 @@ static pjsip_inv_session *pre_session_setup(pjsip_rx_data *rdata, const struct a
                }
                return NULL;
        }
-       if (pjsip_dlg_create_uas(pjsip_ua_instance(), rdata, NULL, &dlg) != PJ_SUCCESS) {
+       dlg = ast_sip_create_dialog_uas(endpoint, rdata);
+       if (!dlg) {
                pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
                return NULL;
        }
@@ -1459,6 +1463,9 @@ static int new_invite(void *data)
        } else {
                pjsip_inv_set_local_sdp(invite->session->inv_session, local);
                pjmedia_sdp_neg_set_prefer_remote_codec_order(invite->session->inv_session->neg, PJ_FALSE);
+#ifdef PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS
+               pjmedia_sdp_neg_set_answer_multiple_codecs(invite->session->inv_session->neg, PJ_TRUE);
+#endif
        }
 
        pjsip_timer_setting_default(&timer);
@@ -1862,17 +1869,33 @@ static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_trans
                break;
        case PJSIP_EVENT_RX_MSG:
                if (tsx->method.id == PJSIP_INVITE_METHOD) {
-                       if (tsx->role == PJSIP_ROLE_UAC && tsx->state == PJSIP_TSX_STATE_COMPLETED) {
-                               /* This means we got a non 2XX final response to our outgoing INVITE */
-                               if (tsx->status_code == PJSIP_SC_REQUEST_PENDING) {
-                                       reschedule_reinvite(session, tsx->mod_data[session_module.id], tsx->last_tx);
-                                       return;
-                               } else if (inv->state == PJSIP_INV_STATE_CONFIRMED &&
-                                          tsx->status_code != 488) {
-                                       /* Other reinvite failures (except 488) result in destroying the session. */
-                                       pjsip_tx_data *tdata;
-                                       if (pjsip_inv_end_session(inv, 500, NULL, &tdata) == PJ_SUCCESS) {
-                                               ast_sip_session_send_request(session, tdata);
+                       if (tsx->role == PJSIP_ROLE_UAC) {
+                               if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {
+                                       /* This means we got a non 2XX final response to our outgoing INVITE */
+                                       if (tsx->status_code == PJSIP_SC_REQUEST_PENDING) {
+                                               reschedule_reinvite(session, tsx->mod_data[session_module.id], tsx->last_tx);
+                                               return;
+                                       } else if (inv->state == PJSIP_INV_STATE_CONFIRMED &&
+                                                  tsx->status_code != 488) {
+                                               /* Other reinvite failures (except 488) result in destroying the session. */
+                                               pjsip_tx_data *tdata;
+                                               if (pjsip_inv_end_session(inv, 500, NULL, &tdata) == PJ_SUCCESS) {
+                                                       ast_sip_session_send_request(session, tdata);
+                                               }
+                                       }
+                               } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
+                                       if (inv->cancelling && tsx->status_code == PJSIP_SC_OK) {
+                                               /* This is a race condition detailed in RFC 5407 section 3.1.2.
+                                                * We sent a CANCEL at the same time that the UAS sent us a 200 OK for
+                                                * the original INVITE. As a result, we have now received a 200 OK for
+                                                * a cancelled call. Our role is to immediately send a BYE to end the
+                                                * dialog.
+                                                */
+                                               pjsip_tx_data *tdata;
+
+                                               if (pjsip_inv_end_session(inv, 500, NULL, &tdata) == PJ_SUCCESS) {
+                                                       ast_sip_session_send_request(session, tdata);
+                                               }
                                        }
                                }
                        }