Ignore:
Timestamp:
Mar 5, 2006 11:53:36 AM (18 years ago)
Author:
bennylp
Message:

Added API to terminate dialog prematurely. Affect: dialog, invite sessions, evsub, and presence

File:
1 edited

Legend:

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

    r267 r283  
    125125                   pjsip_event *e) 
    126126{ 
     127    pjsip_inv_state prev_state = inv->state; 
     128 
     129    /* Set state. */ 
    127130    inv->state = state; 
    128     if (mod_inv.cb.on_state_changed) 
     131 
     132    /* If state is DISCONNECTED, cause code MUST have been set. */ 
     133    pj_assert(inv->state != PJSIP_INV_STATE_DISCONNECTED || 
     134              inv->cause != 0); 
     135 
     136    /* Call on_state_changed() callback. */ 
     137    if (mod_inv.cb.on_state_changed && inv->notify) 
    129138        (*mod_inv.cb.on_state_changed)(inv, e); 
    130139 
    131     if (inv->state == PJSIP_INV_STATE_DISCONNECTED) 
     140    /* Only decrement when previous state is not already DISCONNECTED */ 
     141    if (inv->state == PJSIP_INV_STATE_DISCONNECTED && 
     142        prev_state != PJSIP_INV_STATE_DISCONNECTED)  
     143    { 
    132144        pjsip_dlg_dec_session(inv->dlg, &mod_inv.mod); 
     145    } 
    133146} 
    134147 
     
    291304 
    292305    /* Call on_tsx_state */ 
    293     if (mod_inv.cb.on_tsx_state_changed) 
     306    if (mod_inv.cb.on_tsx_state_changed && inv->notify) 
    294307        (*mod_inv.cb.on_tsx_state_changed)(inv, tsx, e); 
    295308 
     
    379392    inv->dlg = dlg; 
    380393    inv->options = options; 
     394    inv->notify = PJ_TRUE; 
     395    inv->cause = 0; 
    381396 
    382397    /* Object name will use the same dialog pointer. */ 
     
    775790    inv->dlg = dlg; 
    776791    inv->options = options; 
     792    inv->notify = PJ_TRUE; 
     793    inv->cause = 0; 
    777794 
    778795    /* Object name will use the same dialog pointer. */ 
     
    834851} 
    835852 
     853/* 
     854 * Forcefully terminate the session. 
     855 */ 
     856PJ_DEF(pj_status_t) pjsip_inv_terminate( pjsip_inv_session *inv, 
     857                                         int st_code, 
     858                                         pj_bool_t notify) 
     859{ 
     860    PJ_ASSERT_RETURN(inv, PJ_EINVAL); 
     861 
     862    /* Lock dialog. */ 
     863    pjsip_dlg_inc_lock(inv->dlg); 
     864 
     865    /* Set callback notify flag. */ 
     866    inv->notify = notify; 
     867 
     868    /* If there's pending transaction, terminate the transaction.  
     869     * This may subsequently set the INVITE session state to 
     870     * disconnected. 
     871     */ 
     872    if (inv->invite_tsx &&  
     873        inv->invite_tsx->state <= PJSIP_TSX_STATE_COMPLETED) 
     874    { 
     875        pjsip_tsx_terminate(inv->invite_tsx, st_code); 
     876 
     877    } 
     878 
     879    /* Set cause. */ 
     880    inv->cause = st_code; 
     881 
     882    /* Forcefully terminate the session if state is not DISCONNECTED */ 
     883    if (inv->state != PJSIP_INV_STATE_DISCONNECTED) { 
     884        inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, NULL); 
     885    } 
     886 
     887    /* Done. 
     888     * The dec_lock() below will actually destroys the dialog if it 
     889     * has no other session. 
     890     */ 
     891    pjsip_dlg_dec_lock(inv->dlg); 
     892 
     893    return PJ_SUCCESS; 
     894} 
     895 
     896 
    836897static void *clone_sdp(pj_pool_t *pool, const void *data, unsigned len) 
    837898{ 
     
    9751036    PJ_LOG(5,(inv->obj_name, "SDP negotiation done, status=%d", status)); 
    9761037 
    977     if (mod_inv.cb.on_media_update) 
     1038    if (mod_inv.cb.on_media_update && inv->notify) 
    9781039        (*mod_inv.cb.on_media_update)(inv, status); 
    9791040 
     
    10641125        /* Inform application about remote offer. */ 
    10651126 
    1066         if (mod_inv.cb.on_rx_offer) { 
     1127        if (mod_inv.cb.on_rx_offer && inv->notify) { 
    10671128 
    10681129            (*mod_inv.cb.on_rx_offer)(inv, sdp); 
     
    13051366    PJ_ASSERT_RETURN(inv && p_tdata, PJ_EINVAL); 
    13061367 
     1368    /* Set cause code. */ 
     1369    if (inv->cause==0) inv->cause = st_code; 
     1370 
    13071371    /* Create appropriate message. */ 
    13081372    switch (inv->state) { 
     
    13591423    case PJSIP_INV_STATE_DISCONNECTED: 
    13601424        /* No need to do anything. */ 
    1361         PJ_TODO(RETURN_A_PROPER_STATUS_CODE_HERE); 
    1362         return PJ_EINVALIDOP; 
     1425        return PJSIP_ESESSIONTERMINATED; 
    13631426 
    13641427    default: 
     
    16131676    /* Terminate session: */ 
    16141677 
    1615     if (inv->state != PJSIP_INV_STATE_DISCONNECTED) 
     1678    if (inv->state != PJSIP_INV_STATE_DISCONNECTED) { 
     1679        if (inv->cause==0) inv->cause=PJSIP_SC_OK; 
    16161680        inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
     1681    } 
    16171682} 
    16181683 
     
    16281693     
    16291694    if (e->body.tsx_state.type != PJSIP_EVENT_RX_MSG) { 
     1695        if (inv->cause==0) inv->cause=PJSIP_SC_OK; 
    16301696        inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
    16311697        return; 
     
    16471713             * End the session anyway. 
    16481714             */ 
     1715            if (inv->cause==0) inv->cause=PJSIP_SC_OK; 
    16491716            inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
    16501717             
     
    16571724 
    16581725        /* End the session. */ 
    1659  
     1726        if (inv->cause==0) inv->cause=PJSIP_SC_OK; 
    16601727        inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
    16611728    } 
     
    17751842                     * End the session. 
    17761843                     */ 
     1844                    if (inv->cause==0) inv->cause = tsx->status_code; 
    17771845                    inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
    17781846 
     
    17891857            } else { 
    17901858 
     1859                if (inv->cause==0) inv->cause = tsx->status_code; 
    17911860                inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
    17921861 
     
    18161885 
    18171886            } else  { 
     1887                if (inv->cause==0) inv->cause = tsx->status_code; 
    18181888                inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
    18191889            } 
     
    18381908            PJSIP_SC_TSX_TRANSPORT_ERROR) 
    18391909        { 
     1910            if (inv->cause==0) inv->cause = tsx->status_code; 
    18401911            inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
    18411912        } 
     
    18781949             * Transaction sent final response. 
    18791950             */ 
    1880             if (tsx->status_code/100 == 2) 
     1951            if (tsx->status_code/100 == 2) { 
    18811952                inv_set_state(inv, PJSIP_INV_STATE_CONNECTING, e); 
    1882             else 
     1953            } else { 
     1954                if (inv->cause==0) inv->cause = tsx->status_code; 
    18831955                inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
     1956            } 
    18841957            break; 
    18851958 
     
    18891962             * response) 
    18901963             */ 
     1964            if (inv->cause==0) inv->cause = tsx->status_code; 
    18911965            inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
    18921966            break; 
     
    19492023                } 
    19502024 
    1951             } else 
     2025            } else { 
     2026                if (inv->cause==0) inv->cause = tsx->status_code; 
    19522027                inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
     2028            } 
    19532029            break; 
    19542030 
     
    19822058 
    19832059            } else  { 
     2060                if (inv->cause==0) inv->cause = tsx->status_code; 
    19842061                inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
    19852062            } 
     
    20172094            PJSIP_SC_TSX_TRANSPORT_ERROR) 
    20182095        { 
     2096            if (inv->cause==0) inv->cause = tsx->status_code; 
    20192097            inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
    20202098        } 
     
    20502128             */ 
    20512129            if (tsx->status_code/100 != 2) { 
     2130                if (inv->cause==0) inv->cause = tsx->status_code; 
    20522131                inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
    20532132            } 
     
    22412320             * Handle responses that terminates dialog. 
    22422321             */ 
     2322            if (inv->cause==0) inv->cause = tsx->status_code; 
    22432323            inv_set_state(inv, PJSIP_INV_STATE_DISCONNECTED, e); 
    22442324        } 
Note: See TracChangeset for help on using the changeset viewer.