Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
savoirfairelinux
jami-daemon
Commits
13b30305
Commit
13b30305
authored
Aug 28, 2013
by
Patrick Keroulas
Browse files
* #28472 : Add missing files.
parent
093d8afe
Changes
4
Hide whitespace changes
Inline
Side-by-side
daemon/src/sip/pres_sub_client.cpp
0 → 100644
View file @
13b30305
/*
* Copyright (C) 2012, 2013 LOTES TM LLC
* Author : Andrey Loukhnov <aol.nnov@gmail.com>
*
* This file is a part of pult5-voip
*
* pult5-voip 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 3 of the License, or
* (at your option) any later version.
*
* pult5-voip 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 programm. If not, see <http://www.gnu.org/licenses/>.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify pult5-voip, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, LOTES-TM LLC
* grants you additional permission to convey the resulting work.
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#include
<pj/log.h>
#include
<pj/rand.h>
#include
<pjsip/sip_module.h>
#include
<pjsip/sip_types.h>
#include
<pjsip/sip_event.h>
#include
<pjsip/sip_transaction.h>
#include
<pjsip/sip_dialog.h>
#include
<pjsip/sip_endpoint.h>
#include
<string>
#include
<pj/pool.h>
#include
<pjsip/sip_ua_layer.h>
#include
<pjsip-simple/evsub.h>
#include
<unistd.h>
#include
"pres_sub_client.h"
#include
"sipaccount.h"
#include
"sippresence.h"
#include
"sipvoiplink.h"
#include
"manager.h"
#include
"logger.h"
#define BUDDY_SUB_TERM_REASON_LEN 32
#define PRES_TIMER 300
int
modId
;
void
buddy_timer_cb
(
pj_timer_heap_t
*
th
,
pj_timer_entry
*
entry
)
{
(
void
)
th
;
PresSubClient
*
b
=
(
PresSubClient
*
)
entry
->
user_data
;
b
->
reportPresence
();
}
/* Callback called when *client* subscription state has changed. */
void
buddy_evsub_on_state
(
pjsip_evsub
*
sub
,
pjsip_event
*
event
)
{
PresSubClient
*
buddy
;
PJ_UNUSED_ARG
(
event
);
/* Note: #937: no need to acuire PJSUA_LOCK here. Since the buddy has
* a dialog attached to it, lock_buddy() will use the dialog
* lock, which we are currently holding!
*/
buddy
=
(
PresSubClient
*
)
pjsip_evsub_get_mod_data
(
sub
,
modId
);
if
(
buddy
)
{
buddy
->
incLock
();
DEBUG
(
"Presence subscription to '%s' is '%s'"
,
buddy
->
getURI
().
c_str
(),
pjsip_evsub_get_state_name
(
sub
)
?
pjsip_evsub_get_state_name
(
sub
)
:
"null"
);
pjsip_evsub_state
state
=
pjsip_evsub_get_state
(
sub
);
if
(
state
==
PJSIP_EVSUB_STATE_ACCEPTED
){
DEBUG
(
"PresSubClient accepted."
);
buddy
->
accept
();
}
else
if
(
state
==
PJSIP_EVSUB_STATE_TERMINATED
)
{
int
resub_delay
=
-
1
;
// const pj_str_t *pjTermReason = pjsip_evsub_get_termination_reason(sub);
// std::string termReason(pjTermReason->ptr,
// pjTermReason->slen > BUDDY_SUB_TERM_REASON_LEN?
// BUDDY_SUB_TERM_REASON_LEN:
// pjTermReason->slen
// );
pj_strdup_with_null
(
buddy
->
pool
,
&
buddy
->
term_reason
,
pjsip_evsub_get_termination_reason
(
sub
));
// buddy->setTermReason(termReason);
// buddy->setTermCode(200);
buddy
->
term_code
=
200
;
/* Determine whether to resubscribe automatically */
if
(
event
&&
event
->
type
==
PJSIP_EVENT_TSX_STATE
)
{
const
pjsip_transaction
*
tsx
=
event
->
body
.
tsx_state
.
tsx
;
if
(
pjsip_method_cmp
(
&
tsx
->
method
,
&
pjsip_subscribe_method
)
==
0
)
{
// buddy->setTermCode(tsx->status_code);
buddy
->
term_code
=
tsx
->
status_code
;
switch
(
tsx
->
status_code
)
{
case
PJSIP_SC_CALL_TSX_DOES_NOT_EXIST
:
/* 481: we refreshed too late? resubscribe
* immediately.
*/
/* But this must only happen when the 481 is received
* on subscription refresh request. We MUST NOT try to
* resubscribe automatically if the 481 is received
* on the initial SUBSCRIBE (if server returns this
* response for some reason).
*/
if
(
buddy
->
dlg
->
remote
.
contact
)
resub_delay
=
500
;
break
;
}
}
else
if
(
pjsip_method_cmp
(
&
tsx
->
method
,
&
pjsip_notify_method
)
==
0
)
{
if
(
buddy
->
isTermReason
(
"deactivated"
)
||
buddy
->
isTermReason
(
"timeout"
))
{
/* deactivated: The subscription has been terminated,
* but the subscriber SHOULD retry immediately with
* a new subscription.
*/
/* timeout: The subscription has been terminated
* because it was not refreshed before it expired.
* Clients MAY re-subscribe immediately. The
* "retry-after" parameter has no semantics for
* "timeout".
*/
resub_delay
=
500
;
}
else
if
(
buddy
->
isTermReason
(
"probation"
)
||
buddy
->
isTermReason
(
"giveup"
))
{
/* probation: The subscription has been terminated,
* but the client SHOULD retry at some later time.
* If a "retry-after" parameter is also present, the
* client SHOULD wait at least the number of seconds
* specified by that parameter before attempting to re-
* subscribe.
*/
/* giveup: The subscription has been terminated because
* the notifier could not obtain authorization in a
* timely fashion. If a "retry-after" parameter is
* also present, the client SHOULD wait at least the
* number of seconds specified by that parameter before
* attempting to re-subscribe; otherwise, the client
* MAY retry immediately, but will likely get put back
* into pending state.
*/
const
pjsip_sub_state_hdr
*
sub_hdr
;
pj_str_t
sub_state
=
{
"Subscription-State"
,
18
};
const
pjsip_msg
*
msg
;
msg
=
event
->
body
.
tsx_state
.
src
.
rdata
->
msg_info
.
msg
;
sub_hdr
=
(
const
pjsip_sub_state_hdr
*
)
pjsip_msg_find_hdr_by_name
(
msg
,
&
sub_state
,
NULL
);
if
(
sub_hdr
&&
sub_hdr
->
retry_after
>
0
)
resub_delay
=
sub_hdr
->
retry_after
*
1000
;
}
}
}
/* For other cases of subscription termination, if resubscribe
* timer is not set, schedule with default expiration (plus minus
* some random value, to avoid sending SUBSCRIBEs all at once)
*/
if
(
resub_delay
==
-
1
)
{
// pj_assert(PRES_TIMER >= 3);
resub_delay
=
PRES_TIMER
*
1000
;
// - 2500 + (pj_rand() % 5000);
}
buddy
->
sub
=
sub
;
buddy
->
rescheduleTimer
(
PJ_TRUE
,
resub_delay
);
}
/* else {
This will clear the last termination code/reason
buddy->term_code = 0;
buddy->term_reason.ptr = NULL;
}*/
/* Clear subscription */
/* if (pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
pjsip_evsub_terminate(buddy->sub, PJ_FALSE); // = NULL;
buddy->status.info_cnt = 0;
buddy->dlg = NULL;
buddy->rescheduleTimer(PJ_FALSE, 0);
// pjsip_evsub_set_mod_data(sub, modId, NULL);
}*/
// pj_log_pop_indent();
buddy
->
decLock
();
}
}
/* Callback when transaction state has changed. */
void
buddy_evsub_on_tsx_state
(
pjsip_evsub
*
sub
,
pjsip_transaction
*
tsx
,
pjsip_event
*
event
)
{
PresSubClient
*
buddy
;
pjsip_contact_hdr
*
contact_hdr
;
/* Note: #937: no need to acuire PJSUA_LOCK here. Since the buddy has
* a dialog attached to it, lock_buddy() will use the dialog
* lock, which we are currently holding!
*/
buddy
=
(
PresSubClient
*
)
pjsip_evsub_get_mod_data
(
sub
,
modId
);
if
(
!
buddy
)
{
return
;
}
buddy
->
incLock
();
/* We only use this to update buddy's Contact, when it's not
* set.
*/
if
(
buddy
->
contact
.
slen
!=
0
)
{
/* Contact already set */
buddy
->
decLock
();
return
;
}
/* Only care about 2xx response to outgoing SUBSCRIBE */
if
(
tsx
->
status_code
/
100
!=
2
||
tsx
->
role
!=
PJSIP_UAC_ROLE
||
event
->
type
!=
PJSIP_EVENT_RX_MSG
||
pjsip_method_cmp
(
&
tsx
->
method
,
pjsip_get_subscribe_method
())
!=
0
)
{
buddy
->
decLock
();
return
;
}
/* Find contact header. */
contact_hdr
=
(
pjsip_contact_hdr
*
)
pjsip_msg_find_hdr
(
event
->
body
.
rx_msg
.
rdata
->
msg_info
.
msg
,
PJSIP_H_CONTACT
,
NULL
);
if
(
!
contact_hdr
||
!
contact_hdr
->
uri
)
{
buddy
->
decLock
();
return
;
}
buddy
->
contact
.
ptr
=
(
char
*
)
pj_pool_alloc
(
buddy
->
pool
,
PJSIP_MAX_URL_SIZE
);
buddy
->
contact
.
slen
=
pjsip_uri_print
(
PJSIP_URI_IN_CONTACT_HDR
,
contact_hdr
->
uri
,
buddy
->
contact
.
ptr
,
PJSIP_MAX_URL_SIZE
);
if
(
buddy
->
contact
.
slen
<
0
)
buddy
->
contact
.
slen
=
0
;
buddy
->
decLock
();
}
/* Callback called when we receive NOTIFY */
static
void
buddy_evsub_on_rx_notify
(
pjsip_evsub
*
sub
,
pjsip_rx_data
*
rdata
,
int
*
p_st_code
,
pj_str_t
**
p_st_text
,
pjsip_hdr
*
res_hdr
,
pjsip_msg_body
**
p_body
)
{
PresSubClient
*
buddy
;
/* Note: #937: no need to acuire PJSUA_LOCK here. Since the buddy has
* a dialog attached to it, lock_buddy() will use the dialog
* lock, which we are currently holding!
*/
buddy
=
(
PresSubClient
*
)
pjsip_evsub_get_mod_data
(
sub
,
modId
);
if
(
!
buddy
){
ERROR
(
"Couldn't create new buddy"
);
return
;
}
pjsip_pres_get_status
(
sub
,
&
buddy
->
status
);
buddy
->
reportPresence
();
/* The default is to send 200 response to NOTIFY.
* Just leave it there..
*/
PJ_UNUSED_ARG
(
rdata
);
PJ_UNUSED_ARG
(
p_st_code
);
PJ_UNUSED_ARG
(
p_st_text
);
PJ_UNUSED_ARG
(
res_hdr
);
PJ_UNUSED_ARG
(
p_body
);
buddy
->
decLock
();
}
PresSubClient
::
PresSubClient
(
const
std
::
string
&
uri_
,
SIPAccount
*
acc_
)
:
acc
(
acc_
),
uri
(
pj_str
(
strdup
(
uri_
.
c_str
()))),
contact
(
pj_str
(
strdup
(
acc
->
getFromUri
().
c_str
()))),
display
(),
dlg
(
NULL
),
monitor
(
false
),
name
(),
cp_
(),
pool
(
0
),
status
(),
sub
(
NULL
),
term_code
(
0
),
term_reason
(),
timer
(),
user_data
(
NULL
),
lock_count
(
0
)
{
pj_caching_pool_init
(
&
cp_
,
&
pj_pool_factory_default_policy
,
0
);
pool
=
pj_pool_create
(
&
cp_
.
factory
,
"buddy"
,
512
,
512
,
NULL
);
}
PresSubClient
::~
PresSubClient
()
{
while
(
lock_count
>
0
)
{
usleep
(
200
);
}
DEBUG
(
"Destroying buddy object with uri %s"
,
uri
.
ptr
);
rescheduleTimer
(
PJ_FALSE
,
0
);
unsubscribe
();
pj_pool_release
(
pool
);
}
bool
PresSubClient
::
isSubscribed
()
{
return
this
->
monitor
;
}
std
::
string
PresSubClient
::
getURI
()
{
std
::
string
buddyURI
(
uri
.
ptr
,
uri
.
slen
);
return
buddyURI
;
}
bool
PresSubClient
::
isTermReason
(
std
::
string
reason
)
{
std
::
string
myReason
(
term_reason
.
ptr
,
term_reason
.
slen
);
return
!
myReason
.
compare
(
reason
);
}
void
PresSubClient
::
rescheduleTimer
(
bool
reschedule
,
unsigned
msec
)
{
if
(
timer
.
id
)
{
// pjsua_cancel_timer(&timer);
pjsip_endpt_cancel_timer
(((
SIPVoIPLink
*
)
acc
->
getVoIPLink
())
->
getEndpoint
(),
&
timer
);
timer
.
id
=
PJ_FALSE
;
}
if
(
reschedule
)
{
pj_time_val
delay
;
WARN
(
"Resubscribing buddy %.*s in %u ms (reason: %.*s)"
,
uri
.
slen
,
uri
.
ptr
,
msec
,
(
int
)
term_reason
.
slen
,
term_reason
.
ptr
);
monitor
=
PJ_TRUE
;
pj_timer_entry_init
(
&
timer
,
0
,
this
,
&
buddy_timer_cb
);
delay
.
sec
=
0
;
delay
.
msec
=
msec
;
pj_time_val_normalize
(
&
delay
);
// if (pjsua_schedule_timer(&timer, &delay)==PJ_SUCCESS)
if
(
pjsip_endpt_schedule_timer
(((
SIPVoIPLink
*
)
acc
->
getVoIPLink
())
->
getEndpoint
(),
&
timer
,
&
delay
)
==
PJ_SUCCESS
)
{
// timer.id = PJ_TRUE;
}
}
}
void
PresSubClient
::
accept
()
{
acc
->
getPresence
()
->
addPresSubClient
(
this
);
}
void
PresSubClient
::
reportPresence
()
{
//incLock();
/* callback*/
acc
->
getPresence
()
->
reportPresSubClientNotification
(
getURI
(),
&
status
);
//decLock();
}
pj_status_t
PresSubClient
::
updateSubscription
()
{
if
(
!
monitor
)
{
/* unsubscribe */
pjsip_tx_data
*
tdata
;
pj_status_t
retStatus
;
if
(
sub
==
NULL
)
{
WARN
(
"PresSubClient already unsubscribed sub=NULL."
);
return
PJ_SUCCESS
;
}
if
(
pjsip_evsub_get_state
(
sub
)
==
PJSIP_EVSUB_STATE_TERMINATED
)
{
WARN
(
"PresSubClient already unsubscribed sub=TERMINATED."
);
//pjsip_evsub_terminate(sub, PJ_FALSE); //
sub
=
NULL
;
return
PJ_SUCCESS
;
}
WARN
(
"PresSubClient %s: unsubscribing.."
,
uri
.
ptr
);
retStatus
=
pjsip_pres_initiate
(
sub
,
0
,
&
tdata
);
if
(
retStatus
==
PJ_SUCCESS
)
{
acc
->
getPresence
()
->
fillDoc
(
tdata
,
NULL
);
/*if (tdata->msg->type == PJSIP_REQUEST_MSG) {
const pj_str_t STR_USER_AGENT = {"User-Agent", 10};
pj_str_t ua = pj_str(strdup(acc->getUserAgentName().c_str()));
pjsip_hdr *h;
h = (pjsip_hdr*) pjsip_generic_string_hdr_create(tdata->pool, &STR_USER_AGENT, &ua);
pjsip_msg_add_hdr(tdata->msg, h);
}*/
retStatus
=
pjsip_pres_send_request
(
sub
,
tdata
);
}
if
(
retStatus
!=
PJ_SUCCESS
&&
sub
)
{
pjsip_pres_terminate
(
sub
,
PJ_FALSE
);
pjsip_evsub_terminate
(
sub
,
PJ_FALSE
);
// = NULL;
WARN
(
"Unable to unsubscribe presence"
,
status
);
}
pjsip_evsub_set_mod_data
(
sub
,
modId
,
NULL
);
// Not interested with further events
return
PJ_SUCCESS
;
}
//#if 0
if
(
sub
&&
dlg
)
{
//do not bother if already subscribed
// return PJ_SUCCESS;
pjsip_evsub_terminate
(
sub
,
PJ_FALSE
);
DEBUG
(
"Terminate existing sub."
);
}
//#endif
//subscribe
pjsip_evsub_user
pres_callback
;
// pj_pool_t *tmp_pool = NULL; // related to "contact field. TODO: check if this is necessary"
pjsip_tx_data
*
tdata
;
pj_status_t
status
;
/* Event subscription callback. */
pj_bzero
(
&
pres_callback
,
sizeof
(
pres_callback
));
pres_callback
.
on_evsub_state
=
&
buddy_evsub_on_state
;
pres_callback
.
on_tsx_state
=
&
buddy_evsub_on_tsx_state
;
pres_callback
.
on_rx_notify
=
&
buddy_evsub_on_rx_notify
;
DEBUG
(
"PresSubClient %s: subscribing presence,using account %s.."
,
uri
.
ptr
,
acc
->
getAccountID
().
c_str
());
/* Generate suitable Contact header unless one is already set in
* the account
*/
#if 0
if (acc->contact.slen) {
contact = acc->contact;
} else {
tmp_pool = pjsua_pool_create("tmpbuddy", 512, 256);
status = pjsua_acc_create_uac_contact(tmp_pool, &contact,
acc_id, &buddy->uri);
if (status != PJ_SUCCESS) {
pjsua_perror(THIS_FILE, "Unable to generate Contact header",
status);
pj_pool_release(tmp_pool);
pj_log_pop_indent();
return;
}
}
#endif
/* Create UAC dialog */
pj_str_t
from
=
pj_str
(
strdup
(
acc
->
getFromUri
().
c_str
()));
status
=
pjsip_dlg_create_uac
(
pjsip_ua_instance
(),
&
from
,
&
contact
,
&
uri
,
NULL
,
&
dlg
);
if
(
status
!=
PJ_SUCCESS
)
{
ERROR
(
"Unable to create dialog
\n
"
);
return
PJ_FALSE
;
}
// Add credential for auth.
if
(
acc
->
hasCredentials
()
and
pjsip_auth_clt_set_credentials
(
&
dlg
->
auth_sess
,
acc
->
getCredentialCount
(),
acc
->
getCredInfo
())
!=
PJ_SUCCESS
)
{
ERROR
(
"Could not initialize credentials for subscribe session authentication"
);
}
/* Increment the dialog's lock otherwise when presence session creation
* fails the dialog will be destroyed prematurely.
*/
pjsip_dlg_inc_lock
(
dlg
);
status
=
pjsip_pres_create_uac
(
dlg
,
&
pres_callback
,
PJSIP_EVSUB_NO_EVENT_ID
,
&
sub
);
if
(
status
!=
PJ_SUCCESS
)
{
pjsip_evsub_terminate
(
sub
,
PJ_FALSE
);
// = NULL;
WARN
(
"Unable to create presence client"
,
status
);
/* This should destroy the dialog since there's no session
* referencing it
*/
if
(
dlg
)
{
pjsip_dlg_dec_lock
(
dlg
);
}
// if (tmp_pool) pj_pool_release(tmp_pool);
// pj_log_pop_indent();
return
PJ_SUCCESS
;
}
#if 0
/* If account is locked to specific transport, then lock dialog
* to this transport too.
*/
if (acc->cfg.transport_id != PJSUA_INVALID_ID) {
pjsip_tpselector tp_sel;
pjsua_init_tpselector(acc->cfg.transport_id, &tp_sel);
pjsip_dlg_set_transport(buddy->dlg, &tp_sel);
}
/* Set route-set */
if (!pj_list_empty(&acc->route_set)) {
pjsip_dlg_set_route_set(buddy->dlg, &acc->route_set);
}
/* Set credentials */
if (acc->cred_cnt) {
pjsip_auth_clt_set_credentials(&buddy->dlg->auth_sess
acc->cred_cnt, acc->cred);
}
/* Set authentication preference */
pjsip_auth_clt_set_prefs(&buddy->dlg->auth_sess, &acc->cfg.auth_pref);
#endif
modId
=
((
SIPVoIPLink
*
)
acc
->
getVoIPLink
())
->
getModId
();
pjsip_evsub_set_mod_data
(
sub
,
modId
,
this
);
status
=
pjsip_pres_initiate
(
sub
,
-
1
,
&
tdata
);
if
(
status
!=
PJ_SUCCESS
)
{
if
(
dlg
)
pjsip_dlg_dec_lock
(
dlg
);
if
(
sub
)
{
pjsip_pres_terminate
(
sub
,
PJ_FALSE
);
}
pjsip_evsub_terminate
(
sub
,
PJ_FALSE
);
// = NULL;
WARN
(
"Unable to create initial SUBSCRIBE"
,
status
);
// if (tmp_pool) pj_pool_release(tmp_pool);
return
PJ_SUCCESS
;
}
// pjsua_process_msg_data(tdata, NULL);
status
=
pjsip_pres_send_request
(
sub
,
tdata
);
if
(
status
!=
PJ_SUCCESS
)
{
if
(
dlg
)
pjsip_dlg_dec_lock
(
dlg
);
if
(
sub
)
{
pjsip_pres_terminate
(
sub
,
PJ_FALSE
);
sub
=
NULL
;
}
WARN
(
"Unable to send initial SUBSCRIBE"
,
status
);
// if (tmp_pool) pj_pool_release(tmp_pool);
return
PJ_SUCCESS
;
}
pjsip_dlg_dec_lock
(
dlg
);
// if (tmp_pool) pj_pool_release(tmp_pool);
return
PJ_SUCCESS
;
}
bool
PresSubClient
::
subscribe
()
{
monitor
=
true
;
return
((
updateSubscription
()
==
PJ_SUCCESS
))
?
true
:
false
;
}
bool
PresSubClient
::
unsubscribe
()
{
monitor
=
false
;
return
((
updateSubscription
()
==
PJ_SUCCESS
))
?
true
:
false
;
}
bool
PresSubClient
::
match
(
PresSubClient
*
b
){
//return !(strcmp(b->getURI(),getURI()));
return
(
b
->
getURI
()
==
getURI
());
}
daemon/src/sip/pres_sub_client.h
0 → 100644
View file @
13b30305
/*
* Copyright (C) 2012, 2013 LOTES TM LLC
* Author : Andrey Loukhnov <aol.nnov@gmail.com>
* Author : Patrick Keroulas <patrick.keroulas@savoirfairelinux.com>
* This file is a part of pult5-voip
*
* pult5-voip 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 3 of the License, or
* (at your option) any later version.
*
* pult5-voip 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 programm. If not, see <http://www.gnu.org/licenses/>.
*
* Additional permission under GNU GPL version 3 section 7:
*
* If you modify pult5-voip, or any covered work, by linking or
* combining it with the OpenSSL project's OpenSSL library (or a
* modified version of that library), containing parts covered by the
* terms of the OpenSSL or SSLeay licenses, LOTES-TM LLC
* Corresponding Source for a non-source form of such a combination
* shall include the source code for the parts of OpenSSL used as well
* as that of the covered work.
*/
#ifndef SIPBUDDY_H
#define SIPBUDDY_H
#include
<pjsip-simple/presence.h>
#include
<pj/timer.h>
#include
<pj/pool.h>
#include
<string>
#include
<pjsip-simple/evsub.h>
#include
<pjsip-simple/evsub_msg.h>
#include
<pjsip/sip_endpoint.h>
#include
<pjsip/sip_transport.h>
#include
"noncopyable.h"
class
SIPAccount
;
/**
* Transaction functions of event subscription client side.
*/
static
void
buddy_evsub_on_state
(
pjsip_evsub
*
sub
,
pjsip_event
*
event
);
static
void
buddy_evsub_on_tsx_state
(
pjsip_evsub
*
sub
,
pjsip_transaction
*
tsx
,
pjsip_event
*
event
);
static
void
buddy_evsub_on_rx_notify
(
pjsip_evsub
*
sub
,
pjsip_rx_data
*
rdata
,
int
*
p_st_code
,
pj_str_t
**
p_st_text
,
pjsip_hdr
*
res_hdr
,
pjsip_msg_body
**
p_body
);
static
void
buddy_timer_cb
(
pj_timer_heap_t
*
th
,
pj_timer_entry
*
entry
);
class
PresSubClient
{