diff options
author | Benny Prijono <bennylp@teluu.com> | 2006-08-15 20:26:34 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2006-08-15 20:26:34 +0000 |
commit | 540278de72f88da8853d86dc3b655fe9bb3013b5 (patch) | |
tree | da69840039428b7daa2f1806d9d72eae13d51157 /pjsip/src/pjsip-simple/publishc.c | |
parent | ab77e4d8b4ddc20d6018d67c739e3317e4746c49 (diff) |
Support for PUBLISH (RFC 3903):
- API BREAK: pjsua_pres_create_uac() API CHANGED!! Added
options in the function, to allow creating SUBSCRIBE without
";id=" parameter in the Event header.
- the generic event publication in pjsip-simple/publish.[hc]
- split PIDF and X-PIDF body generation and parsing into
pjsip-simple/presence_body.c.
- allow NULL in module parameter in pjsip_endpt_add_capability()
- added "--publish" option in PJSUA.
- by default, PJSUA-LIB will not add ";id=" parameter in Event
header in the SUBSCRIBE request since lots of server and
user agents don't support this correctly.
- Set version to 0.5.7.6.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@685 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip/src/pjsip-simple/publishc.c')
-rw-r--r-- | pjsip/src/pjsip-simple/publishc.c | 512 |
1 files changed, 232 insertions, 280 deletions
diff --git a/pjsip/src/pjsip-simple/publishc.c b/pjsip/src/pjsip-simple/publishc.c index b61fa469..5a0df963 100644 --- a/pjsip/src/pjsip-simple/publishc.c +++ b/pjsip/src/pjsip-simple/publishc.c @@ -16,32 +16,41 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include <pjsip-ua/sip_regc.h> +#include <pjsip-simple/publish.h> +#include <pjsip/sip_auth.h> #include <pjsip/sip_endpoint.h> -#include <pjsip/sip_parser.h> -#include <pjsip/sip_module.h> -#include <pjsip/sip_transaction.h> +#include <pjsip/sip_errno.h> #include <pjsip/sip_event.h> +#include <pjsip/sip_msg.h> +#include <pjsip/sip_transaction.h> +#include <pjsip/sip_uri.h> #include <pjsip/sip_util.h> -#include <pjsip/sip_auth_msg.h> -#include <pjsip/sip_errno.h> #include <pj/assert.h> #include <pj/guid.h> +#include <pj/log.h> #include <pj/os.h> #include <pj/pool.h> -#include <pj/log.h> #include <pj/rand.h> #include <pj/string.h> +#include <pj/timer.h> #define REFRESH_TIMER 1 #define DELAY_BEFORE_REFRESH 5 -#define THIS_FILE "sip_regc.c" +#define THIS_FILE "publishc.c" + + +const pjsip_method pjsip_publish_method = +{ + PJSIP_OTHER_METHOD, + { "PUBLISH", 7 } +}; + /** - * SIP client registration structure. + * SIP client publication structure. */ -struct pjsip_regc +struct pjsip_publishc { pj_pool_t *pool; pjsip_endpoint *endpt; @@ -49,291 +58,228 @@ struct pjsip_regc int pending_tsx; void *token; - pjsip_regc_cb *cb; + pjsip_publishc_cb *cb; - pj_str_t str_srv_url; - pjsip_uri *srv_url; + pj_str_t event; + pj_str_t str_target_uri; + pjsip_uri *target_uri; pjsip_cid_hdr *cid_hdr; pjsip_cseq_hdr *cseq_hdr; pj_str_t from_uri; pjsip_from_hdr *from_hdr; pjsip_to_hdr *to_hdr; - char *contact_buf; - pjsip_generic_string_hdr *contact_hdr; + pj_str_t etag; pjsip_expires_hdr *expires_hdr; - pjsip_contact_hdr *unreg_contact_hdr; - pjsip_expires_hdr *unreg_expires_hdr; pj_uint32_t expires; pjsip_route_hdr route_set; /* Authorization sessions. */ pjsip_auth_clt_sess auth_sess; - /* Auto refresh registration. */ - pj_bool_t auto_reg; - pj_time_val last_reg; - pj_time_val next_reg; + /* Auto refresh publication. */ + pj_bool_t auto_refresh; + pj_time_val last_refresh; + pj_time_val next_refresh; pj_timer_entry timer; }; -PJ_DEF(pj_status_t) pjsip_regc_create( pjsip_endpoint *endpt, void *token, - pjsip_regc_cb *cb, - pjsip_regc **p_regc) +/* + * Initialize client publication module. + */ +PJ_DEF(pj_status_t) pjsip_publishc_init_module(pjsip_endpoint *endpt) +{ + return pjsip_endpt_add_capability( endpt, NULL, PJSIP_H_ALLOW, NULL, + 1, &pjsip_publish_method.name); +} + + +PJ_DEF(pj_status_t) pjsip_publishc_create( pjsip_endpoint *endpt, + unsigned options, + void *token, + pjsip_publishc_cb *cb, + pjsip_publishc **p_pubc) { pj_pool_t *pool; - pjsip_regc *regc; + pjsip_publishc *pubc; pj_status_t status; /* Verify arguments. */ - PJ_ASSERT_RETURN(endpt && cb && p_regc, PJ_EINVAL); + PJ_ASSERT_RETURN(endpt && cb && p_pubc, PJ_EINVAL); + PJ_ASSERT_RETURN(options == 0, PJ_EINVAL); - pool = pjsip_endpt_create_pool(endpt, "regc%p", 1024, 1024); + PJ_UNUSED_ARG(options); + + pool = pjsip_endpt_create_pool(endpt, "pubc%p", 1024, 1024); PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM); - regc = pj_pool_zalloc(pool, sizeof(struct pjsip_regc)); + pubc = pj_pool_zalloc(pool, sizeof(struct pjsip_publishc)); - regc->pool = pool; - regc->endpt = endpt; - regc->token = token; - regc->cb = cb; - regc->contact_buf = pj_pool_alloc(pool, PJSIP_REGC_CONTACT_BUF_SIZE); - regc->expires = PJSIP_REGC_EXPIRATION_NOT_SPECIFIED; + pubc->pool = pool; + pubc->endpt = endpt; + pubc->token = token; + pubc->cb = cb; + pubc->expires = PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED; - status = pjsip_auth_clt_init(®c->auth_sess, endpt, regc->pool, 0); + status = pjsip_auth_clt_init(&pubc->auth_sess, endpt, pubc->pool, 0); if (status != PJ_SUCCESS) return status; - pj_list_init(®c->route_set); + pj_list_init(&pubc->route_set); /* Done */ - *p_regc = regc; + *p_pubc = pubc; return PJ_SUCCESS; } -PJ_DEF(pj_status_t) pjsip_regc_destroy(pjsip_regc *regc) +PJ_DEF(pj_status_t) pjsip_publishc_destroy(pjsip_publishc *pubc) { - PJ_ASSERT_RETURN(regc, PJ_EINVAL); + PJ_ASSERT_RETURN(pubc, PJ_EINVAL); - if (regc->pending_tsx) { - regc->_delete_flag = 1; - regc->cb = NULL; + if (pubc->pending_tsx) { + pubc->_delete_flag = 1; + pubc->cb = NULL; } else { - pjsip_endpt_release_pool(regc->endpt, regc->pool); - } - - return PJ_SUCCESS; -} - - -PJ_DEF(pj_status_t) pjsip_regc_get_info( pjsip_regc *regc, - pjsip_regc_info *info ) -{ - PJ_ASSERT_RETURN(regc && info, PJ_EINVAL); - - info->server_uri = regc->str_srv_url; - info->client_uri = regc->from_uri; - info->is_busy = (regc->pending_tsx != 0); - info->auto_reg = regc->auto_reg; - info->interval = regc->expires; - - if (regc->pending_tsx) - info->next_reg = 0; - else if (regc->auto_reg == 0) - info->next_reg = 0; - else if (regc->expires < 0) - info->next_reg = regc->expires; - else { - pj_time_val now, next_reg; - - next_reg = regc->next_reg; - pj_gettimeofday(&now); - PJ_TIME_VAL_SUB(next_reg, now); - info->next_reg = next_reg.sec; + pjsip_endpt_release_pool(pubc->endpt, pubc->pool); } return PJ_SUCCESS; } -PJ_DEF(pj_pool_t*) pjsip_regc_get_pool(pjsip_regc *regc) +PJ_DEF(pj_pool_t*) pjsip_publishc_get_pool(pjsip_publishc *pubc) { - return regc->pool; + return pubc->pool; } -static void set_expires( pjsip_regc *regc, pj_uint32_t expires) +static void set_expires( pjsip_publishc *pubc, pj_uint32_t expires) { - if (expires != regc->expires) { - regc->expires_hdr = pjsip_expires_hdr_create(regc->pool, expires); + if (expires != pubc->expires) { + pubc->expires_hdr = pjsip_expires_hdr_create(pubc->pool, expires); } else { - regc->expires_hdr = NULL; - } -} - - -static pj_status_t set_contact( pjsip_regc *regc, - int contact_cnt, - const pj_str_t contact[] ) -{ - int i; - char *s; - const pj_str_t contact_STR = { "Contact", 7}; - - /* Concatenate contacts. */ - for (i=0, s=regc->contact_buf; i<contact_cnt; ++i) { - if ((s-regc->contact_buf) + contact[i].slen + 2 > PJSIP_REGC_CONTACT_BUF_SIZE) { - return PJSIP_EURITOOLONG; - } - pj_memcpy(s, contact[i].ptr, contact[i].slen); - s += contact[i].slen; - - if (i != contact_cnt - 1) { - *s++ = ','; - *s++ = ' '; - } + pubc->expires_hdr = NULL; } - - /* Set "Contact" header. */ - regc->contact_hdr = pjsip_generic_string_hdr_create(regc->pool, - &contact_STR, - NULL); - regc->contact_hdr->hvalue.ptr = regc->contact_buf; - regc->contact_hdr->hvalue.slen = (s - regc->contact_buf); - - return PJ_SUCCESS; } -PJ_DEF(pj_status_t) pjsip_regc_init( pjsip_regc *regc, - const pj_str_t *srv_url, - const pj_str_t *from_url, - const pj_str_t *to_url, - int contact_cnt, - const pj_str_t contact[], - pj_uint32_t expires) +PJ_DEF(pj_status_t) pjsip_publishc_init(pjsip_publishc *pubc, + const pj_str_t *event, + const pj_str_t *target_uri, + const pj_str_t *from_uri, + const pj_str_t *to_uri, + pj_uint32_t expires) { pj_str_t tmp; - pj_status_t status; - PJ_ASSERT_RETURN(regc && srv_url && from_url && to_url && - contact_cnt && contact && expires, PJ_EINVAL); + PJ_ASSERT_RETURN(pubc && event && target_uri && from_uri && to_uri && + expires, PJ_EINVAL); + + /* Copy event type */ + pj_strdup_with_null(pubc->pool, &pubc->event, event); /* Copy server URL. */ - pj_strdup_with_null(regc->pool, ®c->str_srv_url, srv_url); + pj_strdup_with_null(pubc->pool, &pubc->str_target_uri, target_uri); /* Set server URL. */ - tmp = regc->str_srv_url; - regc->srv_url = pjsip_parse_uri( regc->pool, tmp.ptr, tmp.slen, 0); - if (regc->srv_url == NULL) { + tmp = pubc->str_target_uri; + pubc->target_uri = pjsip_parse_uri( pubc->pool, tmp.ptr, tmp.slen, 0); + if (pubc->target_uri == NULL) { return PJSIP_EINVALIDURI; } /* Set "From" header. */ - pj_strdup_with_null(regc->pool, ®c->from_uri, from_url); - tmp = regc->from_uri; - regc->from_hdr = pjsip_from_hdr_create(regc->pool); - regc->from_hdr->uri = pjsip_parse_uri(regc->pool, tmp.ptr, tmp.slen, + pj_strdup_with_null(pubc->pool, &pubc->from_uri, from_uri); + tmp = pubc->from_uri; + pubc->from_hdr = pjsip_from_hdr_create(pubc->pool); + pubc->from_hdr->uri = pjsip_parse_uri(pubc->pool, tmp.ptr, tmp.slen, PJSIP_PARSE_URI_AS_NAMEADDR); - if (!regc->from_hdr->uri) { - PJ_LOG(4,(THIS_FILE, "regc: invalid source URI %.*s", - from_url->slen, from_url->ptr)); + if (!pubc->from_hdr->uri) { return PJSIP_EINVALIDURI; } /* Set "To" header. */ - pj_strdup_with_null(regc->pool, &tmp, to_url); - regc->to_hdr = pjsip_to_hdr_create(regc->pool); - regc->to_hdr->uri = pjsip_parse_uri(regc->pool, tmp.ptr, tmp.slen, + pj_strdup_with_null(pubc->pool, &tmp, to_uri); + pubc->to_hdr = pjsip_to_hdr_create(pubc->pool); + pubc->to_hdr->uri = pjsip_parse_uri(pubc->pool, tmp.ptr, tmp.slen, PJSIP_PARSE_URI_AS_NAMEADDR); - if (!regc->to_hdr->uri) { - PJ_LOG(4,(THIS_FILE, "regc: invalid target URI %.*s", to_url->slen, to_url->ptr)); + if (!pubc->to_hdr->uri) { return PJSIP_EINVALIDURI; } - /* Set "Contact" header. */ - status = set_contact( regc, contact_cnt, contact); - if (status != PJ_SUCCESS) - return status; - /* Set "Expires" header, if required. */ - set_expires( regc, expires); + set_expires( pubc, expires); /* Set "Call-ID" header. */ - regc->cid_hdr = pjsip_cid_hdr_create(regc->pool); - pj_create_unique_string(regc->pool, ®c->cid_hdr->id); + pubc->cid_hdr = pjsip_cid_hdr_create(pubc->pool); + pj_create_unique_string(pubc->pool, &pubc->cid_hdr->id); /* Set "CSeq" header. */ - regc->cseq_hdr = pjsip_cseq_hdr_create(regc->pool); - regc->cseq_hdr->cseq = pj_rand() % 0xFFFF; - pjsip_method_set( ®c->cseq_hdr->method, PJSIP_REGISTER_METHOD); - - /* Create "Contact" header used in unregistration. */ - regc->unreg_contact_hdr = pjsip_contact_hdr_create(regc->pool); - regc->unreg_contact_hdr->star = 1; - - /* Create "Expires" header used in unregistration. */ - regc->unreg_expires_hdr = pjsip_expires_hdr_create( regc->pool, 0); + pubc->cseq_hdr = pjsip_cseq_hdr_create(pubc->pool); + pubc->cseq_hdr->cseq = pj_rand() % 0xFFFF; + pjsip_method_set( &pubc->cseq_hdr->method, PJSIP_REGISTER_METHOD); /* Done. */ return PJ_SUCCESS; } -PJ_DEF(pj_status_t) pjsip_regc_set_credentials( pjsip_regc *regc, +PJ_DEF(pj_status_t) pjsip_publishc_set_credentials( pjsip_publishc *pubc, int count, const pjsip_cred_info cred[] ) { - PJ_ASSERT_RETURN(regc && count && cred, PJ_EINVAL); - return pjsip_auth_clt_set_credentials(®c->auth_sess, count, cred); + PJ_ASSERT_RETURN(pubc && count && cred, PJ_EINVAL); + return pjsip_auth_clt_set_credentials(&pubc->auth_sess, count, cred); } -PJ_DEF(pj_status_t) pjsip_regc_set_route_set( pjsip_regc *regc, +PJ_DEF(pj_status_t) pjsip_publishc_set_route_set( pjsip_publishc *pubc, const pjsip_route_hdr *route_set) { const pjsip_route_hdr *chdr; - PJ_ASSERT_RETURN(regc && route_set, PJ_EINVAL); + PJ_ASSERT_RETURN(pubc && route_set, PJ_EINVAL); - pj_list_init(®c->route_set); + pj_list_init(&pubc->route_set); chdr = route_set->next; while (chdr != route_set) { - pj_list_push_back(®c->route_set, pjsip_hdr_clone(regc->pool, chdr)); + pj_list_push_back(&pubc->route_set, pjsip_hdr_clone(pubc->pool, chdr)); chdr = chdr->next; } return PJ_SUCCESS; } -static pj_status_t create_request(pjsip_regc *regc, +static pj_status_t create_request(pjsip_publishc *pubc, pjsip_tx_data **p_tdata) { + const pj_str_t STR_EVENT = { "Event", 5 }; pj_status_t status; + pjsip_generic_string_hdr *hdr; pjsip_tx_data *tdata; - PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL); + PJ_ASSERT_RETURN(pubc && p_tdata, PJ_EINVAL); /* Create the request. */ - status = pjsip_endpt_create_request_from_hdr( regc->endpt, - &pjsip_register_method, - regc->srv_url, - regc->from_hdr, - regc->to_hdr, + status = pjsip_endpt_create_request_from_hdr( pubc->endpt, + &pjsip_publish_method, + pubc->target_uri, + pubc->from_hdr, + pubc->to_hdr, NULL, - regc->cid_hdr, - regc->cseq_hdr->cseq, + pubc->cid_hdr, + pubc->cseq_hdr->cseq, NULL, &tdata); if (status != PJ_SUCCESS) return status; /* Add cached authorization headers. */ - pjsip_auth_clt_init_req( ®c->auth_sess, tdata ); + pjsip_auth_clt_init_req( &pubc->auth_sess, tdata ); /* Add Route headers from route set, ideally after Via header */ - if (!pj_list_empty(®c->route_set)) { + if (!pj_list_empty(&pubc->route_set)) { pjsip_hdr *route_pos; const pjsip_route_hdr *route; @@ -341,8 +287,8 @@ static pj_status_t create_request(pjsip_regc *regc, if (!route_pos) route_pos = &tdata->msg->hdr; - route = regc->route_set.next; - while (route != ®c->route_set) { + route = pubc->route_set.next; + while (route != &pubc->route_set) { pjsip_hdr *new_hdr = pjsip_hdr_shallow_clone(tdata->pool, route); pj_list_insert_after(route_pos, new_hdr); route_pos = new_hdr; @@ -350,37 +296,59 @@ static pj_status_t create_request(pjsip_regc *regc, } } + /* Add Event header */ + hdr = pjsip_generic_string_hdr_create(tdata->pool, &STR_EVENT, + &pubc->event); + if (hdr) + pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr); + + + /* Add SIP-If-Match if we have etag */ + if (pubc->etag.slen) { + const pj_str_t STR_HNAME = { "SIP-If-Match", 12 }; + + hdr = pjsip_generic_string_hdr_create(tdata->pool, &STR_HNAME, + &pubc->etag); + if (hdr) + pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr); + } + + /* Done. */ *p_tdata = tdata; return PJ_SUCCESS; } -PJ_DEF(pj_status_t) pjsip_regc_register(pjsip_regc *regc, pj_bool_t autoreg, - pjsip_tx_data **p_tdata) +PJ_DEF(pj_status_t) pjsip_publishc_publish(pjsip_publishc *pubc, + pj_bool_t auto_refresh, + pjsip_tx_data **p_tdata) { - pjsip_msg *msg; pj_status_t status; pjsip_tx_data *tdata; - PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL); + PJ_ASSERT_RETURN(pubc && p_tdata, PJ_EINVAL); - status = create_request(regc, &tdata); + status = create_request(pubc, &tdata); if (status != PJ_SUCCESS) return status; - /* Add Contact header. */ - msg = tdata->msg; - pjsip_msg_add_hdr(msg, (pjsip_hdr*) regc->contact_hdr); - if (regc->expires_hdr) - pjsip_msg_add_hdr(msg, (pjsip_hdr*) regc->expires_hdr); + /* Add Expires header */ + if (pubc->expires_hdr) { + pjsip_hdr *dup; - if (regc->timer.id != 0) { - pjsip_endpt_cancel_timer(regc->endpt, ®c->timer); - regc->timer.id = 0; + dup = pjsip_hdr_shallow_clone(tdata->pool, pubc->expires_hdr); + if (dup) + pjsip_msg_add_hdr(tdata->msg, dup); } - regc->auto_reg = autoreg; + /* Cancel existing timer */ + if (pubc->timer.id != 0) { + pjsip_endpt_cancel_timer(pubc->endpt, &pubc->timer); + pubc->timer.id = 0; + } + + pubc->auto_refresh = auto_refresh; /* Done */ *p_tdata = tdata; @@ -388,111 +356,99 @@ PJ_DEF(pj_status_t) pjsip_regc_register(pjsip_regc *regc, pj_bool_t autoreg, } -PJ_DEF(pj_status_t) pjsip_regc_unregister(pjsip_regc *regc, - pjsip_tx_data **p_tdata) +PJ_DEF(pj_status_t) pjsip_publishc_unpublish(pjsip_publishc *pubc, + pjsip_tx_data **p_tdata) { pjsip_tx_data *tdata; pjsip_msg *msg; + pjsip_expires_hdr *expires; pj_status_t status; - PJ_ASSERT_RETURN(regc && p_tdata, PJ_EINVAL); + PJ_ASSERT_RETURN(pubc && p_tdata, PJ_EINVAL); - if (regc->timer.id != 0) { - pjsip_endpt_cancel_timer(regc->endpt, ®c->timer); - regc->timer.id = 0; + if (pubc->timer.id != 0) { + pjsip_endpt_cancel_timer(pubc->endpt, &pubc->timer); + pubc->timer.id = 0; } - status = create_request(regc, &tdata); + status = create_request(pubc, &tdata); if (status != PJ_SUCCESS) return status; msg = tdata->msg; - pjsip_msg_add_hdr( msg, (pjsip_hdr*)regc->unreg_contact_hdr); - pjsip_msg_add_hdr( msg, (pjsip_hdr*)regc->unreg_expires_hdr); + + /* Add Expires:0 header */ + expires = pjsip_expires_hdr_create(tdata->pool, 0); + pjsip_msg_add_hdr( msg, (pjsip_hdr*)expires); *p_tdata = tdata; return PJ_SUCCESS; } -PJ_DEF(pj_status_t) pjsip_regc_update_contact( pjsip_regc *regc, - int contact_cnt, - const pj_str_t contact[] ) -{ - PJ_ASSERT_RETURN(regc, PJ_EINVAL); - return set_contact( regc, contact_cnt, contact ); -} - - -PJ_DEF(pj_status_t) pjsip_regc_update_expires( pjsip_regc *regc, - pj_uint32_t expires ) +PJ_DEF(pj_status_t) pjsip_publishc_update_expires( pjsip_publishc *pubc, + pj_uint32_t expires ) { - PJ_ASSERT_RETURN(regc, PJ_EINVAL); - set_expires( regc, expires ); + PJ_ASSERT_RETURN(pubc, PJ_EINVAL); + set_expires( pubc, expires ); return PJ_SUCCESS; } -static void call_callback(pjsip_regc *regc, pj_status_t status, int st_code, - const pj_str_t *reason, - pjsip_rx_data *rdata, pj_int32_t expiration, - int contact_cnt, pjsip_contact_hdr *contact[]) +static void call_callback(pjsip_publishc *pubc, pj_status_t status, + int st_code, const pj_str_t *reason, + pjsip_rx_data *rdata, pj_int32_t expiration) { - struct pjsip_regc_cbparam cbparam; + struct pjsip_publishc_cbparam cbparam; - cbparam.regc = regc; - cbparam.token = regc->token; + cbparam.pubc = pubc; + cbparam.token = pubc->token; cbparam.status = status; cbparam.code = st_code; cbparam.reason = *reason; cbparam.rdata = rdata; - cbparam.contact_cnt = contact_cnt; cbparam.expiration = expiration; - if (contact_cnt) { - pj_memcpy( cbparam.contact, contact, - contact_cnt*sizeof(pjsip_contact_hdr*)); - } - (*regc->cb)(&cbparam); + (*pubc->cb)(&cbparam); } -static void regc_refresh_timer_cb( pj_timer_heap_t *timer_heap, +static void pubc_refresh_timer_cb( pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry) { - pjsip_regc *regc = entry->user_data; + pjsip_publishc *pubc = entry->user_data; pjsip_tx_data *tdata; pj_status_t status; PJ_UNUSED_ARG(timer_heap); entry->id = 0; - status = pjsip_regc_register(regc, 1, &tdata); + status = pjsip_publishc_publish(pubc, 1, &tdata); if (status == PJ_SUCCESS) { - status = pjsip_regc_send(regc, tdata); + status = pjsip_publishc_send(pubc, tdata); } if (status != PJ_SUCCESS) { char errmsg[PJ_ERR_MSG_SIZE]; pj_str_t reason = pj_strerror(status, errmsg, sizeof(errmsg)); - call_callback(regc, status, 400, &reason, NULL, -1, 0, NULL); + call_callback(pubc, status, 400, &reason, NULL, -1); } } static void tsx_callback(void *token, pjsip_event *event) { pj_status_t status; - pjsip_regc *regc = token; + pjsip_publishc *pubc = token; pjsip_transaction *tsx = event->body.tsx_state.tsx; /* Decrement pending transaction counter. */ - pj_assert(regc->pending_tsx > 0); - --regc->pending_tsx; + pj_assert(pubc->pending_tsx > 0); + --pubc->pending_tsx; - /* If registration data has been deleted by user then remove registration + /* If publication data has been deleted by user then remove publication * data from transaction's callback, and don't call callback. */ - if (regc->_delete_flag) { + if (pubc->_delete_flag) { /* Nothing to do */ ; @@ -503,75 +459,69 @@ static void tsx_callback(void *token, pjsip_event *event) pjsip_rx_data *rdata = event->body.tsx_state.src.rdata; pjsip_tx_data *tdata; - status = pjsip_auth_clt_reinit_req( ®c->auth_sess, + status = pjsip_auth_clt_reinit_req( &pubc->auth_sess, rdata, tsx->last_tx, &tdata); if (status == PJ_SUCCESS) { - status = pjsip_regc_send(regc, tdata); + status = pjsip_publishc_send(pubc, tdata); } if (status != PJ_SUCCESS) { - call_callback(regc, status, tsx->status_code, + call_callback(pubc, status, tsx->status_code, &rdata->msg_info.msg->line.status.reason, - rdata, -1, 0, NULL); + rdata, -1); } return; } else { - int contact_cnt = 0; - pjsip_contact_hdr *contact[PJSIP_REGC_MAX_CONTACT]; pjsip_rx_data *rdata; pj_int32_t expiration = 0xFFFF; if (tsx->status_code/100 == 2) { - int i; - pjsip_contact_hdr *hdr; pjsip_msg *msg; pjsip_expires_hdr *expires; + pjsip_generic_string_hdr *etag_hdr; + const pj_str_t STR_ETAG = { "SIP-ETag", 8 }; rdata = event->body.tsx_state.src.rdata; msg = rdata->msg_info.msg; - hdr = pjsip_msg_find_hdr( msg, PJSIP_H_CONTACT, NULL); - while (hdr) { - contact[contact_cnt++] = hdr; - hdr = hdr->next; - if (hdr == (void*)&msg->hdr) - break; - hdr = pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, hdr); + + /* Save ETag value */ + etag_hdr = (pjsip_generic_string_hdr*) + pjsip_msg_find_hdr_by_name(msg, &STR_ETAG, NULL); + if (etag_hdr) { + pj_strdup(pubc->pool, &pubc->etag, &etag_hdr->hvalue); + } else { + pubc->etag.slen = 0; } + /* Update expires value */ expires = pjsip_msg_find_hdr(msg, PJSIP_H_EXPIRES, NULL); if (expires) expiration = expires->ivalue; - for (i=0; i<contact_cnt; ++i) { - hdr = contact[i]; - if (hdr->expires >= 0 && hdr->expires < expiration) - expiration = contact[i]->expires; - } - - if (regc->auto_reg && expiration != 0 && expiration != 0xFFFF) { + if (pubc->auto_refresh && expiration!=0 && expiration!=0xFFFF) { pj_time_val delay = { 0, 0}; delay.sec = expiration - DELAY_BEFORE_REFRESH; - if (regc->expires != PJSIP_REGC_EXPIRATION_NOT_SPECIFIED && - delay.sec > (pj_int32_t)regc->expires) + if (pubc->expires != PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED && + delay.sec > (pj_int32_t)pubc->expires) { - delay.sec = regc->expires; + delay.sec = pubc->expires; } if (delay.sec < DELAY_BEFORE_REFRESH) delay.sec = DELAY_BEFORE_REFRESH; - regc->timer.cb = ®c_refresh_timer_cb; - regc->timer.id = REFRESH_TIMER; - regc->timer.user_data = regc; - pjsip_endpt_schedule_timer( regc->endpt, ®c->timer, &delay); - pj_gettimeofday(®c->last_reg); - regc->next_reg = regc->last_reg; - regc->next_reg.sec += delay.sec; + pubc->timer.cb = &pubc_refresh_timer_cb; + pubc->timer.id = REFRESH_TIMER; + pubc->timer.user_data = pubc; + pjsip_endpt_schedule_timer( pubc->endpt, &pubc->timer, &delay); + pj_gettimeofday(&pubc->last_refresh); + pubc->next_refresh = pubc->last_refresh; + pubc->next_refresh.sec += delay.sec; } } else { @@ -582,29 +532,30 @@ static void tsx_callback(void *token, pjsip_event *event) /* Call callback. */ if (expiration == 0xFFFF) expiration = -1; - call_callback(regc, PJ_SUCCESS, tsx->status_code, + call_callback(pubc, PJ_SUCCESS, tsx->status_code, (rdata ? &rdata->msg_info.msg->line.status.reason : pjsip_get_status_text(tsx->status_code)), - rdata, expiration, - contact_cnt, contact); + rdata, expiration); } - /* Delete the record if user destroy regc during the callback. */ - if (regc->_delete_flag && regc->pending_tsx==0) { - pjsip_regc_destroy(regc); + /* Delete the record if user destroy pubc during the callback. */ + if (pubc->_delete_flag && pubc->pending_tsx==0) { + pjsip_publishc_destroy(pubc); } } -PJ_DEF(pj_status_t) pjsip_regc_send(pjsip_regc *regc, pjsip_tx_data *tdata) + +PJ_DEF(pj_status_t) pjsip_publishc_send(pjsip_publishc *pubc, + pjsip_tx_data *tdata) { pj_status_t status; pjsip_cseq_hdr *cseq_hdr; pj_uint32_t cseq; /* Make sure we don't have pending transaction. */ - if (regc->pending_tsx) { - PJ_LOG(4,(THIS_FILE, "Unable to send request, regc has another " + if (pubc->pending_tsx) { + PJ_LOG(4,(THIS_FILE, "Unable to send request, pubc has another " "transaction pending")); pjsip_tx_data_dec_ref( tdata ); return PJSIP_EBUSY; @@ -614,17 +565,18 @@ PJ_DEF(pj_status_t) pjsip_regc_send(pjsip_regc *regc, pjsip_tx_data *tdata) pjsip_tx_data_invalidate_msg(tdata); /* Increment CSeq */ - cseq = ++regc->cseq_hdr->cseq; + cseq = ++pubc->cseq_hdr->cseq; cseq_hdr = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL); cseq_hdr->cseq = cseq; /* Increment pending transaction first, since transaction callback * may be called even before send_request() returns! */ - ++regc->pending_tsx; - status = pjsip_endpt_send_request(regc->endpt, tdata, -1, regc, &tsx_callback); + ++pubc->pending_tsx; + status = pjsip_endpt_send_request(pubc->endpt, tdata, -1, pubc, + &tsx_callback); if (status!=PJ_SUCCESS) { - --regc->pending_tsx; + --pubc->pending_tsx; PJ_LOG(4,(THIS_FILE, "Error sending request, status=%d", status)); } |