Changeset 1377


Ignore:
Timestamp:
Jun 20, 2007 4:19:46 AM (12 years ago)
Author:
bennylp
Message:

Ticket #339: Respond correctly to incoming INVITE/re-INVITE without offer and receive answer in ACK

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsip-ua/sip_inv.c

    r1366 r1377  
    6363static void inv_on_state_disconnected( pjsip_inv_session *inv, pjsip_event *e); 
    6464 
     65static pj_status_t inv_check_sdp_in_incoming_msg( pjsip_inv_session *inv, 
     66                                                  pjsip_transaction *tsx, 
     67                                                  pjsip_rx_data *rdata); 
     68static pj_status_t process_answer( pjsip_inv_session *inv, 
     69                                   int st_code, 
     70                                   pjsip_tx_data *tdata, 
     71                                   const pjmedia_sdp_session *local_sdp); 
     72 
    6573static void (*inv_state_handler[])( pjsip_inv_session *inv, pjsip_event *e) =  
    6674{ 
     
    142150{ 
    143151    pjsip_inv_state prev_state = inv->state; 
     152    pj_status_t status; 
     153 
     154 
     155    /* If state is confirmed, check that SDP negotiation is done, 
     156     * otherwise disconnect the session. 
     157     */ 
     158    if (state == PJSIP_INV_STATE_CONFIRMED) { 
     159        if (pjmedia_sdp_neg_get_state(inv->neg)!=PJMEDIA_SDP_NEG_STATE_DONE) { 
     160            pjsip_tx_data *bye; 
     161 
     162            PJ_LOG(4,(inv->obj_name, "SDP offer/answer incomplete, ending the " 
     163                      "session")); 
     164 
     165            status = pjsip_inv_end_session(inv, PJSIP_SC_NOT_ACCEPTABLE,  
     166                                           NULL, &bye); 
     167            if (status == PJ_SUCCESS && bye) 
     168                status = pjsip_inv_send_msg(inv, bye); 
     169 
     170            return; 
     171        } 
     172    } 
    144173 
    145174    /* Set state. */ 
     
    268297            inv->invite_tsx->state <= PJSIP_TSX_STATE_COMPLETED) 
    269298        { 
     299            /* Before we terminate INVITE transaction, process the SDP 
     300             * in the ACK request, if any. 
     301             */ 
     302            inv_check_sdp_in_incoming_msg(inv, inv->invite_tsx, rdata); 
     303 
     304            /* Now we can terminate the INVITE transaction */ 
    270305            pj_assert(inv->invite_tsx->status_code >= 200); 
    271306            pjsip_tsx_terminate(inv->invite_tsx,  
     
    21742209 
    21752210        case PJSIP_TSX_STATE_CONFIRMED: 
    2176             /* For some reason can go here */ 
     2211            /* For some reason can go here (maybe when ACK for 2xx has 
     2212             * the same branch value as the INVITE transaction) */ 
    21772213 
    21782214        case PJSIP_TSX_STATE_TERMINATED: 
     
    22622298 
    22632299        case PJSIP_TSX_STATE_CONFIRMED: 
    2264             if (tsx->status_code/100 == 2) 
     2300            /* It can only go here if incoming ACK request has the same Via 
     2301             * branch parameter as the INVITE transaction. 
     2302             */ 
     2303            if (tsx->status_code/100 == 2) { 
     2304                if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) { 
     2305                    inv_check_sdp_in_incoming_msg(inv, tsx, 
     2306                                                  e->body.tsx_state.src.rdata); 
     2307                } 
     2308 
    22652309                inv_set_state(inv, PJSIP_INV_STATE_CONFIRMED, e); 
     2310            } 
    22662311            break; 
    22672312 
     
    24532498                return; 
    24542499 
    2455             /* Process SDP in the answer */ 
    2456             status = process_answer(inv, 200, tdata, NULL); 
     2500            /* If the INVITE request has SDP body, send answer. 
     2501             * Otherwise generate offer from local active SDP. 
     2502             */ 
     2503            if (rdata->msg_info.msg->body != NULL) { 
     2504                status = process_answer(inv, 200, tdata, NULL); 
     2505            } else { 
     2506                const pjmedia_sdp_session *active_sdp; 
     2507                status = pjmedia_sdp_neg_send_local_offer(dlg->pool,  
     2508                                                          inv->neg,  
     2509                                                          &active_sdp); 
     2510                if (status == PJ_SUCCESS) { 
     2511                    tdata->msg->body = create_sdp_body(tdata->pool, active_sdp); 
     2512                } 
     2513            } 
    24572514 
    24582515            if (status != PJ_SUCCESS) { 
     
    24882545            /* Send 2xx regardless of the status of negotiation */ 
    24892546            status = pjsip_inv_send_msg(inv, tdata); 
     2547 
     2548        } else if (tsx->state == PJSIP_TSX_STATE_CONFIRMED) { 
     2549            /* This is the case where ACK has the same branch as 
     2550             * the INVITE request. 
     2551             */ 
     2552            if (tsx->status_code/100 == 2 && 
     2553                e->body.tsx_state.type == PJSIP_EVENT_RX_MSG)  
     2554            { 
     2555                inv_check_sdp_in_incoming_msg(inv, tsx, 
     2556                                              e->body.tsx_state.src.rdata); 
     2557            } 
    24902558 
    24912559        } 
Note: See TracChangeset for help on using the changeset viewer.