diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 9820ae4de..bb0ae00ce 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -220,28 +220,26 @@ static void call_received(SalOp *h){ /* first check if we can answer successfully to this invite */ if (linphone_presence_model_get_basic_status(lc->presence_model) == LinphonePresenceBasicStatusClosed) { - LinphonePresenceActivity activity = LinphonePresenceActivityOffline; - if (linphone_presence_model_get_activity(lc->presence_model, &activity, NULL)) { - switch (activity) { - case LinphonePresenceActivityBusy: - sal_call_decline(h,SalReasonBusy,NULL); - break; - case LinphonePresenceActivityAppointment: - case LinphonePresenceActivityMeeting: - case LinphonePresenceActivityOffline: - case LinphonePresenceActivityWorship: - sal_call_decline(h,SalReasonTemporarilyUnavailable,NULL); - break; - case LinphonePresenceActivityPermanentAbsence: - if (lc->alt_contact != NULL) - sal_call_decline(h,SalReasonRedirect,lc->alt_contact); - break; - default: - break; - } - sal_op_release(h); - return; + LinphonePresenceActivity *activity = linphone_presence_model_get_activity(lc->presence_model); + switch (linphone_presence_activity_get_type(activity)) { + case LinphonePresenceActivityBusy: + sal_call_decline(h,SalReasonBusy,NULL); + break; + case LinphonePresenceActivityAppointment: + case LinphonePresenceActivityMeeting: + case LinphonePresenceActivityOffline: + case LinphonePresenceActivityWorship: + sal_call_decline(h,SalReasonTemporarilyUnavailable,NULL); + break; + case LinphonePresenceActivityPermanentAbsence: + if (lc->alt_contact != NULL) + sal_call_decline(h,SalReasonRedirect,lc->alt_contact); + break; + default: + break; } + sal_op_release(h); + return; } if (!linphone_core_can_we_add_call(lc)){/*busy*/ diff --git a/coreapi/friend.c b/coreapi/friend.c index e02078319..3e3181888 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -280,10 +280,8 @@ LinphoneSubscribePolicy linphone_friend_get_inc_subscribe_policy(const LinphoneF LinphoneOnlineStatus linphone_friend_get_status(const LinphoneFriend *lf){ LinphoneOnlineStatus online_status = LinphoneStatusOffline; LinphonePresenceBasicStatus basic_status = LinphonePresenceBasicStatusClosed; - LinphonePresenceActivity activity = LinphonePresenceActivityUnknown; - char *activity_description = NULL; + LinphonePresenceActivity *activity = NULL; unsigned int nb_activities = 0; - int err = 0; if (lf->presence != NULL) { basic_status = linphone_presence_model_get_basic_status(lf->presence); @@ -298,60 +296,58 @@ LinphoneOnlineStatus linphone_friend_get_status(const LinphoneFriend *lf){ nb_activities = 1; } if (nb_activities == 1) { - err = linphone_presence_model_get_activity(lf->presence, &activity, &activity_description); - if (err == 0) { - switch (activity) { - case LinphonePresenceActivityBreakfast: - case LinphonePresenceActivityDinner: - case LinphonePresenceActivityLunch: - case LinphonePresenceActivityMeal: - online_status = LinphoneStatusOutToLunch; - break; - case LinphonePresenceActivityAppointment: - case LinphonePresenceActivityMeeting: - case LinphonePresenceActivityPerformance: - case LinphonePresenceActivityPresentation: - case LinphonePresenceActivitySpectator: - case LinphonePresenceActivityWorking: - case LinphonePresenceActivityWorship: - online_status = LinphoneStatusDoNotDisturb; - break; - case LinphonePresenceActivityAway: - case LinphonePresenceActivitySleeping: - online_status = LinphoneStatusAway; - break; - case LinphonePresenceActivityHoliday: - case LinphonePresenceActivityTravel: - case LinphonePresenceActivityVacation: - online_status = LinphoneStatusVacation; - break; - case LinphonePresenceActivityBusy: - case LinphonePresenceActivityLookingForWork: - case LinphonePresenceActivityPlaying: - case LinphonePresenceActivityShopping: - case LinphonePresenceActivityTV: - online_status = LinphoneStatusBusy; - break; - case LinphonePresenceActivityInTransit: - case LinphonePresenceActivitySteering: - online_status = LinphoneStatusBeRightBack; - break; - case LinphonePresenceActivityOnThePhone: - online_status = LinphoneStatusOnThePhone; - break; - case LinphonePresenceActivityOther: - case LinphonePresenceActivityPermanentAbsence: - online_status = LinphoneStatusMoved; - break; - case LinphonePresenceActivityUnknown: - /* Rely on the basic status information. */ - break; - case LinphonePresenceActivityOnline: - case LinphonePresenceActivityOffline: - /* Should not happen! */ - ms_warning("LinphonePresenceActivityOnline or LinphonePresenceActivityOffline should not happen here!"); - break; - } + activity = linphone_presence_model_get_activity(lf->presence); + switch (linphone_presence_activity_get_type(activity)) { + case LinphonePresenceActivityBreakfast: + case LinphonePresenceActivityDinner: + case LinphonePresenceActivityLunch: + case LinphonePresenceActivityMeal: + online_status = LinphoneStatusOutToLunch; + break; + case LinphonePresenceActivityAppointment: + case LinphonePresenceActivityMeeting: + case LinphonePresenceActivityPerformance: + case LinphonePresenceActivityPresentation: + case LinphonePresenceActivitySpectator: + case LinphonePresenceActivityWorking: + case LinphonePresenceActivityWorship: + online_status = LinphoneStatusDoNotDisturb; + break; + case LinphonePresenceActivityAway: + case LinphonePresenceActivitySleeping: + online_status = LinphoneStatusAway; + break; + case LinphonePresenceActivityHoliday: + case LinphonePresenceActivityTravel: + case LinphonePresenceActivityVacation: + online_status = LinphoneStatusVacation; + break; + case LinphonePresenceActivityBusy: + case LinphonePresenceActivityLookingForWork: + case LinphonePresenceActivityPlaying: + case LinphonePresenceActivityShopping: + case LinphonePresenceActivityTV: + online_status = LinphoneStatusBusy; + break; + case LinphonePresenceActivityInTransit: + case LinphonePresenceActivitySteering: + online_status = LinphoneStatusBeRightBack; + break; + case LinphonePresenceActivityOnThePhone: + online_status = LinphoneStatusOnThePhone; + break; + case LinphonePresenceActivityOther: + case LinphonePresenceActivityPermanentAbsence: + online_status = LinphoneStatusMoved; + break; + case LinphonePresenceActivityUnknown: + /* Rely on the basic status information. */ + break; + case LinphonePresenceActivityOnline: + case LinphonePresenceActivityOffline: + /* Should not happen! */ + ms_warning("LinphonePresenceActivityOnline or LinphonePresenceActivityOffline should not happen here!"); + break; } } } diff --git a/coreapi/help/buddy_status.c b/coreapi/help/buddy_status.c index 4f9db8ea7..4f1f64906 100644 --- a/coreapi/help/buddy_status.c +++ b/coreapi/help/buddy_status.c @@ -51,15 +51,12 @@ static void stop(int signum){ * presence state change notification callback */ static void notify_presence_recv_updated (LinphoneCore *lc, LinphoneFriend *friend) { - LinphonePresenceActivity activity = LinphonePresenceActivityOffline; const LinphonePresenceModel* model = linphone_friend_get_presence_model(friend); const LinphoneAddress* friend_address = linphone_friend_get_address(friend); - char *description = NULL; - linphone_presence_model_get_activity(model, &activity, &description); - printf("New state state [%s%s%s] for user id [%s] \n" - ,linphone_presence_activity_to_string(activity) - ,(description == NULL) ? "" : ": " - ,(description == NULL) ? "" : description + LinphonePresenceActivity *activity = linphone_presence_model_get_activity(model); + char *activity_str = linphone_presence_activity_to_string(activity); + printf("New state state [%s] for user id [%s] \n" + ,activity_str ,linphone_address_as_string (friend_address)); } static void new_subscription_request (LinphoneCore *lc, LinphoneFriend *friend, const char* url) { diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index ebd674e41..3d391da99 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -3645,52 +3645,52 @@ void linphone_core_set_delayed_timeout(LinphoneCore *lc, int seconds){ void linphone_core_set_presence_info(LinphoneCore *lc, int minutes_away, const char *contact, LinphoneOnlineStatus os) { LinphonePresenceModel *presence = NULL; char *description = NULL; - LinphonePresenceActivity activity = LinphonePresenceActivityUnknown; + LinphonePresenceActivityType acttype = LinphonePresenceActivityUnknown; switch (os) { case LinphoneStatusOffline: - activity = LinphonePresenceActivityOffline; + acttype = LinphonePresenceActivityOffline; break; case LinphoneStatusOnline: - activity = LinphonePresenceActivityOnline; + acttype = LinphonePresenceActivityOnline; break; case LinphoneStatusBusy: - activity = LinphonePresenceActivityBusy; + acttype = LinphonePresenceActivityBusy; break; case LinphoneStatusBeRightBack: - activity = LinphonePresenceActivityInTransit; + acttype = LinphonePresenceActivityInTransit; break; case LinphoneStatusAway: - activity = LinphonePresenceActivityAway; + acttype = LinphonePresenceActivityAway; break; case LinphoneStatusOnThePhone: - activity = LinphonePresenceActivityOnThePhone; + acttype = LinphonePresenceActivityOnThePhone; break; case LinphoneStatusOutToLunch: - activity = LinphonePresenceActivityLunch; + acttype = LinphonePresenceActivityLunch; break; case LinphoneStatusDoNotDisturb: - activity = LinphonePresenceActivityBusy; + acttype = LinphonePresenceActivityBusy; description = "Do not disturb"; break; case LinphoneStatusMoved: - activity = LinphonePresenceActivityPermanentAbsence; + acttype = LinphonePresenceActivityPermanentAbsence; break; case LinphoneStatusAltService: - activity = LinphonePresenceActivityBusy; + acttype = LinphonePresenceActivityBusy; description = "Using another messaging service"; break; case LinphoneStatusPending: - activity = LinphonePresenceActivityOther; + acttype = LinphonePresenceActivityOther; description = "Waiting for user acceptance"; break; case LinphoneStatusVacation: - activity = LinphonePresenceActivityVacation; + acttype = LinphonePresenceActivityVacation; break; case LinphoneStatusEnd: ms_warning("Invalid status LinphoneStatusEnd"); return; } - presence = linphone_presence_model_new_with_activity(activity, description); + presence = linphone_presence_model_new_with_activity(acttype, description); linphone_core_set_presence_model(lc, minutes_away, contact, presence); } @@ -3718,14 +3718,12 @@ void linphone_core_set_presence_model(LinphoneCore *lc, int minutes_away, const } LinphoneOnlineStatus linphone_core_get_presence_info(const LinphoneCore *lc){ - LinphonePresenceActivity activity = LinphonePresenceActivityOffline; - char *description = NULL; + LinphonePresenceActivity *activity = NULL; + const char *description = NULL; - if ((lc->presence_model == NULL) - || (linphone_presence_model_get_activity(lc->presence_model, &activity, &description) < 0)) - return LinphoneStatusOffline; - - switch (activity) { + activity = linphone_presence_model_get_activity(lc->presence_model); + description = linphone_presence_activity_get_description(activity); + switch (linphone_presence_activity_get_type(activity)) { case LinphonePresenceActivityOffline: return LinphoneStatusOffline; case LinphonePresenceActivityOnline: diff --git a/coreapi/linphonepresence.h b/coreapi/linphonepresence.h index cae432afa..c743454d0 100644 --- a/coreapi/linphonepresence.h +++ b/coreapi/linphonepresence.h @@ -138,7 +138,7 @@ typedef enum LinphonePresenceActivity { /** The person is participating in religious rites. */ LinphonePresenceActivityWorship -} LinphonePresenceActivity; +} LinphonePresenceActivityType; /** * Structure holding the information about the presence of a person. @@ -150,6 +150,26 @@ struct _LinphonePresenceModel; */ typedef struct _LinphonePresenceModel LinphonePresenceModel; +/** + * Structure holding the information about a presence activity. + */ +struct _LinphonePresenceActivity; + +/** + * Presence activity type holding information about a presence activity. + */ +typedef struct _LinphonePresenceActivity LinphonePresenceActivity; + +/** + * Structure holding the information about a presence note. + */ +struct _LinphonePresenceNote; + +/** + * Presence note type holding information about a presence note. + */ +typedef struct _LinphonePresenceNote LinphonePresenceNote; + /** @@ -172,7 +192,7 @@ LINPHONE_PUBLIC LinphonePresenceModel * linphone_presence_model_new(void); * * The created presence model has the activity specified in the parameters. */ -LINPHONE_PUBLIC LinphonePresenceModel * linphone_presence_model_new_with_activity(LinphonePresenceActivity activity, const char *description); +LINPHONE_PUBLIC LinphonePresenceModel * linphone_presence_model_new_with_activity(LinphonePresenceActivityType activity, const char *description); /** * @brief Creates a presence model specifying an activity and adding a note. @@ -186,7 +206,7 @@ LINPHONE_PUBLIC LinphonePresenceModel * linphone_presence_model_new_with_activit * * The created presence model has the activity and the note specified in the parameters. */ -LINPHONE_PUBLIC LinphonePresenceModel * linphone_presence_model_new_with_activity_and_note(LinphonePresenceActivity activity, const char *description, const char *note, const char *lang); +LINPHONE_PUBLIC LinphonePresenceModel * linphone_presence_model_new_with_activity_and_note(LinphonePresenceActivityType activity, const char *description, const char *note, const char *lang); /** * @brief Deletes a presence model. @@ -220,39 +240,33 @@ LINPHONE_PUBLIC unsigned int linphone_presence_model_nb_activities(const Linphon * @brief Gets the nth activity of a presence model. * @param[in] model The #LinphonePresenceModel object to get the activity from. * @param[in] idx The index of the activity to get (the first activity having the index 0). - * @param[out] activity The returned #LinphonePresenceActivity (may not be changed in case of error). - * @param[out] description The description of the returned #LinphonePresenceActivity (may not be changed in case of error). - * @return 0 if successful, a value < 0 in case of error. + * @return A pointer to a #LinphonePresenceActivity object if successful, NULL otherwise. */ -LINPHONE_PUBLIC int linphone_presence_model_get_nth_activity(const LinphonePresenceModel *model, unsigned int idx, LinphonePresenceActivity *activity, char **description); +LINPHONE_PUBLIC LinphonePresenceActivity * linphone_presence_model_get_nth_activity(const LinphonePresenceModel *model, unsigned int idx); /** * @brief Gets the first activity of a presence model (there is usually only one). * @param[in] model The #LinphonePresenceModel object to get the activity from. - * @param[out] activity The returned #LinphonePresenceActivity (may not be changed in case of error). - * @param[out] description The description of the returned #LinphonePresenceActivity (may not be changed in case of error). - * @return 0 if successful, a value < 0 in case of error. + * @return A #LinphonePresenceActivity object if successful, NULL otherwise. */ -LINPHONE_PUBLIC int linphone_presence_model_get_activity(const LinphonePresenceModel *model, LinphonePresenceActivity *activity, char **description); +LINPHONE_PUBLIC LinphonePresenceActivity * linphone_presence_model_get_activity(const LinphonePresenceModel *model); /** * @brief Sets the activity of a presence model (limits to only one activity). * @param[in] model The #LinphonePresenceModel object for which to set the activity. - * @param[in] activity The #LinphonePresenceActivity to set for the model. + * @param[in] activity The #LinphonePresenceActivityType to set for the model. * @param[in] description An additional description of the activity to set for the model. Can be NULL if no additional description is to be added. * @return 0 if successful, a value < 0 in case of error. */ -LINPHONE_PUBLIC int linphone_presence_model_set_activity(LinphonePresenceModel *model, LinphonePresenceActivity activity, const char *description); +LINPHONE_PUBLIC int linphone_presence_model_set_activity(LinphonePresenceModel *model, LinphonePresenceActivityType activity, const char *description); /** * @brief Gets the first note of a presence model (there is usually only one). * @param[in] model The #LinphonePresenceModel object to get the note from. * @param[in] lang The language of the note to get. Can be NULL to a note that has no language specified or to get the first note whatever language it is written into. - * @return A pointer to dynamically allocated string in case of success, NULL otherwise. - * - * The string that is returned MUST be freed using ms_free(). + * @return A pointer to a #LinphonePresenceNote object if successful, NULL otherwise. */ -LINPHONE_PUBLIC char * linphone_presence_model_get_note(const LinphonePresenceModel *model, const char *lang); +LINPHONE_PUBLIC LinphonePresenceNote * linphone_presence_model_get_note(const LinphonePresenceModel *model, const char *lang); /** * @brief Adds a note to a presence model. @@ -274,10 +288,40 @@ LINPHONE_PUBLIC int linphone_presence_model_clear_notes(LinphonePresenceModel *m /** * @brief Gets the string representation of a presence activity. - * @param[in] activity The #LinphonePresenceActivity for which to get a string representation. - * @return A pointer to the string representing the given activity. + * @param[in] activity A pointer to the #LinphonePresenceActivity object for which to get a string representation. + * @return A pointer a dynamically allocated string representing the given activity. + * + * The returned string is to be freed by calling ms_free(). */ -LINPHONE_PUBLIC const char * linphone_presence_activity_to_string(LinphonePresenceActivity activity); +LINPHONE_PUBLIC char * linphone_presence_activity_to_string(const LinphonePresenceActivity * activity); + +/** + * @brief Gets the activity type of a presence activity. + * @param[in] activity A pointer to the #LinphonePresenceActivity for which to get the type. + * @return The #LinphonePresenceActivityType of the activity. + */ +LINPHONE_PUBLIC LinphonePresenceActivityType linphone_presence_activity_get_type(const LinphonePresenceActivity *activity); + +/** + * @brief Gets the description of a presence activity. + * @param[in] activity A pointer to the #LinphonePresenceActivity for which to get the description. + * @return A pointer to the description string of the presence activity, or NULL if no description is specified. + */ +LINPHONE_PUBLIC const char * linphone_presence_activity_get_description(const LinphonePresenceActivity *activity); + +/** + * @brief Gets the content of a presence note. + * @param[in] note A pointer to the #LinphonePresenceNote for which to get the content. + * @return A pointer to the content of the presence note. + */ +LINPHONE_PUBLIC const char * linphone_presence_note_get_content(const LinphonePresenceNote *note); + +/** + * @brief Gets the language of a presence note. + * @param[in] note A pointer to the #LinphonePresenceNote for which to get the language. + * @return A pointer to the language string of the presence note, or NULL if no language is specified. + */ +LINPHONE_PUBLIC const char * linphone_presence_note_get_lang(const LinphonePresenceNote *note); /** diff --git a/coreapi/presence.c b/coreapi/presence.c index ddce8fc29..7758ba91d 100644 --- a/coreapi/presence.c +++ b/coreapi/presence.c @@ -48,7 +48,7 @@ struct _LinphonePresenceService { }; struct _LinphonePresenceActivity { - LinphonePresenceActivity activity; + LinphonePresenceActivityType type; char *description; }; @@ -193,9 +193,9 @@ static void presence_service_add_note(struct _LinphonePresenceService *service, service->notes = ms_list_append(service->notes, note); } -static struct _LinphonePresenceActivity * presence_activity_new(LinphonePresenceActivity activity, const char *description) { +static struct _LinphonePresenceActivity * presence_activity_new(LinphonePresenceActivityType acttype, const char *description) { struct _LinphonePresenceActivity *act = ms_new0(struct _LinphonePresenceActivity, 1); - act->activity = activity; + act->type = acttype; if (description != NULL) { act->description = ms_strdup(description); } @@ -315,15 +315,11 @@ static void presence_model_clear_activities(LinphonePresenceModel *model) { ms_list_for_each(model->persons, (MSIterateFunc)presence_person_clear_activities); } -static int presence_model_add_activity(LinphonePresenceModel *model, LinphonePresenceActivity activity, const char *description) { +static int presence_model_add_activity(LinphonePresenceModel *model, LinphonePresenceActivityType acttype, const char *description) { char *id = NULL; struct _LinphonePresencePerson *person = NULL; struct _LinphonePresenceActivity *act = NULL; - /* Do not add activity for special cases Offline and Online. */ - if ((activity == LinphonePresenceActivityOffline) || (activity == LinphonePresenceActivityOnline)) - return 0; - if (ms_list_size(model->persons) == 0) { /* There is no person in the presence model, add one. */ id = generate_presence_id(); @@ -336,7 +332,7 @@ static int presence_model_add_activity(LinphonePresenceModel *model, LinphonePre /* Add the activity to the first person in the model. */ person = (struct _LinphonePresencePerson *)ms_list_nth_data(model->persons, 0); } - act = presence_activity_new(activity, description); + act = presence_activity_new(acttype, description); if (act == NULL) return -1; presence_person_add_activity(person, act); @@ -376,7 +372,7 @@ static bool_t presence_activity_equals(const struct _LinphonePresenceActivity *a || ((a1->description != NULL) && (a2->description == NULL))) return FALSE; - if (a1->activity != a2->activity) + if (a1->type != a2->type) return FALSE; if ((a1->description != NULL) && (a2->description != NULL)) { @@ -421,18 +417,18 @@ LinphonePresenceModel * linphone_presence_model_new(void) { return ms_new0(LinphonePresenceModel, 1); } -LinphonePresenceModel * linphone_presence_model_new_with_activity(LinphonePresenceActivity activity, const char *description) { +LinphonePresenceModel * linphone_presence_model_new_with_activity(LinphonePresenceActivityType acttype, const char *description) { LinphonePresenceModel *model = linphone_presence_model_new(); if (model != NULL) { - linphone_presence_model_set_activity(model, activity, description); + linphone_presence_model_set_activity(model, acttype, description); } return model; } -LinphonePresenceModel * linphone_presence_model_new_with_activity_and_note(LinphonePresenceActivity activity, const char *description, const char *note, const char *lang) { +LinphonePresenceModel * linphone_presence_model_new_with_activity_and_note(LinphonePresenceActivityType acttype, const char *description, const char *note, const char *lang) { LinphonePresenceModel *model = linphone_presence_model_new(); if (model != NULL) { - linphone_presence_model_set_activity(model, activity, description); + linphone_presence_model_set_activity(model, acttype, description); linphone_presence_model_add_note(model, note, lang); } return model; @@ -451,7 +447,7 @@ void linphone_presence_model_delete(LinphonePresenceModel *model) { } bool_t linphone_presence_model_equals(const LinphonePresenceModel *m1, const LinphonePresenceModel *m2) { - LinphonePresenceActivity activity = LinphonePresenceActivityOffline; + LinphonePresenceActivity *activity = NULL; int nb; int i; @@ -461,14 +457,14 @@ bool_t linphone_presence_model_equals(const LinphonePresenceModel *m1, const Lin /* A null activity is equal to an activity with no activity but a basic status of Closed. */ if (m1 == NULL) { - if ((linphone_presence_model_get_activity(m2, &activity, NULL) < 0) - || (activity != LinphonePresenceActivityOffline)) + activity = linphone_presence_model_get_activity(m2); + if (linphone_presence_activity_get_type(activity) != LinphonePresenceActivityOffline) return FALSE; return TRUE; } if (m2 == NULL) { - if ((linphone_presence_model_get_activity(m2, &activity, NULL) < 0) - || (activity != LinphonePresenceActivityOffline)) + activity = linphone_presence_model_get_activity(m2); + if (linphone_presence_activity_get_type(activity) != LinphonePresenceActivityOffline) return FALSE; return TRUE; } @@ -521,64 +517,41 @@ unsigned int linphone_presence_model_nb_activities(const LinphonePresenceModel * struct _get_activity_st { unsigned int requested_idx; unsigned int current_idx; - LinphonePresenceActivity *activity; - char **description; + struct _LinphonePresenceActivity *activity; }; static void presence_model_get_activity(const struct _LinphonePresencePerson *person, struct _get_activity_st *st) { - struct _LinphonePresenceActivity *activity; unsigned int size = ms_list_size(person->activities); if (st->requested_idx < (st->current_idx + size)) { - activity = (struct _LinphonePresenceActivity *)ms_list_nth_data(person->activities, st->requested_idx - st->current_idx); - *st->activity = activity->activity; - if (st->description != NULL) { - *st->description = activity->description; - } + st->activity = (struct _LinphonePresenceActivity *)ms_list_nth_data(person->activities, st->requested_idx - st->current_idx); } else { st->current_idx += size; } } -int linphone_presence_model_get_nth_activity(const LinphonePresenceModel *model, unsigned int idx, LinphonePresenceActivity *activity, char **description) { +LinphonePresenceActivity * linphone_presence_model_get_nth_activity(const LinphonePresenceModel *model, unsigned int idx) { struct _get_activity_st st; - if ((model == NULL) || (activity == NULL) || (idx >= linphone_presence_model_nb_activities(model))) - return -1; + if ((model == NULL) || (idx >= linphone_presence_model_nb_activities(model))) + return NULL; memset(&st, 0, sizeof(st)); st.requested_idx = idx; - st.activity = activity; - *st.activity = LinphonePresenceActivityUnknown; - if (description != NULL) { - st.description = description; - } ms_list_for_each2(model->persons, (MSIterate2Func)presence_model_get_activity, &st); - return 0; + return st.activity; } -int linphone_presence_model_get_activity(const LinphonePresenceModel *model, LinphonePresenceActivity *activity, char **description) { - if ((model == NULL) || (activity == NULL)) - return -1; - - if (linphone_presence_model_get_nth_activity(model, 0, activity, description) < 0) { - /* There is no activities, base the result on the basic status. */ - LinphonePresenceBasicStatus basic_status = linphone_presence_model_get_basic_status(model); - if (basic_status == LinphonePresenceBasicStatusOpen) - *activity = LinphonePresenceActivityOnline; - else - *activity = LinphonePresenceActivityOffline; - } - - return 0; +LinphonePresenceActivity * linphone_presence_model_get_activity(const LinphonePresenceModel *model) { + return linphone_presence_model_get_nth_activity(model, 0); } -int linphone_presence_model_set_activity(LinphonePresenceModel *model, LinphonePresenceActivity activity, const char *description) { +int linphone_presence_model_set_activity(LinphonePresenceModel *model, LinphonePresenceActivityType acttype, const char *description) { LinphonePresenceBasicStatus basic_status = LinphonePresenceBasicStatusOpen; if (model == NULL) return -1; - switch (activity) { + switch (acttype) { case LinphonePresenceActivityAppointment: case LinphonePresenceActivityBusy: case LinphonePresenceActivityMeeting: @@ -594,7 +567,7 @@ int linphone_presence_model_set_activity(LinphonePresenceModel *model, LinphoneP if (presence_model_set_basic_status(model, basic_status) < 0) return -1; presence_model_clear_activities(model); - if (presence_model_add_activity(model, activity, description) < 0) + if (presence_model_add_activity(model, acttype, description) < 0) return -1; return 0; @@ -653,7 +626,7 @@ static void get_first_presence_service_note(struct _LinphonePresenceService *ser st->note = get_first_presence_note_in_list(service->notes); } -char * linphone_presence_model_get_note(const LinphonePresenceModel *model, const char *lang) { +LinphonePresenceNote * linphone_presence_model_get_note(const LinphonePresenceModel *model, const char *lang) { struct _find_note_st st; if (model == NULL) return NULL; @@ -694,10 +667,7 @@ char * linphone_presence_model_get_note(const LinphonePresenceModel *model, cons } } - if (st.note == NULL) - return NULL; - - return ms_strdup(st.note->content); + return st.note; } int linphone_presence_model_add_note(LinphonePresenceModel *model, const char *note_content, const char *lang) { @@ -892,7 +862,7 @@ static const char *person_prefix = "/pidf:presence/dm:person"; struct _presence_activity_name_map { const char *name; - LinphonePresenceActivity activity; + LinphonePresenceActivityType type; }; static struct _presence_activity_name_map activity_map[] = { @@ -925,35 +895,67 @@ static struct _presence_activity_name_map activity_map[] = { { "worship", LinphonePresenceActivityWorship } }; -static int activity_name_to_linphone_presence_activity(const char *name, LinphonePresenceActivity *activity) { +static int activity_name_to_presence_activity_type(const char *name, LinphonePresenceActivityType *acttype) { unsigned int i; for (i = 0; i < (sizeof(activity_map) / sizeof(activity_map[0])); i++) { if (strcmp(name, activity_map[i].name) == 0) { - *activity = activity_map[i].activity; + *acttype = activity_map[i].type; return 0; } } return -1; } -static const char * presence_activity_to_string(LinphonePresenceActivity activity) { +static const char * presence_activity_type_to_string(LinphonePresenceActivityType acttype) { unsigned int i; for (i = 0; i < (sizeof(activity_map) / sizeof(activity_map[0])); i++) { - if (activity == activity_map[i].activity) { + if (acttype == activity_map[i].type) { return activity_map[i].name; } } return NULL; } -const char * linphone_presence_activity_to_string(LinphonePresenceActivity activity) { - if (activity == LinphonePresenceActivityOffline) - return "offline"; - if (activity == LinphonePresenceActivityOnline) - return "online"; - return presence_activity_to_string(activity); +char * linphone_presence_activity_to_string(const LinphonePresenceActivity *activity) { + LinphonePresenceActivityType acttype = linphone_presence_activity_get_type(activity); + const char *description = linphone_presence_activity_get_description(activity); + const char *acttype_str; + + if (acttype == LinphonePresenceActivityOffline) + acttype_str = "offline"; + else if (acttype == LinphonePresenceActivityOnline) + acttype_str = "online"; + else + acttype_str = presence_activity_type_to_string(acttype); + + return ms_strdup_printf("%s: %s", acttype_str, (description == NULL) ? "" : description); } +LinphonePresenceActivityType linphone_presence_activity_get_type(const LinphonePresenceActivity *activity) { + if (activity == NULL) + return LinphonePresenceActivityOffline; + return activity->type; +} + +const char * linphone_presence_activity_get_description(const LinphonePresenceActivity *activity) { + if (activity == NULL) + return NULL; + return activity->description; +} + +const char * linphone_presence_note_get_content(const LinphonePresenceNote *note) { + if (note == NULL) + return NULL; + return note->content; +} + +const char * linphone_presence_note_get_lang(const LinphonePresenceNote *note) { + if (note == NULL) + return NULL; + return note->lang; +} + + static int process_pidf_xml_presence_person_activities(xmlparsing_context_t *xml_ctx, struct _LinphonePresencePerson *person, unsigned int person_idx) { char xpath_str[MAX_XPATH_LENGTH]; xmlXPathObjectPtr activities_nodes_object; @@ -977,15 +979,15 @@ static int process_pidf_xml_presence_person_activities(xmlparsing_context_t *xml && (activity_node->ns != NULL) && (activity_node->ns->prefix != NULL) && (strcmp((const char *)activity_node->ns->prefix, "rpid") == 0)) { - LinphonePresenceActivity linphone_activity; + LinphonePresenceActivityType acttype; description = (const char *)xmlNodeGetContent(activity_node); if ((description != NULL) && (description[0] == '\0')) { free_xml_text_content(description); description = NULL; } - err = activity_name_to_linphone_presence_activity((const char *)activity_node->name, &linphone_activity); + err = activity_name_to_presence_activity_type((const char *)activity_node->name, &acttype); if (err < 0) break; - activity = presence_activity_new(linphone_activity, description); + activity = presence_activity_new(acttype, description); presence_person_add_activity(person, activity); if (description != NULL) free_xml_text_content(description); } @@ -1172,13 +1174,10 @@ void linphone_core_reject_subscriber(LinphoneCore *lc, LinphoneFriend *lf){ void linphone_core_notify_all_friends(LinphoneCore *lc, LinphonePresenceModel *presence){ MSList *elem; - LinphonePresenceActivity activity = LinphonePresenceActivityOffline; - char *description = NULL; - linphone_presence_model_get_activity(presence, &activity, &description); - ms_message("Notifying all friends that we are [%s%s%s]", - linphone_presence_activity_to_string(activity), - (description == NULL) ? "" : ": ", - (description == NULL) ? "" : description); + LinphonePresenceActivity *activity = linphone_presence_model_get_activity(presence); + char *activity_str = linphone_presence_activity_to_string(activity); + ms_message("Notifying all friends that we are [%s]", activity_str); + if (activity_str != NULL) ms_free(activity_str); for(elem=lc->friends;elem!=NULL;elem=elem->next){ LinphoneFriend *lf=(LinphoneFriend *)elem->data; if (lf->insub){ @@ -1257,6 +1256,26 @@ void linphone_notify_parse_presence(SalOp *op, const char *content_type, const c ms_error("Unknown content type '%s/%s' for presence", content_type, content_subtype); } + /* If no activities are present in the model, add a dummy activity so that linphone_presence_activity_get_type() returns + * the expected result. */ + if (model != NULL) { + LinphonePresenceActivity *activity = linphone_presence_model_get_activity(model); + if (activity == NULL) { + LinphonePresenceBasicStatus basic_status = linphone_presence_model_get_basic_status(model); + LinphonePresenceActivityType acttype; + switch (basic_status) { + case LinphonePresenceBasicStatusOpen: + acttype = LinphonePresenceActivityOnline; + break; + case LinphonePresenceBasicStatusClosed: + default: + acttype = LinphonePresenceActivityOffline; + break; + } + presence_model_add_activity(model, acttype, NULL); + } + } + *result = (SalPresenceModel *)model; } @@ -1370,9 +1389,19 @@ static int write_xml_presence_service(xmlTextWriterPtr writer, struct _LinphoneP return err; } +static bool_t is_valid_activity(struct _LinphonePresenceActivity *activity) { + if ((activity->type == LinphonePresenceActivityOffline) || (activity->type == LinphonePresenceActivityOnline)) + return FALSE; + return TRUE; +} + static int write_xml_presence_activity(xmlTextWriterPtr writer, struct _LinphonePresenceActivity *activity) { - int err = xmlTextWriterStartElementNS(writer, (const xmlChar *)"rpid", - (const xmlChar *)presence_activity_to_string(activity->activity), NULL); + int err; + + if (is_valid_activity(activity) == FALSE) return 0; + + err = xmlTextWriterStartElementNS(writer, (const xmlChar *)"rpid", + (const xmlChar *)presence_activity_type_to_string(activity->type), NULL); if ((err >= 0) && (activity->description != NULL)) { err = xmlTextWriterWriteString(writer, (const xmlChar *)activity->description); } @@ -1387,8 +1416,22 @@ static void write_xml_presence_activity_obj(struct _LinphonePresenceActivity *ac if (err < 0) *st->err = err; } +static void person_has_valid_activity(struct _LinphonePresenceActivity *activity, bool_t *has_valid_activities) { + if (is_valid_activity(activity) == TRUE) *has_valid_activities = TRUE; +} + +static bool_t person_has_valid_activities(struct _LinphonePresencePerson *person) { + bool_t has_valid_activities = FALSE; + ms_list_for_each2(person->activities, (MSIterate2Func)person_has_valid_activity, &has_valid_activities); + return has_valid_activities; +} + static int write_xml_presence_person(xmlTextWriterPtr writer, struct _LinphonePresencePerson *person) { - int err = xmlTextWriterStartElementNS(writer, (const xmlChar *)"dm", (const xmlChar *)"person", NULL); + int err; + + if ((person_has_valid_activities(person) == FALSE) && (person->notes == NULL)) return 0; + + err = xmlTextWriterStartElementNS(writer, (const xmlChar *)"dm", (const xmlChar *)"person", NULL); if (err >= 0) { if (person->id == NULL) { char *text = generate_presence_id(); @@ -1398,7 +1441,7 @@ static int write_xml_presence_person(xmlTextWriterPtr writer, struct _LinphonePr err = xmlTextWriterWriteAttribute(writer, (const xmlChar *)"id", (const xmlChar *)person->id); } } - if ((err >= 0) && ((person->activities_notes != NULL) || (person->activities != NULL))) { + if ((err >= 0) && ((person->activities_notes != NULL) || (person_has_valid_activities(person) == TRUE))) { err = xmlTextWriterStartElementNS(writer, (const xmlChar *)"rpid", (const xmlChar *)"activities", NULL); if ((err >= 0) && (person->activities_notes != NULL)) { struct _presence_note_obj_st st; @@ -1528,16 +1571,14 @@ void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, Sa lf=linphone_find_friend_by_out_subscribe(lc->friends,op); if (lf!=NULL){ - LinphonePresenceActivity activity = LinphonePresenceActivityOffline; - char *description = NULL; + LinphonePresenceActivity *activity = NULL; + char *activity_str; friend=lf->uri; tmp=linphone_address_as_string(friend); - linphone_presence_model_get_activity(presence, &activity, &description); - ms_message("We are notified that [%s] has presence [%s%s%s]", - tmp, - linphone_presence_activity_to_string(activity), - (description == NULL) ? "" : ": ", - (description == NULL) ? "" : description); + activity = linphone_presence_model_get_activity(presence); + activity_str = linphone_presence_activity_to_string(activity); + ms_message("We are notified that [%s] has presence [%s]", tmp, activity_str); + if (activity_str != NULL) ms_free(activity_str); linphone_friend_set_presence_model(lf, presence); lf->subscribe_active=TRUE; if (lc->vtable.notify_presence_recv) diff --git a/tester/presence_tester.c b/tester/presence_tester.c index e7122659f..1363c4045 100644 --- a/tester/presence_tester.c +++ b/tester/presence_tester.c @@ -43,7 +43,7 @@ void new_subscribtion_request(LinphoneCore *lc, LinphoneFriend *lf, const char * void notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf) { stats* counters; - LinphonePresenceActivity activity = LinphonePresenceActivityOffline; + LinphonePresenceActivity *activity = NULL; char* from=linphone_address_as_string(linphone_friend_get_address(lf)); ms_message("New Notify request from [%s] ",from); ms_free(from); @@ -51,8 +51,8 @@ void notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf) { counters->number_of_NotifyReceived++; counters->last_received_presence = linphone_friend_get_presence_model(lf); - linphone_presence_model_get_activity(counters->last_received_presence, &activity, NULL); - switch(activity) { + activity = linphone_presence_model_get_activity(counters->last_received_presence); + switch (linphone_presence_activity_get_type(activity)) { case LinphonePresenceActivityOffline: counters->number_of_LinphonePresenceActivityOffline++; break; case LinphonePresenceActivityOnline: @@ -213,9 +213,10 @@ static void presence_information(void) { LinphoneCoreManager *marie = presence_linphone_core_manager_new("marie"); LinphoneCoreManager *pauline = presence_linphone_core_manager_new("pauline"); LinphonePresenceModel *presence; - LinphonePresenceActivity activity = LinphonePresenceActivityOffline; - char *description = NULL; - char *note = NULL; + LinphonePresenceActivity *activity = NULL; + LinphonePresenceNote *note = NULL; + const char *description = NULL; + const char *note_content = NULL; CU_ASSERT_TRUE(subscribe_to_callee_presence(marie, pauline)); @@ -224,8 +225,10 @@ static void presence_information(void) { linphone_core_set_presence_model(pauline->lc, 0, NULL, presence); wait_core(marie->lc); CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityDinner, 1); - linphone_presence_model_get_activity(marie->stat.last_received_presence, &activity, &description); - CU_ASSERT_EQUAL(activity, LinphonePresenceActivityDinner); + activity = linphone_presence_model_get_activity(marie->stat.last_received_presence); + CU_ASSERT_PTR_NOT_NULL(activity); + CU_ASSERT_EQUAL(linphone_presence_activity_get_type(activity), LinphonePresenceActivityDinner); + description = linphone_presence_activity_get_description(activity); CU_ASSERT_PTR_NULL(description); /* Presence activity with description. */ @@ -233,8 +236,10 @@ static void presence_information(void) { linphone_core_set_presence_model(pauline->lc, 0, NULL, presence); wait_core(marie->lc); CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivitySteering, 1); - linphone_presence_model_get_activity(marie->stat.last_received_presence, &activity, &description); - CU_ASSERT_EQUAL(activity, LinphonePresenceActivitySteering); + activity = linphone_presence_model_get_activity(marie->stat.last_received_presence); + CU_ASSERT_PTR_NOT_NULL(activity); + CU_ASSERT_EQUAL(linphone_presence_activity_get_type(activity), LinphonePresenceActivitySteering); + description = linphone_presence_activity_get_description(activity); CU_ASSERT_PTR_NOT_NULL(description); if (description != NULL) CU_ASSERT_EQUAL(strcmp(description, bike_description), 0); @@ -243,14 +248,19 @@ static void presence_information(void) { linphone_core_set_presence_model(pauline->lc, 0, NULL, presence); wait_core(marie->lc); CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePresenceActivityVacation, 1); - linphone_presence_model_get_activity(marie->stat.last_received_presence, &activity, &description); - CU_ASSERT_EQUAL(activity, LinphonePresenceActivityVacation); + activity = linphone_presence_model_get_activity(marie->stat.last_received_presence); + CU_ASSERT_PTR_NOT_NULL(activity); + CU_ASSERT_EQUAL(linphone_presence_activity_get_type(activity), LinphonePresenceActivityVacation); + description = linphone_presence_activity_get_description(activity); CU_ASSERT_PTR_NULL(description); note = linphone_presence_model_get_note(marie->stat.last_received_presence, NULL); CU_ASSERT_PTR_NOT_NULL(note); if (note != NULL) { - CU_ASSERT_EQUAL(strcmp(note, vacation_note), 0); - ms_free(note); + note_content = linphone_presence_note_get_content(note); + CU_ASSERT_PTR_NOT_NULL(note_content); + if (note_content != NULL) { + CU_ASSERT_EQUAL(strcmp(note_content, vacation_note), 0); + } } linphone_core_manager_destroy(marie);