presence_tester.c 41.7 KB
Newer Older
jehan's avatar
jehan committed
1
/*
Simon Morlat's avatar
Simon Morlat committed
2 3
    liblinphone_tester - liblinphone test suite
    Copyright (C) 2013  Belledonne Communications SARL
jehan's avatar
jehan committed
4 5 6

    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
Simon Morlat's avatar
Simon Morlat committed
7
    the Free Software Foundation, either version 2 of the License, or
jehan's avatar
jehan committed
8 9 10 11 12 13 14 15 16 17
    (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, see <http://www.gnu.org/licenses/>.
*/
Ghislain MARY's avatar
Ghislain MARY committed
18

19

jehan's avatar
jehan committed
20 21 22 23
#include "linphonecore.h"
#include "private.h"
#include "liblinphone_tester.h"

24 25
static void enable_publish(LinphoneCoreManager *mgr, bool_t enable);

jehan's avatar
jehan committed
26
static LinphoneCoreManager* presence_linphone_core_manager_new(char* username) {
Simon Morlat's avatar
Simon Morlat committed
27
	LinphoneCoreManager* mgr= linphone_core_manager_new2( "empty_rc", FALSE);
jehan's avatar
jehan committed
28 29 30 31 32
	char* identity_char;
	mgr->identity= linphone_core_get_primary_contact_parsed(mgr->lc);
	linphone_address_set_username(mgr->identity,username);
	identity_char=linphone_address_as_string(mgr->identity);
	linphone_core_set_primary_contact(mgr->lc,identity_char);
33
	ms_free(identity_char);
jehan's avatar
jehan committed
34 35
	return mgr;
}
36

37
void new_subscription_requested(LinphoneCore *lc, LinphoneFriend *lf, const char *url){
jehan's avatar
jehan committed
38
	char* from=linphone_address_as_string(linphone_friend_get_address(lf));
39
	stats* counters;
40
	ms_message("New subscription request from [%s] url [%s]",from,url);
jehan's avatar
jehan committed
41
	ms_free(from);
42
	counters = get_stats(lc);
jehan's avatar
jehan committed
43 44 45
	counters->number_of_NewSubscriptionRequest++;
	linphone_core_add_friend(lc,lf); /*accept subscription*/
}
Ghislain MARY's avatar
Ghislain MARY committed
46

jehan's avatar
jehan committed
47
void notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf) {
48
	stats* counters;
49
	LinphonePresenceActivity *activity = NULL;
jehan's avatar
jehan committed
50
	char* from=linphone_address_as_string(linphone_friend_get_address(lf));
Ghislain MARY's avatar
Ghislain MARY committed
51
	ms_message("New Notify request from [%s] ",from);
jehan's avatar
jehan committed
52
	ms_free(from);
53
	counters = get_stats(lc);
Ghislain MARY's avatar
Ghislain MARY committed
54
	counters->number_of_NotifyPresenceReceived++;
jehan's avatar
jehan committed
55

56
	counters->last_received_presence = linphone_friend_get_presence_model(lf);
57 58
	activity = linphone_presence_model_get_activity(counters->last_received_presence);
	switch (linphone_presence_activity_get_type(activity)) {
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
		case LinphonePresenceActivityOffline:
			counters->number_of_LinphonePresenceActivityOffline++; break;
		case LinphonePresenceActivityOnline:
			counters->number_of_LinphonePresenceActivityOnline++; break;
		case LinphonePresenceActivityAppointment:
			counters->number_of_LinphonePresenceActivityAppointment++; break;
		case LinphonePresenceActivityAway:
			counters->number_of_LinphonePresenceActivityAway++; break;
		case LinphonePresenceActivityBreakfast:
			counters->number_of_LinphonePresenceActivityBreakfast++; break;
		case LinphonePresenceActivityBusy:
			counters->number_of_LinphonePresenceActivityBusy++; break;
		case LinphonePresenceActivityDinner:
			counters->number_of_LinphonePresenceActivityDinner++; break;
		case LinphonePresenceActivityHoliday:
			counters->number_of_LinphonePresenceActivityHoliday++; break;
		case LinphonePresenceActivityInTransit:
			counters->number_of_LinphonePresenceActivityInTransit++; break;
		case LinphonePresenceActivityLookingForWork:
			counters->number_of_LinphonePresenceActivityLookingForWork++; break;
		case LinphonePresenceActivityLunch:
			counters->number_of_LinphonePresenceActivityLunch++; break;
		case LinphonePresenceActivityMeal:
			counters->number_of_LinphonePresenceActivityMeal++; break;
		case LinphonePresenceActivityMeeting:
			counters->number_of_LinphonePresenceActivityMeeting++; break;
		case LinphonePresenceActivityOnThePhone:
			counters->number_of_LinphonePresenceActivityOnThePhone++; break;
		case LinphonePresenceActivityOther:
			counters->number_of_LinphonePresenceActivityOther++; break;
		case LinphonePresenceActivityPerformance:
			counters->number_of_LinphonePresenceActivityPerformance++; break;
		case LinphonePresenceActivityPermanentAbsence:
			counters->number_of_LinphonePresenceActivityPermanentAbsence++; break;
		case LinphonePresenceActivityPlaying:
			counters->number_of_LinphonePresenceActivityPlaying++; break;
		case LinphonePresenceActivityPresentation:
			counters->number_of_LinphonePresenceActivityPresentation++; break;
		case LinphonePresenceActivityShopping:
			counters->number_of_LinphonePresenceActivityShopping++; break;
		case LinphonePresenceActivitySleeping:
			counters->number_of_LinphonePresenceActivitySleeping++; break;
		case LinphonePresenceActivitySpectator:
			counters->number_of_LinphonePresenceActivitySpectator++; break;
		case LinphonePresenceActivitySteering:
			counters->number_of_LinphonePresenceActivitySteering++; break;
		case LinphonePresenceActivityTravel:
			counters->number_of_LinphonePresenceActivityTravel++; break;
		case LinphonePresenceActivityTV:
			counters->number_of_LinphonePresenceActivityTV++; break;
		case LinphonePresenceActivityUnknown:
			counters->number_of_LinphonePresenceActivityUnknown++; break;
		case LinphonePresenceActivityVacation:
			counters->number_of_LinphonePresenceActivityVacation++; break;
		case LinphonePresenceActivityWorking:
			counters->number_of_LinphonePresenceActivityWorking++; break;
		case LinphonePresenceActivityWorship:
			counters->number_of_LinphonePresenceActivityWorship++; break;
jehan's avatar
jehan committed
117
	}
jehan's avatar
jehan committed
118 119
}

jehan's avatar
jehan committed
120
void wait_core(LinphoneCore *core) {
121 122 123 124 125 126 127 128
	int i;

	for (i = 0; i < 10; i++) {
		linphone_core_iterate(core);
		ms_usleep(100000);
	}
}

129
static void simple_publish_with_expire(int expires) {
Simon Morlat's avatar
Simon Morlat committed
130
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
jehan's avatar
jehan committed
131
	LinphoneProxyConfig* proxy;
132
	LinphonePresenceModel* presence;
133

134
	proxy = linphone_core_get_default_proxy_config(marie->lc);
jehan's avatar
jehan committed
135
	linphone_proxy_config_edit(proxy);
136 137 138
	if (expires >0) {
		linphone_proxy_config_set_publish_expires(proxy,expires);
	}
jehan's avatar
jehan committed
139 140
	linphone_proxy_config_enable_publish(proxy,TRUE);
	linphone_proxy_config_done(proxy);
141 142
	wait_core(marie->lc);
	presence =linphone_presence_model_new_with_activity(LinphonePresenceActivityOffline,NULL);
143
	linphone_core_set_presence_model(marie->lc,presence);
144
	wait_core(marie->lc);
jehan's avatar
jehan committed
145 146 147
	linphone_core_manager_destroy(marie);
}

148
static void simple_publish(void) {
149 150 151
	simple_publish_with_expire(-1);
}

152
static void publish_with_expires(void) {
153 154 155
	simple_publish_with_expire(1);
}

jehan's avatar
jehan committed
156 157 158 159
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;
	bool_t result=FALSE;
jehan's avatar
jehan committed
160
	char* identity=linphone_address_as_string_uri_only(callee_mgr->identity);
jehan's avatar
jehan committed
161 162


Ghislain MARY's avatar
Ghislain MARY committed
163
	LinphoneFriend* friend=linphone_friend_new_with_address(identity);
jehan's avatar
jehan committed
164 165 166 167 168
	linphone_friend_edit(friend);
	linphone_friend_enable_subscribes(friend,TRUE);
	linphone_friend_done(friend);

	linphone_core_add_friend(caller_mgr->lc,friend);
169
	linphone_friend_unref(friend);
jehan's avatar
jehan committed
170

jehan's avatar
jehan committed
171 172 173 174
	result=wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphonePresenceActivityOnline,initial_caller.number_of_LinphonePresenceActivityOnline+1);
	/*without proxy, callee cannot subscribe to caller
	result&=wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphonePresenceActivityOnline,initial_callee.number_of_LinphonePresenceActivityOnline+1);
	*/
jehan's avatar
jehan committed
175

176
	BC_ASSERT_EQUAL(callee_mgr->stat.number_of_NewSubscriptionRequest,initial_callee.number_of_NewSubscriptionRequest+1, int, "%d");
jehan's avatar
jehan committed
177
	/*without proxy, callee cannot subscribe to caller
Ghislain MARY's avatar
Ghislain MARY committed
178
	BC_ASSERT_EQUAL(callee_mgr->stat.number_of_NotifyPresenceReceived,initial_callee.number_of_NotifyPresenceReceived+1, int, "%d");
jehan's avatar
jehan committed
179
	*/
Ghislain MARY's avatar
Ghislain MARY committed
180
	BC_ASSERT_EQUAL(caller_mgr->stat.number_of_NotifyPresenceReceived,initial_caller.number_of_NotifyPresenceReceived+1, int, "%d");
jehan's avatar
jehan committed
181

jehan's avatar
jehan committed
182
	ms_free(identity);
jehan's avatar
jehan committed
183 184 185
	return result;

}
186 187
static void subscribe_failure_handle_by_app(void) {
	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
188
	LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_tcp_rc");
189 190 191
	LinphoneProxyConfig* config;
	LinphoneFriend* lf;
	char* lf_identity=linphone_address_as_string_uri_only(pauline->identity);
192
	
193
	config = linphone_core_get_default_proxy_config(marie->lc);
194

195
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline));
196 197 198 199
	wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,1); /*just to wait for unsubscription even if not notified*/

	sal_set_recv_error(marie->lc->sal, 0); /*simulate an error*/

200 201
	BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneRegistrationProgress,2));
	BC_ASSERT_EQUAL(linphone_proxy_config_get_error(config),LinphoneReasonIOError, int, "%d");
202 203 204 205 206 207
	sal_set_recv_error(marie->lc->sal, 1);

	lf = linphone_core_get_friend_by_address(marie->lc,lf_identity);
	linphone_friend_edit(lf);
	linphone_friend_enable_subscribes(lf,FALSE); /*disable subscription*/
	linphone_friend_done(lf);
208
	BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneRegistrationOk,2)); /*wait for register ok*/
209 210 211
	linphone_friend_edit(lf);
	linphone_friend_enable_subscribes(lf,TRUE);
	linphone_friend_done(lf);
212
	BC_ASSERT_FALSE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,2)); /*just to wait for unsubscription even if not notified*/
213 214

	linphone_core_manager_destroy(marie);
215
	BC_ASSERT_FALSE(wait_for(NULL,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,3)); /*just to wait for unsubscription even if not notified*/
216 217 218 219

	linphone_core_manager_destroy(pauline);
}

Ghislain MARY's avatar
Ghislain MARY committed
220
static void simple_subscribe(void) {
jehan's avatar
jehan committed
221 222
	LinphoneCoreManager* marie = presence_linphone_core_manager_new("marie");
	LinphoneCoreManager* pauline = presence_linphone_core_manager_new("pauline");
jehan's avatar
jehan committed
223

224
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline));
jehan's avatar
jehan committed
225

226

jehan's avatar
jehan committed
227
	linphone_core_manager_destroy(marie);
jehan's avatar
jehan committed
228
	/*unsubscribe is not reported ?*/
229
	BC_ASSERT_FALSE(wait_for(NULL,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,2)); /*just to wait for unsubscription even if not notified*/
jehan's avatar
jehan committed
230 231 232

	linphone_core_manager_destroy(pauline);
}
Ghislain MARY's avatar
Ghislain MARY committed
233 234

static void unsubscribe_while_subscribing(void) {
Simon Morlat's avatar
Simon Morlat committed
235
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
Ghislain MARY's avatar
Ghislain MARY committed
236
	LinphoneFriend* friend = linphone_friend_new_with_address("sip:toto@git.linphone.org"); /*any unexisting address*/
jehan's avatar
jehan committed
237 238 239 240
	linphone_friend_edit(friend);
	linphone_friend_enable_subscribes(friend,TRUE);
	linphone_friend_done(friend);
	linphone_core_add_friend(marie->lc,friend);
241
	linphone_friend_unref(friend);
jehan's avatar
jehan committed
242 243 244 245
	linphone_core_iterate(marie->lc);
	linphone_core_manager_destroy(marie);
}

246 247
#if 0
/* the core no longer changes the presence status when a call is ongoing, this is left to the application*/
jehan's avatar
jehan committed
248
static void call_with_presence(void) {
jehan's avatar
jehan committed
249 250
	LinphoneCoreManager* marie = presence_linphone_core_manager_new("marie");
	LinphoneCoreManager* pauline = presence_linphone_core_manager_new("pauline");
251 252
	LinphoneVideoPolicy pol={0};
	linphone_core_set_video_policy(marie->lc,&pol);
253 254
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline));
	BC_ASSERT_TRUE(subscribe_to_callee_presence(pauline,marie));
jehan's avatar
jehan committed
255

256 257 258
	BC_ASSERT_TRUE(call(marie,pauline));
	BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityOnThePhone,1));
	BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePresenceActivityOnThePhone,1));
jehan's avatar
jehan committed
259 260 261 262

	reset_counters(&marie->stat);
	reset_counters(&pauline->stat);
	linphone_core_terminate_all_calls(marie->lc);
263 264
	BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphonePresenceActivityOnline,1));
	BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityOnline,1));
jehan's avatar
jehan committed
265 266 267
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
Ghislain MARY's avatar
Ghislain MARY committed
268

269 270
#endif

271 272 273 274
static void presence_information(void) {
	const char *bike_description = "Riding my bike";
	const char *vacation_note = "I'm on vacation until July 4th";
	const char *vacation_lang = "en";
275
	const char *contact = "sip:toto@example.com";
276 277 278
	LinphoneCoreManager *marie = presence_linphone_core_manager_new("marie");
	LinphoneCoreManager *pauline = presence_linphone_core_manager_new("pauline");
	LinphonePresenceModel *presence;
279 280 281 282
	LinphonePresenceActivity *activity = NULL;
	LinphonePresenceNote *note = NULL;
	const char *description = NULL;
	const char *note_content = NULL;
283
	char *contact2;
284
	time_t current_timestamp, presence_timestamp;
285

286
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie, pauline));
287 288 289

	/* Presence activity without description. */
	presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityDinner, NULL);
290
	linphone_core_set_presence_model(pauline->lc, presence);
jehan's avatar
jehan committed
291
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityDinner,1);
292
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityDinner, 1, int, "%d");
293
	activity = linphone_presence_model_get_activity(marie->stat.last_received_presence);
294 295
	BC_ASSERT_PTR_NOT_NULL(activity);
	BC_ASSERT_EQUAL(linphone_presence_activity_get_type(activity), LinphonePresenceActivityDinner, int, "%d");
296
	description = linphone_presence_activity_get_description(activity);
297
	BC_ASSERT_PTR_NULL(description);
298 299 300

	/* Presence activity with description. */
	presence = linphone_presence_model_new_with_activity(LinphonePresenceActivitySteering, bike_description);
301
	linphone_core_set_presence_model(pauline->lc, presence);
jehan's avatar
jehan committed
302
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivitySteering,1);
303
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivitySteering, 1, int, "%d");
304
	activity = linphone_presence_model_get_activity(marie->stat.last_received_presence);
305 306
	BC_ASSERT_PTR_NOT_NULL(activity);
	BC_ASSERT_EQUAL(linphone_presence_activity_get_type(activity), LinphonePresenceActivitySteering, int, "%d");
307
	description = linphone_presence_activity_get_description(activity);
308
	BC_ASSERT_PTR_NOT_NULL(description);
309
	if (description != NULL) BC_ASSERT_STRING_EQUAL(description, bike_description);
310 311 312

	/* Presence activity with description and note. */
	presence = linphone_presence_model_new_with_activity_and_note(LinphonePresenceActivityVacation, NULL, vacation_note, vacation_lang);
313
	linphone_core_set_presence_model(pauline->lc, presence);
jehan's avatar
jehan committed
314
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityVacation,1);
315
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityVacation, 1, int, "%d");
316
	activity = linphone_presence_model_get_activity(marie->stat.last_received_presence);
317 318
	BC_ASSERT_PTR_NOT_NULL(activity);
	BC_ASSERT_EQUAL(linphone_presence_activity_get_type(activity), LinphonePresenceActivityVacation, int, "%d");
319
	description = linphone_presence_activity_get_description(activity);
320
	BC_ASSERT_PTR_NULL(description);
321
	note = linphone_presence_model_get_note(marie->stat.last_received_presence, NULL);
322
	BC_ASSERT_PTR_NOT_NULL(note);
323
	if (note != NULL) {
324
		note_content = linphone_presence_note_get_content(note);
325
		BC_ASSERT_PTR_NOT_NULL(note_content);
326
		if (note_content != NULL) {
327
			BC_ASSERT_STRING_EQUAL(note_content, vacation_note);
328
		}
329 330
	}

331 332 333 334
	/* Presence contact. */
	presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityOnThePhone, NULL);
	linphone_presence_model_set_contact(presence, contact);
	linphone_core_set_presence_model(pauline->lc, presence);
jehan's avatar
jehan committed
335
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityOnThePhone,1);
336
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityOnThePhone, 1, int, "%d");
337
	contact2 = linphone_presence_model_get_contact(presence);
338
	BC_ASSERT_PTR_NOT_NULL(contact2);
339
	if (contact2 != NULL) {
340
		BC_ASSERT_STRING_EQUAL(contact, contact2);
341 342 343
		ms_free(contact2);
	}

344
	/* Presence timestamp. */
345
	current_timestamp = ms_time(NULL);
346 347
	presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityShopping, NULL);
	linphone_core_set_presence_model(pauline->lc, presence);
jehan's avatar
jehan committed
348
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityShopping,1);
349
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityShopping, 1, int, "%d");
350
	presence_timestamp = linphone_presence_model_get_timestamp(presence);
351
	BC_ASSERT_GREATER((unsigned)presence_timestamp , (unsigned)current_timestamp, unsigned, "%u");
352

353 354 355
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
356 357


358
static void subscribe_presence_forked(void){
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
	LinphoneCoreManager* pauline1 = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
	LinphoneCoreManager* pauline2 = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
	LinphoneFriend *lf;
	MSList *lcs = NULL;
	
	lcs = ms_list_append(lcs, marie->lc);
	lcs = ms_list_append(lcs, pauline1->lc);
	lcs = ms_list_append(lcs, pauline2->lc);
	
	lf = linphone_core_create_friend(marie->lc);
	linphone_friend_set_address(lf, pauline1->identity);
	linphone_friend_enable_subscribes(lf, TRUE);
	
	linphone_core_add_friend(marie->lc, lf);
	linphone_friend_unref(lf);
	
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_NewSubscriptionRequest,1, 10000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline2->stat.number_of_NewSubscriptionRequest,1, 2000));
	/*we should get two notifies*/
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePresenceActivityOnline,2, 10000));
	
381 382 383 384 385 386 387
	/*marie also shall receive two SUBSCRIBEs from the two paulines, but won't be notified to the app since 
	 Marie set Pauline as a friend.*/
	BC_ASSERT_EQUAL(marie->stat.number_of_NewSubscriptionRequest, 0, int, "%d");
	/*and the two paulines shall be notified of marie's presence*/
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_LinphonePresenceActivityOnline,1, 3000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline2->stat.number_of_LinphonePresenceActivityOnline,1, 2000));
	
388 389 390 391 392 393 394
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline1);
	linphone_core_manager_destroy(pauline2);
	
	ms_list_free(lcs);
}

395
static void subscribe_presence_expired(void){
396 397
	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
	LinphoneCoreManager* pauline1 = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
Simon Morlat's avatar
Simon Morlat committed
398 399 400 401 402 403 404
	LinphoneFriend *lf;
	MSList *lcs = NULL;
	
	lcs = ms_list_append(lcs, marie->lc);
	lcs = ms_list_append(lcs, pauline1->lc);
	
	lp_config_set_int(marie->lc->config, "sip", "subscribe_expires", 10);
405

Simon Morlat's avatar
Simon Morlat committed
406 407 408 409 410 411 412 413 414
	lf = linphone_core_create_friend(marie->lc);
	linphone_friend_set_address(lf, pauline1->identity);
	linphone_friend_enable_subscribes(lf, TRUE);
	
	linphone_core_add_friend(marie->lc, lf);
	linphone_friend_unref(lf);
	BC_ASSERT_TRUE(wait_for_list(lcs,&pauline1->stat.number_of_NewSubscriptionRequest,1, 5000));
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePresenceActivityOnline,1, 2000));
	
415
	lf = linphone_core_find_friend(pauline1->lc, marie->identity);
Simon Morlat's avatar
Simon Morlat committed
416
	BC_ASSERT_PTR_NOT_NULL(lf->insubs);
417
	
Simon Morlat's avatar
Simon Morlat committed
418 419 420 421 422
	/*marie comes offline suddenly*/
	linphone_core_set_network_reachable(marie->lc, FALSE);
	/*after a certain time, pauline shall see the incoming SUBSCRIBE expired*/
	wait_for_list(lcs,NULL, 0, 11000);
	BC_ASSERT_PTR_NULL(lf->insubs);
423

424 425
	/*just make network reachable so that marie can unregister properly*/
	linphone_core_set_network_reachable(marie->lc, TRUE);
426
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneRegistrationOk,2, 10000));
Simon Morlat's avatar
Simon Morlat committed
427 428 429 430 431 432
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline1);
	
	ms_list_free(lcs);
}

433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479
static void subscriber_no_longuer_reachable(void){
	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
	LinphoneCoreManager* pauline1 = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
	LinphoneFriend *lf;
	MSList *lcs = NULL;
	LinphonePresenceModel * presence;
	
	lcs = ms_list_append(lcs, marie->lc);
	lcs = ms_list_append(lcs, pauline1->lc);
	
	lp_config_set_int(marie->lc->config, "sip", "subscribe_expires", 40);
	linphone_core_set_user_agent(marie->lc, "full-presence-support", NULL);
	linphone_core_set_user_agent(pauline1->lc, "full-presence-support", NULL);
	
	enable_publish(pauline1, TRUE);
	
	lf = linphone_core_create_friend(marie->lc);
	linphone_friend_set_address(lf, pauline1->identity);
	linphone_friend_enable_subscribes(lf, TRUE);
	
	linphone_core_add_friend(marie->lc, lf);
	linphone_friend_unref(lf);
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePresenceActivityOnline,1, 2000));
	
	
	presence =linphone_presence_model_new_with_activity(LinphonePresenceActivityBusy,NULL);
	linphone_core_set_presence_model(pauline1->lc,presence);

	/*don't schedule marie to simulate Notify timeout server side*/
	wait_for_until(pauline1->lc, NULL, 0, 0, 35000);
	
	//sal_set_send_error(marie->lc->sal,0);
	
	/*because of notify timeout detected by server, so subscription is reset*/
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePresenceActivityOffline,2, 4000));
	
	// now subscribetion is supposed to be dead because notify was not answered in time.
	presence =linphone_presence_model_new_with_activity(LinphonePresenceActivityOnline,NULL);
	linphone_core_set_presence_model(pauline1->lc,presence);
	
	/*becasue subscription is automatically restarted*/
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePresenceActivityOnline,2, 4000));
	
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline1);
	
	ms_list_free(lcs);
Simon Morlat's avatar
Simon Morlat committed
480

481
}
jehan's avatar
jehan committed
482 483 484 485 486 487 488 489

static void test_subscribe_notify_publish(void) {

	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
	LinphoneProxyConfig* proxy;
	LinphonePresenceModel* presence;

490 491
	linphone_core_set_user_agent(marie->lc, "full-presence-support", NULL);
	linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL);
jehan's avatar
jehan committed
492 493 494 495 496 497 498 499 500
	LpConfig *pauline_lp = linphone_core_get_config(pauline->lc);
	char* lf_identity=linphone_address_as_string_uri_only(marie->identity);
	LinphoneFriend *lf = linphone_core_create_friend_with_address(pauline->lc,lf_identity);

	lp_config_set_int(pauline_lp,"sip","subscribe_expires",5);

	linphone_core_add_friend(pauline->lc,lf);

	/*wait for subscribe acknowledgment*/
Ghislain MARY's avatar
Ghislain MARY committed
501
	wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_NotifyPresenceReceived,1,2000);
502
	BC_ASSERT_EQUAL(LinphoneStatusOffline,linphone_friend_get_status(lf), int, "%d");
jehan's avatar
jehan committed
503 504 505

	/*enable publish*/

506
	proxy = linphone_core_get_default_proxy_config(marie->lc);
jehan's avatar
jehan committed
507 508 509 510 511 512 513
	linphone_proxy_config_edit(proxy);

	linphone_proxy_config_enable_publish(proxy,TRUE);
	linphone_proxy_config_set_publish_expires(proxy,3);
	linphone_proxy_config_done(proxy);

	/*wait for marie status*/
Ghislain MARY's avatar
Ghislain MARY committed
514
	wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_NotifyPresenceReceived,2,2000);
515
	BC_ASSERT_EQUAL(LinphoneStatusOnline,linphone_friend_get_status(lf), int, "%d");
jehan's avatar
jehan committed
516

jehan's avatar
jehan committed
517
	presence =linphone_presence_model_new_with_activity(LinphonePresenceActivityBusy,NULL);
jehan's avatar
jehan committed
518 519 520
	linphone_core_set_presence_model(marie->lc,presence);

	/*wait for new status*/
Ghislain MARY's avatar
Ghislain MARY committed
521
	wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_NotifyPresenceReceived,3,2000);
522
	BC_ASSERT_EQUAL(LinphoneStatusBusy,linphone_friend_get_status(lf), int, "%d");
jehan's avatar
jehan committed
523 524

	/*wait for refresh*/
Ghislain MARY's avatar
Ghislain MARY committed
525
	wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_NotifyPresenceReceived,4,5000);
526
	BC_ASSERT_EQUAL(LinphoneStatusBusy,linphone_friend_get_status(lf), int, "%d");
jehan's avatar
jehan committed
527

jehan's avatar
jehan committed
528
	/*linphone_core_remove_friend(pauline->lc,lf);*/
jehan's avatar
jehan committed
529
	/*wait for final notify*/
Ghislain MARY's avatar
Ghislain MARY committed
530
	/*wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_NotifyPresenceReceived,4,5000);
531
	BC_ASSERT_EQUAL(LinphonePresenceActivityOffline,linphone_friend_get_status(lf), int, "%d");
jehan's avatar
jehan committed
532
	 */
jehan's avatar
jehan committed
533 534 535 536 537
	
	/*Expect a notify at publication expiration*/
	wait_for_until(pauline->lc,pauline->lc,&pauline->stat.number_of_NotifyPresenceReceived,6,5000);
	BC_ASSERT_EQUAL(LinphoneStatusOffline,linphone_friend_get_status(lf), int, "%d");
	
jehan's avatar
jehan committed
538 539 540 541 542 543 544 545 546 547
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
static void test_forked_subscribe_notify_publish(void) {

	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
	LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc");
	LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
	LinphoneProxyConfig* proxy;
	LinphonePresenceModel* presence;
548 549 550
	LpConfig *pauline_lp;
	char* lf_identity;
	LinphoneFriend *lf;
jehan's avatar
jehan committed
551 552 553 554
	MSList* lcs=ms_list_append(NULL,pauline->lc);
	lcs=ms_list_append(lcs,marie->lc);
	lcs=ms_list_append(lcs,marie->lc);
	lcs=ms_list_append(lcs,marie2->lc);
555 556 557
	linphone_core_set_user_agent(marie->lc, "full-presence-support", NULL);
	linphone_core_set_user_agent(marie2->lc, "full-presence-support", NULL);
	linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL);
jehan's avatar
jehan committed
558

559
	
560 561 562
	pauline_lp = linphone_core_get_config(pauline->lc);
	lf_identity=linphone_address_as_string_uri_only(marie->identity);
	lf = linphone_core_create_friend_with_address(pauline->lc,lf_identity);
jehan's avatar
jehan committed
563 564 565 566 567 568

	lp_config_set_int(pauline_lp,"sip","subscribe_expires",5);

	linphone_core_add_friend(pauline->lc,lf);

	/*wait for subscribe acknowledgment*/
Ghislain MARY's avatar
Ghislain MARY committed
569
	wait_for_list(lcs,&pauline->stat.number_of_NotifyPresenceReceived,1,2000);
570
	BC_ASSERT_EQUAL(LinphoneStatusOffline,linphone_friend_get_status(lf), int, "%d");
jehan's avatar
jehan committed
571 572 573

	/*enable publish*/

jehan's avatar
jehan committed
574
	proxy = linphone_core_get_default_proxy_config(marie->lc);
jehan's avatar
jehan committed
575 576 577 578 579
	linphone_proxy_config_edit(proxy);
	linphone_proxy_config_enable_publish(proxy,TRUE);
	linphone_proxy_config_set_publish_expires(proxy,3);
	linphone_proxy_config_done(proxy);

jehan's avatar
jehan committed
580
	proxy = linphone_core_get_default_proxy_config(marie2->lc);
jehan's avatar
jehan committed
581 582 583 584 585 586 587
	linphone_proxy_config_edit(proxy);
	linphone_proxy_config_enable_publish(proxy,TRUE);
	linphone_proxy_config_set_publish_expires(proxy,3);
	linphone_proxy_config_done(proxy);


	/*wait for marie status*/
Ghislain MARY's avatar
Ghislain MARY committed
588
	wait_for_list(lcs,&pauline->stat.number_of_NotifyPresenceReceived,3,2000);
589
	BC_ASSERT_EQUAL(LinphoneStatusOnline,linphone_friend_get_status(lf), int, "%d");
jehan's avatar
jehan committed
590 591 592 593 594

	presence =linphone_presence_model_new_with_activity(LinphonePresenceActivityBusy,NULL);
	linphone_core_set_presence_model(marie->lc,presence);

	/*wait for new status*/
Ghislain MARY's avatar
Ghislain MARY committed
595
	wait_for_list(lcs,&pauline->stat.number_of_NotifyPresenceReceived,4,2000);
596
	BC_ASSERT_EQUAL(LinphoneStatusBusy,linphone_friend_get_status(lf), int, "%d");
jehan's avatar
jehan committed
597 598 599 600 601


	presence =linphone_presence_model_new_with_activity(  LinphonePresenceActivityMeeting,NULL);
	linphone_core_set_presence_model(marie2->lc,presence);
	/*wait for new status*/
Ghislain MARY's avatar
Ghislain MARY committed
602
	wait_for_list(lcs,&pauline->stat.number_of_NotifyPresenceReceived,5,2000);
603 604
	BC_ASSERT_TRUE(LinphoneStatusBusy == linphone_friend_get_status(lf)
				   || LinphoneStatusDoNotDisturb == linphone_friend_get_status(lf)); /*because liblinphone compositor is very simple for now */
jehan's avatar
jehan committed
605 606

	linphone_core_manager_destroy(marie);
jehan's avatar
jehan committed
607
	linphone_core_manager_destroy(marie2);
jehan's avatar
jehan committed
608 609 610
	linphone_core_manager_destroy(pauline);
}

Ghislain MARY's avatar
Ghislain MARY committed
611 612 613 614 615 616 617 618 619
const char * get_identity(LinphoneCoreManager *mgr) {
	LinphoneProxyConfig *cfg = linphone_core_get_default_proxy_config(mgr->lc);
	return linphone_proxy_config_get_identity(cfg);
}

static void enable_publish(LinphoneCoreManager *mgr, bool_t enable) {
	LinphoneProxyConfig *cfg = linphone_core_get_default_proxy_config(mgr->lc);
	linphone_proxy_config_edit(cfg);
	linphone_proxy_config_enable_publish(cfg, enable);
Ghislain MARY's avatar
Ghislain MARY committed
620
	linphone_proxy_config_set_publish_expires(cfg, 60);
Ghislain MARY's avatar
Ghislain MARY committed
621 622 623 624 625 626 627 628 629 630 631 632 633 634
	linphone_proxy_config_done(cfg);
}

static void test_presence_list(void) {
	LinphoneCoreManager *laure = linphone_core_manager_new("laure_tcp_rc");
	LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
	LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc");
	const char *rls_uri = "sip:rls@sip.example.org";
	LinphoneFriendList *lfl;
	LinphoneFriend *lf;
	const char *laure_identity;
	const char *marie_identity;
	const char *pauline_identity;
	MSList* lcs = NULL;
Ghislain MARY's avatar
Ghislain MARY committed
635
	int dummy = 0;
Ghislain MARY's avatar
Ghislain MARY committed
636 637 638 639 640 641

	laure_identity = get_identity(laure);
	marie_identity = get_identity(marie);
	pauline_identity = get_identity(pauline);
	enable_publish(marie, TRUE);
	enable_publish(pauline, TRUE);
Ghislain MARY's avatar
Ghislain MARY committed
642
	enable_publish(laure, TRUE);
Ghislain MARY's avatar
Ghislain MARY committed
643 644 645 646 647 648 649 650 651 652 653 654 655

	linphone_core_set_presence_model(marie->lc, linphone_core_create_presence_model_with_activity(marie->lc, LinphonePresenceActivityBusy, NULL));
	linphone_core_set_presence_model(pauline->lc, linphone_core_create_presence_model_with_activity(pauline->lc, LinphonePresenceActivityVacation, NULL));

	lfl = linphone_core_create_friend_list(laure->lc);
	linphone_friend_list_set_rls_uri(lfl, rls_uri);
	lf = linphone_core_create_friend_with_address(laure->lc, marie_identity);
	linphone_friend_list_add_friend(lfl, lf);
	lf = linphone_core_create_friend_with_address(laure->lc, pauline_identity);
	linphone_friend_list_add_friend(lfl, lf);
	lf = linphone_core_create_friend_with_address(laure->lc, "sip:michelle@sip.inexistentdomain.com");
	linphone_friend_list_add_friend(lfl, lf);
	linphone_core_set_friend_list(laure->lc, lfl);
656
	linphone_friend_list_unref(lfl);
Ghislain MARY's avatar
Ghislain MARY committed
657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683
	linphone_core_set_presence_model(laure->lc, linphone_core_create_presence_model_with_activity(laure->lc, LinphonePresenceActivityOnline, NULL));

	lcs = ms_list_append(lcs, laure->lc);
	lcs = ms_list_append(lcs, marie->lc);
	lcs = ms_list_append(lcs, pauline->lc);

	wait_for_list(lcs, &laure->stat.number_of_NotifyPresenceReceived, 2, 2000);
	BC_ASSERT_EQUAL(laure->stat.number_of_NotifyPresenceReceived, 2, int, "%d");
	BC_ASSERT_EQUAL(laure->lc->friendlist->expected_notification_version, 1, int, "%d");
	lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, marie_identity);
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusBusy, int, "%d");
	BC_ASSERT_EQUAL(lf->presence_received, TRUE, int, "%d");
	BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");
	lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, pauline_identity);
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusVacation, int, "%d");
	BC_ASSERT_EQUAL(lf->presence_received, TRUE, int, "%d");
	BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");
	lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, "sip:michelle@sip.inexistentdomain.com");
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
	BC_ASSERT_EQUAL(lf->presence_received, FALSE, int, "%d");
	BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");

	lfl = linphone_core_create_friend_list(marie->lc);
	linphone_friend_list_set_rls_uri(lfl, rls_uri);
	lf = linphone_core_create_friend_with_address(marie->lc, laure_identity);
	linphone_friend_list_add_friend(lfl, lf);
	linphone_core_set_friend_list(marie->lc, lfl);
684
	linphone_friend_list_unref(lfl);
Ghislain MARY's avatar
Ghislain MARY committed
685
	linphone_friend_list_update_subscriptions(marie->lc->friendlist, NULL, FALSE);
Ghislain MARY's avatar
Ghislain MARY committed
686 687 688 689 690 691 692 693 694 695 696 697 698 699

	wait_for_list(lcs, &marie->stat.number_of_NotifyPresenceReceived, 1, 2000);
	BC_ASSERT_EQUAL(marie->stat.number_of_NotifyPresenceReceived, 1, int, "%d");
	BC_ASSERT_EQUAL(marie->lc->friendlist->expected_notification_version, 1, int, "%d");
	lf = linphone_friend_list_find_friend_by_uri(marie->lc->friendlist, laure_identity);
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnline, int, "%d");
	BC_ASSERT_EQUAL(lf->presence_received, TRUE, int, "%d");
	BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");

	lfl = linphone_core_create_friend_list(pauline->lc);
	linphone_friend_list_set_rls_uri(lfl, rls_uri);
	lf = linphone_core_create_friend_with_address(pauline->lc, marie_identity);
	linphone_friend_list_add_friend(lfl, lf);
	linphone_core_set_friend_list(pauline->lc, lfl);
700
	linphone_friend_list_unref(lfl);
Ghislain MARY's avatar
Ghislain MARY committed
701 702 703 704 705 706 707 708 709 710
	linphone_friend_list_update_subscriptions(pauline->lc->friendlist, NULL, FALSE);

	wait_for_list(lcs, &pauline->stat.number_of_NotifyPresenceReceived, 1, 2000);
	BC_ASSERT_EQUAL(pauline->stat.number_of_NotifyPresenceReceived, 1, int, "%d");
	BC_ASSERT_EQUAL(pauline->lc->friendlist->expected_notification_version, 1, int, "%d");
	lf = linphone_friend_list_find_friend_by_uri(pauline->lc->friendlist, marie_identity);
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusBusy, int, "%d");
	BC_ASSERT_EQUAL(lf->presence_received, TRUE, int, "%d");
	BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");

711 712 713
	linphone_core_set_presence_model(marie->lc, linphone_core_create_presence_model_with_activity(marie->lc, LinphonePresenceActivityOnThePhone, NULL));

	wait_for_list(lcs, &laure->stat.number_of_NotifyPresenceReceived, 4, 2000);
Ghislain MARY's avatar
Ghislain MARY committed
714 715 716
	/* The number of PresenceReceived events can be 3 or 4 here. TODO: ideally it should always be 3. */
	BC_ASSERT_GREATER(laure->stat.number_of_NotifyPresenceReceived, 3, int, "%d");
	BC_ASSERT_LOWER(laure->stat.number_of_NotifyPresenceReceived, 4, int, "%d");
717 718 719 720 721 722 723 724 725 726
	BC_ASSERT_EQUAL(laure->lc->friendlist->expected_notification_version, 2, int, "%d");
	lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, marie_identity);
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnThePhone, int, "%d");

	wait_for_list(lcs, &pauline->stat.number_of_NotifyPresenceReceived, 2, 2000);
	BC_ASSERT_EQUAL(pauline->stat.number_of_NotifyPresenceReceived, 2, int, "%d");
	BC_ASSERT_EQUAL(pauline->lc->friendlist->expected_notification_version, 2, int, "%d");
	lf = linphone_friend_list_find_friend_by_uri(pauline->lc->friendlist, marie_identity);
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnThePhone, int, "%d");

Ghislain MARY's avatar
Ghislain MARY committed
727 728 729 730
	enable_publish(laure, FALSE);
	enable_publish(marie, FALSE);
	enable_publish(pauline, FALSE);

Ghislain MARY's avatar
Ghislain MARY committed
731
	wait_for_list(lcs, &dummy, 1, 2000); /* Wait a little bit for the presence notifications. TODO: Wait for the correct number of PresenceReceived events. */
jehan's avatar
jehan committed
732 733 734
	
	lf = linphone_friend_list_find_friend_by_uri(pauline->lc->friendlist, marie_identity);
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
735 736 737
	lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, pauline_identity);
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
	lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, marie_identity);
jehan's avatar
jehan committed
738
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
739 740
	
	lf = linphone_friend_list_find_friend_by_uri(marie->lc->friendlist, laure_identity);
jehan's avatar
jehan committed
741 742
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
	
Ghislain MARY's avatar
Ghislain MARY committed
743 744 745 746 747
	linphone_core_manager_destroy(laure);
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}

748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768
static void test_presence_list_subscribe_before_publish(void) {
	LinphoneCoreManager *laure = linphone_core_manager_new("laure_tcp_rc");
	LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc");
	const char *rls_uri = "sip:rls@sip.example.org";
	LinphoneFriendList *lfl;
	LinphoneFriend *lf;
	const char *pauline_identity;
	MSList* lcs = NULL;
	int dummy = 0;

	pauline_identity = get_identity(pauline);

	linphone_core_set_presence_model(pauline->lc, linphone_core_create_presence_model_with_activity(pauline->lc, LinphonePresenceActivityVacation, NULL));

	lfl = linphone_core_create_friend_list(laure->lc);
	linphone_friend_list_set_rls_uri(lfl, rls_uri);
	lf = linphone_core_create_friend_with_address(laure->lc, pauline_identity);
	linphone_friend_list_add_friend(lfl, lf);
	lf = linphone_core_create_friend_with_address(laure->lc, "sip:michelle@sip.inexistentdomain.com");
	linphone_friend_list_add_friend(lfl, lf);
	linphone_core_set_friend_list(laure->lc, lfl);
769
	linphone_friend_list_unref(lfl);
770
	linphone_core_set_presence_model(laure->lc, linphone_core_create_presence_model_with_activity(laure->lc, LinphonePresenceActivityOnline, NULL));
Ghislain MARY's avatar
Ghislain MARY committed
771
	linphone_friend_list_update_subscriptions(laure->lc->friendlist, NULL, FALSE);
772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797

	lcs = ms_list_append(lcs, laure->lc);
	lcs = ms_list_append(lcs, pauline->lc);

	wait_for_list(lcs, &dummy, 1, 2000); /* Wait a little bit for the subscribe to happen */

	enable_publish(pauline, TRUE);
	wait_for_list(lcs, &pauline->stat.number_of_NotifyPresenceReceived, 1, 2000);
	BC_ASSERT_GREATER(laure->stat.number_of_NotifyPresenceReceived, 1, int, "%d");
	BC_ASSERT_GREATER(laure->lc->friendlist->expected_notification_version, 1, int, "%d");
	lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, pauline_identity);
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusVacation, int, "%d");
	BC_ASSERT_EQUAL(lf->presence_received, TRUE, int, "%d");
	BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");
	lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, "sip:michelle@sip.inexistentdomain.com");
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
	BC_ASSERT_EQUAL(lf->presence_received, FALSE, int, "%d");
	BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");

	enable_publish(laure, FALSE);
	enable_publish(pauline, FALSE);

	linphone_core_manager_destroy(laure);
	linphone_core_manager_destroy(pauline);
}

798
static void test_presence_list_subscription_expire_for_unknown(void) {
799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816
	LinphoneCoreManager *laure = linphone_core_manager_new("laure_tcp_rc");
	const char *rls_uri = "sip:rls@sip.example.org";
	LinphoneFriendList *lfl;
	LinphoneFriend *lf;
	lp_config_set_int(laure->lc->config, "sip", "rls_presence_expires", 3);
	
	lfl = linphone_core_create_friend_list(laure->lc);
	linphone_friend_list_set_rls_uri(lfl, rls_uri);
	lf = linphone_core_create_friend_with_address(laure->lc, "sip:michelle@sip.inexistentdomain.com");
	linphone_friend_list_add_friend(lfl, lf);
	linphone_core_set_friend_list(laure->lc, lfl);
	linphone_friend_list_update_subscriptions(lfl,NULL,FALSE);
	
	linphone_friend_list_unref(lfl);
	
	/* wait for refresh*/
	BC_ASSERT_FALSE(wait_for_until(laure->lc, NULL, &laure->stat.number_of_NotifyPresenceReceived, 1, 4000));
	
817 818
	linphone_core_manager_destroy(laure);
}
819

820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874
static void test_presence_list_subscribe_dialog_expire(void) {
	LinphoneCoreManager *laure = linphone_core_manager_new("laure_tcp_rc");
	LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc");
	const char *rls_uri = "sip:rls@sip.example.org";
	LinphoneFriendList *lfl;
	LinphoneFriend *lf;
	const char *pauline_identity;
	MSList* lcs = NULL;
	int dummy = 0;
	lp_config_set_int(laure->lc->config, "sip", "rls_presence_expires", 3);
	

	pauline_identity = get_identity(pauline);
	
	linphone_core_set_presence_model(pauline->lc, linphone_core_create_presence_model_with_activity(pauline->lc, LinphonePresenceActivityVacation, NULL));
	
	lfl = linphone_core_create_friend_list(laure->lc);
	linphone_friend_list_set_rls_uri(lfl, rls_uri);
	lf = linphone_core_create_friend_with_address(laure->lc, pauline_identity);
	linphone_friend_list_add_friend(lfl, lf);
	lf = linphone_core_create_friend_with_address(laure->lc, "sip:michelle@sip.inexistentdomain.com");
	linphone_friend_list_add_friend(lfl, lf);
	linphone_core_set_friend_list(laure->lc, lfl);
	linphone_friend_list_unref(lfl);
	linphone_core_set_presence_model(laure->lc, linphone_core_create_presence_model_with_activity(laure->lc, LinphonePresenceActivityOnline, NULL));
	linphone_friend_list_update_subscriptions(laure->lc->friendlist, NULL, FALSE);
	
	lcs = ms_list_append(lcs, laure->lc);
	lcs = ms_list_append(lcs, pauline->lc);
	
	wait_for_list(lcs, &dummy, 1, 2000); /* Wait a little bit for the subscribe to happen */
	
	enable_publish(pauline, TRUE);
	wait_for_list(lcs, &pauline->stat.number_of_NotifyPresenceReceived, 1, 2000);
	BC_ASSERT_GREATER(laure->stat.number_of_NotifyPresenceReceived, 1, int, "%d");
	BC_ASSERT_GREATER(laure->lc->friendlist->expected_notification_version, 1, int, "%d");
	lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, pauline_identity);
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusVacation, int, "%d");
	BC_ASSERT_EQUAL(lf->presence_received, TRUE, int, "%d");
	BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");
	lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, "sip:michelle@sip.inexistentdomain.com");
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
	BC_ASSERT_EQUAL(lf->presence_received, FALSE, int, "%d");
	BC_ASSERT_EQUAL(lf->subscribe_active, TRUE, int, "%d");
	
	BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_NotifyPresenceReceived, 2, 5000));
	ms_message("Simulating in/out packets losses");
	sal_set_send_error(laure->lc->sal,1500); /*make sure no refresh is sent, trash the message without generating error*/
	sal_set_recv_error(laure->lc->sal, 1500); /*make sure server notify to close the dialog is also ignored*/
	
	wait_for_list(lcs, &dummy, 1, 3000); /* Wait a little bit for the subscribe to happen */
	
	/*restart normal behavior*/
	sal_set_send_error(laure->lc->sal,0);
	sal_set_recv_error(laure->lc->sal, 1);
875
	
876 877 878 879 880 881
	
	linphone_core_set_presence_model(pauline->lc, linphone_core_create_presence_model_with_activity(pauline->lc, LinphonePresenceActivityAway, NULL));

	BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_NotifyPresenceReceived, 3, 5000));
	lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, pauline_identity);
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusAway, int, "%d");
882 883
	
	linphone_core_manager_destroy(laure);
884
	linphone_core_manager_destroy(pauline);
885 886 887
}


888

Ghislain MARY's avatar
Ghislain MARY committed
889
test_t presence_tests[] = {
890 891 892 893 894 895 896 897 898
	TEST_NO_TAG("Simple Subscribe", simple_subscribe),
	TEST_NO_TAG("Simple Publish", simple_publish),
	TEST_NO_TAG("Simple Publish with expires", publish_with_expires),
	/*TEST_NO_TAG("Call with presence", call_with_presence),*/
	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_NO_TAG("Presence SUBSCRIBE forked", subscribe_presence_forked),
	TEST_NO_TAG("Presence SUBSCRIBE expired", subscribe_presence_expired),
899
	TEST_NO_TAG("Subscriber no loguer reachable using server",subscriber_no_longuer_reachable),
900 901 902
	TEST_NO_TAG("Subscribe with late publish", test_subscribe_notify_publish),
	TEST_NO_TAG("Forked subscribe with late publish", test_forked_subscribe_notify_publish),
	TEST_NO_TAG("Presence list", test_presence_list),
903 904
	TEST_NO_TAG("Presence list, subscription expiration for unknown contact",test_presence_list_subscription_expire_for_unknown),
	TEST_NO_TAG("Presence list, silent subscription expiration", test_presence_list_subscribe_dialog_expire)
Ghislain MARY's avatar
Ghislain MARY committed
905 906
};

907
test_suite_t presence_test_suite = {"Presence", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,
908
									sizeof(presence_tests) / sizeof(presence_tests[0]), presence_tests};