presence_tester.c 26 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/>.
*/
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){
jehan's avatar
jehan committed
40
	char* from=linphone_address_as_string(linphone_friend_get_address(lf));
41
	stats* counters;
42
	ms_message("New subscription request from [%s] url [%s]",from,url);
jehan's avatar
jehan committed
43
	ms_free(from);
44
	counters = get_stats(lc);
jehan's avatar
jehan committed
45 46 47
	counters->number_of_NewSubscriptionRequest++;
	linphone_core_add_friend(lc,lf); /*accept subscription*/
}
48

jehan's avatar
jehan committed
49
void notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf) {
50
	stats* counters;
51 52
	
	int i;
jehan's avatar
jehan committed
53
	char* from=linphone_address_as_string(linphone_friend_get_address(lf));
Ghislain MARY's avatar
Ghislain MARY committed
54
	ms_message("New Notify request from [%s] ",from);
jehan's avatar
jehan committed
55
	ms_free(from);
56
	counters = get_stats(lc);
Ghislain MARY's avatar
Ghislain MARY committed
57
	counters->number_of_NotifyPresenceReceived++;
58
	counters->last_received_presence = linphone_friend_get_presence_model(lf);
59 60 61 62 63
	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
64
		ms_error("Unexpected basic status [%i]",linphone_presence_model_get_basic_status(counters->last_received_presence));
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 117 118 119 120 121 122 123 124 125 126 127
	}
	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
128
	}
jehan's avatar
jehan committed
129 130
}

131
static void simple_publish_with_expire(int expires) {
Simon Morlat's avatar
Simon Morlat committed
132
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
jehan's avatar
jehan committed
133
	LinphoneProxyConfig* proxy;
134
	LinphonePresenceModel* presence;
135 136 137
	LinphoneCoreVTable *vtable = linphone_core_v_table_new();
	vtable->publish_state_changed = linphone_publish_state_changed;
	_linphone_core_add_listener(marie->lc, vtable, TRUE, TRUE );
138

139
	proxy = linphone_core_get_default_proxy_config(marie->lc);
jehan's avatar
jehan committed
140
	linphone_proxy_config_edit(proxy);
141 142 143
	if (expires >0) {
		linphone_proxy_config_set_publish_expires(proxy,expires);
	}
jehan's avatar
jehan committed
144 145
	linphone_proxy_config_enable_publish(proxy,TRUE);
	linphone_proxy_config_done(proxy);
146

147 148
	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));
149

150
	presence =linphone_presence_model_new_with_activity(LinphonePresenceActivityOffline,NULL);
151
	linphone_core_set_presence_model(marie->lc,presence);
152

153 154
	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));
155

156 157 158
	linphone_proxy_config_edit(proxy);
	linphone_proxy_config_done(proxy);
	/*make sure no publish is sent*/
159
	BC_ASSERT_FALSE(wait_for_until(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3,2000));
160 161 162 163

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

165

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

171 172 173 174 175 176 177 178 179 180 181 182
	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
183
	linphone_core_manager_destroy(marie);
184
	/*fixme we should wait untill 200okBC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishCleared,2,int,"%i");*/
185 186
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,4,int,"%i");

jehan's avatar
jehan committed
187 188
}

189
static void simple_publish(void) {
190 191 192
	simple_publish_with_expire(-1);
}

193
static void publish_with_expires(void) {
194
	simple_publish_with_expire(2);
195 196
}

jehan's avatar
jehan committed
197 198 199 200
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
201
	char* identity=linphone_address_as_string_uri_only(callee_mgr->identity);
jehan's avatar
jehan committed
202 203


jehan's avatar
jehan committed
204
	LinphoneFriend* friend=linphone_core_create_friend_with_address(caller_mgr->lc,identity);
jehan's avatar
jehan committed
205 206 207 208 209
	linphone_friend_edit(friend);
	linphone_friend_enable_subscribes(friend,TRUE);
	linphone_friend_done(friend);

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

jehan's avatar
jehan committed
212 213 214 215
	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
216

217
	BC_ASSERT_EQUAL(callee_mgr->stat.number_of_NewSubscriptionRequest,initial_callee.number_of_NewSubscriptionRequest+1, int, "%d");
jehan's avatar
jehan committed
218
	/*without proxy, callee cannot subscribe to caller
Ghislain MARY's avatar
Ghislain MARY committed
219
	BC_ASSERT_EQUAL(callee_mgr->stat.number_of_NotifyPresenceReceived,initial_callee.number_of_NotifyPresenceReceived+1, int, "%d");
jehan's avatar
jehan committed
220
	*/
Ghislain MARY's avatar
Ghislain MARY committed
221
	BC_ASSERT_EQUAL(caller_mgr->stat.number_of_NotifyPresenceReceived,initial_caller.number_of_NotifyPresenceReceived+1, int, "%d");
jehan's avatar
jehan committed
222

jehan's avatar
jehan committed
223
	ms_free(identity);
jehan's avatar
jehan committed
224 225 226
	return result;

}
227 228
static void subscribe_failure_handle_by_app(void) {
	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
229
	LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_tcp_rc");
230 231 232
	LinphoneProxyConfig* config;
	LinphoneFriend* lf;
	char* lf_identity=linphone_address_as_string_uri_only(pauline->identity);
233

234
	config = linphone_core_get_default_proxy_config(marie->lc);
235

236
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline));
237 238 239 240
	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*/

241 242
	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");
243 244 245
	sal_set_recv_error(marie->lc->sal, 1);

	lf = linphone_core_get_friend_by_address(marie->lc,lf_identity);
246
	BC_ASSERT_PTR_NOT_NULL(lf);
247 248 249
	linphone_friend_edit(lf);
	linphone_friend_enable_subscribes(lf,FALSE); /*disable subscription*/
	linphone_friend_done(lf);
250
	BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneRegistrationOk,2)); /*wait for register ok*/
251 252 253
	linphone_friend_edit(lf);
	linphone_friend_enable_subscribes(lf,TRUE);
	linphone_friend_done(lf);
254
	BC_ASSERT_FALSE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,2)); /*just to wait for unsubscription even if not notified*/
255 256

	linphone_core_manager_destroy(marie);
257
	BC_ASSERT_FALSE(wait_for(NULL,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,3)); /*just to wait for unsubscription even if not notified*/
258 259 260 261

	linphone_core_manager_destroy(pauline);
}

262
static void simple_subscribe(void) {
jehan's avatar
jehan committed
263 264
	LinphoneCoreManager* marie = presence_linphone_core_manager_new("marie");
	LinphoneCoreManager* pauline = presence_linphone_core_manager_new("pauline");
jehan's avatar
jehan committed
265

266
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline));
jehan's avatar
jehan committed
267

268

jehan's avatar
jehan committed
269
	linphone_core_manager_destroy(marie);
jehan's avatar
jehan committed
270
	/*unsubscribe is not reported ?*/
271
	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
272 273 274

	linphone_core_manager_destroy(pauline);
}
275 276 277 278 279 280 281 282 283 284 285 286 287
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
288 289
	pauline_lp = linphone_core_get_config(pauline->lc);
	lp_config_set_int(pauline_lp,"sip","notify_pending_state",1);
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
	
	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
310
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityOnline,marie->stat.number_of_LinphonePresenceActivityOnline+1);
311 312 313 314 315 316 317 318 319 320 321
	
	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);
}

322 323

static void unsubscribe_while_subscribing(void) {
Simon Morlat's avatar
Simon Morlat committed
324
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
325
	LinphoneFriend* friend = linphone_core_create_friend_with_address(marie->lc, "sip:toto@git.linphone.org"); /*any unexisting address*/
jehan's avatar
jehan committed
326 327 328 329
	linphone_friend_edit(friend);
	linphone_friend_enable_subscribes(friend,TRUE);
	linphone_friend_done(friend);
	linphone_core_add_friend(marie->lc,friend);
330
	linphone_friend_unref(friend);
jehan's avatar
jehan committed
331 332 333 334
	linphone_core_iterate(marie->lc);
	linphone_core_manager_destroy(marie);
}

335 336
#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
337
static void call_with_presence(void) {
jehan's avatar
jehan committed
338 339
	LinphoneCoreManager* marie = presence_linphone_core_manager_new("marie");
	LinphoneCoreManager* pauline = presence_linphone_core_manager_new("pauline");
340 341
	LinphoneVideoPolicy pol={0};
	linphone_core_set_video_policy(marie->lc,&pol);
342 343
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline));
	BC_ASSERT_TRUE(subscribe_to_callee_presence(pauline,marie));
jehan's avatar
jehan committed
344

345 346 347
	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
348 349 350 351

	reset_counters(&marie->stat);
	reset_counters(&pauline->stat);
	linphone_core_terminate_all_calls(marie->lc);
352 353
	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
354 355 356
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
357

358 359
#endif

360 361 362 363
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";
364
	const char *contact = "sip:toto@example.com";
365 366 367
	LinphoneCoreManager *marie = presence_linphone_core_manager_new("marie");
	LinphoneCoreManager *pauline = presence_linphone_core_manager_new("pauline");
	LinphonePresenceModel *presence;
368 369 370 371
	LinphonePresenceActivity *activity = NULL;
	LinphonePresenceNote *note = NULL;
	const char *description = NULL;
	const char *note_content = NULL;
372
	char *contact2;
373
	time_t current_timestamp, presence_timestamp;
374

375
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie, pauline));
376 377 378

	/* Presence activity without description. */
	presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityDinner, NULL);
379
	linphone_core_set_presence_model(pauline->lc, presence);
jehan's avatar
jehan committed
380
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityDinner,1);
381
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityDinner, 1, int, "%d");
382
	activity = linphone_presence_model_get_activity(marie->stat.last_received_presence);
383 384
	BC_ASSERT_PTR_NOT_NULL(activity);
	BC_ASSERT_EQUAL(linphone_presence_activity_get_type(activity), LinphonePresenceActivityDinner, int, "%d");
385
	description = linphone_presence_activity_get_description(activity);
386
	BC_ASSERT_PTR_NULL(description);
387 388 389

	/* Presence activity with description. */
	presence = linphone_presence_model_new_with_activity(LinphonePresenceActivitySteering, bike_description);
390
	linphone_core_set_presence_model(pauline->lc, presence);
jehan's avatar
jehan committed
391
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivitySteering,1);
392
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivitySteering, 1, int, "%d");
393
	activity = linphone_presence_model_get_activity(marie->stat.last_received_presence);
394 395
	BC_ASSERT_PTR_NOT_NULL(activity);
	BC_ASSERT_EQUAL(linphone_presence_activity_get_type(activity), LinphonePresenceActivitySteering, int, "%d");
396
	description = linphone_presence_activity_get_description(activity);
397
	BC_ASSERT_PTR_NOT_NULL(description);
398
	if (description != NULL) BC_ASSERT_STRING_EQUAL(description, bike_description);
399 400 401

	/* Presence activity with description and note. */
	presence = linphone_presence_model_new_with_activity_and_note(LinphonePresenceActivityVacation, NULL, vacation_note, vacation_lang);
402
	linphone_core_set_presence_model(pauline->lc, presence);
jehan's avatar
jehan committed
403
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityVacation,1);
404
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityVacation, 1, int, "%d");
405
	activity = linphone_presence_model_get_activity(marie->stat.last_received_presence);
406 407
	BC_ASSERT_PTR_NOT_NULL(activity);
	BC_ASSERT_EQUAL(linphone_presence_activity_get_type(activity), LinphonePresenceActivityVacation, int, "%d");
408
	description = linphone_presence_activity_get_description(activity);
409
	BC_ASSERT_PTR_NULL(description);
410
	note = linphone_presence_model_get_note(marie->stat.last_received_presence, NULL);
411
	BC_ASSERT_PTR_NOT_NULL(note);
412
	if (note != NULL) {
413
		note_content = linphone_presence_note_get_content(note);
414
		BC_ASSERT_PTR_NOT_NULL(note_content);
415
		if (note_content != NULL) {
416
			BC_ASSERT_STRING_EQUAL(note_content, vacation_note);
417
		}
418 419
	}

420 421 422 423
	/* 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
424
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityOnThePhone,1);
425
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityOnThePhone, 1, int, "%d");
426
	contact2 = linphone_presence_model_get_contact(presence);
427
	BC_ASSERT_PTR_NOT_NULL(contact2);
428
	if (contact2 != NULL) {
429
		BC_ASSERT_STRING_EQUAL(contact, contact2);
430 431 432
		ms_free(contact2);
	}

433
	/* Presence timestamp. */
434
	current_timestamp = ms_time(NULL);
435 436
	presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityShopping, NULL);
	linphone_core_set_presence_model(pauline->lc, presence);
jehan's avatar
jehan committed
437
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityShopping,1);
438
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityShopping, 1, int, "%d");
439
	presence_timestamp = linphone_presence_model_get_timestamp(presence);
440
	BC_ASSERT_GREATER((unsigned)presence_timestamp , (unsigned)current_timestamp, unsigned, "%u");
441

442 443 444
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
445 446


447
static void subscribe_presence_forked(void){
448
	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
449 450
	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");
451 452
	LinphoneFriend *lf;
	MSList *lcs = NULL;
453

454 455 456
	lcs = ms_list_append(lcs, marie->lc);
	lcs = ms_list_append(lcs, pauline1->lc);
	lcs = ms_list_append(lcs, pauline2->lc);
457

458 459 460
	lf = linphone_core_create_friend(marie->lc);
	linphone_friend_set_address(lf, pauline1->identity);
	linphone_friend_enable_subscribes(lf, TRUE);
461

462 463
	linphone_core_add_friend(marie->lc, lf);
	linphone_friend_unref(lf);
464

465 466
	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));
467 468 469 470
	
	/*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));
471 472

	/*marie also shall receive two SUBSCRIBEs from the two paulines, but won't be notified to the app since
473 474 475 476 477
	 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));
478

479 480 481
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline1);
	linphone_core_manager_destroy(pauline2);
482

483 484 485
	ms_list_free(lcs);
}

486
static void subscribe_presence_expired(void){
487 488
	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
489 490
	LinphoneFriend *lf;
	MSList *lcs = NULL;
491

Simon Morlat's avatar
Simon Morlat committed
492 493
	lcs = ms_list_append(lcs, marie->lc);
	lcs = ms_list_append(lcs, pauline1->lc);
494

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

Simon Morlat's avatar
Simon Morlat committed
497 498 499
	lf = linphone_core_create_friend(marie->lc);
	linphone_friend_set_address(lf, pauline1->identity);
	linphone_friend_enable_subscribes(lf, TRUE);
500

Simon Morlat's avatar
Simon Morlat committed
501 502 503 504
	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));
505

506
	lf = linphone_core_find_friend(pauline1->lc, marie->identity);
507 508 509 510 511 512 513 514 515 516 517 518 519 520
	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
521 522
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline1);
523

Simon Morlat's avatar
Simon Morlat committed
524 525 526
	ms_list_free(lcs);
}

527 528 529 530
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;
531

532
	BC_ASSERT_EQUAL(ms_list_size(linphone_core_get_friend_list(marie->lc)), 1, int , "%i");
533

534 535 536 537
	if (ms_list_size(linphone_core_get_friend_list(marie->lc))>0) {
		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*/
	}
538

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

541 542
	BC_ASSERT_EQUAL(pauline->stat.number_of_NewSubscriptionRequest,1, int, "%d");
	BC_ASSERT_EQUAL(marie->stat.number_of_NotifyPresenceReceived,1, int, "%d");
543

544 545 546
	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*/
547 548 549 550

	linphone_core_manager_destroy(pauline);
}

551
test_t presence_tests[] = {
jehan's avatar
jehan committed
552
	TEST_ONE_TAG("Simple Subscribe", simple_subscribe,"presence"),
553
	TEST_ONE_TAG("Simple Subscribe with early NOTIFY", simple_subscribe_with_early_notify,"presence"),
554
	TEST_NO_TAG("Simple Subscribe with friend from rc", simple_subscribe_with_friend_from_rc),
555 556 557
	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"),*/
558 559 560 561 562
	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),
563 564
};

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