diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index bb0ae00ce..89bc20846 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -215,6 +215,7 @@ static void call_received(SalOp *h){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h)); LinphoneCall *call; const char *from,*to; + char *alt_contact; LinphoneAddress *from_addr, *to_addr; bool_t prevent_colliding_calls=lp_config_get_int(lc->config,"sip","prevent_colliding_calls",TRUE); @@ -232,8 +233,11 @@ static void call_received(SalOp *h){ sal_call_decline(h,SalReasonTemporarilyUnavailable,NULL); break; case LinphonePresenceActivityPermanentAbsence: - if (lc->alt_contact != NULL) - sal_call_decline(h,SalReasonRedirect,lc->alt_contact); + alt_contact = linphone_presence_model_get_contact(lc->presence_model); + if (alt_contact != NULL) { + sal_call_decline(h,SalReasonRedirect,alt_contact); + ms_free(alt_contact); + } break; default: break; diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 5e1820ce4..3549f34b6 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -3648,11 +3648,6 @@ void linphone_core_set_presence_info(LinphoneCore *lc, int minutes_away, const c LinphonePresenceActivityType acttype = LinphonePresenceActivityUnknown; if (minutes_away>0) lc->minutes_away=minutes_away; - if (lc->alt_contact!=NULL) { - ms_free(lc->alt_contact); - lc->alt_contact=NULL; - } - if (contact) lc->alt_contact=ms_strdup(contact); switch (os) { case LinphoneStatusOffline: @@ -3699,6 +3694,7 @@ void linphone_core_set_presence_info(LinphoneCore *lc, int minutes_away, const c return; } presence = linphone_presence_model_new_with_activity(acttype, description); + linphone_presence_model_set_contact(presence, contact); linphone_core_set_presence_model(lc, presence); } diff --git a/coreapi/linphonepresence.h b/coreapi/linphonepresence.h index c9624bcd9..835ba855b 100644 --- a/coreapi/linphonepresence.h +++ b/coreapi/linphonepresence.h @@ -251,6 +251,22 @@ LINPHONE_PUBLIC bool_t linphone_presence_model_equals(const LinphonePresenceMode */ LINPHONE_PUBLIC LinphonePresenceBasicStatus linphone_presence_model_get_basic_status(const LinphonePresenceModel *model); +/** + * @brief Gets the contact of a presence model. + * @param[in] model The #LinphonePresenceModel object to get the contact from. + * @return A pointer to a dynamically allocated string containing the contact, or NULL if no contact is found. + * + * The returned string is to be freed by calling ms_free(). + */ +LINPHONE_PUBLIC char * linphone_presence_model_get_contact(const LinphonePresenceModel *model); + +/** + * @brief Sets the contact of a presence model. + * @param[in] model The #LinphonePresenceModel object for which to set the contact. + * @param[in] contact The contact string to set. + */ +LINPHONE_PUBLIC void linphone_presence_model_set_contact(LinphonePresenceModel *model, const char *contact); + /** * @brief Gets the number of activities included in the presence model. * @param[in] model The #LinphonePresenceModel object to get the number of activities from. diff --git a/coreapi/presence.c b/coreapi/presence.c index 52289d85b..260b2a47d 100644 --- a/coreapi/presence.c +++ b/coreapi/presence.c @@ -539,6 +539,33 @@ LinphonePresenceBasicStatus linphone_presence_model_get_basic_status(const Linph return status; } +static void presence_model_find_contact(struct _LinphonePresenceService *service, char **contact) { + if ((service->contact != NULL) && (*contact == NULL)) + *contact = service->contact; +} + +char * linphone_presence_model_get_contact(const LinphonePresenceModel *model) { + char *contact = NULL; + ms_list_for_each2(model->services, (MSIterate2Func)presence_model_find_contact, &contact); + if (contact == NULL) return NULL; + return ms_strdup(contact); +} + +void linphone_presence_model_set_contact(LinphonePresenceModel *model, const char *contact) { + struct _LinphonePresenceService *service; + if (model != NULL) { + service = (struct _LinphonePresenceService *)ms_list_nth_data(model->services, 0); + if (service != NULL) { + if (service->contact != NULL) + ms_free(service->contact); + if (contact != NULL) + service->contact = ms_strdup(contact); + else + service->contact = NULL; + } + } +} + static void presence_model_count_activities(const struct _LinphonePresencePerson *person, unsigned int *nb) { *nb += ms_list_size(person->activities); } diff --git a/coreapi/private.h b/coreapi/private.h index d83ab161a..f1b0ccee2 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -601,7 +601,6 @@ struct _LinphoneCore MSList *subscribers; /* unknown subscribers */ int minutes_away; LinphonePresenceModel *presence_model; - char *alt_contact; void *data; char *play_file; char *rec_file; diff --git a/tester/presence_tester.c b/tester/presence_tester.c index 029d2e01a..3ca907d92 100644 --- a/tester/presence_tester.c +++ b/tester/presence_tester.c @@ -210,6 +210,7 @@ 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"; + const char *contact = "sip:toto@example.com"; LinphoneCoreManager *marie = presence_linphone_core_manager_new("marie"); LinphoneCoreManager *pauline = presence_linphone_core_manager_new("pauline"); LinphonePresenceModel *presence; @@ -217,6 +218,7 @@ static void presence_information(void) { LinphonePresenceNote *note = NULL; const char *description = NULL; const char *note_content = NULL; + char *contact2; CU_ASSERT_TRUE(subscribe_to_callee_presence(marie, pauline)); @@ -263,6 +265,19 @@ static void presence_information(void) { } } + /* 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); + wait_core(marie->lc); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityOnThePhone, 1); + contact2 = linphone_presence_model_get_contact(presence); + CU_ASSERT_PTR_NOT_NULL(contact2); + if (contact2 != NULL) { + CU_ASSERT_EQUAL(strcmp(contact, contact2), 0); + ms_free(contact2); + } + linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); }