diff --git a/coreapi/linphonepresence.h b/coreapi/linphonepresence.h index b4cef5252..ede8e9358 100644 --- a/coreapi/linphonepresence.h +++ b/coreapi/linphonepresence.h @@ -382,6 +382,36 @@ LINPHONE_PUBLIC int linphone_presence_model_add_service(LinphonePresenceModel *m */ LINPHONE_PUBLIC int linphone_presence_model_clear_services(LinphonePresenceModel *model); +/** + * @brief Gets the number of persons included in the presence model. + * @param[in] model The #LinphonePresenceModel object to get the number of persons from. + * @return The number of persons included in the #LinphonePresenceModel object. + */ +LINPHONE_PUBLIC unsigned int linphone_presence_model_nb_persons(const LinphonePresenceModel *model); + +/** + * @brief Gets the nth person of a presence model. + * @param[in] model The #LinphonePresenceModel object to get the person from. + * @param[in] idx The index of the person to get (the first person having the index 0). + * @return A pointer to a #LinphonePresencePerson object if successful, NULL otherwise. + */ +LINPHONE_PUBLIC LinphonePresencePerson * linphone_presence_model_get_nth_person(const LinphonePresenceModel *model, unsigned int idx); + +/** + * @brief Adds a person to a presence model. + * @param[in] model The #LinphonePresenceModel object for which to add a person. + * @param[in] person The #LinphonePresencePerson object to add to the model. + * @return 0 if successful, a value < 0 in case of error. + */ +LINPHONE_PUBLIC int linphone_presence_model_add_person(LinphonePresenceModel *model, LinphonePresencePerson *person); + +/** + * @brief Clears the persons of a presence model. + * @param[in] model The #LinphonePresenceModel object for which to clear the persons. + * @return 0 if successful, a value < 0 in case of error. + */ +LINPHONE_PUBLIC int linphone_presence_model_clear_persons(LinphonePresenceModel *model); + /***************************************************************************** * PRESENCE SERVICE FUNCTIONS TO GET ACCESS TO ALL FUNCTIONALITIES * @@ -398,6 +428,23 @@ LINPHONE_PUBLIC int linphone_presence_model_clear_services(LinphonePresenceModel */ LINPHONE_PUBLIC LinphonePresenceService * linphone_presence_service_new(const char *id, LinphonePresenceBasicStatus, const char *contact); +/** + * @brief Gets the id of a presence service. + * @param[in] service The #LinphonePresenceService object to get the id from. + * @return A pointer to a dynamically allocated string containing the id, or NULL in case of error. + * + * The returned string is to be freed by calling ms_free(). + */ +LINPHONE_PUBLIC char * linphone_presence_service_get_id(const LinphonePresenceService *service); + +/** + * @brief Sets the id of a presence service. + * @param[in] service The #LinphonePresenceService object for which to set the id. + * @param[in] id The id string to set. Can be NULL to generate it automatically. + * @return 0 if successful, a value < 0 in case of error. + */ +LINPHONE_PUBLIC int linphone_presence_service_set_id(LinphonePresenceService *service, const char *id); + /** * @brief Gets the basic status of a presence service. * @param[in] service The #LinphonePresenceService object to get the basic status from. @@ -423,14 +470,74 @@ LINPHONE_PUBLIC int linphone_presence_service_set_basic_status(LinphonePresenceS LINPHONE_PUBLIC char * linphone_presence_service_get_contact(const LinphonePresenceService *service); /** - * @brief Sets the contact of a presence model. - * @param[in] model The #LinphonePresenceModel object for which to set the contact. + * @brief Sets the contact of a presence service. + * @param[in] service The #LinphonePresenceService object for which to set the contact. * @param[in] contact The contact string to set. * @return 0 if successful, a value < 0 in case of error. */ LINPHONE_PUBLIC int linphone_presence_service_set_contact(LinphonePresenceService *service, const char *contact); +/***************************************************************************** + * PRESENCE PERSON FUNCTIONS TO GET ACCESS TO ALL FUNCTIONALITIES * + ****************************************************************************/ + +/** + * @brief Creates a presence person. + * @param[in] id The id of the presence person to be created. Can be NULL to generate it automatically. + * @returns The created presence person, NULL on error. + */ +LINPHONE_PUBLIC LinphonePresencePerson * linphone_presence_person_new(const char *id); + +/** + * @brief Gets the id of a presence person. + * @param[in] person The #LinphonePresencePerson object to get the id from. + * @return A pointer to a dynamically allocated string containing the id, or NULL in case of error. + * + * The returned string is to be freed by calling ms_free(). + */ +LINPHONE_PUBLIC char * linphone_presence_person_get_id(const LinphonePresencePerson *person); + +/** + * @brief Sets the id of a presence person. + * @param[in] person The #LinphonePresencePerson object for which to set the id. + * @param[in] id The id string to set. Can be NULL to generate it automatically. + * @return 0 if successful, a value < 0 in case of error. + */ +LINPHONE_PUBLIC int linphone_presence_person_set_id(LinphonePresencePerson *person, const char *id); + +/** + * @brief Gets the number of activities included in the presence person. + * @param[in] person The #LinphonePresencePerson object to get the number of activities from. + * @return The number of activities included in the #LinphonePresencePerson object. + */ +LINPHONE_PUBLIC unsigned int linphone_presence_person_nb_activities(const LinphonePresencePerson *person); + +/** + * @brief Gets the nth activity of a presence person. + * @param[in] person The #LinphonePresencePerson object to get the activity from. + * @param[in] idx The index of the activity to get (the first activity having the index 0). + * @return A pointer to a #LinphonePresenceActivity object if successful, NULL otherwise. + */ +LINPHONE_PUBLIC LinphonePresenceActivity * linphone_presence_person_get_nth_activity(const LinphonePresencePerson *person, unsigned int idx); + +/** + * @brief Adds an activity to a presence person. + * @param[in] person The #LinphonePresencePerson object for which to add an activity. + * @param[in] activity The #LinphonePresenceActivity object to add to the person. + * @return 0 if successful, a value < 0 in case of error. + */ +LINPHONE_PUBLIC int linphone_presence_person_add_activity(LinphonePresencePerson *person, LinphonePresenceActivity *activity); + +/** + * @brief Clears the activities of a presence person. + * @param[in] person The #LinphonePresencePerson object for which to clear the activities. + * @return 0 if successful, a value < 0 in case of error. + */ +LINPHONE_PUBLIC int linphone_presence_person_clear_activities(LinphonePresencePerson *person); + + + /***************************************************************************** * PRESENCE ACTIVITY FUNCTIONS TO GET ACCESS TO ALL FUNCTIONALITIES * ****************************************************************************/ @@ -562,6 +669,34 @@ void linphone_presence_service_set_user_data(LinphonePresenceService *service, v */ void * linphone_presence_service_get_user_data(LinphonePresenceService *service); +/** + * Increase the reference count of the #LinphonePresencePerson object. + * @param[in] person The #LinphonePresencePerson object for which the reference count is to be increased. + * @return The #LinphonePresencePerson object with the increased reference count. + */ +LinphonePresencePerson * linphone_presence_person_ref(LinphonePresencePerson *person); + +/** + * Decrease the reference count of the #LinphonePresencePerson object and destroy it if it reaches 0. + * @param[in] person The #LinphonePresencePerson object for which the reference count is to be decreased. + * @return The #LinphonePresencePerson object if the reference count is still positive, NULL if the object has been destroyed. + */ +LinphonePresencePerson * linphone_presence_person_unref(LinphonePresencePerson *person); + +/** + * Sets the user data of a #LinphonePresencePerson object. + * @param[in] person The #LinphonePresencePerson object for which to set the user data. + * @param[in] user_data A pointer to the user data to set. + */ +void linphone_presence_person_set_user_data(LinphonePresencePerson *person, void *user_data); + +/** + * Gets the user data of a #LinphonePresencePerson object. + * @param[in] person The #LinphonePresencePerson object for which to get the user data. + * @return A pointer to the user data. + */ +void * linphone_presence_person_get_user_data(LinphonePresencePerson *person); + /** * Increase the reference count of the #LinphonePresenceActivity object. * @param[in] activity The #LinphonePresenceActivity object for which the reference count is to be increased. diff --git a/coreapi/presence.c b/coreapi/presence.c index 314946c4f..ef6af42d1 100644 --- a/coreapi/presence.c +++ b/coreapi/presence.c @@ -62,6 +62,8 @@ struct _LinphonePresenceActivity { }; struct _LinphonePresencePerson { + void *user_data; + int refcnt; char *id; MSList *activities; /**< A list of _LinphonePresenceActivity structures. */ MSList *activities_notes; /**< A list of _LinphonePresenceNote structures. */ @@ -249,6 +251,7 @@ static char * timestamp_to_string(time_t timestamp) { static LinphonePresencePerson * presence_person_new(const char *id, time_t timestamp) { LinphonePresencePerson *person = ms_new0(LinphonePresencePerson, 1); + person->refcnt = 1; if (id != NULL) { person->id = ms_strdup(id); } @@ -272,10 +275,6 @@ static void presence_person_delete(LinphonePresencePerson *person) { ms_free(person); } -static void presence_person_add_activity(LinphonePresencePerson *person, LinphonePresenceActivity *activity) { - person->activities = ms_list_append(person->activities, activity); -} - static void presence_person_add_activities_note(LinphonePresencePerson *person, LinphonePresenceNote *note) { person->activities_notes = ms_list_append(person->activities_notes, note); } @@ -284,12 +283,6 @@ static void presence_person_add_note(LinphonePresencePerson *person, LinphonePre person->notes = ms_list_append(person->notes, note); } -static void presence_person_clear_activities(LinphonePresencePerson *person) { - ms_list_for_each(person->activities, (MSIterateFunc)linphone_presence_activity_unref); - ms_list_free(person->activities); - person->activities = NULL; -} - static void presence_model_add_person(LinphonePresenceModel *model, LinphonePresencePerson *person) { model->persons = ms_list_append(model->persons, person); } @@ -309,7 +302,7 @@ static void presence_model_delete(LinphonePresenceModel *model) { ms_list_for_each(model->services, (MSIterateFunc)linphone_presence_service_unref); ms_list_free(model->services); - ms_list_for_each(model->persons, (MSIterateFunc)presence_person_delete); + ms_list_for_each(model->persons, (MSIterateFunc)linphone_presence_person_unref); ms_list_free(model->persons); ms_list_for_each(model->notes, (MSIterateFunc)linphone_presence_note_unref); ms_list_free(model->notes); @@ -498,14 +491,14 @@ int linphone_presence_model_add_activity(LinphonePresenceModel *model, LinphoneP person = (LinphonePresencePerson *)ms_list_nth_data(model->persons, 0); } - presence_person_add_activity(person, activity); + linphone_presence_person_add_activity(person, activity); return 0; } int linphone_presence_model_clear_activities(LinphonePresenceModel *model) { if (model == NULL) return -1; - ms_list_for_each(model->persons, (MSIterateFunc)presence_person_clear_activities); + ms_list_for_each(model->persons, (MSIterateFunc)linphone_presence_person_clear_activities); return 0; } @@ -701,6 +694,32 @@ int linphone_presence_model_clear_services(LinphonePresenceModel *model) { return 0; } +unsigned int linphone_presence_model_nb_persons(const LinphonePresenceModel *model) { + return ms_list_size(model->persons); +} + +LinphonePresencePerson * linphone_presence_model_get_nth_person(const LinphonePresenceModel *model, unsigned int idx) { + if ((model == NULL) || (idx >= linphone_presence_model_nb_persons(model))) + return NULL; + + return (LinphonePresencePerson *)ms_list_nth_data(model->persons, idx); +} + +int linphone_presence_model_add_person(LinphonePresenceModel *model, LinphonePresencePerson *person) { + if ((model == NULL) || (person == NULL)) return -1; + model->persons = ms_list_append(model->persons, person); + return 0; +} + +int linphone_presence_model_clear_persons(LinphonePresenceModel *model) { + if (model == NULL) return -1; + + ms_list_for_each(model->persons, (MSIterateFunc)linphone_presence_person_unref); + ms_list_free(model->persons); + model->persons = NULL; + return 0; +} + /***************************************************************************** @@ -721,6 +740,22 @@ LinphonePresenceService * linphone_presence_service_new(const char *id, Linphone return service; } +char * linphone_presence_service_get_id(const LinphonePresenceService *service) { + if (service == NULL) return NULL; + return ms_strdup(service->id); +} + +int linphone_presence_service_set_id(LinphonePresenceService *service, const char *id) { + if (service == NULL) return -1; + if (service->id != NULL) + ms_free(service->id); + if (id == NULL) + service->id = generate_presence_id(); + else + service->id = ms_strdup(id); + return 0; +} + LinphonePresenceBasicStatus linphone_presence_service_get_basic_status(const LinphonePresenceService *service) { if (service == NULL) return LinphonePresenceBasicStatusClosed; return service->status; @@ -750,6 +785,57 @@ int linphone_presence_service_set_contact(LinphonePresenceService *service, cons +/***************************************************************************** + * PRESENCE PERSON FUNCTIONS TO GET ACCESS TO ALL FUNCTIONALITIES * + ****************************************************************************/ + +LinphonePresencePerson * linphone_presence_person_new(const char *id) { + return presence_person_new(id, time(NULL)); +} + +char * linphone_presence_person_get_id(const LinphonePresencePerson *person) { + if (person == NULL) return NULL; + return ms_strdup(person->id); +} + +int linphone_presence_person_set_id(LinphonePresencePerson *person, const char *id) { + if (person == NULL) return -1; + if (person->id != NULL) + ms_free(person->id); + if (id == NULL) + person->id = generate_presence_id(); + else + person->id = ms_strdup(id); + return 0; +} + +unsigned int linphone_presence_person_nb_activities(const LinphonePresencePerson *person) { + if (person == NULL) return 0; + return ms_list_size(person->activities); +} + +LinphonePresenceActivity * linphone_presence_person_get_nth_activity(const LinphonePresencePerson *person, unsigned int idx) { + if ((person == NULL) || (idx >= linphone_presence_person_nb_activities(person))) + return NULL; + return (LinphonePresenceActivity *)ms_list_nth_data(person->activities, idx); +} + +int linphone_presence_person_add_activity(LinphonePresencePerson *person, LinphonePresenceActivity *activity) { + if ((person == NULL) || (activity == NULL)) return -1; + person->activities = ms_list_append(person->activities, activity); + return 0; +} + +int linphone_presence_person_clear_activities(LinphonePresencePerson *person) { + if (person == NULL) return -1; + ms_list_for_each(person->activities, (MSIterateFunc)linphone_presence_activity_unref); + ms_list_free(person->activities); + person->activities = NULL; + return 0; +} + + + /***************************************************************************** * PRESENCE ACTIVITY FUNCTIONS TO GET ACCESS TO ALL FUNCTIONALITIES * ****************************************************************************/ @@ -934,6 +1020,28 @@ void * linphone_presence_service_get_user_data(LinphonePresenceService *service) return service->user_data; } +LinphonePresencePerson * linphone_presence_person_ref(LinphonePresencePerson *person) { + person->refcnt++; + return person; +} + +LinphonePresencePerson * linphone_presence_person_unref(LinphonePresencePerson *person) { + person->refcnt--; + if (person->refcnt == 0) { + presence_person_delete(person); + return NULL; + } + return person; +} + +void linphone_presence_person_set_user_data(LinphonePresencePerson *person, void *user_data) { + person->user_data = user_data; +} + +void * linphone_presence_person_get_user_data(LinphonePresencePerson *person) { + return person->user_data; +} + LinphonePresenceActivity * linphone_presence_activity_ref(LinphonePresenceActivity *activity) { activity->refcnt++; return activity; @@ -1152,7 +1260,7 @@ static int process_pidf_xml_presence_person_activities(xmlparsing_context_t *xml err = activity_name_to_presence_activity_type((const char *)activity_node->name, &acttype); if (err < 0) break; activity = linphone_presence_activity_new(acttype, description); - presence_person_add_activity(person, activity); + linphone_presence_person_add_activity(person, activity); if (description != NULL) free_xml_text_content(description); } } @@ -1243,7 +1351,7 @@ static int process_pidf_xml_presence_persons(xmlparsing_context_t *xml_ctx, Linp if (err == 0) { presence_model_add_person(model, person); } else { - presence_person_delete(person); + linphone_presence_person_unref(person); break; } } @@ -1255,7 +1363,7 @@ static int process_pidf_xml_presence_persons(xmlparsing_context_t *xml_ctx, Linp if (err < 0) { /* Remove all the persons added since there was an error. */ - ms_list_for_each(model->persons, (MSIterateFunc)presence_person_delete); + ms_list_for_each(model->persons, (MSIterateFunc)linphone_presence_person_unref); } return err; }