Changeset 2149


Ignore:
Timestamp:
Jul 17, 2008 1:53:41 PM (16 years ago)
Author:
bennylp
Message:

Ticket #574: Add new API to know why the outgoing subscription request is terminated and added support for delaying subscription acceptance

Location:
pjproject/trunk/pjsip
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/include/pjsip-simple/evsub.h

    r2121 r2149  
    347347 
    348348/** 
     349 * Get subscription termination reason, if any. If remote did not 
     350 * send termination reason, this function will return empty string. 
     351 * 
     352 * @param sub           Event subscription instance. 
     353 * 
     354 * @return              NULL terminated string. 
     355 */ 
     356PJ_DECL(const pj_str_t*) pjsip_evsub_get_termination_reason(pjsip_evsub *sub); 
     357 
     358 
     359/** 
    349360 * Call this function to create request to initiate subscription, to  
    350361 * refresh subcription, or to request subscription termination. 
  • pjproject/trunk/pjsip/src/pjsip-simple/evsub.c

    r2147 r2149  
    222222    pjsip_evsub_state     dst_state;    /**< Pending state to be set.       */ 
    223223    pj_str_t              dst_state_str;/**< Pending state to be set.       */ 
     224    pj_str_t              term_reason;  /**< Termination reason.            */ 
    224225    pjsip_method          method;       /**< Method that established subscr.*/ 
    225226    pjsip_event_hdr      *event;        /**< Event description.             */ 
     
    551552 */ 
    552553static void set_state( pjsip_evsub *sub, pjsip_evsub_state state, 
    553                        const pj_str_t *state_str, pjsip_event *event) 
     554                       const pj_str_t *state_str, pjsip_event *event, 
     555                       const pj_str_t *reason) 
    554556{ 
    555557    pjsip_evsub_state prev_state = sub->state; 
     
    562564    else 
    563565        sub->state_str = evsub_state_names[state]; 
     566 
     567    if (reason && sub->term_reason.slen==0) 
     568        pj_strdup(sub->pool, &sub->term_reason, reason); 
    564569 
    565570    PJ_LOG(4,(sub->obj_name,  
     
    639644    case TIMER_TYPE_UAC_TERMINATE: 
    640645        { 
     646            pj_str_t timeout = {"timeout", 7}; 
     647 
    641648            PJ_LOG(5,(sub->obj_name, "Timeout waiting for final NOTIFY. " 
    642649                                     "Terminating..")); 
    643             set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, NULL); 
     650            set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, NULL,  
     651                      &timeout); 
    644652        } 
    645653        break; 
     
    913921 
    914922    sub->call_cb = notify; 
    915     set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, NULL); 
     923    set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, NULL, NULL); 
    916924 
    917925    pjsip_dlg_dec_lock(sub->dlg); 
     
    935943} 
    936944 
     945/* 
     946 * Get termination reason. 
     947 */ 
     948PJ_DEF(const pj_str_t*) pjsip_evsub_get_termination_reason(pjsip_evsub *sub) 
     949{ 
     950    return &sub->term_reason; 
     951} 
    937952 
    938953/* 
     
    10861101    case PJSIP_EVSUB_STATE_NULL: 
    10871102    case PJSIP_EVSUB_STATE_SENT: 
    1088     case PJSIP_EVSUB_STATE_ACCEPTED: 
    10891103        pj_assert(!"Invalid state!"); 
    10901104        /* Treat as pending */ 
    10911105 
     1106    case PJSIP_EVSUB_STATE_ACCEPTED: 
    10921107    case PJSIP_EVSUB_STATE_PENDING: 
    10931108        sub_state->sub_state = STR_PENDING; 
     
    11561171    pjsip_auth_clt_init_req( &sub->dlg->auth_sess, tdata ); 
    11571172 
    1158      
     1173    /* Update reason */ 
     1174    if (reason) 
     1175        pj_strdup(sub->dlg->pool, &sub->term_reason, reason); 
    11591176 
    11601177    /* Save destination state. */ 
     
    12191236        set_state(sub, sub->dst_state,  
    12201237                  (sub->dst_state_str.slen ? &sub->dst_state_str : NULL),  
    1221                   NULL); 
     1238                  NULL, NULL); 
    12221239 
    12231240        sub->dst_state = PJSIP_EVSUB_STATE_NULL; 
     
    15471564            tsx->state == PJSIP_TSX_STATE_CALLING) 
    15481565        { 
    1549             set_state(sub, PJSIP_EVSUB_STATE_SENT, NULL, event); 
     1566            set_state(sub, PJSIP_EVSUB_STATE_SENT, NULL, event, NULL); 
    15501567            return; 
    15511568        } 
     
    15881605                /* Authentication failed! */ 
    15891606                set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, 
    1590                                NULL, 
    1591                                event); 
     1607                          NULL, event, &tsx->status_text); 
    15921608                return; 
    15931609            } 
     
    16471663            pj_assert(sub->state != PJSIP_EVSUB_STATE_NULL); 
    16481664            if (sub->state == PJSIP_EVSUB_STATE_SENT) { 
    1649                 set_state(sub, PJSIP_EVSUB_STATE_ACCEPTED, NULL, event); 
     1665                set_state(sub, PJSIP_EVSUB_STATE_ACCEPTED, NULL, event, NULL); 
    16501666            } 
    16511667 
     
    16861702            /* Set state to TERMINATED */ 
    16871703            set_state(sub, PJSIP_EVSUB_STATE_TERMINATED,  
    1688                       NULL, event); 
     1704                      NULL, event, &tsx->status_text); 
    16891705 
    16901706        } 
     
    17721788                set_timer(sub, TIMER_TYPE_UAC_WAIT_NOTIFY, timeout); 
    17731789            } else { 
    1774                 set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, NULL); 
     1790                char errmsg[PJ_ERR_MSG_SIZE]; 
     1791                pj_str_t reason; 
     1792 
     1793                reason = pj_strerror(status, errmsg, sizeof(errmsg)); 
     1794                set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, NULL,  
     1795                          &reason); 
    17751796            } 
    17761797 
     
    18161837        /* Set the state */ 
    18171838        if (status == PJ_SUCCESS) { 
    1818             set_state(sub, new_state, new_state_str, event); 
     1839            set_state(sub, new_state, new_state_str, event,  
     1840                      &sub_state->reason_param); 
    18191841        } else { 
    1820             set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, event); 
     1842            char errmsg[PJ_ERR_MSG_SIZE]; 
     1843            pj_str_t reason; 
     1844 
     1845            reason = pj_strerror(status, errmsg, sizeof(errmsg)); 
     1846            set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, event,  
     1847                      &reason); 
    18211848        } 
    18221849 
     
    18591886        pjsip_evsub_state old_state; 
    18601887        pj_str_t old_state_str; 
     1888        pj_str_t reason = { NULL, 0 }; 
    18611889        pj_status_t status; 
    18621890 
     
    19451973             
    19461974            if (sub->expires->ivalue == 0) { 
    1947                 set_state(sub, sub->state, NULL, event); 
     1975                set_state(sub, sub->state, NULL, event, &reason); 
    19481976            } else  if (sub->state == PJSIP_EVSUB_STATE_NULL) { 
    1949                 set_state(sub, sub->state, NULL, event); 
     1977                set_state(sub, sub->state, NULL, event, &reason); 
    19501978            } 
    19511979 
     
    19812009            if (status != PJ_SUCCESS) { 
    19822010                /* Can't authenticate. Terminate session (?) */ 
    1983                 set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, NULL); 
     2011                set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, NULL,  
     2012                          &tsx->status_text); 
    19842013                return; 
    19852014            } 
     
    19942023             tsx->status_code/100 == 7)) 
    19952024        { 
    1996             set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, event); 
     2025            set_state(sub, PJSIP_EVSUB_STATE_TERMINATED, NULL, event, 
     2026                      &tsx->status_text); 
    19972027            return; 
    19982028        } 
  • pjproject/trunk/pjsip/src/pjsip-simple/evsub_msg.c

    r2039 r2149  
    2020#include <pjsip/print_util.h> 
    2121#include <pjsip/sip_parser.h> 
     22#include <pjlib-util/string.h> 
    2223#include <pj/pool.h> 
    2324#include <pj/string.h> 
     
    167168    *p++ = ' '; 
    168169 
    169     copy_advance(p, hdr->sub_state); 
    170     copy_advance_pair(p, ";reason=", 8, hdr->reason_param); 
     170    copy_advance_escape(p, hdr->sub_state, pc->pjsip_TOKEN_SPEC); 
     171    copy_advance_pair_escape(p, ";reason=", 8, hdr->reason_param, 
     172                             pc->pjsip_TOKEN_SPEC); 
    171173    if (hdr->expires_param >= 0) { 
    172174        pj_memcpy(p, ";expires=", 9); 
  • pjproject/trunk/pjsip/src/pjsip-simple/presence.c

    r2039 r2149  
    462462    PJ_ASSERT_RETURN(pres != NULL, PJSIP_SIMPLE_ENOPRESENCE); 
    463463 
    464     /* Must have at least one presence info. */ 
    465     PJ_ASSERT_RETURN(pres->status.info_cnt > 0, PJSIP_SIMPLE_ENOPRESENCEINFO); 
     464    /* Must have at least one presence info, unless state is  
     465     * PJSIP_EVSUB_STATE_TERMINATED. This could happen if subscription 
     466     * has not been active (e.g. we're waiting for user authorization) 
     467     * and remote cancels the subscription. 
     468     */ 
     469    PJ_ASSERT_RETURN(state==PJSIP_EVSUB_STATE_TERMINATED || 
     470                     pres->status.info_cnt > 0, PJSIP_SIMPLE_ENOPRESENCEINFO); 
    466471 
    467472 
     
    475480 
    476481 
    477     /* Create message body to reflect the presence status. */ 
    478     status = pres_create_msg_body( pres, tdata ); 
    479     if (status != PJ_SUCCESS) 
    480         goto on_return; 
    481  
     482    /* Create message body to reflect the presence status.  
     483     * Only do this if we have presence status info to send (see above). 
     484     */ 
     485    if (pres->status.info_cnt > 0) { 
     486        status = pres_create_msg_body( pres, tdata ); 
     487        if (status != PJ_SUCCESS) 
     488            goto on_return; 
     489    } 
    482490 
    483491    /* Done. */ 
     
    508516    PJ_ASSERT_RETURN(pres != NULL, PJSIP_SIMPLE_ENOPRESENCE); 
    509517 
    510     /* Must have at least one presence info. */ 
    511     PJ_ASSERT_RETURN(pres->status.info_cnt > 0, PJSIP_SIMPLE_ENOPRESENCEINFO); 
     518    /* We may not have a presence info yet, e.g. when we receive SUBSCRIBE 
     519     * to refresh subscription while we're waiting for user authorization. 
     520     */ 
     521    //PJ_ASSERT_RETURN(pres->status.info_cnt > 0,  
     522    //                 PJSIP_SIMPLE_ENOPRESENCEINFO); 
    512523 
    513524 
     
    522533 
    523534    /* Create message body to reflect the presence status. */ 
    524     status = pres_create_msg_body( pres, tdata ); 
    525     if (status != PJ_SUCCESS) 
    526         goto on_return; 
    527  
     535    if (pres->status.info_cnt > 0) { 
     536        status = pres_create_msg_body( pres, tdata ); 
     537        if (status != PJ_SUCCESS) 
     538            goto on_return; 
     539    } 
    528540 
    529541    /* Done. */ 
Note: See TracChangeset for help on using the changeset viewer.