presence_tester.c 26.5 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 LinphoneCoreManager* presence_linphone_core_manager_new_with_rc_name(char* username, char * rc_name) {
	LinphoneCoreManager* mgr= linphone_core_manager_new2( rc_name, FALSE);
jehan's avatar
jehan committed
26 27 28 29 30
	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);
31
	ms_free(identity_char);
jehan's avatar
jehan committed
32 33
	return mgr;
}
34 35 36 37
static LinphoneCoreManager* presence_linphone_core_manager_new(char* username) {
	return presence_linphone_core_manager_new_with_rc_name(username, "empty_rc");
}

38

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

jehan's avatar
jehan committed
51
void notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf) {
52
	stats* counters;
53
	unsigned int i;
54 55
	LinphoneAddress *addr = linphone_friend_get_address(lf);
	char* from=linphone_address_as_string(addr);
Ghislain MARY's avatar
Ghislain MARY committed
56
	ms_message("New Notify request from [%s] ",from);
57
	linphone_address_unref(addr);
jehan's avatar
jehan committed
58
	ms_free(from);
59
	counters = get_stats(lc);
Ghislain MARY's avatar
Ghislain MARY committed
60
	counters->number_of_NotifyPresenceReceived++;
61
	counters->last_received_presence = linphone_friend_get_presence_model(lf);
jehan's avatar
jehan committed
62 63 64 65 66
	if (linphone_presence_model_get_basic_status(counters->last_received_presence) == LinphonePresenceBasicStatusOpen) {
		counters->number_of_LinphonePresenceBasicStatusOpen++;
	} else if (linphone_presence_model_get_basic_status(counters->last_received_presence) == LinphonePresenceBasicStatusClosed) {
		counters->number_of_LinphonePresenceBasicStatusClosed++;
	} else {
Ghislain MARY's avatar
Ghislain MARY committed
67
		ms_error("Unexpected basic status [%i]",linphone_presence_model_get_basic_status(counters->last_received_presence));
jehan's avatar
jehan committed
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 117 118 119 120 121 122 123 124 125 126 127 128 129 130
	}
	for (i=0;i<linphone_presence_model_get_nb_activities(counters->last_received_presence); i++) {
		LinphonePresenceActivity *activity = linphone_presence_model_get_nth_activity(counters->last_received_presence, i);
		switch (linphone_presence_activity_get_type(activity)) {
			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
131
	}
jehan's avatar
jehan committed
132 133
}

134 135 136 137 138 139
void notify_presence_received_for_uri_or_tel(LinphoneCore *lc, LinphoneFriend *lf, const char *uri_or_tel, const LinphonePresenceModel *presence) {
	stats *counters = get_stats(lc);
	ms_message("Presence notification for URI or phone number [%s]", uri_or_tel);
	counters->number_of_NotifyPresenceReceivedForUriOrTel++;
}

140
static void simple_publish_with_expire(int expires) {
Simon Morlat's avatar
Simon Morlat committed
141
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
jehan's avatar
jehan committed
142
	LinphoneProxyConfig* proxy;
143
	LinphonePresenceModel* presence;
144 145 146
	LinphoneCoreVTable *vtable = linphone_core_v_table_new();
	vtable->publish_state_changed = linphone_publish_state_changed;
	_linphone_core_add_listener(marie->lc, vtable, TRUE, TRUE );
147

148
	proxy = linphone_core_get_default_proxy_config(marie->lc);
jehan's avatar
jehan committed
149
	linphone_proxy_config_edit(proxy);
150 151 152
	if (expires >0) {
		linphone_proxy_config_set_publish_expires(proxy,expires);
	}
jehan's avatar
jehan committed
153 154
	linphone_proxy_config_enable_publish(proxy,TRUE);
	linphone_proxy_config_done(proxy);
155

156 157
	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));
158

159
	presence =linphone_presence_model_new_with_activity(LinphonePresenceActivityOffline,NULL);
160
	linphone_core_set_presence_model(marie->lc,presence);
161

162 163
	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));
164

165 166 167
	linphone_proxy_config_edit(proxy);
	linphone_proxy_config_done(proxy);
	/*make sure no publish is sent*/
168
	BC_ASSERT_FALSE(wait_for_until(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3,2000));
169 170 171 172

	linphone_proxy_config_edit(proxy);
	linphone_proxy_config_enable_publish(proxy,FALSE);
	linphone_proxy_config_done(proxy);
173

174

jehan's avatar
jehan committed
175
	/*fixme PUBLISH state machine is too simple, clear state should only be propagated at API level  when 200ok is received*/
176
	/*BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3));*/
jehan's avatar
jehan committed
177
	wait_for_until(marie->lc,marie->lc,NULL,0,2000);
178
	BC_ASSERT_TRUE(wait_for(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishCleared,1));
179

180 181 182 183 184 185 186 187 188 189 190 191
	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
192
	linphone_core_manager_destroy(marie);
193
	/*fixme we should wait untill 200okBC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishCleared,2,int,"%i");*/
194 195
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,4,int,"%i");

jehan's avatar
jehan committed
196 197
}

198
static void simple_publish(void) {
199 200 201
	simple_publish_with_expire(-1);
}

202
static void publish_with_expires(void) {
203
	simple_publish_with_expire(2);
204 205
}

jehan's avatar
jehan committed
206 207 208 209
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
210
	char* identity=linphone_address_as_string_uri_only(callee_mgr->identity);
jehan's avatar
jehan committed
211 212


jehan's avatar
jehan committed
213
	LinphoneFriend* friend=linphone_core_create_friend_with_address(caller_mgr->lc,identity);
jehan's avatar
jehan committed
214 215 216 217 218
	linphone_friend_edit(friend);
	linphone_friend_enable_subscribes(friend,TRUE);
	linphone_friend_done(friend);

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

jehan's avatar
jehan committed
221 222 223 224
	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
225

226
	BC_ASSERT_EQUAL(callee_mgr->stat.number_of_NewSubscriptionRequest,initial_callee.number_of_NewSubscriptionRequest+1, int, "%d");
jehan's avatar
jehan committed
227
	/*without proxy, callee cannot subscribe to caller
Ghislain MARY's avatar
Ghislain MARY committed
228
	BC_ASSERT_EQUAL(callee_mgr->stat.number_of_NotifyPresenceReceived,initial_callee.number_of_NotifyPresenceReceived+1, int, "%d");
jehan's avatar
jehan committed
229
	*/
Ghislain MARY's avatar
Ghislain MARY committed
230
	BC_ASSERT_EQUAL(caller_mgr->stat.number_of_NotifyPresenceReceived,initial_caller.number_of_NotifyPresenceReceived+1, int, "%d");
jehan's avatar
jehan committed
231

jehan's avatar
jehan committed
232
	ms_free(identity);
jehan's avatar
jehan committed
233 234 235
	return result;

}
236 237
static void subscribe_failure_handle_by_app(void) {
	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
238
	LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_tcp_rc");
239 240 241
	LinphoneProxyConfig* config;
	LinphoneFriend* lf;
	char* lf_identity=linphone_address_as_string_uri_only(pauline->identity);
242

243
	config = linphone_core_get_default_proxy_config(marie->lc);
244

245
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline));
246 247 248 249
	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*/

250 251
	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");
252 253 254
	sal_set_recv_error(marie->lc->sal, 1);

	lf = linphone_core_get_friend_by_address(marie->lc,lf_identity);
Ghislain MARY's avatar
Ghislain MARY committed
255
	ms_free(lf_identity);
256
	BC_ASSERT_PTR_NOT_NULL(lf);
257 258 259
	linphone_friend_edit(lf);
	linphone_friend_enable_subscribes(lf,FALSE); /*disable subscription*/
	linphone_friend_done(lf);
260
	BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneRegistrationOk,2)); /*wait for register ok*/
261 262 263
	linphone_friend_edit(lf);
	linphone_friend_enable_subscribes(lf,TRUE);
	linphone_friend_done(lf);
264
	BC_ASSERT_FALSE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,2)); /*just to wait for unsubscription even if not notified*/
265 266

	linphone_core_manager_destroy(marie);
267
	BC_ASSERT_FALSE(wait_for(NULL,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,3)); /*just to wait for unsubscription even if not notified*/
268 269 270 271

	linphone_core_manager_destroy(pauline);
}

Ghislain MARY's avatar
Ghislain MARY committed
272
static void simple_subscribe(void) {
jehan's avatar
jehan committed
273 274
	LinphoneCoreManager* marie = presence_linphone_core_manager_new("marie");
	LinphoneCoreManager* pauline = presence_linphone_core_manager_new("pauline");
jehan's avatar
jehan committed
275

276
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline));
jehan's avatar
jehan committed
277

278

jehan's avatar
jehan committed
279
	linphone_core_manager_destroy(marie);
jehan's avatar
jehan committed
280
	/*unsubscribe is not reported ?*/
281
	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
282 283 284

	linphone_core_manager_destroy(pauline);
}
285 286 287 288 289 290 291 292 293 294 295 296 297
static void simple_subscribe_with_early_notify(void) {
	
	LinphoneCoreManager* marie = presence_linphone_core_manager_new("marie");
	LinphoneCoreManager* pauline = presence_linphone_core_manager_new("pauline");
	LinphoneAddress *marie_identity_addr = linphone_address_clone(marie->identity);
	LpConfig *pauline_lp;
	
	char* pauline_identity=linphone_address_as_string_uri_only(pauline->identity);
	char* marie_identity;
	
	LinphoneFriend* pauline_s_friend;
	LinphoneFriend* marie_s_friend=linphone_core_create_friend_with_address(marie->lc,pauline_identity);
	
Sylvain Berfini's avatar
Sylvain Berfini committed
298 299
	pauline_lp = linphone_core_get_config(pauline->lc);
	lp_config_set_int(pauline_lp,"sip","notify_pending_state",1);
300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
	
	linphone_friend_edit(marie_s_friend);
	linphone_friend_enable_subscribes(marie_s_friend,TRUE);
	linphone_friend_done(marie_s_friend);
	linphone_core_add_friend(marie->lc,marie_s_friend);
	ms_free(pauline_identity);
	
	
	/*to simulate pending state.*/

	linphone_address_set_port(marie_identity_addr,0);
	marie_identity=linphone_address_as_string_uri_only(marie_identity_addr);
	pauline_s_friend=linphone_core_create_friend_with_address(pauline->lc,marie_identity);
	linphone_core_add_friend(pauline->lc,pauline_s_friend);
	
	ms_free(marie_identity);

	BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_NotifyPresenceReceived,1));
	BC_ASSERT_EQUAL(linphone_friend_get_subscription_state(marie_s_friend), LinphoneSubscriptionPending,int, "%d");
	
Sylvain Berfini's avatar
Sylvain Berfini committed
320
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityOnline,marie->stat.number_of_LinphonePresenceActivityOnline+1);
321 322 323 324 325 326 327 328 329 330 331
	
	BC_ASSERT_EQUAL(marie->stat.number_of_NotifyPresenceReceived,2, int, "%d");
	
	linphone_friend_unref(marie_s_friend);
	linphone_friend_unref(pauline_s_friend);
	linphone_address_unref(marie_identity_addr);
	linphone_core_manager_destroy(marie);
	
	linphone_core_manager_destroy(pauline);
}

Ghislain MARY's avatar
Ghislain MARY committed
332 333

static void unsubscribe_while_subscribing(void) {
Simon Morlat's avatar
Simon Morlat committed
334
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
335
	LinphoneFriend* friend = linphone_core_create_friend_with_address(marie->lc, "sip:toto@git.linphone.org"); /*any unexisting address*/
jehan's avatar
jehan committed
336 337 338 339
	linphone_friend_edit(friend);
	linphone_friend_enable_subscribes(friend,TRUE);
	linphone_friend_done(friend);
	linphone_core_add_friend(marie->lc,friend);
340
	linphone_friend_unref(friend);
jehan's avatar
jehan committed
341 342 343 344
	linphone_core_iterate(marie->lc);
	linphone_core_manager_destroy(marie);
}

345 346
#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
347
static void call_with_presence(void) {
jehan's avatar
jehan committed
348 349
	LinphoneCoreManager* marie = presence_linphone_core_manager_new("marie");
	LinphoneCoreManager* pauline = presence_linphone_core_manager_new("pauline");
350 351
	LinphoneVideoPolicy pol={0};
	linphone_core_set_video_policy(marie->lc,&pol);
352 353
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline));
	BC_ASSERT_TRUE(subscribe_to_callee_presence(pauline,marie));
jehan's avatar
jehan committed
354

355 356 357
	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
358 359 360 361

	reset_counters(&marie->stat);
	reset_counters(&pauline->stat);
	linphone_core_terminate_all_calls(marie->lc);
362 363
	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
364 365 366
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
Ghislain MARY's avatar
Ghislain MARY committed
367

368 369
#endif

370 371 372 373
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";
374
	const char *contact = "sip:toto@example.com";
375 376 377
	LinphoneCoreManager *marie = presence_linphone_core_manager_new("marie");
	LinphoneCoreManager *pauline = presence_linphone_core_manager_new("pauline");
	LinphonePresenceModel *presence;
378 379 380 381
	LinphonePresenceActivity *activity = NULL;
	LinphonePresenceNote *note = NULL;
	const char *description = NULL;
	const char *note_content = NULL;
382
	char *contact2;
383
	time_t current_timestamp, presence_timestamp;
384

385
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie, pauline));
386 387 388

	/* Presence activity without description. */
	presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityDinner, NULL);
389
	linphone_core_set_presence_model(pauline->lc, presence);
jehan's avatar
jehan committed
390
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityDinner,1);
391
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityDinner, 1, int, "%d");
392
	activity = linphone_presence_model_get_activity(marie->stat.last_received_presence);
393 394
	BC_ASSERT_PTR_NOT_NULL(activity);
	BC_ASSERT_EQUAL(linphone_presence_activity_get_type(activity), LinphonePresenceActivityDinner, int, "%d");
395
	description = linphone_presence_activity_get_description(activity);
396
	BC_ASSERT_PTR_NULL(description);
397 398 399

	/* Presence activity with description. */
	presence = linphone_presence_model_new_with_activity(LinphonePresenceActivitySteering, bike_description);
400
	linphone_core_set_presence_model(pauline->lc, presence);
jehan's avatar
jehan committed
401
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivitySteering,1);
402
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivitySteering, 1, int, "%d");
403
	activity = linphone_presence_model_get_activity(marie->stat.last_received_presence);
404 405
	BC_ASSERT_PTR_NOT_NULL(activity);
	BC_ASSERT_EQUAL(linphone_presence_activity_get_type(activity), LinphonePresenceActivitySteering, int, "%d");
406
	description = linphone_presence_activity_get_description(activity);
407
	BC_ASSERT_PTR_NOT_NULL(description);
408
	if (description != NULL) BC_ASSERT_STRING_EQUAL(description, bike_description);
409 410 411

	/* Presence activity with description and note. */
	presence = linphone_presence_model_new_with_activity_and_note(LinphonePresenceActivityVacation, NULL, vacation_note, vacation_lang);
412
	linphone_core_set_presence_model(pauline->lc, presence);
jehan's avatar
jehan committed
413
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityVacation,1);
414
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityVacation, 1, int, "%d");
415
	activity = linphone_presence_model_get_activity(marie->stat.last_received_presence);
416 417
	BC_ASSERT_PTR_NOT_NULL(activity);
	BC_ASSERT_EQUAL(linphone_presence_activity_get_type(activity), LinphonePresenceActivityVacation, int, "%d");
418
	description = linphone_presence_activity_get_description(activity);
419
	BC_ASSERT_PTR_NULL(description);
420
	note = linphone_presence_model_get_note(marie->stat.last_received_presence, NULL);
421
	BC_ASSERT_PTR_NOT_NULL(note);
422
	if (note != NULL) {
423
		note_content = linphone_presence_note_get_content(note);
424
		BC_ASSERT_PTR_NOT_NULL(note_content);
425
		if (note_content != NULL) {
426
			BC_ASSERT_STRING_EQUAL(note_content, vacation_note);
427
		}
428 429
	}

430 431 432 433
	/* 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
434
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityOnThePhone,1);
435
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityOnThePhone, 1, int, "%d");
436
	contact2 = linphone_presence_model_get_contact(presence);
437
	BC_ASSERT_PTR_NOT_NULL(contact2);
438
	if (contact2 != NULL) {
439
		BC_ASSERT_STRING_EQUAL(contact, contact2);
440 441 442
		ms_free(contact2);
	}

443
	/* Presence timestamp. */
444
	current_timestamp = ms_time(NULL);
445 446
	presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityShopping, NULL);
	linphone_core_set_presence_model(pauline->lc, presence);
jehan's avatar
jehan committed
447
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityShopping,1);
448
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityShopping, 1, int, "%d");
449
	presence_timestamp = linphone_presence_model_get_timestamp(presence);
450
	BC_ASSERT_GREATER((unsigned)presence_timestamp , (unsigned)current_timestamp, unsigned, "%u");
451

452 453 454
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
455 456


457
static void subscribe_presence_forked(void){
458
	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
459 460
	LinphoneCoreManager* pauline1 = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_tcp_rc" : "pauline_tcp_rc");
	LinphoneCoreManager* pauline2 = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_tcp_rc" : "pauline_tcp_rc");
461
	LinphoneFriend *lf;
462
	bctbx_list_t *lcs = NULL;
463

464 465 466
	lcs = bctbx_list_append(lcs, marie->lc);
	lcs = bctbx_list_append(lcs, pauline1->lc);
	lcs = bctbx_list_append(lcs, pauline2->lc);
467

468 469 470
	lf = linphone_core_create_friend(marie->lc);
	linphone_friend_set_address(lf, pauline1->identity);
	linphone_friend_enable_subscribes(lf, TRUE);
471

472 473
	linphone_core_add_friend(marie->lc, lf);
	linphone_friend_unref(lf);
474

475 476
	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));
477 478 479 480
	
	/*we should get only one notify*/
	BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphonePresenceActivityOnline,1, 10000));
	BC_ASSERT_FALSE(wait_for_list(lcs,&marie->stat.number_of_LinphonePresenceActivityOnline,2, 2000));
481 482

	/*marie also shall receive two SUBSCRIBEs from the two paulines, but won't be notified to the app since
483 484 485 486 487
	 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));
488

489 490 491
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline1);
	linphone_core_manager_destroy(pauline2);
492

493
	bctbx_list_free(lcs);
494 495
}

496
static void subscribe_presence_expired(void){
497 498
	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
499
	LinphoneFriend *lf;
500
	bctbx_list_t *lcs = NULL;
501

502 503
	lcs = bctbx_list_append(lcs, marie->lc);
	lcs = bctbx_list_append(lcs, pauline1->lc);
504

Simon Morlat's avatar
Simon Morlat committed
505
	lp_config_set_int(marie->lc->config, "sip", "subscribe_expires", 10);
506

Simon Morlat's avatar
Simon Morlat committed
507 508 509
	lf = linphone_core_create_friend(marie->lc);
	linphone_friend_set_address(lf, pauline1->identity);
	linphone_friend_enable_subscribes(lf, TRUE);
510

Simon Morlat's avatar
Simon Morlat committed
511 512 513 514
	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));
515

516
	lf = linphone_core_find_friend(pauline1->lc, marie->identity);
517 518 519 520 521 522 523 524 525 526 527 528 529 530
	BC_ASSERT_PTR_NOT_NULL(lf);
	if (lf) {
		BC_ASSERT_PTR_NOT_NULL(lf->insubs);

		/*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);

		/*just make network reachable so that marie can unregister properly*/
		linphone_core_set_network_reachable(marie->lc, TRUE);
		BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneRegistrationOk,2, 10000));
	}
Simon Morlat's avatar
Simon Morlat committed
531 532
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline1);
533

534
	bctbx_list_free(lcs);
Simon Morlat's avatar
Simon Morlat committed
535 536
}

537 538 539 540
static void simple_subscribe_with_friend_from_rc(void) {
	LinphoneCoreManager* pauline = presence_linphone_core_manager_new("pauline");
	LinphoneCoreManager *marie = presence_linphone_core_manager_new_with_rc_name("marie", "pauline_as_friend_rc");
	LinphoneFriend *pauline_as_friend;
541

Ghislain MARY's avatar
Ghislain MARY committed
542
	BC_ASSERT_EQUAL((unsigned int)bctbx_list_size(linphone_core_get_friend_list(marie->lc)), 1, unsigned int , "%u");
543

544
	if (bctbx_list_size(linphone_core_get_friend_list(marie->lc))>0) {
545 546 547
		pauline_as_friend = (LinphoneFriend*)linphone_core_get_friend_list(marie->lc)->data;
		linphone_friend_set_address(pauline_as_friend, pauline->identity); /*hack to update addr with port number*/
	}
548

549
	BC_ASSERT_TRUE (wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityOnline,1));
550

551 552
	BC_ASSERT_EQUAL(pauline->stat.number_of_NewSubscriptionRequest,1, int, "%d");
	BC_ASSERT_EQUAL(marie->stat.number_of_NotifyPresenceReceived,1, int, "%d");
553

554 555 556
	linphone_core_manager_destroy(marie);
	/*unsubscribe is not reported ?*/
	BC_ASSERT_FALSE(wait_for(NULL,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,2)); /*just to wait for unsubscription even if not notified*/
557 558 559 560

	linphone_core_manager_destroy(pauline);
}

Ghislain MARY's avatar
Ghislain MARY committed
561
test_t presence_tests[] = {
jehan's avatar
jehan committed
562
	TEST_ONE_TAG("Simple Subscribe", simple_subscribe,"presence"),
563
	TEST_ONE_TAG("Simple Subscribe with early NOTIFY", simple_subscribe_with_early_notify,"presence"),
564
	TEST_NO_TAG("Simple Subscribe with friend from rc", simple_subscribe_with_friend_from_rc),
565 566 567
	TEST_ONE_TAG("Simple Publish", simple_publish, "LeaksMemory"),
	TEST_ONE_TAG("Simple Publish with expires", publish_with_expires, "LeaksMemory"),
	/*TEST_ONE_TAG("Call with presence", call_with_presence, "LeaksMemory"),*/
568 569 570 571 572
	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),
Ghislain MARY's avatar
Ghislain MARY committed
573 574
};

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