Ignore:
Timestamp:
Feb 9, 2006 1:26:14 AM (18 years ago)
Author:
bennylp
Message:

Done media integration in pjsua. Needs to do actual voice testing

File:
1 edited

Legend:

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

    r162 r163  
    2929#include <pj/assert.h> 
    3030#include <pj/os.h> 
     31#include <pj/log.h> 
     32 
    3133 
    3234#define THIS_FILE       "sip_invite_session.c" 
     
    8789 
    8890 
     91/* Invite session data to be attached to transaction. */ 
     92struct tsx_inv_data 
     93{ 
     94    pjsip_inv_session   *inv; 
     95    pj_bool_t            sdp_done; 
     96}; 
     97 
     98 
    8999/* 
    90100 * Module load() 
     
    705715{ 
    706716    pjsip_inv_session *inv; 
     717    struct tsx_inv_data *tsx_inv_data; 
    707718    pjsip_msg *msg; 
    708719    pjmedia_sdp_session *rem_sdp = NULL; 
     
    778789    /* Save the invite transaction. */ 
    779790    inv->invite_tsx = pjsip_rdata_get_tsx(rdata); 
    780     inv->invite_tsx->mod_data[mod_inv.mod.id] = inv; 
     791 
     792    /* Attach our data to the transaction. */ 
     793    tsx_inv_data = pj_pool_zalloc(inv->invite_tsx->pool,  
     794                                  sizeof(struct tsx_inv_data)); 
     795    tsx_inv_data->inv = inv; 
     796    inv->invite_tsx->mod_data[mod_inv.mod.id] = tsx_inv_data; 
    781797 
    782798    /* Done */ 
     
    892908    return status; 
    893909} 
     910 
     911/* 
     912 * Check in incoming message for SDP offer/answer. 
     913 */ 
     914static void inv_check_sdp_in_incoming_msg( pjsip_inv_session *inv, 
     915                                           pjsip_transaction *tsx, 
     916                                           pjsip_rx_data *rdata) 
     917{ 
     918    struct tsx_inv_data *tsx_inv_data; 
     919    static const pj_str_t str_application = { "application", 11 }; 
     920    static const pj_str_t str_sdp = { "sdp", 3 }; 
     921    pj_status_t status; 
     922    pjsip_msg *msg; 
     923    pjmedia_sdp_session *sdp; 
     924 
     925    /* Get/attach invite session's transaction data */ 
     926    tsx_inv_data = tsx->mod_data[mod_inv.mod.id]; 
     927    if (tsx_inv_data == NULL) { 
     928        tsx_inv_data = pj_pool_zalloc(tsx->pool, sizeof(struct tsx_inv_data)); 
     929        tsx_inv_data->inv = inv; 
     930        tsx->mod_data[mod_inv.mod.id] = tsx_inv_data; 
     931    } 
     932 
     933    /* MUST NOT do multiple SDP offer/answer in a single transaction.  
     934     */ 
     935 
     936    if (tsx_inv_data->sdp_done) 
     937        return; 
     938 
     939    /* Check if SDP is present in the message. */ 
     940 
     941    msg = rdata->msg_info.msg; 
     942    if (msg->body == NULL) { 
     943        /* Message doesn't have body. */ 
     944        return; 
     945    } 
     946 
     947    if (pj_stricmp(&msg->body->content_type.type, &str_application) || 
     948        pj_stricmp(&msg->body->content_type.subtype, &str_sdp)) 
     949    { 
     950        /* Message body is not "application/sdp" */ 
     951        return; 
     952    } 
     953 
     954    /* Parse the SDP body. */ 
     955 
     956    status = pjmedia_sdp_parse(rdata->tp_info.pool, msg->body->data, 
     957                               msg->body->len, &sdp); 
     958    if (status != PJ_SUCCESS) { 
     959        char errmsg[PJ_ERR_MSG_SIZE]; 
     960        pj_strerror(status, errmsg, sizeof(errmsg)); 
     961        PJ_LOG(4,(THIS_FILE, "Error parsing SDP in %s: %s", 
     962                  pjsip_rx_data_get_info(rdata), errmsg)); 
     963        return; 
     964    } 
     965 
     966    /* The SDP can be an offer or answer, depending on negotiator's state */ 
     967 
     968    if (inv->neg == NULL || 
     969        pjmedia_sdp_neg_get_state(inv->neg) == PJMEDIA_SDP_NEG_STATE_DONE)  
     970    { 
     971 
     972        /* This is an offer. */ 
     973 
     974        if (inv->neg == NULL) { 
     975            status=pjmedia_sdp_neg_create_w_remote_offer(inv->pool, NULL,  
     976                                                         sdp, &inv->neg); 
     977        } else { 
     978            status=pjmedia_sdp_neg_set_remote_offer(inv->pool, inv->neg, sdp); 
     979        } 
     980 
     981        if (status != PJ_SUCCESS) { 
     982            char errmsg[PJ_ERR_MSG_SIZE]; 
     983            pj_strerror(status, errmsg, sizeof(errmsg)); 
     984            PJ_LOG(4,(THIS_FILE, "Error processing SDP offer in %s: %s", 
     985                      pjsip_rx_data_get_info(rdata), errmsg)); 
     986            return; 
     987        } 
     988 
     989        /* Inform application about remote offer. */ 
     990 
     991        if (mod_inv.cb.on_rx_offer) 
     992            (*mod_inv.cb.on_rx_offer)(inv); 
     993 
     994    } else if (pjmedia_sdp_neg_get_state(inv->neg) ==  
     995                PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER)  
     996    { 
     997 
     998        /* This is an answer.  
     999         * Process and negotiate remote answer. 
     1000         */ 
     1001 
     1002        status = pjmedia_sdp_neg_set_remote_answer(inv->pool, inv->neg, sdp); 
     1003 
     1004        if (status != PJ_SUCCESS) { 
     1005            char errmsg[PJ_ERR_MSG_SIZE]; 
     1006            pj_strerror(status, errmsg, sizeof(errmsg)); 
     1007            PJ_LOG(4,(THIS_FILE, "Error processing SDP answer in %s: %s", 
     1008                      pjsip_rx_data_get_info(rdata), errmsg)); 
     1009            return; 
     1010        } 
     1011 
     1012        /* Negotiate SDP */ 
     1013 
     1014        inv_negotiate_sdp(inv); 
     1015 
     1016        /* Mark this transaction has having SDP offer/answer done. */ 
     1017 
     1018        tsx_inv_data->sdp_done = 1; 
     1019 
     1020    } else { 
     1021         
     1022        PJ_LOG(5,(THIS_FILE, "Ignored SDP in %s: negotiator state is %s", 
     1023              pjsip_rx_data_get_info(rdata),  
     1024              pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_get_state(inv->neg)))); 
     1025    } 
     1026 
     1027} 
     1028 
     1029 
    8941030 
    8951031/* 
     
    9491085     */ 
    9501086    if (st_code/10 == 18 || st_code/10 == 20) { 
    951         const pjmedia_sdp_session *local; 
    952  
    953         status = pjmedia_sdp_neg_get_neg_local(inv->neg, &local); 
    954         if (status == PJ_SUCCESS) 
    955             last_res->msg->body = create_sdp_body(last_res->pool, local); 
     1087 
     1088        pjmedia_sdp_neg_state neg_state; 
     1089 
     1090        neg_state = inv->neg ? pjmedia_sdp_neg_get_state(inv->neg) : 
     1091                    PJMEDIA_SDP_NEG_STATE_NULL; 
     1092 
     1093        if (neg_state == PJMEDIA_SDP_NEG_STATE_LOCAL_OFFER || 
     1094            neg_state == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) 
     1095        { 
     1096            const pjmedia_sdp_session *local; 
     1097 
     1098            status = pjmedia_sdp_neg_get_neg_local(inv->neg, &local); 
     1099            if (status == PJ_SUCCESS) 
     1100                last_res->msg->body = create_sdp_body(last_res->pool, local); 
     1101        } 
    9561102 
    9571103        /* Start negotiation, if ready. */ 
    958         if (pjmedia_sdp_neg_get_state(inv->neg) == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) { 
     1104        if (neg_state == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) { 
    9591105            status = inv_negotiate_sdp(inv); 
    9601106            if (status != PJ_SUCCESS) { 
     
    11071253    if (tdata->msg->type == PJSIP_REQUEST_MSG) { 
    11081254        pjsip_transaction *tsx; 
     1255        struct tsx_inv_data *tsx_inv_data; 
    11091256 
    11101257        status = pjsip_dlg_send_request(inv->dlg, tdata, &tsx); 
     
    11121259            return status; 
    11131260 
    1114         tsx->mod_data[mod_inv.mod.id] = inv; 
     1261        tsx_inv_data = pj_pool_zalloc(tsx->pool, sizeof(struct tsx_inv_data)); 
     1262        tsx_inv_data->inv = inv; 
     1263 
     1264        tsx->mod_data[mod_inv.mod.id] = tsx_inv_data; 
    11151265        tsx->mod_data[mod_inv.app_user->id] = token; 
    11161266 
     
    13321482        case PJSIP_TSX_STATE_PROCEEDING: 
    13331483            if (dlg->remote.info->tag.slen) { 
     1484 
    13341485                inv_set_state(inv, PJSIP_INV_STATE_EARLY, e); 
     1486 
     1487                inv_check_sdp_in_incoming_msg(inv, tsx,  
     1488                                              e->body.tsx_state.src.rdata); 
     1489 
    13351490            } else { 
    13361491                /* Ignore 100 (Trying) response, as it doesn't change 
     
    13481503                pj_assert(0); 
    13491504                inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e); 
     1505     
     1506                inv_check_sdp_in_incoming_msg(inv, tsx,  
     1507                                              e->body.tsx_state.src.rdata); 
    13501508 
    13511509            } else if (tsx->status_code==401 || tsx->status_code==407) { 
     
    13961554                inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e); 
    13971555 
     1556                inv_check_sdp_in_incoming_msg(inv, tsx,  
     1557                                              e->body.tsx_state.src.rdata); 
     1558 
    13981559                /* Send ACK */ 
    13991560                pj_assert(e->body.tsx_state.type == PJSIP_EVENT_RX_MSG); 
    14001561 
    14011562                inv_send_ack(inv, e->body.tsx_state.src.rdata); 
     1563 
    14021564 
    14031565            } else  { 
     
    14971659            /* Send/received another provisional response. */ 
    14981660            inv_set_state(inv, PJSIP_INV_STATE_EARLY, e); 
     1661 
     1662            if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) { 
     1663                inv_check_sdp_in_incoming_msg(inv, tsx,  
     1664                                              e->body.tsx_state.src.rdata); 
     1665            } 
    14991666            break; 
    15001667 
    15011668        case PJSIP_TSX_STATE_COMPLETED: 
    1502             if (tsx->status_code/100 == 2) 
     1669            if (tsx->status_code/100 == 2) { 
    15031670                inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e); 
    1504             else 
     1671                if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) { 
     1672                    inv_check_sdp_in_incoming_msg(inv, tsx,  
     1673                                                  e->body.tsx_state.src.rdata); 
     1674                } 
     1675 
     1676            } else 
    15051677                inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
    15061678            break; 
     
    15171689                /* Set state to CONNECTING */ 
    15181690                inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e); 
     1691 
     1692                if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) { 
     1693                    inv_check_sdp_in_incoming_msg(inv, tsx,  
     1694                                                  e->body.tsx_state.src.rdata); 
     1695                } 
    15191696 
    15201697                /* if UAC, send ACK and move state to confirmed. */ 
     
    16061783    } else if (tsx->method.id == PJSIP_BYE_METHOD && 
    16071784               tsx->role == PJSIP_ROLE_UAC && 
    1608                tsx->state == PJSIP_TSX_STATE_COMPLETED) 
     1785               (tsx->state == PJSIP_TSX_STATE_COMPLETED || 
     1786                tsx->state == PJSIP_TSX_STATE_TERMINATED)) 
    16091787    { 
    16101788 
     
    16311809    if (tsx->method.id == PJSIP_BYE_METHOD && 
    16321810        tsx->role == PJSIP_ROLE_UAC && 
    1633         tsx->state == PJSIP_TSX_STATE_COMPLETED) 
     1811        (tsx->state == PJSIP_TSX_STATE_COMPLETED || 
     1812         tsx->state == PJSIP_TSX_STATE_TERMINATED)) 
    16341813    { 
    16351814 
     
    16381817         */ 
    16391818 
    1640         if (e->body.tsx_state.type == PJSIP_EVENT_RX_MSG) 
    1641             inv_handle_bye_response( inv, tsx, e->body.tsx_state.src.rdata, e); 
    1642         else 
    1643             inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
     1819        inv_handle_bye_response( inv, tsx, e->body.tsx_state.src.rdata, e); 
    16441820 
    16451821    } 
Note: See TracChangeset for help on using the changeset viewer.