presence_tester.c 26.1 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
	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));
jehan's avatar
jehan committed
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);
}

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

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

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

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

	reset_counters(&marie->stat);
	reset_counters(&pauline->stat);
	linphone_core_terminate_all_calls(marie->lc);
353 354
	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
355 356 357
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
Ghislain MARY's avatar
Ghislain MARY committed
358

359 360
#endif

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

484 485 486
	ms_list_free(lcs);
}

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

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

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

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

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

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

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

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

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

535 536 537 538
	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*/
	}
539

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

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

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

	linphone_core_manager_destroy(pauline);
}

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

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