mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 19:18:06 +00:00
update proxy config etag on status PublishOk. It allows PUBLISH to be consistent over network state changes, avoiding orphan tuples to remain server side.
This commit is contained in:
parent
6c7c56271a
commit
5a985ca79d
3 changed files with 174 additions and 108 deletions
|
|
@ -826,6 +826,13 @@ LinphoneAddress* linphone_proxy_config_normalize_sip_uri(LinphoneProxyConfig *pr
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void linphone_proxy_config_set_etag(LinphoneProxyConfig *cfg,const char* sip_etag) {
|
||||
if (cfg->sip_etag) ms_free(cfg->sip_etag);
|
||||
if (sip_etag)
|
||||
cfg->sip_etag = ms_strdup(sip_etag);
|
||||
else
|
||||
cfg->sip_etag = NULL;
|
||||
}
|
||||
/**
|
||||
* Commits modification made to the proxy configuration.
|
||||
**/
|
||||
|
|
@ -867,11 +874,7 @@ LinphoneStatus linphone_proxy_config_done(LinphoneProxyConfig *cfg)
|
|||
ms_message("Publish params have changed on proxy config [%p]",cfg);
|
||||
if (cfg->presence_publish_event) {
|
||||
if (cfg->publish) {
|
||||
const char * sip_etag = linphone_event_get_custom_header(cfg->presence_publish_event, "SIP-ETag");
|
||||
if (sip_etag) {
|
||||
if (cfg->sip_etag) ms_free(cfg->sip_etag);
|
||||
cfg->sip_etag = ms_strdup(sip_etag);
|
||||
}
|
||||
linphone_proxy_config_set_etag(cfg, linphone_event_get_custom_header(cfg->presence_publish_event, "SIP-ETag"));
|
||||
}
|
||||
/*publish is terminated*/
|
||||
linphone_event_terminate(cfg->presence_publish_event);
|
||||
|
|
@ -1542,9 +1545,22 @@ void linphone_proxy_config_set_nat_policy(LinphoneProxyConfig *cfg, LinphoneNatP
|
|||
}
|
||||
|
||||
void linphone_proxy_config_notify_publish_state_changed(LinphoneProxyConfig *cfg, LinphonePublishState state) {
|
||||
if ((cfg->presence_publish_event != NULL) && ((state == LinphonePublishCleared) || (state == LinphonePublishError))) {
|
||||
linphone_event_unref(cfg->presence_publish_event);
|
||||
cfg->presence_publish_event = NULL;
|
||||
|
||||
if (cfg->presence_publish_event != NULL) {
|
||||
switch (state) {
|
||||
case LinphonePublishCleared:
|
||||
linphone_proxy_config_set_etag(cfg,NULL);
|
||||
case LinphonePublishError:
|
||||
linphone_event_unref(cfg->presence_publish_event);
|
||||
cfg->presence_publish_event = NULL;
|
||||
break;
|
||||
case LinphonePublishOk:
|
||||
linphone_proxy_config_set_etag(cfg,linphone_event_get_custom_header(cfg->presence_publish_event, "SIP-ETag"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1571,8 +1571,157 @@ static void extended_notify_sub_unsub_sub2(void) {
|
|||
|
||||
bctbx_list_free(lcs);
|
||||
}
|
||||
static void simple_publish_with_expire(int expires) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneProxyConfig* proxy;
|
||||
LinphonePresenceModel* presence;
|
||||
LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());
|
||||
|
||||
linphone_core_cbs_set_publish_state_changed(cbs, linphone_publish_state_changed);
|
||||
_linphone_core_add_callbacks(marie->lc, cbs, TRUE);
|
||||
linphone_core_cbs_unref(cbs);
|
||||
|
||||
proxy = linphone_core_get_default_proxy_config(marie->lc);
|
||||
linphone_proxy_config_edit(proxy);
|
||||
if (expires > 0) {
|
||||
linphone_proxy_config_set_publish_expires(proxy,expires);
|
||||
}
|
||||
linphone_proxy_config_enable_publish(proxy,TRUE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,1));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,1));
|
||||
|
||||
presence = linphone_presence_model_new();
|
||||
linphone_presence_model_set_basic_status(presence, LinphonePresenceBasicStatusClosed);
|
||||
linphone_core_set_presence_model(marie->lc,presence);
|
||||
linphone_presence_model_unref(presence);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,2));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,2));
|
||||
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_done(proxy);
|
||||
/*make sure no publish is sent*/
|
||||
BC_ASSERT_FALSE(wait_for_until(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3,2000));
|
||||
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_enable_publish(proxy,FALSE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
|
||||
|
||||
/*fixme PUBLISH state machine is too simple, clear state should only be propagated at API level when 200ok is received*/
|
||||
/*BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3));*/
|
||||
wait_for_until(marie->lc,marie->lc,NULL,0,2000);
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishCleared,1));
|
||||
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_enable_publish(proxy,TRUE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,3));
|
||||
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_set_publish_expires(proxy, linphone_proxy_config_get_publish_expires(proxy)+1);
|
||||
linphone_proxy_config_done(proxy);
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,4));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,4));
|
||||
|
||||
linphone_core_manager_stop(marie);
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishCleared,3,int,"%i"); /*yes it is 3 because when we change the expires, a new LinphoneEvent is created*/
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,4,int,"%i");
|
||||
linphone_core_manager_destroy(marie);
|
||||
}
|
||||
|
||||
static void simple_publish(void) {
|
||||
simple_publish_with_expire(-1);
|
||||
}
|
||||
|
||||
static void publish_with_expires(void) {
|
||||
simple_publish_with_expire(2);
|
||||
}
|
||||
|
||||
static void publish_with_dual_identity(void) {
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new("multi_account_rc");
|
||||
const bctbx_list_t* proxies;
|
||||
LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());
|
||||
|
||||
linphone_core_cbs_set_publish_state_changed(cbs, linphone_publish_state_changed);
|
||||
_linphone_core_add_callbacks(pauline->lc, cbs, TRUE);
|
||||
linphone_core_cbs_unref(cbs);
|
||||
|
||||
for (proxies = linphone_core_get_proxy_config_list(pauline->lc); proxies!=NULL; proxies = proxies->next) {
|
||||
LinphoneProxyConfig *proxy = (LinphoneProxyConfig *) proxies->data;
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_enable_publish(proxy,TRUE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
}
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishProgress,4));
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishOk,4));
|
||||
|
||||
linphone_core_manager_stop(pauline);
|
||||
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishCleared,4,int,"%i");
|
||||
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishOk,4,int,"%i");
|
||||
linphone_core_manager_destroy(pauline);
|
||||
|
||||
}
|
||||
static void publish_with_network_state_changes(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
|
||||
LinphoneFriend* marie_as_friend = linphone_core_create_friend_with_address(pauline->lc, get_identity(marie));
|
||||
|
||||
LinphoneProxyConfig* proxy;
|
||||
LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());
|
||||
|
||||
linphone_core_cbs_set_publish_state_changed(cbs, linphone_publish_state_changed);
|
||||
_linphone_core_add_callbacks(marie->lc, cbs,TRUE);
|
||||
linphone_core_cbs_unref(cbs);
|
||||
|
||||
linphone_core_set_user_agent(marie->lc, "full-presence-support", NULL);
|
||||
linphone_core_set_user_agent(marie->lc, "full-presence-support-bypass", NULL);
|
||||
|
||||
proxy = linphone_core_get_default_proxy_config(marie->lc);
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_enable_publish(proxy,TRUE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,1));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,1));
|
||||
|
||||
linphone_core_set_network_reachable(marie->lc, FALSE);
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphoneRegistrationNone,1));
|
||||
BC_ASSERT_FALSE(wait_for_until(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,2,1000));
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,1,int,"%i");
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishError,0,int,"%i");
|
||||
|
||||
linphone_core_set_network_reachable(marie->lc, TRUE);
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,2));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,2));
|
||||
|
||||
|
||||
|
||||
linphone_core_manager_stop(marie);
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishCleared,1,int,"%i"); /*yes it is 3 because when we change the expires, a new LinphoneEvent is created*/
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,2,int,"%i");
|
||||
linphone_core_manager_destroy(marie);
|
||||
|
||||
/*make sure there is no remaining publish caused by network failure*/
|
||||
linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL);
|
||||
linphone_core_set_user_agent(pauline->lc, "full-presence-support-bypass", NULL);
|
||||
linphone_core_add_friend(pauline->lc, marie_as_friend);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,pauline->lc,&pauline->stat.number_of_LinphonePresenceActivityAway,1));
|
||||
linphone_friend_unref(marie_as_friend);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
|
||||
}
|
||||
|
||||
test_t presence_server_tests[] = {
|
||||
TEST_NO_TAG("Simple Publish", simple_publish),
|
||||
TEST_NO_TAG("Publish with 2 identities", publish_with_dual_identity),
|
||||
TEST_NO_TAG("Simple Publish with expires", publish_with_expires),
|
||||
TEST_ONE_TAG("Publish with network state changes", publish_with_network_state_changes, "presence"),
|
||||
TEST_NO_TAG("Simple", simple),
|
||||
TEST_NO_TAG("Fast activity change", fast_activity_change),
|
||||
TEST_NO_TAG("Forked subscribe with late publish", test_forked_subscribe_notify_publish),
|
||||
|
|
|
|||
|
|
@ -142,101 +142,6 @@ void notify_presence_received_for_uri_or_tel(LinphoneCore *lc, LinphoneFriend *l
|
|||
counters->number_of_NotifyPresenceReceivedForUriOrTel++;
|
||||
}
|
||||
|
||||
static void simple_publish_with_expire(int expires) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneProxyConfig* proxy;
|
||||
LinphonePresenceModel* presence;
|
||||
LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());
|
||||
|
||||
linphone_core_cbs_set_publish_state_changed(cbs, linphone_publish_state_changed);
|
||||
_linphone_core_add_callbacks(marie->lc, cbs, TRUE);
|
||||
linphone_core_cbs_unref(cbs);
|
||||
|
||||
proxy = linphone_core_get_default_proxy_config(marie->lc);
|
||||
linphone_proxy_config_edit(proxy);
|
||||
if (expires > 0) {
|
||||
linphone_proxy_config_set_publish_expires(proxy,expires);
|
||||
}
|
||||
linphone_proxy_config_enable_publish(proxy,TRUE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,1));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,1));
|
||||
|
||||
presence = linphone_presence_model_new();
|
||||
linphone_presence_model_set_basic_status(presence, LinphonePresenceBasicStatusClosed);
|
||||
linphone_core_set_presence_model(marie->lc,presence);
|
||||
linphone_presence_model_unref(presence);
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,2));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,2));
|
||||
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_done(proxy);
|
||||
/*make sure no publish is sent*/
|
||||
BC_ASSERT_FALSE(wait_for_until(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3,2000));
|
||||
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_enable_publish(proxy,FALSE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
|
||||
|
||||
/*fixme PUBLISH state machine is too simple, clear state should only be propagated at API level when 200ok is received*/
|
||||
/*BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3));*/
|
||||
wait_for_until(marie->lc,marie->lc,NULL,0,2000);
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishCleared,1));
|
||||
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_enable_publish(proxy,TRUE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,3));
|
||||
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_set_publish_expires(proxy, linphone_proxy_config_get_publish_expires(proxy)+1);
|
||||
linphone_proxy_config_done(proxy);
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,4));
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishOk,4));
|
||||
|
||||
linphone_core_manager_stop(marie);
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishCleared,3,int,"%i"); /*yes it is 3 because when we change the expires, a new LinphoneEvent is created*/
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,4,int,"%i");
|
||||
linphone_core_manager_destroy(marie);
|
||||
}
|
||||
|
||||
static void simple_publish(void) {
|
||||
simple_publish_with_expire(-1);
|
||||
}
|
||||
|
||||
static void publish_with_expires(void) {
|
||||
simple_publish_with_expire(2);
|
||||
}
|
||||
|
||||
static void publish_with_dual_identity(void) {
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new("multi_account_rc");
|
||||
const bctbx_list_t* proxies;
|
||||
LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());
|
||||
|
||||
linphone_core_cbs_set_publish_state_changed(cbs, linphone_publish_state_changed);
|
||||
_linphone_core_add_callbacks(pauline->lc, cbs, TRUE);
|
||||
linphone_core_cbs_unref(cbs);
|
||||
|
||||
for (proxies = linphone_core_get_proxy_config_list(pauline->lc); proxies!=NULL; proxies = proxies->next) {
|
||||
LinphoneProxyConfig *proxy = (LinphoneProxyConfig *) proxies->data;
|
||||
linphone_proxy_config_edit(proxy);
|
||||
linphone_proxy_config_enable_publish(proxy,TRUE);
|
||||
linphone_proxy_config_done(proxy);
|
||||
}
|
||||
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishProgress,4));
|
||||
BC_ASSERT_TRUE(wait_for(pauline->lc,pauline->lc,&pauline->stat.number_of_LinphonePublishOk,4));
|
||||
|
||||
linphone_core_manager_stop(pauline);
|
||||
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishCleared,4,int,"%i");
|
||||
BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePublishOk,4,int,"%i");
|
||||
linphone_core_manager_destroy(pauline);
|
||||
|
||||
}
|
||||
static bool_t subscribe_to_callee_presence(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr) {
|
||||
stats initial_caller=caller_mgr->stat;
|
||||
stats initial_callee=callee_mgr->stat;
|
||||
|
|
@ -640,14 +545,10 @@ test_t presence_tests[] = {
|
|||
TEST_ONE_TAG("Simple Subscribe", simple_subscribe,"presence"),
|
||||
TEST_ONE_TAG("Simple Subscribe with early NOTIFY", simple_subscribe_with_early_notify,"presence"),
|
||||
TEST_NO_TAG("Simple Subscribe with friend from rc", simple_subscribe_with_friend_from_rc),
|
||||
TEST_NO_TAG("Simple Publish", simple_publish),
|
||||
TEST_NO_TAG("Publish with 2 identities", publish_with_dual_identity),
|
||||
TEST_NO_TAG("Simple Publish with expires", publish_with_expires),
|
||||
TEST_ONE_TAG("Publish with network state changes", publish_with_network_state_changes, "presence"),
|
||||
/*TEST_ONE_TAG("Call with presence", call_with_presence, "LeaksMemory"),*/
|
||||
TEST_NO_TAG("Unsubscribe while subscribing", unsubscribe_while_subscribing),
|
||||
TEST_NO_TAG("Presence information", presence_information),
|
||||
TEST_NO_TAG("App managed presence failure", subscribe_failure_handle_by_app),
|
||||
TEST_ONE_TAG("App managed presence failure", subscribe_failure_handle_by_app, "LeaksMemory"),
|
||||
TEST_NO_TAG("Presence SUBSCRIBE forked", subscribe_presence_forked),
|
||||
TEST_NO_TAG("Presence SUBSCRIBE expired", subscribe_presence_expired),
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue