Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
liblinphone
Commits
f9aee351
Commit
f9aee351
authored
Sep 22, 2016
by
Simon Morlat
Browse files
heavy rework of lists, presence list subscriptions, and fix many memory leaks
parent
c0fa38c6
Changes
24
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
226 additions
and
213 deletions
+226
-213
console/commands.c
console/commands.c
+2
-3
console/linphonec.c
console/linphonec.c
+1
-2
coreapi/bellesip_sal/sal_impl.c
coreapi/bellesip_sal/sal_impl.c
+1
-1
coreapi/bellesip_sal/sal_op_call.c
coreapi/bellesip_sal/sal_op_call.c
+1
-1
coreapi/callbacks.c
coreapi/callbacks.c
+1
-1
coreapi/friend.c
coreapi/friend.c
+39
-76
coreapi/friendlist.c
coreapi/friendlist.c
+101
-59
coreapi/friendlist.h
coreapi/friendlist.h
+22
-2
coreapi/help/buddy_status.c
coreapi/help/buddy_status.c
+9
-7
coreapi/linphonecall.c
coreapi/linphonecall.c
+5
-2
coreapi/linphonecore.c
coreapi/linphonecore.c
+18
-24
coreapi/linphonefriend.h
coreapi/linphonefriend.h
+4
-3
coreapi/misc.c
coreapi/misc.c
+1
-1
coreapi/presence.c
coreapi/presence.c
+2
-4
coreapi/private.h
coreapi/private.h
+6
-3
coreapi/proxy.c
coreapi/proxy.c
+1
-1
coreapi/vtables.c
coreapi/vtables.c
+1
-1
gtk/friendlist.c
gtk/friendlist.c
+9
-19
gtk/main.c
gtk/main.c
+1
-2
gtk/propertybox.c
gtk/propertybox.c
+1
-1
No files found.
console/commands.c
View file @
f9aee351
...
...
@@ -1829,7 +1829,7 @@ linphonec_proxy_use(LinphoneCore *lc, int index)
static
void
linphonec_friend_display
(
LinphoneFriend
*
fr
)
{
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
fr
);
const
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
fr
);
char
*
str
=
NULL
;
linphonec_out
(
"name: %s
\n
"
,
linphone_friend_get_name
(
fr
));
...
...
@@ -1875,12 +1875,11 @@ linphonec_friend_call(LinphoneCore *lc, unsigned int num)
if
(
n
==
num
)
{
int
ret
;
LinphoneAddress
*
addr
=
linphone_friend_get_address
((
LinphoneFriend
*
)
friend
->
data
);
const
LinphoneAddress
*
addr
=
linphone_friend_get_address
((
LinphoneFriend
*
)
friend
->
data
);
if
(
addr
)
{
addr_str
=
linphone_address_as_string
(
addr
);
ret
=
lpc_cmd_call
(
lc
,
addr_str
);
ms_free
(
addr_str
);
linphone_address_unref
(
addr
);
return
ret
;
}
else
{
linphonec_out
(
"Friend %u does not have an address
\n
"
,
num
);
...
...
console/linphonec.c
View file @
f9aee351
...
...
@@ -291,12 +291,11 @@ linphonec_transfer_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneC
static
void
linphonec_notify_presence_received
(
LinphoneCore
*
lc
,
LinphoneFriend
*
fid
)
{
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
fid
);
const
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
fid
);
if
(
addr
)
{
char
*
tmp
=
linphone_address_as_string
(
addr
);
printf
(
"Friend %s is %s
\n
"
,
tmp
,
linphone_online_status_to_string
(
linphone_friend_get_status
(
fid
)));
ms_free
(
tmp
);
linphone_address_unref
(
addr
);
}
// todo: update Friend list state (unimplemented)
}
...
...
coreapi/bellesip_sal/sal_impl.c
View file @
f9aee351
...
...
@@ -1137,7 +1137,7 @@ void sal_remove_supported_tag(Sal *ctx, const char* tag){
bctbx_list_t
*
elem
=
bctbx_list_find_custom
(
ctx
->
supported_tags
,(
bctbx_compare_func
)
strcasecmp
,
tag
);
if
(
elem
){
ms_free
(
elem
->
data
);
ctx
->
supported_tags
=
bctbx_list_
remov
e_link
(
ctx
->
supported_tags
,
elem
);
ctx
->
supported_tags
=
bctbx_list_
eras
e_link
(
ctx
->
supported_tags
,
elem
);
make_supported_header
(
ctx
);
}
}
...
...
coreapi/bellesip_sal/sal_op_call.c
View file @
f9aee351
...
...
@@ -538,7 +538,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
bool_t
is_update
=
FALSE
;
bool_t
drop_op
=
FALSE
;
if
(
strcmp
(
"ACK"
,
method
)
!=
0
){
/*ACK does
'
nt create srv transaction*/
if
(
strcmp
(
"ACK"
,
method
)
!=
0
){
/*ACK doesn
'
t create
a
s
e
rv
er
transaction*/
server_transaction
=
belle_sip_provider_create_server_transaction
(
op
->
base
.
root
->
prov
,
belle_sip_request_event_get_request
(
event
));
belle_sip_object_ref
(
server_transaction
);
belle_sip_transaction_set_application_data
(
BELLE_SIP_TRANSACTION
(
server_transaction
),
sal_op_ref
(
op
));
...
...
coreapi/callbacks.c
View file @
f9aee351
...
...
@@ -1106,7 +1106,7 @@ static bool_t is_duplicate_msg(LinphoneCore *lc, const char *msg_id){
}
if
(
i
>=
10
){
ms_free
(
tail
->
data
);
lc
->
last_recv_msg_ids
=
bctbx_list_
remov
e_link
(
lc
->
last_recv_msg_ids
,
tail
);
lc
->
last_recv_msg_ids
=
bctbx_list_
eras
e_link
(
lc
->
last_recv_msg_ids
,
tail
);
}
return
is_duplicate
;
}
...
...
coreapi/friend.c
View file @
f9aee351
...
...
@@ -125,7 +125,7 @@ static LinphoneFriendPresence * find_presence_model_for_uri_or_tel(const Linphon
}
static
void
add_presence_model_for_uri_or_tel
(
LinphoneFriend
*
lf
,
const
char
*
uri_or_tel
,
LinphonePresenceModel
*
presence
)
{
LinphoneFriendPresence
*
lfp
=
ms_new
(
LinphoneFriendPresence
,
1
);
LinphoneFriendPresence
*
lfp
=
ms_new
0
(
LinphoneFriendPresence
,
1
);
lfp
->
uri_or_tel
=
ms_strdup
(
uri_or_tel
);
lfp
->
presence
=
presence
;
lf
->
presence_models
=
bctbx_list_append
(
lf
->
presence_models
,
lfp
);
...
...
@@ -134,11 +134,13 @@ static void add_presence_model_for_uri_or_tel(LinphoneFriend *lf, const char *ur
static
void
free_friend_presence
(
LinphoneFriendPresence
*
lfp
)
{
ms_free
(
lfp
->
uri_or_tel
);
if
(
lfp
->
presence
)
linphone_presence_model_unref
(
lfp
->
presence
);
ms_free
(
lfp
);
}
static
void
free_phone_number_sip_uri
(
LinphoneFriendPhoneNumberSipUri
*
lfpnsu
)
{
ms_free
(
lfpnsu
->
number
);
ms_free
(
lfpnsu
->
uri
);
ms_free
(
lfpnsu
);
}
...
...
@@ -156,7 +158,7 @@ bctbx_list_t *linphone_find_friend_by_address(bctbx_list_t *fl, const LinphoneAd
void
__linphone_friend_do_subscribe
(
LinphoneFriend
*
fr
){
LinphoneCore
*
lc
=
fr
->
lc
;
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
fr
);
const
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
fr
);
if
(
addr
!=
NULL
)
{
if
(
fr
->
outsub
==
NULL
){
...
...
@@ -174,7 +176,6 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){
linphone_configure_op
(
lc
,
fr
->
outsub
,
addr
,
NULL
,
TRUE
);
sal_subscribe_presence
(
fr
->
outsub
,
NULL
,
NULL
,
lp_config_get_int
(
lc
->
config
,
"sip"
,
"subscribe_expires"
,
600
));
fr
->
subscribe_active
=
TRUE
;
linphone_address_unref
(
addr
);
}
}
...
...
@@ -260,7 +261,7 @@ void linphone_core_interpret_friend_uri(LinphoneCore *lc, const char *uri, char
}
}
LinphoneAddress
*
linphone_friend_get_address
(
const
LinphoneFriend
*
lf
)
{
const
LinphoneAddress
*
linphone_friend_get_address
(
const
LinphoneFriend
*
lf
)
{
if
(
linphone_core_vcard_supported
())
{
if
(
lf
->
vcard
)
{
bctbx_list_t
*
sip_addresses
=
linphone_vcard_get_sip_addresses
(
lf
->
vcard
);
...
...
@@ -269,12 +270,16 @@ LinphoneAddress * linphone_friend_get_address(const LinphoneFriend *lf) {
LinphoneAddress
*
addr
=
NULL
;
if
(
uri
)
addr
=
linphone_address_new
(
uri
);
bctbx_list_free
(
sip_addresses
);
if
(
lf
->
uri
){
linphone_address_unref
(
lf
->
uri
);
}
((
LinphoneFriend
*
)
lf
)
->
uri
=
addr
;
return
addr
;
}
}
return
NULL
;
}
if
(
lf
->
uri
)
return
linphone_address_clone
(
lf
->
uri
)
;
if
(
lf
->
uri
)
return
lf
->
uri
;
return
NULL
;
}
...
...
@@ -321,7 +326,7 @@ void linphone_friend_add_address(LinphoneFriend *lf, const LinphoneAddress *addr
}
}
bctbx_list_t
*
linphone_friend_get_addresses
(
LinphoneFriend
*
lf
)
{
bctbx_list_t
*
linphone_friend_get_addresses
(
const
LinphoneFriend
*
lf
)
{
bctbx_list_t
*
sip_addresses
=
NULL
;
bctbx_list_t
*
addresses
=
NULL
;
bctbx_list_t
*
iterator
=
NULL
;
...
...
@@ -411,12 +416,11 @@ int linphone_friend_set_inc_subscribe_policy(LinphoneFriend *fr, LinphoneSubscri
void
linphone_friend_notify
(
LinphoneFriend
*
lf
,
LinphonePresenceModel
*
presence
){
bctbx_list_t
*
elem
;
if
(
lf
->
insubs
){
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
lf
);
const
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
lf
);
if
(
addr
)
{
char
*
addr_str
=
linphone_address_as_string
(
addr
);
ms_message
(
"Want to notify %s"
,
addr_str
);
ms_free
(
addr_str
);
linphone_address_unref
(
addr
);
}
}
for
(
elem
=
lf
->
insubs
;
elem
!=
NULL
;
elem
=
bctbx_list_next
(
elem
)){
...
...
@@ -538,12 +542,11 @@ LinphoneOnlineStatus linphone_friend_get_status(const LinphoneFriend *lf){
online_status
=
(
basic_status
==
LinphonePresenceBasicStatusOpen
)
?
LinphoneStatusOnline
:
LinphoneStatusOffline
;
if
(
nb_activities
>
1
)
{
char
*
tmp
=
NULL
;
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
lf
);
const
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
lf
);
if
(
addr
)
tmp
=
linphone_address_as_string
(
addr
);
ms_warning
(
"Friend %s has several activities, get status from the first one"
,
tmp
?
tmp
:
"unknown"
);
if
(
tmp
)
{
ms_free
(
tmp
);
linphone_address_unref
(
addr
);
}
nb_activities
=
1
;
}
...
...
@@ -621,26 +624,25 @@ const LinphonePresenceModel * linphone_friend_get_presence_model(const LinphoneF
LinphoneFriend
*
fuckconst
=
(
LinphoneFriend
*
)
lf
;
bctbx_list_t
*
addrs
=
linphone_friend_get_addresses
(
fuckconst
);
bctbx_list_t
*
phones
=
NULL
;
bctbx_list_t
*
it
;
while
(
addrs
)
{
LinphoneAddress
*
addr
=
addrs
->
data
;
for
(
it
=
addrs
;
it
!=
NULL
;
it
=
it
->
next
)
{
LinphoneAddress
*
addr
=
(
LinphoneAddress
*
)
it
->
data
;
char
*
uri
=
linphone_address_as_string_uri_only
(
addr
);
presence
=
linphone_friend_get_presence_model_for_uri_or_tel
(
fuckconst
,
uri
);
ms_free
(
uri
);
linphone_address_unref
(
addr
);
if
(
presence
)
return
presence
;
addrs
=
addrs
->
next
;
if
(
presence
)
break
;
}
bctbx_list_free_with_data
(
addrs
,
(
bctbx_list_free_func
)
linphone_address_unref
);
if
(
presence
)
return
presence
;
phones
=
linphone_friend_get_phone_numbers
(
fuckconst
);
while
(
phones
)
{
presence
=
linphone_friend_get_presence_model_for_uri_or_tel
(
fuckconst
,
phones
->
data
);
if
(
presence
)
return
presence
;
phones
=
phones
->
next
;
for
(
it
=
phones
;
it
!=
NULL
;
it
=
it
->
next
)
{
presence
=
linphone_friend_get_presence_model_for_uri_or_tel
(
fuckconst
,
it
->
data
);
if
(
presence
)
break
;
}
return
NULL
;
bctbx_list_free
(
phones
);
return
presence
;
}
const
LinphonePresenceModel
*
linphone_friend_get_presence_model_for_uri_or_tel
(
const
LinphoneFriend
*
lf
,
const
char
*
uri_or_tel
)
{
...
...
@@ -650,12 +652,11 @@ const LinphonePresenceModel * linphone_friend_get_presence_model_for_uri_or_tel(
}
void
linphone_friend_set_presence_model
(
LinphoneFriend
*
lf
,
LinphonePresenceModel
*
presence
)
{
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
lf
);
const
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
lf
);
if
(
addr
)
{
char
*
uri
=
linphone_address_as_string_uri_only
(
addr
);
linphone_friend_set_presence_model_for_uri_or_tel
(
lf
,
uri
,
presence
);
ms_free
(
uri
);
linphone_address_unref
(
addr
);
}
}
...
...
@@ -683,14 +684,13 @@ BuddyInfo * linphone_friend_get_info(const LinphoneFriend *lf){
* Otherwise if the proxy config goes to unregistered state, the subscription refresh will be suspended.
* An optional proxy whose state has changed can be passed to optimize the processing.
**/
void
linphone_friend_update_subscribes
(
LinphoneFriend
*
fr
,
LinphoneProxyConfig
*
proxy
,
bool_t
only_when_registered
){
void
linphone_friend_update_subscribes
(
LinphoneFriend
*
fr
,
bool_t
only_when_registered
){
int
can_subscribe
=
1
;
if
(
only_when_registered
&&
(
fr
->
subscribe
||
fr
->
subscribe_active
)){
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
fr
);
const
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
fr
);
if
(
addr
!=
NULL
)
{
LinphoneProxyConfig
*
cfg
=
linphone_core_lookup_known_proxy
(
fr
->
lc
,
addr
);
if
(
proxy
&&
proxy
!=
cfg
)
return
;
if
(
cfg
&&
cfg
->
state
!=
LinphoneRegistrationOk
){
char
*
tmp
=
linphone_address_as_string
(
addr
);
ms_message
(
"Friend [%s] belongs to proxy config with identity [%s], but this one isn't registered. Subscription is suspended."
,
...
...
@@ -698,7 +698,6 @@ void linphone_friend_update_subscribes(LinphoneFriend *fr, LinphoneProxyConfig *
ms_free
(
tmp
);
can_subscribe
=
0
;
}
linphone_address_unref
(
addr
);
}
}
if
(
can_subscribe
&&
fr
->
subscribe
&&
fr
->
subscribe_active
==
FALSE
){
...
...
@@ -727,13 +726,12 @@ void linphone_friend_save(LinphoneFriend *fr, LinphoneCore *lc) {
void
linphone_friend_apply
(
LinphoneFriend
*
fr
,
LinphoneCore
*
lc
)
{
LinphonePresenceModel
*
model
;
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
fr
);
const
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
fr
);
if
(
!
addr
)
{
ms_debug
(
"No sip url defined in friend %s"
,
linphone_friend_get_name
(
fr
));
return
;
}
linphone_address_unref
(
addr
);
if
(
!
linphone_core_ready
(
lc
))
{
/* lc not ready, deffering subscription */
fr
->
commit
=
TRUE
;
...
...
@@ -757,15 +755,9 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc) {
}
fr
->
inc_subscribe_pending
=
FALSE
;
}
#if 0
/*triggering a list subscription update from here is probably not a good idea, as linphone_friend_done() may be called
* for thousand of LinphoneFriend sequentially.
* It is preferable that the application calls linphone_friend_list_update_subscriptions() once it has performmed
* all modifications to friends in the list.*/
if (fr->lc) {
linphone_friend_list_update_subscriptions(fr->friend_list, NULL, linphone_core_should_subscribe_friends_only_when_registered(fr->lc));
}
#endif
linphone_friend_update_subscribes
(
fr
,
linphone_core_should_subscribe_friends_only_when_registered
(
lc
));
ms_debug
(
"linphone_friend_apply() done."
);
lc
->
bl_refresh
=
TRUE
;
fr
->
commit
=
FALSE
;
...
...
@@ -832,11 +824,11 @@ void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend *lf) {
}
}
void
linphone_core_update_friends_subscriptions
(
LinphoneCore
*
lc
,
LinphoneProxyConfig
*
cfg
,
bool_t
only_when_registered
)
{
void
linphone_core_update_friends_subscriptions
(
LinphoneCore
*
lc
)
{
bctbx_list_t
*
lists
=
lc
->
friends_lists
;
while
(
lists
)
{
LinphoneFriendList
*
list
=
(
LinphoneFriendList
*
)
bctbx_list_get_data
(
lists
);
linphone_friend_list_update_subscriptions
(
list
,
cfg
,
only_when_registered
);
linphone_friend_list_update_subscriptions
(
list
);
lists
=
bctbx_list_next
(
lists
);
}
}
...
...
@@ -846,39 +838,11 @@ bool_t linphone_core_should_subscribe_friends_only_when_registered(const Linphon
}
void
linphone_core_send_initial_subscribes
(
LinphoneCore
*
lc
)
{
bctbx_list_t
*
lists
=
lc
->
friends_lists
;
bool_t
proxy_config_for_rls_presence_uri_domain
=
FALSE
;
LinphoneAddress
*
rls_address
=
NULL
;
const
bctbx_list_t
*
elem
;
if
(
lc
->
initial_subscribes_sent
)
return
;
lc
->
initial_subscribes_sent
=
TRUE
;
while
(
lists
)
{
LinphoneFriendList
*
list
=
(
LinphoneFriendList
*
)
bctbx_list_get_data
(
lists
);
if
(
list
->
rls_uri
!=
NULL
)
{
rls_address
=
linphone_core_create_address
(
lc
,
list
->
rls_uri
);
if
(
rls_address
!=
NULL
)
{
const
char
*
rls_domain
=
linphone_address_get_domain
(
rls_address
);
if
(
rls_domain
!=
NULL
)
{
for
(
elem
=
linphone_core_get_proxy_config_list
(
lc
);
elem
!=
NULL
;
elem
=
bctbx_list_next
(
elem
))
{
LinphoneProxyConfig
*
cfg
=
(
LinphoneProxyConfig
*
)
bctbx_list_get_data
(
elem
);
const
char
*
proxy_domain
=
linphone_proxy_config_get_domain
(
cfg
);
if
(
strcmp
(
rls_domain
,
proxy_domain
)
==
0
)
{
proxy_config_for_rls_presence_uri_domain
=
TRUE
;
break
;
}
}
}
linphone_address_unref
(
rls_address
);
}
}
if
(
proxy_config_for_rls_presence_uri_domain
==
TRUE
)
{
ms_message
(
"Presence list activated so do not send initial subscribes it will be done when registered"
);
}
else
{
linphone_core_update_friends_subscriptions
(
lc
,
NULL
,
linphone_core_should_subscribe_friends_only_when_registered
(
lc
));
}
lists
=
bctbx_list_next
(
lists
);
}
linphone_core_update_friends_subscriptions
(
lc
);
}
void
linphone_core_invalidate_friend_subscriptions
(
LinphoneCore
*
lc
)
{
...
...
@@ -1426,7 +1390,7 @@ void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) {
char
*
buf
;
int
store_friends
=
lp_config_get_int
(
lc
->
config
,
"misc"
,
"store_friends"
,
1
);
LinphoneVcard
*
vcard
=
NULL
;
LinphoneAddress
*
addr
;
const
LinphoneAddress
*
addr
;
char
*
addr_str
=
NULL
;
if
(
!
store_friends
)
{
...
...
@@ -1473,7 +1437,7 @@ void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf) {
);
}
if
(
addr_str
!=
NULL
)
ms_free
(
addr_str
);
if
(
addr
!=
NULL
)
linphone_address_unref
(
addr
);
linphone_sql_request_generic
(
lc
->
friends_db
,
buf
);
sqlite3_free
(
buf
);
...
...
@@ -1685,7 +1649,7 @@ void linphone_core_migrate_friends_from_rc_to_db(LinphoneCore *lc) {
for
(
i
=
0
;
(
lf
=
linphone_friend_new_from_config_file
(
lc
,
i
))
!=
NULL
;
i
++
)
{
char
friend_section
[
32
];
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
lf
);
const
LinphoneAddress
*
addr
=
linphone_friend_get_address
(
lf
);
if
(
addr
)
{
char
*
address
=
NULL
;
const
char
*
displayName
=
linphone_address_get_display_name
(
addr
);
...
...
@@ -1708,7 +1672,6 @@ void linphone_core_migrate_friends_from_rc_to_db(LinphoneCore *lc) {
snprintf
(
friend_section
,
sizeof
(
friend_section
),
"friend_%i"
,
i
);
lp_config_clean_section
(
lpc
,
friend_section
);
linphone_address_unref
(
addr
);
}
}
...
...
@@ -1748,7 +1711,7 @@ const char * linphone_friend_phone_number_to_sip_uri(LinphoneFriend *lf, const c
linphone_address_set_uri_param
(
addr
,
"user"
,
"phone"
);
full_uri
=
linphone_address_as_string_uri_only
(
addr
);
linphone_address_unref
(
addr
);
lfpnsu
=
ms_new
(
LinphoneFriendPhoneNumberSipUri
,
1
);
lfpnsu
=
ms_new
0
(
LinphoneFriendPhoneNumberSipUri
,
1
);
lfpnsu
->
number
=
ms_strdup
(
phone_number
);
lfpnsu
->
uri
=
full_uri
;
lf
->
phone_number_sip_uri_map
=
bctbx_list_append
(
lf
->
phone_number_sip_uri_map
,
lfpnsu
);
...
...
coreapi/friendlist.c
View file @
f9aee351
...
...
@@ -174,13 +174,11 @@ static char * create_resource_list_xml(const LinphoneFriendList *list) {
{
bctbx_list_t
*
entries
=
uri_list
(
list
);
bctbx_list_t
*
it
=
entries
;
while
(
it
)
{
bctbx_list_t
*
it
;
for
(
it
=
entries
;
it
!=
NULL
;
it
=
it
->
next
)
{
err
=
add_uri_entry
(
writer
,
err
,
it
->
data
);
ms_free
(
it
->
data
);
it
=
it
->
next
;
}
bctbx_
free
(
entries
);
bctbx_
list_free_with_data
(
entries
,
ms_free
);
}
if
(
err
>=
0
)
{
/* Close the "list" element. */
...
...
@@ -232,7 +230,7 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList
linphone_free_xml_text_content
(
version_str
);
if
(
version
<
list
->
expected_notification_version
)
{
ms_warning
(
"rlmi+xml: Discarding received notification with version %d because %d was expected"
,
version
,
list
->
expected_notification_version
);
linphone_friend_list_update_subscriptions
(
list
,
NULL
,
FALSE
);
/* Refresh subscription to get new full state notify. */
linphone_friend_list_update_subscriptions
(
list
);
/* Refresh subscription to get new full state notify. */
goto
end
;
}
...
...
@@ -265,6 +263,7 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList
if
(
uri
==
NULL
)
continue
;
addr
=
linphone_address_new
(
uri
);
lf
=
addr
?
linphone_friend_list_find_friend_by_address
(
list
,
addr
)
:
NULL
;
linphone_address_unref
(
addr
);
if
(
lf
!=
NULL
)
{
const
char
*
state
=
NULL
;
snprintf
(
xpath_str
,
sizeof
(
xpath_str
),
"/rlmi:list/rlmi:resource[%i]/rlmi:instance/@state"
,
i
);
...
...
@@ -369,6 +368,7 @@ static LinphoneFriendList * linphone_friend_list_new(void) {
static
void
linphone_friend_list_destroy
(
LinphoneFriendList
*
list
)
{
if
(
list
->
display_name
!=
NULL
)
ms_free
(
list
->
display_name
);
if
(
list
->
rls_addr
)
linphone_address_unref
(
list
->
rls_addr
);
if
(
list
->
rls_uri
!=
NULL
)
ms_free
(
list
->
rls_uri
);
if
(
list
->
content_digest
!=
NULL
)
ms_free
(
list
->
content_digest
);
if
(
list
->
event
!=
NULL
)
{
...
...
@@ -450,24 +450,40 @@ void linphone_friend_list_set_display_name(LinphoneFriendList *list, const char
}
}
const
char
*
linphone_friend_list_get_rls_
uri
(
const
LinphoneFriendList
*
list
)
{
return
list
->
rls_
uri
;
const
LinphoneAddress
*
linphone_friend_list_get_rls_
address
(
const
LinphoneFriendList
*
list
){
return
list
->
rls_
addr
;
}
void
linphone_friend_list_set_rls_uri
(
LinphoneFriendList
*
list
,
const
char
*
rls_uri
)
{
if
(
list
->
rls_uri
!=
NULL
)
{
void
linphone_friend_list_set_rls_address
(
LinphoneFriendList
*
list
,
const
LinphoneAddress
*
rls_addr
){
LinphoneAddress
*
new_rls_addr
=
rls_addr
?
linphone_address_clone
(
rls_addr
)
:
NULL
;
if
(
list
->
rls_addr
){
linphone_address_unref
(
list
->
rls_addr
);
}
list
->
rls_addr
=
new_rls_addr
;
if
(
list
->
rls_uri
!=
NULL
){
ms_free
(
list
->
rls_uri
);
list
->
rls_uri
=
NULL
;
}
if
(
rls_uri
!=
NULL
)
{
list
->
rls_uri
=
ms_strdup
(
rls_uri
);
if
(
list
->
rls_addr
)
{
list
->
rls_uri
=
linphone_address_as_string
(
list
->
rls_addr
);
linphone_core_store_friends_list_in_db
(
list
->
lc
,
list
);
}
}
const
char
*
linphone_friend_list_get_rls_uri
(
const
LinphoneFriendList
*
list
)
{
return
list
->
rls_uri
;
}
void
linphone_friend_list_set_rls_uri
(
LinphoneFriendList
*
list
,
const
char
*
rls_uri
)
{
LinphoneAddress
*
addr
=
rls_uri
?
linphone_core_create_address
(
list
->
lc
,
rls_uri
)
:
NULL
;
linphone_friend_list_set_rls_address
(
list
,
addr
);
if
(
addr
)
linphone_address_destroy
(
addr
);
}
static
LinphoneFriendListStatus
_linphone_friend_list_add_friend
(
LinphoneFriendList
*
list
,
LinphoneFriend
*
lf
,
bool_t
synchronize
)
{
LinphoneFriendListStatus
status
=
LinphoneFriendListInvalidFriend
;
LinphoneAddress
*
addr
;
const
LinphoneAddress
*
addr
;
if
(
!
list
||
lf
->
friend_list
)
{
if
(
!
list
)
...
...
@@ -486,7 +502,7 @@ static LinphoneFriendListStatus _linphone_friend_list_add_friend(LinphoneFriendL
status
=
linphone_friend_list_import_friend
(
list
,
lf
,
synchronize
);
linphone_friend_save
(
lf
,
lf
->
lc
);
}
if
(
addr
)
linphone_address_unref
(
addr
);
if
(
list
->
rls_uri
==
NULL
)
{
/* Mimic the behaviour of linphone_core_add_friend() when a resource list server is not in use */
linphone_friend_apply
(
lf
,
lf
->
lc
);
...
...
@@ -552,7 +568,7 @@ static LinphoneFriendListStatus _linphone_friend_list_remove_friend(LinphoneFrie
lf
->
friend_list
=
NULL
;
linphone_friend_unref
(
lf
);
list
->
friends
=
bctbx_list_
remov
e_link
(
list
->
friends
,
elem
);
list
->
friends
=
bctbx_list_
eras
e_link
(
list
->
friends
,
elem
);
return
LinphoneFriendListOK
;
}
...
...
@@ -721,58 +737,84 @@ static void linphone_friend_list_close_subscriptions(LinphoneFriendList *list) {
bctbx_list_for_each
(
list
->
friends
,
(
void
(
*
)(
void
*
))
linphone_friend_close_subscriptions
);
}
void
linphone_friend_list_update_subscriptions
(
LinphoneFriendList
*
list
,
LinphoneProxyConfig
*
cfg
,
bool_t
only_when_registered
)
{
const
bctbx_list_t
*
elem
;
if
(
list
->
rls_uri
!=
NULL
)
{
static
void
linphone_friend_list_send_list_subscription
(
LinphoneFriendList
*
list
){
const
LinphoneAddress
*
address
=
list
->
rls_addr
;
char
*
xml_content
=
create_resource_list_xml
(
list
);
if
((
address
!=
NULL
)
&&
(
xml_content
!=
NULL
)
&&
(
linphone_friend_list_has_subscribe_inactive
(
list
)
==
TRUE
))
{
unsigned
char
digest
[
16
];
bctbx_md5
((
unsigned
char
*
)
xml_content
,
strlen
(
xml_content
),
digest
);
if
((
list
->
event
!=
NULL
)
&&
(
list
->
content_digest
!=
NULL
)
&&
(
memcmp
(
list
->
content_digest
,
digest
,
sizeof
(
digest
))
==
0
))
{
/* The content has not changed, only refresh the event. */
linphone_event_refresh_subscribe
(
list
->
event
);
}
else
{
LinphoneContent
*
content
;
int
expires
=
lp_config_get_int
(
list
->
lc
->
config
,
"sip"
,
"rls_presence_expires"
,
3600
);
list
->
expected_notification_version
=
0
;
if
(
list
->
content_digest
!=
NULL
)
ms_free
(
list
->
content_digest
);
list
->
content_digest
=
ms_malloc
(
sizeof
(
digest
));
memcpy
(
list
->
content_digest
,
digest
,
sizeof
(
digest
));
if
(
list
->
event
!=
NULL
)
{
linphone_event_terminate
(
list
->
event
);
linphone_event_unref
(
list
->
event
);
}
list
->
event
=
linphone_core_create_subscribe
(
list
->
lc
,
address
,
"presence"
,
expires
);
linphone_event_ref
(
list
->
event
);
linphone_event_set_internal
(
list
->
event
,
TRUE
);
linphone_event_add_custom_header
(
list
->
event
,
"Require"
,
"recipient-list-subscribe"
);
linphone_event_add_custom_header
(
list
->
event
,
"Supported"
,
"eventlist"
);
linphone_event_add_custom_header
(
list
->
event
,
"Accept"
,
"multipart/related, application/pidf+xml, application/rlmi+xml"
);
linphone_event_add_custom_header
(
list
->
event
,
"Content-Disposition"
,
"recipient-list"
);
content
=
linphone_core_create_content
(
list
->
lc
);
linphone_content_set_type
(
content
,
"application"
);
linphone_content_set_subtype
(
content
,
"resource-lists+xml"
);
linphone_content_set_string_buffer
(
content
,
xml_content
);
if
(
linphone_core_content_encoding_supported
(
list
->
lc
,
"deflate"
))
{
linphone_content_set_encoding
(
content
,
"deflate"
);
linphone_event_add_custom_header
(
list
->
event
,
"Accept-Encoding"
,
"deflate"
);
}
linphone_event_send_subscribe
(
list
->
event
,
content
);
linphone_content_unref
(
content
);
linphone_event_set_user_data
(
list
->
event
,
list
);
}
}
if
(
xml_content
!=
NULL
)
ms_free
(
xml_content
);
}
void
linphone_friend_list_update_subscriptions
(
LinphoneFriendList
*
list
){
LinphoneProxyConfig
*
cfg
=
NULL
;
const
LinphoneAddress
*
address
=
linphone_friend_list_get_rls_address
(
list
);
bool_t
only_when_registered
=
FALSE
;
bool_t
should_send_list_subscribe
=
FALSE
;
if
(
list
->
lc
){
if
(
address
)
cfg
=
linphone_core_lookup_known_proxy
(
list
->
lc
,
address
);
only_when_registered
=
linphone_core_should_subscribe_friends_only_when_registered
(
list
->
lc
);
should_send_list_subscribe
=
(
!
only_when_registered
||
!
cfg
||
cfg
->
state
==
LinphoneRegistrationOk
);
}
if
(
list
->
rls_addr
!=
NULL
)
{
if
(
list
->
enable_subscriptions
)
{
LinphoneAddress
*
address
=
linphone_address_new
(
list
->
rls_uri
);
char
*
xml_content
=
create_resource_list_xml
(
list
);
if
((
address
!=
NULL
)
&&
(
xml_content
!=
NULL
)
&&
(
linphone_friend_list_has_subscribe_inactive
(
list
)
==
TRUE
))
{
unsigned
char
digest
[
16
];
bctbx_md5
((
unsigned
char
*
)
xml_content
,
strlen
(
xml_content
),
digest
);
if
((
list
->
event
!=
NULL
)
&&
(
list
->
content_digest
!=
NULL
)
&&
(
memcmp
(
list
->
content_digest
,
digest
,
sizeof
(
digest
))
==
0
))
{
/* The content has not changed, only refresh the event. */
linphone_event_refresh_subscribe
(
list
->
event
);
}
else
{
LinphoneContent
*
content
;
int
expires
=
lp_config_get_int
(
list
->
lc
->
config
,
"sip"
,
"rls_presence_expires"
,
3600
);
list
->
expected_notification_version
=
0
;
if
(
list
->
content_digest
!=
NULL
)
ms_free
(
list
->
content_digest
);
list
->
content_digest
=
ms_malloc
(
sizeof
(
digest
));
memcpy
(
list
->
content_digest
,
digest
,
sizeof
(
digest
));
if
(
list
->
event
!=
NULL
)
{
linphone_event_terminate
(
list
->
event
);
linphone_event_unref
(
list
->
event
);
}
list
->
event
=
linphone_core_create_subscribe
(
list
->
lc
,
address
,
"presence"
,
expires
);
linphone_event_ref
(
list
->
event
);
linphone_event_set_internal
(
list
->
event
,
TRUE
);
linphone_event_add_custom_header
(
list
->
event
,
"Require"
,
"recipient-list-subscribe"
);
linphone_event_add_custom_header
(
list
->
event
,
"Supported"
,
"eventlist"
);
linphone_event_add_custom_header
(
list
->
event
,
"Accept"
,
"multipart/related, application/pidf+xml, application/rlmi+xml"
);
linphone_event_add_custom_header
(
list
->
event
,
"Content-Disposition"
,
"recipient-list"
);
content
=
linphone_core_create_content
(
list
->
lc
);
linphone_content_set_type
(
content
,
"application"
);
linphone_content_set_subtype
(
content
,
"resource-lists+xml"
);
linphone_content_set_string_buffer
(
content
,
xml_content
);
if
(
linphone_core_content_encoding_supported
(
list
->
lc
,
"deflate"
))
{
linphone_content_set_encoding
(
content
,
"deflate"
);
linphone_event_add_custom_header
(
list
->
event
,
"Accept-Encoding"
,
"deflate"
);
}
linphone_event_send_subscribe
(
list
->
event
,
content
);
linphone_content_unref
(
content
);
linphone_event_set_user_data
(
list
->
event
,
list
);
if
(
should_send_list_subscribe
){
linphone_friend_list_send_list_subscription
(
list
);
}
else
{
if
(
list
->
event
){
linphone_event_terminate
(
list
->
event
);
linphone_event_unref
(
list
->
event
);
list
->
event
=
NULL
;
ms_message
(
"Friends list [%p] subscription terminated because proxy config lost connection"
,
list
);
}
else
{
ms_message
(
"Friends list [%p] subscription update skipped since dependant proxy config is not yet registered"
,
list
);
}
}
if
(
address
!=
NULL
)
linphone_address_unref
(
address
);
if
(
xml_content
!=
NULL
)
ms_free
(
xml_content
);