📄 pjsua_pres.c
字号:
/* $Id: pjsua_pres.c 1311 2007-05-29 00:33:09Z 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 <pjsua-lib/pjsua.h>
#include <pjsua-lib/pjsua_internal.h>
#define THIS_FILE "pjsua_pres.c"
#ifndef PJSUA_PRES_TIMER
# define PJSUA_PRES_TIMER 120
#endif
/*
* Get total number of buddies.
*/
PJ_DEF(unsigned) pjsua_get_buddy_count(void)
{
return pjsua_var.buddy_cnt;
}
/*
* Check if buddy ID is valid.
*/
PJ_DEF(pj_bool_t) pjsua_buddy_is_valid(pjsua_buddy_id buddy_id)
{
return buddy_id>=0 && buddy_id<(int)PJ_ARRAY_SIZE(pjsua_var.buddy) &&
pjsua_var.buddy[buddy_id].uri.slen != 0;
}
/*
* Enum buddy IDs.
*/
PJ_DEF(pj_status_t) pjsua_enum_buddies( pjsua_buddy_id ids[],
unsigned *count)
{
unsigned i, c;
PJ_ASSERT_RETURN(ids && count, PJ_EINVAL);
PJSUA_LOCK();
for (i=0, c=0; c<*count && i<PJ_ARRAY_SIZE(pjsua_var.buddy); ++i) {
if (!pjsua_var.buddy[i].uri.slen)
continue;
ids[c] = i;
++c;
}
*count = c;
PJSUA_UNLOCK();
return PJ_SUCCESS;
}
/*
* Get detailed buddy info.
*/
PJ_DEF(pj_status_t) pjsua_buddy_get_info( pjsua_buddy_id buddy_id,
pjsua_buddy_info *info)
{
int total=0;
pjsua_buddy *buddy;
PJ_ASSERT_RETURN(buddy_id>=0 &&
buddy_id<(int)PJ_ARRAY_SIZE(pjsua_var.buddy),
PJ_EINVAL);
PJSUA_LOCK();
pj_bzero(info, sizeof(pjsua_buddy_info));
buddy = &pjsua_var.buddy[buddy_id];
info->id = buddy->index;
if (pjsua_var.buddy[buddy_id].uri.slen == 0) {
PJSUA_UNLOCK();
return PJ_SUCCESS;
}
/* uri */
info->uri.ptr = info->buf_ + total;
pj_strncpy(&info->uri, &buddy->uri, sizeof(info->buf_)-total);
total += info->uri.slen;
/* contact */
info->contact.ptr = info->buf_ + total;
pj_strncpy(&info->contact, &buddy->contact, sizeof(info->buf_)-total);
total += info->contact.slen;
/* status and status text */
if (buddy->sub == NULL || buddy->status.info_cnt==0) {
info->status = PJSUA_BUDDY_STATUS_UNKNOWN;
info->status_text = pj_str("?");
} else if (pjsua_var.buddy[buddy_id].status.info[0].basic_open) {
info->status = PJSUA_BUDDY_STATUS_ONLINE;
info->status_text = pj_str("Online");
} else {
info->status = PJSUA_BUDDY_STATUS_OFFLINE;
info->status_text = pj_str("Offline");
}
/* monitor pres */
info->monitor_pres = buddy->monitor;
PJSUA_UNLOCK();
return PJ_SUCCESS;
}
/*
* Reset buddy descriptor.
*/
static void reset_buddy(pjsua_buddy_id id)
{
pj_bzero(&pjsua_var.buddy[id], sizeof(pjsua_var.buddy[id]));
pjsua_var.buddy[id].index = id;
}
/*
* Add new buddy.
*/
PJ_DEF(pj_status_t) pjsua_buddy_add( const pjsua_buddy_config *cfg,
pjsua_buddy_id *p_buddy_id)
{
pjsip_name_addr *url;
pjsip_sip_uri *sip_uri;
int index;
pj_str_t tmp;
PJ_ASSERT_RETURN(pjsua_var.buddy_cnt <=
PJ_ARRAY_SIZE(pjsua_var.buddy),
PJ_ETOOMANY);
PJSUA_LOCK();
/* Find empty slot */
for (index=0; index<(int)PJ_ARRAY_SIZE(pjsua_var.buddy); ++index) {
if (pjsua_var.buddy[index].uri.slen == 0)
break;
}
/* Expect to find an empty slot */
if (index == PJ_ARRAY_SIZE(pjsua_var.buddy)) {
PJSUA_UNLOCK();
/* This shouldn't happen */
pj_assert(!"index < PJ_ARRAY_SIZE(pjsua_var.buddy)");
return PJ_ETOOMANY;
}
/* Get name and display name for buddy */
pj_strdup_with_null(pjsua_var.pool, &tmp, &cfg->uri);
url = (pjsip_name_addr*)pjsip_parse_uri(pjsua_var.pool, tmp.ptr, tmp.slen,
PJSIP_PARSE_URI_AS_NAMEADDR);
if (url == NULL) {
pjsua_perror(THIS_FILE, "Unable to add buddy", PJSIP_EINVALIDURI);
PJSUA_UNLOCK();
return PJSIP_EINVALIDURI;
}
/* Only support SIP schemes */
if (!PJSIP_URI_SCHEME_IS_SIP(url) && !PJSIP_URI_SCHEME_IS_SIPS(url))
return PJSIP_EINVALIDSCHEME;
/* Reset buddy, to make sure everything is cleared with default
* values
*/
reset_buddy(index);
/* Save URI */
pjsua_var.buddy[index].uri = tmp;
sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(url->uri);
pjsua_var.buddy[index].name = sip_uri->user;
pjsua_var.buddy[index].display = url->display;
pjsua_var.buddy[index].host = sip_uri->host;
pjsua_var.buddy[index].port = sip_uri->port;
pjsua_var.buddy[index].monitor = cfg->subscribe;
if (pjsua_var.buddy[index].port == 0)
pjsua_var.buddy[index].port = 5060;
if (p_buddy_id)
*p_buddy_id = index;
pjsua_var.buddy_cnt++;
pjsua_buddy_subscribe_pres(index, cfg->subscribe);
PJSUA_UNLOCK();
return PJ_SUCCESS;
}
/*
* Delete buddy.
*/
PJ_DEF(pj_status_t) pjsua_buddy_del(pjsua_buddy_id buddy_id)
{
PJ_ASSERT_RETURN(buddy_id>=0 &&
buddy_id<(int)PJ_ARRAY_SIZE(pjsua_var.buddy),
PJ_EINVAL);
PJSUA_LOCK();
if (pjsua_var.buddy[buddy_id].uri.slen == 0) {
PJSUA_UNLOCK();
return PJ_SUCCESS;
}
/* Unsubscribe presence */
pjsua_buddy_subscribe_pres(buddy_id, PJ_FALSE);
/* Remove buddy */
pjsua_var.buddy[buddy_id].uri.slen = 0;
pjsua_var.buddy_cnt--;
/* Reset buddy struct */
reset_buddy(buddy_id);
PJSUA_UNLOCK();
return PJ_SUCCESS;
}
/*
* Enable/disable buddy's presence monitoring.
*/
PJ_DEF(pj_status_t) pjsua_buddy_subscribe_pres( pjsua_buddy_id buddy_id,
pj_bool_t subscribe)
{
pjsua_buddy *buddy;
PJ_ASSERT_RETURN(buddy_id>=0 &&
buddy_id<(int)PJ_ARRAY_SIZE(pjsua_var.buddy),
PJ_EINVAL);
PJSUA_LOCK();
buddy = &pjsua_var.buddy[buddy_id];
buddy->monitor = subscribe;
pjsua_pres_refresh();
PJSUA_UNLOCK();
return PJ_SUCCESS;
}
/*
* Dump presence subscriptions to log file.
*/
PJ_DEF(void) pjsua_pres_dump(pj_bool_t verbose)
{
unsigned acc_id;
unsigned i;
PJSUA_LOCK();
/*
* When no detail is required, just dump number of server and client
* subscriptions.
*/
if (verbose == PJ_FALSE) {
int count = 0;
for (acc_id=0; acc_id<PJ_ARRAY_SIZE(pjsua_var.acc); ++acc_id) {
if (!pjsua_var.acc[acc_id].valid)
continue;
if (!pj_list_empty(&pjsua_var.acc[acc_id].pres_srv_list)) {
struct pjsua_srv_pres *uapres;
uapres = pjsua_var.acc[acc_id].pres_srv_list.next;
while (uapres != &pjsua_var.acc[acc_id].pres_srv_list) {
++count;
uapres = uapres->next;
}
}
}
PJ_LOG(3,(THIS_FILE, "Number of server/UAS subscriptions: %d",
count));
count = 0;
for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.buddy); ++i) {
if (pjsua_var.buddy[i].uri.slen == 0)
continue;
if (pjsua_var.buddy[i].sub) {
++count;
}
}
PJ_LOG(3,(THIS_FILE, "Number of client/UAC subscriptions: %d",
count));
PJSUA_UNLOCK();
return;
}
/*
* Dumping all server (UAS) subscriptions
*/
PJ_LOG(3,(THIS_FILE, "Dumping pjsua server subscriptions:"));
for (acc_id=0; acc_id<(int)PJ_ARRAY_SIZE(pjsua_var.acc); ++acc_id) {
if (!pjsua_var.acc[acc_id].valid)
continue;
PJ_LOG(3,(THIS_FILE, " %.*s",
(int)pjsua_var.acc[acc_id].cfg.id.slen,
pjsua_var.acc[acc_id].cfg.id.ptr));
if (pj_list_empty(&pjsua_var.acc[acc_id].pres_srv_list)) {
PJ_LOG(3,(THIS_FILE, " - none - "));
} else {
struct pjsua_srv_pres *uapres;
uapres = pjsua_var.acc[acc_id].pres_srv_list.next;
while (uapres != &pjsua_var.acc[acc_id].pres_srv_list) {
PJ_LOG(3,(THIS_FILE, " %10s %s",
pjsip_evsub_get_state_name(uapres->sub),
uapres->remote));
uapres = uapres->next;
}
}
}
/*
* Dumping all client (UAC) subscriptions
*/
PJ_LOG(3,(THIS_FILE, "Dumping pjsua client subscriptions:"));
if (pjsua_var.buddy_cnt == 0) {
PJ_LOG(3,(THIS_FILE, " - no buddy list - "));
} else {
for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.buddy); ++i) {
if (pjsua_var.buddy[i].uri.slen == 0)
continue;
if (pjsua_var.buddy[i].sub) {
PJ_LOG(3,(THIS_FILE, " %10s %.*s",
pjsip_evsub_get_state_name(pjsua_var.buddy[i].sub),
(int)pjsua_var.buddy[i].uri.slen,
pjsua_var.buddy[i].uri.ptr));
} else {
PJ_LOG(3,(THIS_FILE, " %10s %.*s",
"(null)",
(int)pjsua_var.buddy[i].uri.slen,
pjsua_var.buddy[i].uri.ptr));
}
}
}
PJSUA_UNLOCK();
}
/***************************************************************************
* Server subscription.
*/
/* Proto */
static pj_bool_t pres_on_rx_request(pjsip_rx_data *rdata);
/* The module instance. */
static pjsip_module mod_pjsua_pres =
{
NULL, NULL, /* prev, next. */
{ "mod-pjsua-pres", 14 }, /* Name. */
-1, /* Id */
PJSIP_MOD_PRIORITY_APPLICATION, /* Priority */
NULL, /* load() */
NULL, /* start() */
NULL, /* stop() */
NULL, /* unload() */
&pres_on_rx_request, /* on_rx_request() */
NULL, /* on_rx_response() */
NULL, /* on_tx_request. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -