presence_tester.c 45.4 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 135 136
	LinphoneCoreVTable *vtable = linphone_core_v_table_new();
	vtable->publish_state_changed = linphone_publish_state_changed;
	_linphone_core_add_listener(marie->lc, vtable, TRUE, TRUE );
	
137
	proxy = linphone_core_get_default_proxy_config(marie->lc);
jehan's avatar
jehan committed
138
	linphone_proxy_config_edit(proxy);
139 140 141
	if (expires >0) {
		linphone_proxy_config_set_publish_expires(proxy,expires);
	}
jehan's avatar
jehan committed
142 143
	linphone_proxy_config_enable_publish(proxy,TRUE);
	linphone_proxy_config_done(proxy);
144 145 146 147
	
	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));
	
148
	presence =linphone_presence_model_new_with_activity(LinphonePresenceActivityOffline,NULL);
149
	linphone_core_set_presence_model(marie->lc,presence);
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
	
	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,expires*1000/2));

	linphone_proxy_config_edit(proxy);
	linphone_proxy_config_enable_publish(proxy,FALSE);
	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_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));

jehan's avatar
jehan committed
178
	linphone_core_manager_destroy(marie);
179 180 181
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishCleared,2,int,"%i");
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,4,int,"%i");

jehan's avatar
jehan committed
182 183
}

184
static void simple_publish(void) {
185 186 187
	simple_publish_with_expire(-1);
}

188
static void publish_with_expires(void) {
189
	simple_publish_with_expire(2);
190 191
}

jehan's avatar
jehan committed
192 193 194 195
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
196
	char* identity=linphone_address_as_string_uri_only(callee_mgr->identity);
jehan's avatar
jehan committed
197 198


Ghislain MARY's avatar
Ghislain MARY committed
199
	LinphoneFriend* friend=linphone_friend_new_with_address(identity);
jehan's avatar
jehan committed
200 201 202 203 204
	linphone_friend_edit(friend);
	linphone_friend_enable_subscribes(friend,TRUE);
	linphone_friend_done(friend);

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

jehan's avatar
jehan committed
207 208 209 210
	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
211

212
	BC_ASSERT_EQUAL(callee_mgr->stat.number_of_NewSubscriptionRequest,initial_callee.number_of_NewSubscriptionRequest+1, int, "%d");
jehan's avatar
jehan committed
213
	/*without proxy, callee cannot subscribe to caller
Ghislain MARY's avatar
Ghislain MARY committed
214
	BC_ASSERT_EQUAL(callee_mgr->stat.number_of_NotifyPresenceReceived,initial_callee.number_of_NotifyPresenceReceived+1, int, "%d");
jehan's avatar
jehan committed
215
	*/
Ghislain MARY's avatar
Ghislain MARY committed
216
	BC_ASSERT_EQUAL(caller_mgr->stat.number_of_NotifyPresenceReceived,initial_caller.number_of_NotifyPresenceReceived+1, int, "%d");
jehan's avatar
jehan committed
217

jehan's avatar
jehan committed
218
	ms_free(identity);
jehan's avatar
jehan committed
219 220 221
	return result;

}
222 223
static void subscribe_failure_handle_by_app(void) {
	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
224
	LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_tcp_rc");
225 226 227
	LinphoneProxyConfig* config;
	LinphoneFriend* lf;
	char* lf_identity=linphone_address_as_string_uri_only(pauline->identity);
228
	
229
	config = linphone_core_get_default_proxy_config(marie->lc);
230

231
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline));
232 233 234 235
	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*/

236 237
	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");
238 239 240 241 242 243
	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);
244
	BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneRegistrationOk,2)); /*wait for register ok*/
245 246 247
	linphone_friend_edit(lf);
	linphone_friend_enable_subscribes(lf,TRUE);
	linphone_friend_done(lf);
248
	BC_ASSERT_FALSE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,2)); /*just to wait for unsubscription even if not notified*/
249 250

	linphone_core_manager_destroy(marie);
251
	BC_ASSERT_FALSE(wait_for(NULL,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,3)); /*just to wait for unsubscription even if not notified*/
252 253 254 255

	linphone_core_manager_destroy(pauline);
}

Ghislain MARY's avatar
Ghislain MARY committed
256
static void simple_subscribe(void) {
jehan's avatar
jehan committed
257 258
	LinphoneCoreManager* marie = presence_linphone_core_manager_new("marie");
	LinphoneCoreManager* pauline = presence_linphone_core_manager_new("pauline");
jehan's avatar
jehan committed
259

260
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline));
jehan's avatar
jehan committed
261

262

jehan's avatar
jehan committed
263
	linphone_core_manager_destroy(marie);
jehan's avatar
jehan committed
264
	/*unsubscribe is not reported ?*/
265
	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
266 267 268

	linphone_core_manager_destroy(pauline);
}
Ghislain MARY's avatar
Ghislain MARY committed
269 270

static void unsubscribe_while_subscribing(void) {
Simon Morlat's avatar
Simon Morlat committed
271
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
Ghislain MARY's avatar
Ghislain MARY committed
272
	LinphoneFriend* friend = linphone_friend_new_with_address("sip:toto@git.linphone.org"); /*any unexisting address*/
jehan's avatar
jehan committed
273 274 275 276
	linphone_friend_edit(friend);
	linphone_friend_enable_subscribes(friend,TRUE);
	linphone_friend_done(friend);
	linphone_core_add_friend(marie->lc,friend);
277
	linphone_friend_unref(friend);
jehan's avatar
jehan committed
278 279 280 281
	linphone_core_iterate(marie->lc);
	linphone_core_manager_destroy(marie);
}

282 283
#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
284
static void call_with_presence(void) {
jehan's avatar
jehan committed
285 286
	LinphoneCoreManager* marie = presence_linphone_core_manager_new("marie");
	LinphoneCoreManager* pauline = presence_linphone_core_manager_new("pauline");
287 288
	LinphoneVideoPolicy pol={0};
	linphone_core_set_video_policy(marie->lc,&pol);
289 290
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline));
	BC_ASSERT_TRUE(subscribe_to_callee_presence(pauline,marie));
jehan's avatar
jehan committed
291

292 293 294
	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
295 296 297 298

	reset_counters(&marie->stat);
	reset_counters(&pauline->stat);
	linphone_core_terminate_all_calls(marie->lc);
299 300
	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
301 302 303
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
Ghislain MARY's avatar
Ghislain MARY committed
304

305 306
#endif

307 308 309 310
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";
311
	const char *contact = "sip:toto@example.com";
312 313 314
	LinphoneCoreManager *marie = presence_linphone_core_manager_new("marie");
	LinphoneCoreManager *pauline = presence_linphone_core_manager_new("pauline");
	LinphonePresenceModel *presence;
315 316 317 318
	LinphonePresenceActivity *activity = NULL;
	LinphonePresenceNote *note = NULL;
	const char *description = NULL;
	const char *note_content = NULL;
319
	char *contact2;
320
	time_t current_timestamp, presence_timestamp;
321

322
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie, pauline));
323 324 325

	/* Presence activity without description. */
	presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityDinner, NULL);
326
	linphone_core_set_presence_model(pauline->lc, presence);
jehan's avatar
jehan committed
327
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityDinner,1);
328
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityDinner, 1, int, "%d");
329
	activity = linphone_presence_model_get_activity(marie->stat.last_received_presence);
330 331
	BC_ASSERT_PTR_NOT_NULL(activity);
	BC_ASSERT_EQUAL(linphone_presence_activity_get_type(activity), LinphonePresenceActivityDinner, int, "%d");
332
	description = linphone_presence_activity_get_description(activity);
333
	BC_ASSERT_PTR_NULL(description);
334 335 336

	/* Presence activity with description. */
	presence = linphone_presence_model_new_with_activity(LinphonePresenceActivitySteering, bike_description);
337
	linphone_core_set_presence_model(pauline->lc, presence);
jehan's avatar
jehan committed
338
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivitySteering,1);
339
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivitySteering, 1, int, "%d");
340
	activity = linphone_presence_model_get_activity(marie->stat.last_received_presence);
341 342
	BC_ASSERT_PTR_NOT_NULL(activity);
	BC_ASSERT_EQUAL(linphone_presence_activity_get_type(activity), LinphonePresenceActivitySteering, int, "%d");
343
	description = linphone_presence_activity_get_description(activity);
344
	BC_ASSERT_PTR_NOT_NULL(description);
345
	if (description != NULL) BC_ASSERT_STRING_EQUAL(description, bike_description);
346 347 348

	/* Presence activity with description and note. */
	presence = linphone_presence_model_new_with_activity_and_note(LinphonePresenceActivityVacation, NULL, vacation_note, vacation_lang);
349
	linphone_core_set_presence_model(pauline->lc, presence);
jehan's avatar
jehan committed
350
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityVacation,1);
351
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityVacation, 1, int, "%d");
352
	activity = linphone_presence_model_get_activity(marie->stat.last_received_presence);
353 354
	BC_ASSERT_PTR_NOT_NULL(activity);
	BC_ASSERT_EQUAL(linphone_presence_activity_get_type(activity), LinphonePresenceActivityVacation, int, "%d");
355
	description = linphone_presence_activity_get_description(activity);
356
	BC_ASSERT_PTR_NULL(description);
357
	note = linphone_presence_model_get_note(marie->stat.last_received_presence, NULL);
358
	BC_ASSERT_PTR_NOT_NULL(note);
359
	if (note != NULL) {
360
		note_content = linphone_presence_note_get_content(note);
361
		BC_ASSERT_PTR_NOT_NULL(note_content);
362
		if (note_content != NULL) {
363
			BC_ASSERT_STRING_EQUAL(note_content, vacation_note);
364
		}
365 366
	}

367 368 369 370
	/* 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
371
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityOnThePhone,1);
372
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityOnThePhone, 1, int, "%d");
373
	contact2 = linphone_presence_model_get_contact(presence);
374
	BC_ASSERT_PTR_NOT_NULL(contact2);
375
	if (contact2 != NULL) {
376
		BC_ASSERT_STRING_EQUAL(contact, contact2);
377 378 379
		ms_free(contact2);
	}

380
	/* Presence timestamp. */
381
	current_timestamp = ms_time(NULL);
382 383
	presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityShopping, NULL);
	linphone_core_set_presence_model(pauline->lc, presence);
jehan's avatar
jehan committed
384
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityShopping,1);
385
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityShopping, 1, int, "%d");
386
	presence_timestamp = linphone_presence_model_get_timestamp(presence);
387
	BC_ASSERT_GREATER((unsigned)presence_timestamp , (unsigned)current_timestamp, unsigned, "%u");
388

389 390 391
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
392 393


394
static void subscribe_presence_forked(void){
395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416
	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));
	
417 418 419 420 421 422 423
	/*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));
	
424 425 426 427 428 429 430
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline1);
	linphone_core_manager_destroy(pauline2);
	
	ms_list_free(lcs);
}

431
static void subscribe_presence_expired(void){
432 433
	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
434 435 436 437 438 439 440
	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);
441

Simon Morlat's avatar
Simon Morlat committed
442 443 444 445 446 447 448 449 450
	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));
	
451
	lf = linphone_core_find_friend(pauline1->lc, marie->identity);
Simon Morlat's avatar
Simon Morlat committed
452
	BC_ASSERT_PTR_NOT_NULL(lf->insubs);
453
	
Simon Morlat's avatar
Simon Morlat committed
454 455 456 457 458
	/*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);
459

460 461
	/*just make network reachable so that marie can unregister properly*/
	linphone_core_set_network_reachable(marie->lc, TRUE);
462
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneRegistrationOk,2, 10000));
Simon Morlat's avatar
Simon Morlat committed
463 464 465 466 467 468
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline1);
	
	ms_list_free(lcs);
}

469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515
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
516

517
}
jehan's avatar
jehan committed
518 519 520 521 522 523 524

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;
buildbot's avatar
buildbot committed
525 526 527
	LpConfig *pauline_lp;
	char* lf_identity;
 	LinphoneFriend *lf;
528
	
529 530
	linphone_core_set_user_agent(marie->lc, "full-presence-support", NULL);
	linphone_core_set_user_agent(pauline->lc, "full-presence-support", NULL);
buildbot's avatar
buildbot committed
531 532 533
	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
534 535 536 537 538 539

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

	linphone_core_add_friend(pauline->lc,lf);

	/*wait for subscribe acknowledgment*/
540
	BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_NotifyPresenceReceived,1,2000));
541
	BC_ASSERT_EQUAL(LinphoneStatusOffline,linphone_friend_get_status(lf), int, "%d");
jehan's avatar
jehan committed
542 543 544

	/*enable publish*/

545
	proxy = linphone_core_get_default_proxy_config(marie->lc);
jehan's avatar
jehan committed
546 547 548 549 550 551 552
	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*/
553
	BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_NotifyPresenceReceived,2,2000));
554
	BC_ASSERT_EQUAL(LinphoneStatusOnline,linphone_friend_get_status(lf), int, "%d");
jehan's avatar
jehan committed
555

jehan's avatar
jehan committed
556
	presence =linphone_presence_model_new_with_activity(LinphonePresenceActivityBusy,NULL);
jehan's avatar
jehan committed
557 558 559
	linphone_core_set_presence_model(marie->lc,presence);

	/*wait for new status*/
560
	BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_NotifyPresenceReceived,3,2000));
561
	BC_ASSERT_EQUAL(LinphoneStatusBusy,linphone_friend_get_status(lf), int, "%d");
jehan's avatar
jehan committed
562 563

	/*wait for refresh*/
564
	BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_NotifyPresenceReceived,4,5000));
565
	BC_ASSERT_EQUAL(LinphoneStatusBusy,linphone_friend_get_status(lf), int, "%d");
jehan's avatar
jehan committed
566

jehan's avatar
jehan committed
567
	/*linphone_core_remove_friend(pauline->lc,lf);*/
jehan's avatar
jehan committed
568
	/*wait for final notify*/
Ghislain MARY's avatar
Ghislain MARY committed
569
	/*wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_NotifyPresenceReceived,4,5000);
570
	BC_ASSERT_EQUAL(LinphonePresenceActivityOffline,linphone_friend_get_status(lf), int, "%d");
jehan's avatar
jehan committed
571
	 */
jehan's avatar
jehan committed
572
	
573 574
	/*Expect a notify at publication expiration because marie is no longuer scheduled*/
	BC_ASSERT_TRUE(wait_for_until(pauline->lc,pauline->lc,&pauline->stat.number_of_NotifyPresenceReceived,6,5000));
jehan's avatar
jehan committed
575 576
	BC_ASSERT_EQUAL(LinphoneStatusOffline,linphone_friend_get_status(lf), int, "%d");
	
577 578 579 580 581 582 583 584 585 586 587 588 589 590
	BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphonePresenceActivityBusy,4,5000));/*re- schedule marie to clean up things*/
	
	/*simulate a rapid presence change to make sure only first and last are transmited*/
	linphone_core_set_presence_model(marie->lc,linphone_presence_model_new_with_activity(LinphonePresenceActivityAway,NULL));
	linphone_core_set_presence_model(marie->lc,linphone_presence_model_new_with_activity(LinphonePresenceActivityBreakfast,NULL));
	linphone_core_set_presence_model(marie->lc,linphone_presence_model_new_with_activity(LinphonePresenceActivityAppointment,NULL));
	
	BC_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphonePresenceActivityAppointment,1,5000));
	
	BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePresenceActivityAway, 1, int,"%i");
	BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePresenceActivityBreakfast, 0, int,"%i");
	BC_ASSERT_EQUAL(pauline->stat.number_of_LinphonePresenceActivityAppointment, 1, int,"%i");
	
	
jehan's avatar
jehan committed
591 592 593 594 595 596 597 598 599 600
	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;
601 602 603
	LpConfig *pauline_lp;
	char* lf_identity;
	LinphoneFriend *lf;
jehan's avatar
jehan committed
604 605 606 607
	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);
608 609 610
	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
611

612
	
613 614 615
	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
616 617 618 619 620 621

	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
622
	wait_for_list(lcs,&pauline->stat.number_of_NotifyPresenceReceived,1,2000);
623
	BC_ASSERT_EQUAL(LinphoneStatusOffline,linphone_friend_get_status(lf), int, "%d");
jehan's avatar
jehan committed
624 625 626

	/*enable publish*/

jehan's avatar
jehan committed
627
	proxy = linphone_core_get_default_proxy_config(marie->lc);
jehan's avatar
jehan committed
628 629 630 631 632
	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
633
	proxy = linphone_core_get_default_proxy_config(marie2->lc);
jehan's avatar
jehan committed
634 635 636 637 638 639 640
	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
641
	wait_for_list(lcs,&pauline->stat.number_of_NotifyPresenceReceived,3,2000);
642
	BC_ASSERT_EQUAL(LinphoneStatusOnline,linphone_friend_get_status(lf), int, "%d");
jehan's avatar
jehan committed
643 644 645 646 647

	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
648
	wait_for_list(lcs,&pauline->stat.number_of_NotifyPresenceReceived,4,2000);
649
	BC_ASSERT_EQUAL(LinphoneStatusBusy,linphone_friend_get_status(lf), int, "%d");
jehan's avatar
jehan committed
650 651 652 653 654


	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
655
	wait_for_list(lcs,&pauline->stat.number_of_NotifyPresenceReceived,5,2000);
656 657
	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
658 659

	linphone_core_manager_destroy(marie);
jehan's avatar
jehan committed
660
	linphone_core_manager_destroy(marie2);
jehan's avatar
jehan committed
661 662 663
	linphone_core_manager_destroy(pauline);
}

Ghislain MARY's avatar
Ghislain MARY committed
664 665 666 667 668 669 670 671 672
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
673
	linphone_proxy_config_set_publish_expires(cfg, 60);
Ghislain MARY's avatar
Ghislain MARY committed
674 675 676 677 678 679 680 681 682 683 684 685 686 687
	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
688
	int dummy = 0;
Ghislain MARY's avatar
Ghislain MARY committed
689 690 691 692 693 694

	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
695
	enable_publish(laure, TRUE);
Ghislain MARY's avatar
Ghislain MARY committed
696 697 698 699 700 701 702 703 704 705 706 707 708

	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);
709
	linphone_friend_list_unref(lfl);
Ghislain MARY's avatar
Ghislain MARY committed
710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736
	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);
737
	linphone_friend_list_unref(lfl);
Ghislain MARY's avatar
Ghislain MARY committed
738
	linphone_friend_list_update_subscriptions(marie->lc->friendlist, NULL, FALSE);
Ghislain MARY's avatar
Ghislain MARY committed
739 740 741 742 743 744 745 746 747 748 749 750 751 752

	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);
753
	linphone_friend_list_unref(lfl);
Ghislain MARY's avatar
Ghislain MARY committed
754 755 756 757 758 759 760 761 762 763
	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");

764 765 766
	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
767 768 769
	/* 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");
770 771 772 773 774 775 776 777 778 779
	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");

780
	ms_message("Disabling publish");
Ghislain MARY's avatar
Ghislain MARY committed
781 782 783 784
	enable_publish(laure, FALSE);
	enable_publish(marie, FALSE);
	enable_publish(pauline, FALSE);

Ghislain MARY's avatar
Ghislain MARY committed
785
	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
786 787 788
	
	lf = linphone_friend_list_find_friend_by_uri(pauline->lc->friendlist, marie_identity);
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
789 790 791
	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
792
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
793 794
	
	lf = linphone_friend_list_find_friend_by_uri(marie->lc->friendlist, laure_identity);
jehan's avatar
jehan committed
795 796
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
	
Ghislain MARY's avatar
Ghislain MARY committed
797 798 799 800
	linphone_core_manager_destroy(laure);
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
buildbot's avatar
buildbot committed
801
#if 0
802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822
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);
823
	linphone_friend_list_unref(lfl);
824
	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
825
	linphone_friend_list_update_subscriptions(laure->lc->friendlist, NULL, FALSE);
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

	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);
}
buildbot's avatar
buildbot committed
851
#endif
852
static void test_presence_list_subscription_expire_for_unknown(void) {
853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870
	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));
	
871 872
	linphone_core_manager_destroy(laure);
}
873

874
static void test_presence_list_subscribe_with_error(bool_t io_error) {
875 876 877 878 879 880 881 882
	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;
883
	lp_config_set_int(laure->lc->config, "sip", "rls_presence_expires", 5);
884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906
	

	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);
907
	BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_LinphonePresenceActivityVacation, 1, 6000));
908 909 910 911 912 913 914 915 916 917 918
	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");
	
919
	BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_LinphonePresenceActivityVacation, 2, 6000));
920 921 922
	if (io_error) {
		ms_message("Simulating socket error");
		sal_set_recv_error(laure->lc->sal, -1);
923
		wait_for_list(lcs, &dummy, 1, 500); /* just time for socket to be closed */
924 925 926 927
	} else {
		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*/
928
		wait_for_list(lcs, &dummy, 1, 5000); /* Wait a little bit for the subscribe to happen */
929
	}
930 931 932
	/*restart normal behavior*/
	sal_set_send_error(laure->lc->sal,0);
	sal_set_recv_error(laure->lc->sal, 1);
933
	
934 935
	BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_LinphonePresenceActivityVacation, 3, 6000)); /* give time for subscription to recover to avoid to receive 491 Request pending*/
	
936 937
	linphone_core_set_presence_model(pauline->lc, linphone_core_create_presence_model_with_activity(pauline->lc, LinphonePresenceActivityAway, NULL));

938
	BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_LinphonePresenceActivityAway, 1, 6000));
939 940
	lf = linphone_friend_list_find_friend_by_uri(laure->lc->friendlist, pauline_identity);
	BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusAway, int, "%d");
941 942
	
	linphone_core_manager_destroy(laure);
943
	linphone_core_manager_destroy(pauline);
944 945
}

946 947 948
static void test_presence_list_subscribe_dialog_expire(void) {
	test_presence_list_subscribe_with_error(FALSE);
}
949

950 951 952
static void test_presence_list_subscribe_io_error(void) {
	test_presence_list_subscribe_with_error(TRUE);
}
953

Ghislain MARY's avatar
Ghislain MARY committed
954
test_t presence_tests[] = {
955 956 957 958 959 960 961 962 963
	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),
964
	TEST_NO_TAG("Subscriber no loguer reachable using server",subscriber_no_longuer_reachable),
965 966 967
	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),
968
	TEST_NO_TAG("Presence list, subscription expiration for unknown contact",test_presence_list_subscription_expire_for_unknown),
969 970
	TEST_NO_TAG("Presence list, silent subscription expiration", test_presence_list_subscribe_dialog_expire),
	TEST_NO_TAG("Presence list, io error",test_presence_list_subscribe_io_error)
Ghislain MARY's avatar
Ghislain MARY committed
971 972
};

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