📄 publishc.c
字号:
/* $Id: publishc.c 974 2007-02-19 01:13:53Z bennylp $ *//* * Copyright (C) 2003-2007 Benny Prijono <benny@prijono.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * 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-simple/publish.h>#include <pjsip/sip_auth.h>#include <pjsip/sip_endpoint.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 <pj/assert.h>#include <pj/guid.h>#include <pj/log.h>#include <pj/os.h>#include <pj/pool.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 "publishc.c"/* Let's define this enum, so that it'll trigger compilation error * when somebody define the same enum in sip_msg.h */enum{ PJSIP_PUBLISH_METHOD = PJSIP_OTHER_METHOD,};const pjsip_method pjsip_publish_method = { PJSIP_PUBLISH_METHOD, { "PUBLISH", 7 }};/** * SIP client publication structure. */struct pjsip_publishc{ pj_pool_t *pool; pjsip_endpoint *endpt; pj_bool_t _delete_flag; int pending_tsx; void *token; pjsip_publishc_cb *cb; 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; pj_str_t etag; pjsip_expires_hdr *expires_hdr; pj_uint32_t expires; pjsip_route_hdr route_set; /* Authorization sessions. */ pjsip_auth_clt_sess auth_sess; /* Auto refresh publication. */ pj_bool_t auto_refresh; pj_time_val last_refresh; pj_time_val next_refresh; pj_timer_entry timer;};/* * 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_publishc *pubc; pj_status_t status; /* Verify arguments. */ PJ_ASSERT_RETURN(endpt && cb && p_pubc, PJ_EINVAL); PJ_ASSERT_RETURN(options == 0, PJ_EINVAL); PJ_UNUSED_ARG(options); pool = pjsip_endpt_create_pool(endpt, "pubc%p", 1024, 1024); PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM); pubc = pj_pool_zalloc(pool, sizeof(struct pjsip_publishc)); pubc->pool = pool; pubc->endpt = endpt; pubc->token = token; pubc->cb = cb; pubc->expires = PJSIP_PUBC_EXPIRATION_NOT_SPECIFIED; status = pjsip_auth_clt_init(&pubc->auth_sess, endpt, pubc->pool, 0); if (status != PJ_SUCCESS) return status; pj_list_init(&pubc->route_set); /* Done */ *p_pubc = pubc; return PJ_SUCCESS;}PJ_DEF(pj_status_t) pjsip_publishc_destroy(pjsip_publishc *pubc){ PJ_ASSERT_RETURN(pubc, PJ_EINVAL); if (pubc->pending_tsx) { pubc->_delete_flag = 1; pubc->cb = NULL; } else { pjsip_endpt_release_pool(pubc->endpt, pubc->pool); } return PJ_SUCCESS;}PJ_DEF(pj_pool_t*) pjsip_publishc_get_pool(pjsip_publishc *pubc){ return pubc->pool;}static void set_expires( pjsip_publishc *pubc, pj_uint32_t expires){ if (expires != pubc->expires) { pubc->expires_hdr = pjsip_expires_hdr_create(pubc->pool, expires); } else { pubc->expires_hdr = NULL; }}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_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(pubc->pool, &pubc->str_target_uri, target_uri); /* Set server URL. */ 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(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 (!pubc->from_hdr->uri) { return PJSIP_EINVALIDURI; } /* Set "To" header. */ 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 (!pubc->to_hdr->uri) { return PJSIP_EINVALIDURI; } /* Set "Expires" header, if required. */ set_expires( pubc, expires); /* Set "Call-ID" header. */ pubc->cid_hdr = pjsip_cid_hdr_create(pubc->pool); pj_create_unique_string(pubc->pool, &pubc->cid_hdr->id); /* Set "CSeq" header. */ 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_publishc_set_credentials( pjsip_publishc *pubc, int count, const pjsip_cred_info 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_publishc_set_route_set( pjsip_publishc *pubc, const pjsip_route_hdr *route_set){ const pjsip_route_hdr *chdr; PJ_ASSERT_RETURN(pubc && route_set, PJ_EINVAL); pj_list_init(&pubc->route_set); chdr = route_set->next; while (chdr != route_set) { 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_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(pubc && p_tdata, PJ_EINVAL); /* Create the request. */ status = pjsip_endpt_create_request_from_hdr( pubc->endpt, &pjsip_publish_method, pubc->target_uri, pubc->from_hdr, pubc->to_hdr, NULL, pubc->cid_hdr, pubc->cseq_hdr->cseq, NULL, &tdata); if (status != PJ_SUCCESS) return status; /* Add cached authorization headers. */ pjsip_auth_clt_init_req( &pubc->auth_sess, tdata ); /* Add Route headers from route set, ideally after Via header */ if (!pj_list_empty(&pubc->route_set)) { pjsip_hdr *route_pos; const pjsip_route_hdr *route; route_pos = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL); if (!route_pos) route_pos = &tdata->msg->hdr; route = pubc->route_set.next;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -