presence_tester.c 23.3 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;
51
	LinphonePresenceActivity *activity = NULL;
jehan's avatar
jehan committed
52
	char* from=linphone_address_as_string(linphone_friend_get_address(lf));
Ghislain MARY's avatar
Ghislain MARY committed
53
	ms_message("New Notify request from [%s] ",from);
jehan's avatar
jehan committed
54
	ms_free(from);
55
	counters = get_stats(lc);
Ghislain MARY's avatar
Ghislain MARY committed
56
	counters->number_of_NotifyPresenceReceived++;
jehan's avatar
jehan committed
57

58
	counters->last_received_presence = linphone_friend_get_presence_model(lf);
59 60
	activity = linphone_presence_model_get_activity(counters->last_received_presence);
	switch (linphone_presence_activity_get_type(activity)) {
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
		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
119
	}
jehan's avatar
jehan committed
120 121
}

122
static void simple_publish_with_expire(int expires) {
Simon Morlat's avatar
Simon Morlat committed
123
	LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
jehan's avatar
jehan committed
124
	LinphoneProxyConfig* proxy;
125
	LinphonePresenceModel* presence;
126 127 128
	LinphoneCoreVTable *vtable = linphone_core_v_table_new();
	vtable->publish_state_changed = linphone_publish_state_changed;
	_linphone_core_add_listener(marie->lc, vtable, TRUE, TRUE );
129

130
	proxy = linphone_core_get_default_proxy_config(marie->lc);
jehan's avatar
jehan committed
131
	linphone_proxy_config_edit(proxy);
132 133 134
	if (expires >0) {
		linphone_proxy_config_set_publish_expires(proxy,expires);
	}
jehan's avatar
jehan committed
135 136
	linphone_proxy_config_enable_publish(proxy,TRUE);
	linphone_proxy_config_done(proxy);
137

138 139
	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));
140

141
	presence =linphone_presence_model_new_with_activity(LinphonePresenceActivityOffline,NULL);
142
	linphone_core_set_presence_model(marie->lc,presence);
143

144 145
	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));
146

147 148 149
	linphone_proxy_config_edit(proxy);
	linphone_proxy_config_done(proxy);
	/*make sure no publish is sent*/
150
	BC_ASSERT_FALSE(wait_for_until(marie->lc,marie->lc,&marie->stat.number_of_LinphonePublishProgress,3,2000));
151 152 153 154

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

156

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

162 163 164 165 166 167 168 169 170 171 172 173
	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
174
	linphone_core_manager_destroy(marie);
175
	/*fixme we should wait untill 200okBC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishCleared,2,int,"%i");*/
176 177
	BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,4,int,"%i");

jehan's avatar
jehan committed
178 179
}

180
static void simple_publish(void) {
181 182 183
	simple_publish_with_expire(-1);
}

184
static void publish_with_expires(void) {
185
	simple_publish_with_expire(2);
186 187
}

jehan's avatar
jehan committed
188 189 190 191
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
192
	char* identity=linphone_address_as_string_uri_only(callee_mgr->identity);
jehan's avatar
jehan committed
193 194


jehan's avatar
jehan committed
195
	LinphoneFriend* friend=linphone_core_create_friend_with_address(caller_mgr->lc,identity);
jehan's avatar
jehan committed
196 197 198 199 200
	linphone_friend_edit(friend);
	linphone_friend_enable_subscribes(friend,TRUE);
	linphone_friend_done(friend);

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

jehan's avatar
jehan committed
203 204 205 206
	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
207

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

jehan's avatar
jehan committed
214
	ms_free(identity);
jehan's avatar
jehan committed
215 216 217
	return result;

}
218 219
static void subscribe_failure_handle_by_app(void) {
	LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
220
	LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_tcp_rc");
221 222 223
	LinphoneProxyConfig* config;
	LinphoneFriend* lf;
	char* lf_identity=linphone_address_as_string_uri_only(pauline->identity);
224

225
	config = linphone_core_get_default_proxy_config(marie->lc);
226

227
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline));
228 229 230 231
	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*/

232 233
	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");
234 235 236
	sal_set_recv_error(marie->lc->sal, 1);

	lf = linphone_core_get_friend_by_address(marie->lc,lf_identity);
237
	BC_ASSERT_PTR_NOT_NULL(lf);
238 239 240
	linphone_friend_edit(lf);
	linphone_friend_enable_subscribes(lf,FALSE); /*disable subscription*/
	linphone_friend_done(lf);
241
	BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneRegistrationOk,2)); /*wait for register ok*/
242 243 244
	linphone_friend_edit(lf);
	linphone_friend_enable_subscribes(lf,TRUE);
	linphone_friend_done(lf);
245
	BC_ASSERT_FALSE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,2)); /*just to wait for unsubscription even if not notified*/
246 247

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

	linphone_core_manager_destroy(pauline);
}

Ghislain MARY's avatar
Ghislain MARY committed
253
static void simple_subscribe(void) {
jehan's avatar
jehan committed
254 255
	LinphoneCoreManager* marie = presence_linphone_core_manager_new("marie");
	LinphoneCoreManager* pauline = presence_linphone_core_manager_new("pauline");
jehan's avatar
jehan committed
256

257
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline));
jehan's avatar
jehan committed
258

259

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

	linphone_core_manager_destroy(pauline);
}
Ghislain MARY's avatar
Ghislain MARY committed
266 267

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

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

289 290 291
	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
292 293 294 295

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

302 303
#endif

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

319
	BC_ASSERT_TRUE(subscribe_to_callee_presence(marie, pauline));
320 321 322

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

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

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

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

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

386 387 388
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline);
}
389 390


391
static void subscribe_presence_forked(void){
392 393 394 395 396
	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;
397

398 399 400
	lcs = ms_list_append(lcs, marie->lc);
	lcs = ms_list_append(lcs, pauline1->lc);
	lcs = ms_list_append(lcs, pauline2->lc);
401

402 403 404
	lf = linphone_core_create_friend(marie->lc);
	linphone_friend_set_address(lf, pauline1->identity);
	linphone_friend_enable_subscribes(lf, TRUE);
405

406 407
	linphone_core_add_friend(marie->lc, lf);
	linphone_friend_unref(lf);
408

409 410 411 412
	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));
413 414

	/*marie also shall receive two SUBSCRIBEs from the two paulines, but won't be notified to the app since
415 416 417 418 419
	 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));
420

421 422 423
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline1);
	linphone_core_manager_destroy(pauline2);
424

425 426 427
	ms_list_free(lcs);
}

428
static void subscribe_presence_expired(void){
429 430
	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
431 432
	LinphoneFriend *lf;
	MSList *lcs = NULL;
433

Simon Morlat's avatar
Simon Morlat committed
434 435
	lcs = ms_list_append(lcs, marie->lc);
	lcs = ms_list_append(lcs, pauline1->lc);
436

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

Simon Morlat's avatar
Simon Morlat committed
439 440 441
	lf = linphone_core_create_friend(marie->lc);
	linphone_friend_set_address(lf, pauline1->identity);
	linphone_friend_enable_subscribes(lf, TRUE);
442

Simon Morlat's avatar
Simon Morlat committed
443 444 445 446
	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));
447

448
	lf = linphone_core_find_friend(pauline1->lc, marie->identity);
449 450 451 452 453 454 455 456 457 458 459 460 461 462
	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
463 464
	linphone_core_manager_destroy(marie);
	linphone_core_manager_destroy(pauline1);
465

Simon Morlat's avatar
Simon Morlat committed
466 467 468
	ms_list_free(lcs);
}

469 470 471 472
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;
473

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

476 477 478 479
	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*/
	}
480

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

483 484
	BC_ASSERT_EQUAL(pauline->stat.number_of_NewSubscriptionRequest,1, int, "%d");
	BC_ASSERT_EQUAL(marie->stat.number_of_NotifyPresenceReceived,1, int, "%d");
485

486 487 488
	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*/
489 490 491 492

	linphone_core_manager_destroy(pauline);
}

Ghislain MARY's avatar
Ghislain MARY committed
493
test_t presence_tests[] = {
jehan's avatar
jehan committed
494
	TEST_ONE_TAG("Simple Subscribe", simple_subscribe,"presence"),
495
	TEST_NO_TAG("Simple Subscribe with friend from rc", simple_subscribe_with_friend_from_rc),
496 497 498
	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"),*/
499 500 501 502 503
	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
504 505
};

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