presence_tester.c 24 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){
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*/
}
Ghislain MARY's avatar
Ghislain MARY committed
48

jehan's avatar
jehan committed
49
void notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf) {
50
	stats* counters;
jehan's avatar
jehan committed
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);
jehan's avatar
jehan committed
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 117 118 119 120 121 122 123 124 125 126 127
	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 {
		ms_error("unexpeted basioc status [%i]",linphone_presence_model_get_basic_status(counters->last_received_presence));
	}
	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);
}

Ghislain MARY's avatar
Ghislain MARY committed
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);
}
Ghislain MARY's avatar
Ghislain MARY committed
275 276

static void unsubscribe_while_subscribing(void) {
Simon Morlat's avatar
Simon Morlat committed
277
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
278
	LinphoneFriend* friend = linphone_core_create_friend_with_address(marie->lc, "sip:toto@git.linphone.org"); /*any unexisting address*/
jehan's avatar
jehan committed
279 280 281 282
	linphone_friend_edit(friend);
	linphone_friend_enable_subscribes(friend,TRUE);
	linphone_friend_done(friend);
	linphone_core_add_friend(marie->lc,friend);
283
	linphone_friend_unref(friend);
jehan's avatar
jehan committed
284 285 286 287
	linphone_core_iterate(marie->lc);
	linphone_core_manager_destroy(marie);
}

288 289
#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
290
static void call_with_presence(void) {
jehan's avatar
jehan committed
291 292
	LinphoneCoreManager* marie = presence_linphone_core_manager_new("marie");
	LinphoneCoreManager* pauline = presence_linphone_core_manager_new("pauline");
293 294
	LinphoneVideoPolicy pol={0};
	linphone_core_set_video_policy(marie->lc,&pol);
295 296
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline));
	BC_ASSERT_TRUE(subscribe_to_callee_presence(pauline,marie));
jehan's avatar
jehan committed
297

298 299 300
	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
301 302 303 304

	reset_counters(&marie->stat);
	reset_counters(&pauline->stat);
	linphone_core_terminate_all_calls(marie->lc);
305 306
	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
307 308 309
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
Ghislain MARY's avatar
Ghislain MARY committed
310

311 312
#endif

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

328
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie, pauline));
329 330 331

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

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

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

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

386
	/* Presence timestamp. */
387
	current_timestamp = ms_time(NULL);
388 389
	presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityShopping, NULL);
	linphone_core_set_presence_model(pauline->lc, presence);
jehan's avatar
jehan committed
390
	wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePresenceActivityShopping,1);
391
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityShopping, 1, int, "%d");
392
	presence_timestamp = linphone_presence_model_get_timestamp(presence);
393
	BC_ASSERT_GREATER((unsigned)presence_timestamp , (unsigned)current_timestamp, unsigned, "%u");
394

395 396 397
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
398 399


400
static void subscribe_presence_forked(void){
401 402 403 404 405
	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;
406

407 408 409
	lcs = ms_list_append(lcs, marie->lc);
	lcs = ms_list_append(lcs, pauline1->lc);
	lcs = ms_list_append(lcs, pauline2->lc);
410

411 412 413
	lf = linphone_core_create_friend(marie->lc);
	linphone_friend_set_address(lf, pauline1->identity);
	linphone_friend_enable_subscribes(lf, TRUE);
414

415 416
	linphone_core_add_friend(marie->lc, lf);
	linphone_friend_unref(lf);
417

418 419 420 421
	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));
422 423

	/*marie also shall receive two SUBSCRIBEs from the two paulines, but won't be notified to the app since
424 425 426 427 428
	 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));
429

430 431 432
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline1);
	linphone_core_manager_destroy(pauline2);
433

434 435 436
	ms_list_free(lcs);
}

437
static void subscribe_presence_expired(void){
438 439
	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
440 441
	LinphoneFriend *lf;
	MSList *lcs = NULL;
442

Simon Morlat's avatar
Simon Morlat committed
443 444
	lcs = ms_list_append(lcs, marie->lc);
	lcs = ms_list_append(lcs, pauline1->lc);
445

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

Simon Morlat's avatar
Simon Morlat committed
448 449 450
	lf = linphone_core_create_friend(marie->lc);
	linphone_friend_set_address(lf, pauline1->identity);
	linphone_friend_enable_subscribes(lf, TRUE);
451

Simon Morlat's avatar
Simon Morlat committed
452 453 454 455
	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));
456

457
	lf = linphone_core_find_friend(pauline1->lc, marie->identity);
458 459 460 461 462 463 464 465 466 467 468 469 470 471
	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
472 473
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline1);
474

Simon Morlat's avatar
Simon Morlat committed
475 476 477
	ms_list_free(lcs);
}

478 479 480 481
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;
482

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

485 486 487 488
	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*/
	}
489

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

492 493
	BC_ASSERT_EQUAL(pauline->stat.number_of_NewSubscriptionRequest,1, int, "%d");
	BC_ASSERT_EQUAL(marie->stat.number_of_NotifyPresenceReceived,1, int, "%d");
494

495 496 497
	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*/
498 499 500 501

	linphone_core_manager_destroy(pauline);
}

Ghislain MARY's avatar
Ghislain MARY committed
502
test_t presence_tests[] = {
jehan's avatar
jehan committed
503
	TEST_ONE_TAG("Simple Subscribe", simple_subscribe,"presence"),
504
	TEST_NO_TAG("Simple Subscribe with friend from rc", simple_subscribe_with_friend_from_rc),
505 506 507
	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"),*/
508 509 510 511 512
	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
513 514
};

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