Add chat room callbacks to handle subscription to registration state of participants + add new group chat tester.

This commit is contained in:
Ghislain MARY 2018-03-14 18:18:39 +01:00
parent 12660bea3a
commit 09025ed3c8
9 changed files with 185 additions and 20 deletions

View file

@ -291,8 +291,10 @@ void _linphone_chat_room_notify_undecryptable_message_received(LinphoneChatRoom
void _linphone_chat_room_notify_chat_message_received(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
void _linphone_chat_room_notify_chat_message_sent(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
void _linphone_chat_room_notify_conference_address_generation(LinphoneChatRoom *cr);
void _linphone_chat_room_notify_participant_device_fetched(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
void _linphone_chat_room_notify_participant_device_fetch_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
void _linphone_chat_room_notify_participants_capabilities_checked(LinphoneChatRoom *cr, const LinphoneAddress *deviceAddr, const bctbx_list_t *participantsAddr);
void _linphone_chat_room_notify_participant_registration_subscription_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
void _linphone_chat_room_notify_participant_registration_unsubscription_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
void _linphone_chat_room_notify_chat_message_should_be_stored(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
void _linphone_chat_room_clear_callbacks (LinphoneChatRoom *cr);

View file

@ -239,7 +239,7 @@ typedef void (*LinphoneChatRoomCbsConferenceAddressGenerationCb) (LinphoneChatRo
* @param[in] cr #LinphoneChatRoom object
* @param[in] participantAddr #LinphoneAddress object
*/
typedef void (*LinphoneChatRoomCbsParticipantDeviceFetchedCb) (LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
typedef void (*LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb) (LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
/**
* Callback used when a group chat room server is checking participants capabilities.
@ -249,6 +249,20 @@ typedef void (*LinphoneChatRoomCbsParticipantDeviceFetchedCb) (LinphoneChatRoom
*/
typedef void (*LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb) (LinphoneChatRoom *cr, const LinphoneAddress *deviceAddr, const bctbx_list_t *participantsAddr);
/**
* Callback used when a group chat room server is subscribing to registration state of a participant.
* @param[in] cr #LinphoneChatRoom object
* @param[in] participantAddr #LinphoneAddress object
*/
typedef void (*LinphoneChatRoomCbsParticipantRegistrationSubscriptionRequestedCb) (LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
/**
* Callback used when a group chat room server is unsubscribing to registration state of a participant.
* @param[in] cr #LinphoneChatRoom object
* @param[in] participantAddr #LinphoneAddress object
*/
typedef void (*LinphoneChatRoomCbsParticipantRegistrationUnsubscriptionRequestedCb) (LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
/**
* Callback used to tell the core whether or not to store the incoming message in db or not using linphone_chat_message_set_to_be_stored().
* @param[in] cr #LinphoneChatRoom object

View file

@ -244,18 +244,18 @@ LINPHONE_PUBLIC LinphoneChatRoomCbsConferenceAddressGenerationCb linphone_chat_r
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_conference_address_generation (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsConferenceAddressGenerationCb cb);
/**
* Get the participant device getting callback.
* Get the participant device fetching callback.
* @param[in] cbs LinphoneChatRoomCbs object
* @return The participant device getting callback
* @return The participant device fetching callback
*/
LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantDeviceFetchedCb linphone_chat_room_cbs_get_participant_device_fetched (const LinphoneChatRoomCbs *cbs);
LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb linphone_chat_room_cbs_get_participant_device_fetch_requested (const LinphoneChatRoomCbs *cbs);
/**
* Set the participant device getting callback.
* Set the participant device fetching callback.
* @param[in] cbs LinphoneChatRoomCbs object
* @param[in] cb The participant device getting callback to be used
* @param[in] cb The participant device fetching callback to be used
*/
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_device_fetched (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantDeviceFetchedCb cb);
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_device_fetch_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb cb);
/**
* Get the participants capabilities callback.
@ -271,6 +271,34 @@ LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb linphone_ch
*/
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participants_capabilities_checked (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb cb);
/**
* Get the participant registration subscription callback.
* @param[in] cbs LinphoneChatRoomCbs object
* @return The participant registration subscription callback
*/
LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantRegistrationSubscriptionRequestedCb linphone_chat_room_cbs_get_participant_registration_subscription_requested (const LinphoneChatRoomCbs *cbs);
/**
* Set the participant registration subscription callback.
* @param[in] cbs LinphoneChatRoomCbs object
* @param[in] cb The participant registration subscription callback to be used
*/
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_registration_subscription_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantRegistrationSubscriptionRequestedCb cb);
/**
* Get the participant registration unsubscription callback.
* @param[in] cbs LinphoneChatRoomCbs object
* @return The participant registration unsubscription callback
*/
LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantRegistrationUnsubscriptionRequestedCb linphone_chat_room_cbs_get_participant_registration_unsubscription_requested (const LinphoneChatRoomCbs *cbs);
/**
* Set the participant registration unsubscription callback.
* @param[in] cbs LinphoneChatRoomCbs object
* @param[in] cb The participant registration unsubscription callback to be used
*/
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_registration_unsubscription_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantRegistrationUnsubscriptionRequestedCb cb);
/**
* Get the message should be stored callback.
* @param[in] cbs LinphoneChatRoomCbs object

View file

@ -454,13 +454,22 @@ LINPHONE_PUBLIC void linphone_chat_room_set_conference_address (LinphoneChatRoom
/**
* Set the participant device. This function needs to be called from the
* LinphoneChatRoomCbsParticipantDeviceFetchedCb callback and only there.
* LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb callback and only there.
* @param[in] cr A LinphoneChatRoom object
* @param[in] partAddr The participant address
* @param[in] partDevices \bctbx_list{LinphoneAddress} list of the participant devices to be used by the group chat room
*/
LINPHONE_PUBLIC void linphone_chat_room_set_participant_devices (LinphoneChatRoom *cr, const LinphoneAddress *partAddr, const bctbx_list_t *partDevices);
/**
* Add a participant device.
* This is to used if a new device registers itself after the chat room creation.
* @param[in] cr A #LinphoneChatRoom object
* @param[in] participantAddress The address of the participant for which a new device is to be added
* @param[in] deviceAddress The address of the new device to be added
*/
LINPHONE_PUBLIC void linphone_chat_room_add_participant_device (LinphoneChatRoom *cr, const LinphoneAddress *participantAddress, const LinphoneAddress *deviceAddress);
/**
* Set the participant device. This function needs to be called from the
* LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb callback and only there.

View file

@ -39,8 +39,10 @@ struct _LinphoneChatRoomCbs {
LinphoneChatRoomCbsChatMessageReceivedCb chatMessageReceivedCb;
LinphoneChatRoomCbsChatMessageSentCb chatMessageSentCb;
LinphoneChatRoomCbsConferenceAddressGenerationCb conferenceAddressGenerationCb;
LinphoneChatRoomCbsParticipantDeviceFetchedCb participantDeviceFetchedCb;
LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb participantDeviceFetchRequestedCb;
LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb participantsCapabilitiesChecked;
LinphoneChatRoomCbsParticipantRegistrationSubscriptionRequestedCb participantRegistrationSubscriptionRequestedCb;
LinphoneChatRoomCbsParticipantRegistrationUnsubscriptionRequestedCb participantRegistrationUnsubscriptionRequestedCb;
LinphoneChatRoomCbsShouldChatMessageBeStoredCb shouldMessageBeStoredCb;
};
@ -182,12 +184,12 @@ void linphone_chat_room_cbs_set_conference_address_generation (LinphoneChatRoomC
cbs->conferenceAddressGenerationCb = cb;
}
LinphoneChatRoomCbsParticipantDeviceFetchedCb linphone_chat_room_cbs_get_participant_device_fetched (const LinphoneChatRoomCbs *cbs) {
return cbs->participantDeviceFetchedCb;
LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb linphone_chat_room_cbs_get_participant_device_fetch_requested (const LinphoneChatRoomCbs *cbs) {
return cbs->participantDeviceFetchRequestedCb;
}
void linphone_chat_room_cbs_set_participant_device_fetched (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantDeviceFetchedCb cb) {
cbs->participantDeviceFetchedCb = cb;
void linphone_chat_room_cbs_set_participant_device_fetch_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb cb) {
cbs->participantDeviceFetchRequestedCb = cb;
}
LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb linphone_chat_room_cbs_get_participants_capabilities_checked (const LinphoneChatRoomCbs *cbs) {
@ -198,6 +200,22 @@ void linphone_chat_room_cbs_set_participants_capabilities_checked (LinphoneChatR
cbs->participantsCapabilitiesChecked = cb;
}
LinphoneChatRoomCbsParticipantRegistrationSubscriptionRequestedCb linphone_chat_room_cbs_get_participant_registration_subscription_requested (const LinphoneChatRoomCbs *cbs) {
return cbs->participantRegistrationSubscriptionRequestedCb;
}
void linphone_chat_room_cbs_set_participant_registration_subscription_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantRegistrationSubscriptionRequestedCb cb) {
cbs->participantRegistrationSubscriptionRequestedCb = cb;
}
LinphoneChatRoomCbsParticipantRegistrationUnsubscriptionRequestedCb linphone_chat_room_cbs_get_participant_registration_unsubscription_requested (const LinphoneChatRoomCbs *cbs) {
return cbs->participantRegistrationUnsubscriptionRequestedCb;
}
void linphone_chat_room_cbs_set_participant_registration_unsubscription_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantRegistrationUnsubscriptionRequestedCb cb) {
cbs->participantRegistrationUnsubscriptionRequestedCb = cb;
}
LinphoneChatRoomCbsShouldChatMessageBeStoredCb linphone_chat_room_cbs_get_chat_message_should_be_stored( LinphoneChatRoomCbs *cbs) {
return cbs->shouldMessageBeStoredCb;
}

View file

@ -382,6 +382,16 @@ void linphone_chat_room_set_participant_devices (LinphoneChatRoom *cr, const Lin
bctbx_free(addrStr);
}
void linphone_chat_room_add_participant_device (LinphoneChatRoom *cr, const LinphoneAddress *participantAddress, const LinphoneAddress *deviceAddress) {
char *participantAddressStr = linphone_address_as_string(participantAddress);
char *deviceAddressStr = linphone_address_as_string(deviceAddress);
LinphonePrivate::ServerGroupChatRoomPrivate *sgcr = dynamic_cast<LinphonePrivate::ServerGroupChatRoomPrivate *>(L_GET_PRIVATE_FROM_C_OBJECT(cr));
if (sgcr)
sgcr->addParticipantDevice(LinphonePrivate::IdentityAddress(participantAddressStr), LinphonePrivate::IdentityAddress(deviceAddressStr));
bctbx_free(participantAddressStr);
bctbx_free(deviceAddressStr);
}
void linphone_chat_room_add_compatible_participants (LinphoneChatRoom *cr, const LinphoneAddress *deviceAddr, const bctbx_list_t *participantsCompatible) {
list<LinphonePrivate::Address> lPartsComp = L_GET_RESOLVED_CPP_LIST_FROM_C_LIST(participantsCompatible, Address);
LinphonePrivate::ServerGroupChatRoomPrivate *sgcr = dynamic_cast<LinphonePrivate::ServerGroupChatRoomPrivate *>(L_GET_PRIVATE_FROM_C_OBJECT(cr));
@ -486,14 +496,22 @@ void _linphone_chat_room_notify_conference_address_generation(LinphoneChatRoom *
NOTIFY_IF_EXIST(ConferenceAddressGeneration, conference_address_generation, cr)
}
void _linphone_chat_room_notify_participant_device_fetched(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr) {
NOTIFY_IF_EXIST(ParticipantDeviceFetched, participant_device_fetched, cr, participantAddr)
void _linphone_chat_room_notify_participant_device_fetch_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr) {
NOTIFY_IF_EXIST(ParticipantDeviceFetchRequested, participant_device_fetch_requested, cr, participantAddr)
}
void _linphone_chat_room_notify_participants_capabilities_checked(LinphoneChatRoom *cr, const LinphoneAddress *deviceAddr, const bctbx_list_t *participantsAddr) {
NOTIFY_IF_EXIST(ParticipantsCapabilitiesChecked, participants_capabilities_checked, cr, deviceAddr, participantsAddr)
}
void _linphone_chat_room_notify_participant_registration_subscription_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr) {
NOTIFY_IF_EXIST(ParticipantRegistrationSubscriptionRequested, participant_registration_subscription_requested, cr, participantAddr)
}
void _linphone_chat_room_notify_participant_registration_unsubscription_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr) {
NOTIFY_IF_EXIST(ParticipantRegistrationUnsubscriptionRequested, participant_registration_unsubscription_requested, cr, participantAddr)
}
void _linphone_chat_room_notify_chat_message_should_be_stored(LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
NOTIFY_IF_EXIST(ShouldChatMessageBeStored, chat_message_should_be_stored, cr, msg)
}

View file

@ -60,6 +60,7 @@ public:
void setConferenceAddress (const IdentityAddress &conferenceAddress);
void setParticipantDevices (const IdentityAddress &addr, const std::list<IdentityAddress> &devices);
void addParticipantDevice (const IdentityAddress &participantAddress, const IdentityAddress &deviceAddress);
void addCompatibleParticipants (const IdentityAddress &deviceAddr, const std::list<IdentityAddress> &compatibleParticipants);
void checkCompatibleParticipants (const IdentityAddress &deviceAddr, const std::list<IdentityAddress> &addressesToCheck);
@ -67,17 +68,29 @@ public:
private:
struct Message {
Message (const std::string &from, const std::string &contentType, const std::string &text) : fromAddr(from) {
Message (const std::string &from, const std::string &contentType, const std::string &text, const SalCustomHeader *salCustomHeaders)
: fromAddr(from)
{
content.setContentType(contentType);
if (!text.empty())
content.setBodyFromUtf8(text);
if (salCustomHeaders)
customHeaders = sal_custom_header_clone(salCustomHeaders);
}
~Message () {
if (customHeaders)
sal_custom_header_free(customHeaders);
}
IdentityAddress fromAddr;
Content content;
std::chrono::system_clock::time_point timestamp = std::chrono::system_clock::now();
SalCustomHeader *customHeaders = nullptr;
};
static void copyMessageHeaders (const std::shared_ptr<Message> &fromMessage, const std::shared_ptr<ChatMessage> &toMessage);
void designateAdmin ();
void dispatchMessage (const std::shared_ptr<Message> &message, const std::string &uri);
void finalizeCreation ();

View file

@ -80,6 +80,8 @@ void ServerGroupChatRoomPrivate::setConferenceAddress (const IdentityAddress &)
void ServerGroupChatRoomPrivate::setParticipantDevices (const IdentityAddress &addr, const list<IdentityAddress> &devices) {}
void ServerGroupChatRoomPrivate::addParticipantDevice (const IdentityAddress &participantAddress, const IdentityAddress &deviceAddress) {}
void ServerGroupChatRoomPrivate::addCompatibleParticipants (const IdentityAddress &deviceAddr, const list<IdentityAddress> &participantCompatible) {}
// -----------------------------------------------------------------------------

View file

@ -2874,7 +2874,7 @@ static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2
linphone_core_manager_destroy(pauline2);
}
#if 0
static void group_chat_room_join_one_to_one_chat_room_with_a_new_device (void) {
LinphoneCoreManager *marie1 = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
@ -2963,6 +2963,7 @@ static void group_chat_room_join_one_to_one_chat_room_with_a_new_device (void) {
linphone_core_manager_destroy(marie1);
linphone_core_manager_destroy(pauline);
}
#endif
static void group_chat_room_new_unique_one_to_one_chat_room_after_both_participants_left (void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
@ -3179,6 +3180,65 @@ static void find_one_to_one_chat_room (void) {
linphone_core_manager_destroy(chloe);
}
static void group_chat_room_new_device_after_creation (void) {
LinphoneCoreManager *marie1 = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline1 = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *pauline2 = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie1);
coresManagerList = bctbx_list_append(coresManagerList, pauline1);
coresManagerList = bctbx_list_append(coresManagerList, pauline2);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline1->lc)));
participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarie1Stats = marie1->stat;
stats initialPauline1Stats = pauline1->stat;
stats initialPauline2Stats = pauline2->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marie1Cr = create_chat_room_client_side(coresList, marie1, &initialMarie1Stats, participantsAddresses, initialSubject, -1);
participantsAddresses = NULL;
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marie1Cr);
// Check that the chat room is correctly created on Pauline1 and Pauline2's sides and that the participants are added
LinphoneChatRoom *pauline1Cr = check_creation_chat_room_client_side(coresList, pauline1, &initialPauline1Stats, confAddr, initialSubject, 2, FALSE);
LinphoneChatRoom *pauline2Cr = check_creation_chat_room_client_side(coresList, pauline2, &initialPauline2Stats, confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr = check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
// Marie adds a new device
LinphoneCoreManager *marie2 = linphone_core_manager_create("marie_rc");
stats initialMarie2Stats = marie2->stat;
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, marie2);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
start_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
LinphoneChatRoom *marie2Cr = check_creation_chat_room_client_side(coresList, marie2, &initialMarie2Stats, confAddr, initialSubject, 2, TRUE);
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie1, marie1Cr, coresList);
linphone_core_delete_chat_room(marie2->lc, marie2Cr);
linphone_core_manager_delete_chat_room(pauline1, pauline1Cr, coresList);
linphone_core_delete_chat_room(pauline2->lc, pauline2Cr);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie1);
linphone_core_manager_destroy(marie2);
linphone_core_manager_destroy(pauline1);
linphone_core_manager_destroy(pauline2);
linphone_core_manager_destroy(laure);
}
test_t group_chat_tests[] = {
TEST_NO_TAG("Group chat room creation server", group_chat_room_creation_server),
TEST_ONE_TAG("Add participant", group_chat_room_add_participant, "LeaksMemory"),
@ -3218,11 +3278,12 @@ test_t group_chat_tests[] = {
TEST_NO_TAG("Unique one-to-one chatroom", group_chat_room_unique_one_to_one_chat_room),
TEST_NO_TAG("Unique one-to-one chatroom recreated from message", group_chat_room_unique_one_to_one_chat_room_recreated_from_message),
TEST_ONE_TAG("Unique one-to-one chatroom recreated from message with app restart", group_chat_room_unique_one_to_one_chat_room_recreated_from_message_with_app_restart, "LeaksMemory"),
TEST_NO_TAG("Join one-to-one chat room with a new device", group_chat_room_join_one_to_one_chat_room_with_a_new_device),
//TEST_NO_TAG("Join one-to-one chat room with a new device", group_chat_room_join_one_to_one_chat_room_with_a_new_device),
TEST_NO_TAG("New unique one-to-one chatroom after both participants left", group_chat_room_new_unique_one_to_one_chat_room_after_both_participants_left),
TEST_NO_TAG("Unique one-to-one chatroom re-created from the party that deleted it, with inactive devices", group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2),
TEST_NO_TAG("IMDN for group chat room", imdn_for_group_chat_room),
TEST_NO_TAG("Find one to one chat room", find_one_to_one_chat_room)
TEST_NO_TAG("Find one to one chat room", find_one_to_one_chat_room),
TEST_NO_TAG("New device after group chat room creation", group_chat_room_new_device_after_creation)
};
test_suite_t group_chat_test_suite = {