diff --git a/include/linphone/api/c-friend.h b/include/linphone/api/c-friend.h index 4eea43a5e8f66541ab5a4783cb5a4f73f0fe0ac7..5de27a53015f96a50e2c5accf81a1e636772ad36 100644 --- a/include/linphone/api/c-friend.h +++ b/include/linphone/api/c-friend.h @@ -161,7 +161,7 @@ LINPHONE_PUBLIC void linphone_friend_remove_phone_number_with_label(LinphoneFrie const LinphoneFriendPhoneNumber *phone_number); /** - * Set the display name for this friend + * Sets the display name for this friend * @param linphone_friend #LinphoneFriend object @notnil * @param name the display name to set @maybenil * @return 0 if successful, -1 otherwise @@ -169,12 +169,42 @@ LINPHONE_PUBLIC void linphone_friend_remove_phone_number_with_label(LinphoneFrie LINPHONE_PUBLIC LinphoneStatus linphone_friend_set_name(LinphoneFriend *linphone_friend, const char *name); /** - * Get the display name for this friend + * Sets the last name for this friend if vCard is available + * @param linphone_friend #LinphoneFriend object @notnil + * @param last_name the last name to set @maybenil + * @return 0 if successful, -1 otherwise + */ +LINPHONE_PUBLIC LinphoneStatus linphone_friend_set_last_name(LinphoneFriend *linphone_friend, const char *last_name); + +/** + * Sets the first name for this friend is available + * @param linphone_friend #LinphoneFriend object @notnil + * @param first_name the first name to set @maybenil + * @return 0 if successful, -1 otherwise + */ +LINPHONE_PUBLIC LinphoneStatus linphone_friend_set_first_name(LinphoneFriend *linphone_friend, const char *first_name); + +/** + * Gets the display name for this friend * @param linphone_friend #LinphoneFriend object @notnil * @return The display name of this friend. @maybenil */ LINPHONE_PUBLIC const char *linphone_friend_get_name(const LinphoneFriend *linphone_friend); +/** + * Gets the last name for this friend if vCard exists + * @param linphone_friend #LinphoneFriend object @notnil + * @return The last name of this friend. @maybenil + */ +LINPHONE_PUBLIC const char *linphone_friend_get_last_name(const LinphoneFriend *linphone_friend); + +/** + * Gets the first name for this friend if vCard exists + * @param linphone_friend #LinphoneFriend object @notnil + * @return The first name of this friend. @maybenil + */ +LINPHONE_PUBLIC const char *linphone_friend_get_first_name(const LinphoneFriend *linphone_friend); + /** * get subscription flag value * @param linphone_friend #LinphoneFriend object @notnil @@ -357,6 +387,13 @@ LINPHONE_PUBLIC LinphoneCore *linphone_friend_get_core(const LinphoneFriend *lin */ LINPHONE_PUBLIC LinphoneVcard *linphone_friend_get_vcard(const LinphoneFriend *linphone_friend); +/** + * Returns the a string matching the vCard inside the friend, if any + * @param linphone_friend #LinphoneFriend object @notnil + * @return the vCard as a string or NULL. @maybenil + */ +LINPHONE_PUBLIC const char *linphone_friend_dump_vcard(const LinphoneFriend *linphone_friend); + /** * Binds a vCard object to a friend * @param linphone_friend #LinphoneFriend object @notnil diff --git a/include/linphone/utils/utils.h b/include/linphone/utils/utils.h index b7668e2219682d9ffe68b38f59dc79e250ff475f..e2916d635bb057f80fe3eb7c65e7b1bfc6a01b89 100644 --- a/include/linphone/utils/utils.h +++ b/include/linphone/utils/utils.h @@ -140,6 +140,7 @@ inline std::string join(const std::vector<T> &elems, const S &delim) { } LINPHONE_PUBLIC std::string trim(const std::string &str); LINPHONE_PUBLIC std::string normalizeFilename(const std::string &str); +LINPHONE_PUBLIC std::string flattenPhoneNumber(const std::string &str); template <typename T> inline const T &getEmptyConstRefObject() { diff --git a/src/c-wrapper/api/c-account.cpp b/src/c-wrapper/api/c-account.cpp index 99769b8a161fc8d53363307c3efea373d33b3993..97f2c7de244ab1642af9771c8533f94fe65644ad 100644 --- a/src/c-wrapper/api/c-account.cpp +++ b/src/c-wrapper/api/c-account.cpp @@ -329,23 +329,6 @@ bool_t linphone_account_is_phone_number(const LinphoneAccount *account, const ch return TRUE; } -static char *linphone_account_flatten_phone_number(const char *number) { - char *unescaped_phone_number = belle_sip_username_unescape_unnecessary_characters(number); - char *result = reinterpret_cast<char *>(ms_malloc0(strlen(unescaped_phone_number) + 1)); - char *w = result; - const char *r; - - for (r = unescaped_phone_number; *r != '\0'; ++r) { - if (*r == '+' || isdigit(*r)) { - *w++ = *r; - } - } - - *w++ = '\0'; - belle_sip_free(unescaped_phone_number); - return result; -} - char *linphone_account_normalize_phone_number(const LinphoneAccount *account, const char *username) { AccountLogContextualizer logContextualizer(account); @@ -368,7 +351,7 @@ char *linphone_account_normalize_phone_number(const LinphoneAccount *account, co linphone_account_params_unref(accountParams); } - char *flatten = linphone_account_flatten_phone_number(username); + char *flatten = ms_strdup(Utils::flattenPhoneNumber(username).c_str()); lDebug() << "Flattened number is [" << flatten << "] for [" << username << "]"; // if local short number, do not add international prefix diff --git a/src/c-wrapper/api/c-friend.cpp b/src/c-wrapper/api/c-friend.cpp index dce4d693be45d703a3a9a051f7b804d4d33a4e45..a534f8d8993a043df674f72599bbb99d52ad2804 100644 --- a/src/c-wrapper/api/c-friend.cpp +++ b/src/c-wrapper/api/c-friend.cpp @@ -171,6 +171,18 @@ const char *linphone_friend_get_name(const LinphoneFriend *lf) { return L_STRING_TO_C(Friend::toCpp(lf)->getName()); } +const char *linphone_friend_get_last_name(const LinphoneFriend *lf) { + if (!lf) return NULL; + const std::shared_ptr<Vcard> vcard = Friend::toCpp(lf)->getVcard(); + return vcard ? L_STRING_TO_C(vcard->getFamilyName()) : NULL; +} + +const char *linphone_friend_get_first_name(const LinphoneFriend *lf) { + if (!lf) return NULL; + const std::shared_ptr<Vcard> vcard = Friend::toCpp(lf)->getVcard(); + return vcard ? L_STRING_TO_C(vcard->getGivenName()) : NULL; +} + const char *linphone_friend_get_native_uri(const LinphoneFriend *lf) { if (!lf) return NULL; return L_STRING_TO_C(Friend::toCpp(lf)->getNativeUri()); @@ -241,6 +253,12 @@ LinphoneVcard *linphone_friend_get_vcard(const LinphoneFriend *lf) { return vcard ? vcard->toC() : nullptr; } +const char *linphone_friend_dump_vcard(const LinphoneFriend *lf) { + if (!lf) return NULL; + const std::shared_ptr<Vcard> vcard = Friend::toCpp(lf)->getVcard(); + return vcard ? L_STRING_TO_C(vcard->asVcard4String()) : NULL; +} + bool_t linphone_friend_has_capability(const LinphoneFriend *lf, const LinphoneFriendCapability capability) { return Friend::toCpp(lf)->hasCapability(capability); } @@ -328,6 +346,24 @@ LinphoneStatus linphone_friend_set_name(LinphoneFriend *lf, const char *name) { return Friend::toCpp(lf)->setName(L_C_TO_STRING(name)); } +LinphoneStatus linphone_friend_set_last_name(LinphoneFriend *lf, const char *last_name) { + const std::shared_ptr<Vcard> vcard = Friend::toCpp(lf)->getVcard(); + if (vcard) { + vcard->setFamilyName(L_C_TO_STRING(last_name)); + return 0; + } + return -1; +} + +LinphoneStatus linphone_friend_set_first_name(LinphoneFriend *lf, const char *first_name) { + const std::shared_ptr<Vcard> vcard = Friend::toCpp(lf)->getVcard(); + if (vcard) { + vcard->setGivenName(L_C_TO_STRING(first_name)); + return 0; + } + return -1; +} + void linphone_friend_set_native_uri(LinphoneFriend *lf, const char *native_uri) { if (!lf) return; Friend::toCpp(lf)->setNativeUri(L_C_TO_STRING(native_uri)); diff --git a/src/friend/friend.cpp b/src/friend/friend.cpp index 0871b300e434b1268c91c189ed4818a7959cd8a5..948097602377c4045b6443aef2686fa7e497b5da 100644 --- a/src/friend/friend.cpp +++ b/src/friend/friend.cpp @@ -548,9 +548,10 @@ void Friend::addAddress(const std::shared_ptr<const Address> &address) { void Friend::addPhoneNumber(const std::string &phoneNumber) { if (phoneNumber.empty()) return; + auto flattenedPhoneNumber = Utils::flattenPhoneNumber(phoneNumber); for (auto existing : getPhoneNumbers()) { - if (existing == phoneNumber) { + if (flattenedPhoneNumber == Utils::flattenPhoneNumber(existing)) { lInfo() << "Trying to add an already existing phone number to friend, skipping"; return; } @@ -570,10 +571,12 @@ void Friend::addPhoneNumberWithLabel(const std::shared_ptr<const FriendPhoneNumb if (!phoneNumber) return; const std::string &phone = phoneNumber->getPhoneNumber(); if (phone.empty()) return; + auto flattenedPhoneNumber = Utils::flattenPhoneNumber(phone); const std::string &label = phoneNumber->getLabel(); for (auto &existing : getPhoneNumbersWithLabel()) { - if (existing->getPhoneNumber() == phone && existing->getLabel() == label) { + if (existing->getLabel() == label && + flattenedPhoneNumber == Utils::flattenPhoneNumber(existing->getPhoneNumber())) { lInfo() << "Trying to add an already existing phone number / label to friend, skipping"; return; } diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp index b9c30d268584cf2256ed3166ea2b48ea94dc7b1d..f296bb65a9d5d75982f9e786da78e2e1aad1b619 100644 --- a/src/utils/utils.cpp +++ b/src/utils/utils.cpp @@ -228,6 +228,22 @@ string Utils::trim(const string &str) { return (itBack <= itFront ? string() : string(itFront, itBack)); } +std::string Utils::flattenPhoneNumber(const std::string &str) { + std::string result; + const char *number = str.c_str(); + char *unescaped_phone_number = belle_sip_username_unescape_unnecessary_characters(number); + const char *r; + + for (r = unescaped_phone_number; *r != '\0'; ++r) { + if (*r == '+' || isdigit(*r)) { + result += *r; + } + } + + belle_sip_free(unescaped_phone_number); + return result; +} + std::string Utils::normalizeFilename(const std::string &str) { std::string result(str); #ifdef _WIN32