Ignore:
Timestamp:
Feb 7, 2006 6:48:01 PM (18 years ago)
Author:
bennylp
Message:

Tested initial implementation: basic UAC, client registration, authentication, etc

File:
1 edited

Legend:

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

    r65 r141  
    1717 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  
    1818 */ 
    19 #include <pjsip_mod_ua/sip_reg.h> 
     19#include <pjsip-ua/sip_regc.h> 
    2020#include <pjsip/sip_endpoint.h> 
    2121#include <pjsip/sip_parser.h> 
     
    2525#include <pjsip/sip_util.h> 
    2626#include <pjsip/sip_auth_msg.h> 
     27#include <pjsip/sip_errno.h> 
    2728#include <pj/pool.h> 
    2829#include <pj/string.h> 
    2930#include <pj/guid.h> 
    3031#include <pj/log.h> 
     32#include <pj/assert.h> 
     33 
    3134 
    3235#define REFRESH_TIMER           1 
     
    4245    pjsip_endpoint      *endpt; 
    4346    pj_bool_t            _delete_flag; 
    44     int                 pending_tsx; 
     47    int                  pending_tsx; 
    4548 
    4649    void                *token; 
    4750    pjsip_regc_cb       *cb; 
    4851 
    49     pj_str_t            str_srv_url; 
     52    pj_str_t             str_srv_url; 
    5053    pjsip_uri           *srv_url; 
    5154    pjsip_cid_hdr       *cid_hdr; 
     
    6063    pj_uint32_t          expires; 
    6164 
    62     /* Credentials. */ 
    63     int                  cred_count; 
    64     pjsip_cred_info     *cred_info; 
    65      
    6665    /* Authorization sessions. */ 
    67     pjsip_auth_session   auth_sess_list; 
     66    pjsip_auth_clt_sess  auth_sess; 
    6867 
    6968    /* Auto refresh registration. */ 
     
    7473 
    7574 
    76 PJ_DEF(pjsip_regc*) pjsip_regc_create( pjsip_endpoint *endpt, void *token, 
    77                                        pjsip_regc_cb *cb) 
     75PJ_DEF(pj_status_t) pjsip_regc_create( pjsip_endpoint *endpt, void *token, 
     76                                       pjsip_regc_cb *cb, 
     77                                       pjsip_regc **p_regc) 
    7878{ 
    7979    pj_pool_t *pool; 
    8080    pjsip_regc *regc; 
    81  
    82     if (cb == NULL) 
    83         return NULL; 
     81    pj_status_t status; 
     82 
     83    /* Verify arguments. */ 
     84    PJ_ASSERT_RETURN(endpt && cb && p_regc, PJ_EINVAL); 
    8485 
    8586    pool = pjsip_endpt_create_pool(endpt, "regc%p", 1024, 1024); 
    86     regc = pj_pool_calloc(pool, 1, sizeof(struct pjsip_regc)); 
     87    PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM); 
     88 
     89    regc = pj_pool_zalloc(pool, sizeof(struct pjsip_regc)); 
    8790 
    8891    regc->pool = pool; 
     
    9396    regc->expires = PJSIP_REGC_EXPIRATION_NOT_SPECIFIED; 
    9497 
    95     pj_list_init(&regc->auth_sess_list); 
    96  
    97     return regc; 
    98 } 
    99  
    100  
    101 PJ_DEF(void) pjsip_regc_destroy(pjsip_regc *regc) 
     98    status = pjsip_auth_clt_init(&regc->auth_sess, endpt, regc->pool, 0); 
     99    if (status != PJ_SUCCESS) 
     100        return status; 
     101 
     102    /* Done */ 
     103    *p_regc = regc; 
     104    return PJ_SUCCESS; 
     105} 
     106 
     107 
     108PJ_DEF(pj_status_t) pjsip_regc_destroy(pjsip_regc *regc) 
    102109{ 
    103110    if (regc->pending_tsx) { 
     
    105112        regc->cb = NULL; 
    106113    } else { 
    107         pjsip_endpt_destroy_pool(regc->endpt, regc->pool); 
    108     } 
     114        pjsip_endpt_release_pool(regc->endpt, regc->pool); 
     115    } 
     116 
     117    return PJ_SUCCESS; 
    109118} 
    110119 
     
    118127{ 
    119128    if (expires != regc->expires) { 
    120         regc->expires_hdr = pjsip_expires_hdr_create(regc->pool); 
    121         regc->expires_hdr->ivalue = expires; 
     129        regc->expires_hdr = pjsip_expires_hdr_create(regc->pool, expires); 
    122130    } else { 
    123131        regc->expires_hdr = NULL; 
     
    137145    for (i=0, s=regc->contact_buf; i<contact_cnt; ++i) { 
    138146        if ((s-regc->contact_buf) + contact[i].slen + 2 > PJSIP_REGC_CONTACT_BUF_SIZE) { 
    139             return -1; 
     147            return PJSIP_EURITOOLONG; 
    140148        } 
    141149        pj_memcpy(s, contact[i].ptr, contact[i].slen); 
     
    149157 
    150158    /* Set "Contact" header. */ 
    151     regc->contact_hdr = pjsip_generic_string_hdr_create( regc->pool, &contact_STR); 
     159    regc->contact_hdr = pjsip_generic_string_hdr_create(regc->pool,  
     160                                                        &contact_STR, 
     161                                                        NULL); 
    152162    regc->contact_hdr->hvalue.ptr = regc->contact_buf; 
    153163    regc->contact_hdr->hvalue.slen = (s - regc->contact_buf); 
    154164 
    155     return 0; 
     165    return PJ_SUCCESS; 
    156166} 
    157167 
     
    166176{ 
    167177    pj_str_t tmp; 
     178    pj_status_t status; 
     179 
     180    PJ_ASSERT_RETURN(regc && srv_url && from_url && to_url &&  
     181                     contact_cnt && contact && expires, PJ_EINVAL); 
    168182 
    169183    /* Copy server URL. */ 
     
    174188    regc->srv_url = pjsip_parse_uri( regc->pool, tmp.ptr, tmp.slen, 0); 
    175189    if (regc->srv_url == NULL) { 
    176         return -1; 
     190        return PJSIP_EINVALIDURI; 
    177191    } 
    178192 
     
    183197                                          PJSIP_PARSE_URI_AS_NAMEADDR); 
    184198    if (!regc->from_hdr->uri) { 
    185         PJ_LOG(4,(THIS_FILE, "regc: invalid source URI %.*s", from_url->slen, from_url->ptr)); 
    186         return -1; 
     199        PJ_LOG(4,(THIS_FILE, "regc: invalid source URI %.*s",  
     200                  from_url->slen, from_url->ptr)); 
     201        return PJSIP_EINVALIDURI; 
    187202    } 
    188203 
     
    194209    if (!regc->to_hdr->uri) { 
    195210        PJ_LOG(4,(THIS_FILE, "regc: invalid target URI %.*s", to_url->slen, to_url->ptr)); 
    196         return -1; 
     211        return PJSIP_EINVALIDURI; 
    197212    } 
    198213 
    199214 
    200215    /* Set "Contact" header. */ 
    201     if (set_contact( regc, contact_cnt, contact) != 0) 
    202         return -1; 
     216    status = set_contact( regc, contact_cnt, contact); 
     217    if (status != PJ_SUCCESS) 
     218        return status; 
    203219 
    204220    /* Set "Expires" header, if required. */ 
     
    219235 
    220236    /* Create "Expires" header used in unregistration. */ 
    221     regc->unreg_expires_hdr = pjsip_expires_hdr_create( regc->pool); 
    222     regc->unreg_expires_hdr->ivalue = 0; 
     237    regc->unreg_expires_hdr = pjsip_expires_hdr_create( regc->pool, 0); 
    223238 
    224239    /* Done. */ 
    225     return 0; 
     240    return PJ_SUCCESS; 
    226241} 
    227242 
     
    230245                                                const pjsip_cred_info cred[] ) 
    231246{ 
    232     if (count > 0) { 
    233         regc->cred_info = pj_pool_alloc(regc->pool, count * sizeof(pjsip_cred_info)); 
    234         pj_memcpy(regc->cred_info, cred, count * sizeof(pjsip_cred_info)); 
    235     } 
    236     regc->cred_count = count; 
    237     return 0; 
    238 } 
    239  
    240 static pjsip_tx_data *create_request(pjsip_regc *regc) 
    241 { 
     247    PJ_ASSERT_RETURN(regc && count && cred, PJ_EINVAL); 
     248    return pjsip_auth_clt_set_credentials(&regc->auth_sess, count, cred); 
     249} 
     250 
     251static pj_status_t create_request(pjsip_regc *regc,  
     252                                  pjsip_tx_data **p_tdata) 
     253{ 
     254    pj_status_t status; 
    242255    pjsip_tx_data *tdata; 
     256 
     257    PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL); 
     258 
     259    /* Create the request. */ 
     260    status = pjsip_endpt_create_request_from_hdr( regc->endpt,  
     261                                                  &pjsip_register_method, 
     262                                                  regc->srv_url, 
     263                                                  regc->from_hdr, 
     264                                                  regc->to_hdr, 
     265                                                  NULL, 
     266                                                  regc->cid_hdr, 
     267                                                  regc->cseq_hdr->cseq, 
     268                                                  NULL, 
     269                                                  &tdata); 
     270    if (status != PJ_SUCCESS) 
     271        return status; 
     272 
     273    /* Add cached authorization headers. */ 
     274    pjsip_auth_clt_init_req( &regc->auth_sess, tdata ); 
     275 
     276    /* Done. */ 
     277    *p_tdata = tdata; 
     278    return PJ_SUCCESS; 
     279} 
     280 
     281 
     282PJ_DEF(pj_status_t) pjsip_regc_register(pjsip_regc *regc, pj_bool_t autoreg, 
     283                                        pjsip_tx_data **p_tdata) 
     284{ 
    243285    pjsip_msg *msg; 
    244  
    245     /* Create transmit data. */ 
    246     tdata = pjsip_endpt_create_tdata(regc->endpt); 
    247     if (!tdata) { 
    248         return NULL; 
    249     } 
    250  
    251     /* Create request message. */ 
    252     msg = pjsip_msg_create(tdata->pool, PJSIP_REQUEST_MSG); 
    253     tdata->msg = msg; 
    254  
    255     /* Initialize request line. */ 
    256     pjsip_method_set(&msg->line.req.method, PJSIP_REGISTER_METHOD); 
    257     msg->line.req.uri = regc->srv_url; 
    258  
    259     /* Add headers. */ 
    260     pjsip_msg_add_hdr(msg, (pjsip_hdr*) regc->from_hdr); 
    261     pjsip_msg_add_hdr(msg, (pjsip_hdr*) regc->to_hdr); 
    262     pjsip_msg_add_hdr(msg, (pjsip_hdr*) regc->cid_hdr); 
    263     pjsip_msg_add_hdr(msg, (pjsip_hdr*) regc->cseq_hdr); 
    264      
    265     /* Add cached authorization headers. */ 
    266     pjsip_auth_init_req( regc->pool, tdata, &regc->auth_sess_list, 
    267                          regc->cred_count, regc->cred_info ); 
    268  
    269     /* Add reference counter to transmit data. */ 
    270     pjsip_tx_data_add_ref(tdata); 
    271  
    272     return tdata; 
    273 } 
    274  
    275  
    276 PJ_DEF(pjsip_tx_data*) pjsip_regc_register(pjsip_regc *regc, pj_bool_t autoreg) 
    277 { 
    278     pjsip_msg *msg; 
     286    pj_status_t status; 
    279287    pjsip_tx_data *tdata; 
    280288 
    281     tdata = create_request(regc); 
    282     if (!tdata) 
    283         return NULL; 
    284  
     289    status = create_request(regc, &tdata); 
     290    if (status != PJ_SUCCESS) 
     291        return status; 
     292 
     293    /* Add Contact header. */ 
    285294    msg = tdata->msg; 
    286295    pjsip_msg_add_hdr(msg, (pjsip_hdr*) regc->contact_hdr); 
     
    295304    regc->auto_reg = autoreg; 
    296305 
    297     return tdata; 
    298 } 
    299  
    300  
    301 PJ_DEF(pjsip_tx_data*) pjsip_regc_unregister(pjsip_regc *regc) 
     306    /* Done */ 
     307    *p_tdata = tdata; 
     308    return PJ_SUCCESS; 
     309} 
     310 
     311 
     312PJ_DEF(pj_status_t) pjsip_regc_unregister(pjsip_regc *regc, 
     313                                          pjsip_tx_data **p_tdata) 
    302314{ 
    303315    pjsip_tx_data *tdata; 
    304316    pjsip_msg *msg; 
     317    pj_status_t status; 
    305318 
    306319    if (regc->timer.id != 0) { 
     
    309322    } 
    310323 
    311     tdata = create_request(regc); 
    312     if (!tdata) 
    313         return NULL; 
     324    status = create_request(regc, &tdata); 
     325    if (status != PJ_SUCCESS) 
     326        return status; 
    314327 
    315328    msg = tdata->msg; 
     
    317330    pjsip_msg_add_hdr( msg, (pjsip_hdr*)regc->unreg_expires_hdr); 
    318331 
    319     return tdata; 
     332    *p_tdata = tdata; 
     333    return PJ_SUCCESS; 
    320334} 
    321335 
     
    333347{ 
    334348    set_expires( regc, expires ); 
    335     return 0; 
     349    return PJ_SUCCESS; 
    336350} 
    337351 
     
    364378    pjsip_regc *regc = entry->user_data; 
    365379    pjsip_tx_data *tdata; 
     380    pj_status_t status; 
    366381     
    367     PJ_UNUSED_ARG(timer_heap) 
     382    PJ_UNUSED_ARG(timer_heap); 
    368383 
    369384    entry->id = 0; 
    370     tdata = pjsip_regc_register(regc, 1); 
    371     if (tdata) { 
     385    status = pjsip_regc_register(regc, 1, &tdata); 
     386    if (status == PJ_SUCCESS) { 
    372387        pjsip_regc_send(regc, tdata); 
    373388    } else { 
    374         pj_str_t reason = pj_str("Unable to create txdata"); 
     389        char errmsg[PJ_ERR_MSG_SIZE]; 
     390        pj_str_t reason = pj_strerror(status, errmsg, sizeof(errmsg)); 
    375391        call_callback(regc, -1, &reason, NULL, -1, 0, NULL); 
    376392    } 
     
    379395static void tsx_callback(void *token, pjsip_event *event) 
    380396{ 
     397    pj_status_t status; 
    381398    pjsip_regc *regc = token; 
    382     pjsip_transaction *tsx = event->obj.tsx; 
     399    pjsip_transaction *tsx = event->body.tsx_state.tsx; 
    383400     
    384401    /* If registration data has been deleted by user then remove registration  
     
    391408               tsx->status_code == PJSIP_SC_UNAUTHORIZED) 
    392409    { 
    393         pjsip_rx_data *rdata = event->src.rdata; 
     410        pjsip_rx_data *rdata = event->body.tsx_state.src.rdata; 
    394411        pjsip_tx_data *tdata; 
    395412 
    396         tdata = pjsip_auth_reinit_req( regc->endpt, 
    397                                        regc->pool, &regc->auth_sess_list, 
    398                                        regc->cred_count, regc->cred_info, 
    399                                        tsx->last_tx, event->src.rdata ); 
    400  
    401         if (tdata) { 
     413        status = pjsip_auth_clt_reinit_req( &regc->auth_sess, 
     414                                            rdata,  
     415                                            tsx->last_tx,   
     416                                            &tdata); 
     417 
     418        if (status == PJ_SUCCESS) { 
    402419            --regc->pending_tsx; 
    403420            pjsip_regc_send(regc, tdata); 
    404421            return; 
    405422        } else { 
    406             call_callback(regc, tsx->status_code, &rdata->msg->line.status.reason, 
     423            call_callback(regc, tsx->status_code, &rdata->msg_info.msg->line.status.reason, 
    407424                          rdata, -1, 0, NULL); 
    408425            --regc->pending_tsx; 
     
    420437            pjsip_expires_hdr *expires; 
    421438 
    422             rdata = event->src.rdata; 
    423             msg = rdata->msg; 
     439            rdata = event->body.tsx_state.src.rdata; 
     440            msg = rdata->msg_info.msg; 
    424441            hdr = pjsip_msg_find_hdr( msg, PJSIP_H_CONTACT, NULL); 
    425442            while (hdr) { 
     
    460477 
    461478        } else { 
    462             rdata = (event->src_type==PJSIP_EVENT_RX_MSG) ? event->src.rdata : NULL; 
     479            rdata = (event->body.tsx_state.type==PJSIP_EVENT_RX_MSG) ?  
     480                        event->body.tsx_state.src.rdata : NULL; 
    463481        } 
    464482 
     
    467485        if (expiration == 0xFFFF) expiration = -1; 
    468486        call_callback(regc, tsx->status_code,  
    469                       (rdata ? &rdata->msg->line.status.reason  
     487                      (rdata ? &rdata->msg_info.msg->line.status.reason  
    470488                        : pjsip_get_status_text(tsx->status_code)), 
    471489                      rdata, expiration,  
     
    481499} 
    482500 
    483 PJ_DEF(void) pjsip_regc_send(pjsip_regc *regc, pjsip_tx_data *tdata) 
    484 { 
    485     int status; 
     501PJ_DEF(pj_status_t) pjsip_regc_send(pjsip_regc *regc, pjsip_tx_data *tdata) 
     502{ 
     503    pj_status_t status; 
    486504 
    487505    /* Make sure we don't have pending transaction. */ 
     
    490508        call_callback(regc, -1, &reason, NULL, -1, 0, NULL); 
    491509        pjsip_tx_data_dec_ref( tdata ); 
    492         return; 
     510        return PJ_EINVALIDOP; 
    493511    } 
    494512 
     
    501519    /* Send. */ 
    502520    status = pjsip_endpt_send_request(regc->endpt, tdata, -1, regc, &tsx_callback); 
    503     if (status==0) 
     521    if (status==PJ_SUCCESS) 
    504522        ++regc->pending_tsx; 
    505523    else { 
    506         pj_str_t reason = pj_str("Unable to send request."); 
     524        char errmsg[PJ_ERR_MSG_SIZE]; 
     525        pj_str_t reason = pj_strerror(status, errmsg, sizeof(errmsg)); 
    507526        call_callback(regc, status, &reason, NULL, -1, 0, NULL); 
    508527    } 
    509 } 
    510  
    511  
     528 
     529    return status; 
     530} 
     531 
     532 
Note: See TracChangeset for help on using the changeset viewer.