diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 6302d92f6..c8dc6ab9b 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -616,14 +616,18 @@ static void notify(SalSubscribeOp *op, SalSubscribeStatus st, const char *eventn } } -static void subscribe_received(SalSubscribeOp *op, const char *eventname, const SalBodyHandler *body_handler){ +static void subscribe_received(SalSubscribeOp *op, const char *eventname, SalBodyHandler *body_handler){ LinphoneEvent *lev=(LinphoneEvent*)op->get_user_pointer(); LinphoneCore *lc=(LinphoneCore *)op->get_sal()->get_user_pointer(); if (lev==NULL) { lev=linphone_event_new_with_op(lc,op,LinphoneSubscriptionIncoming,eventname); linphone_event_set_state(lev,LinphoneSubscriptionIncomingReceived); - }else{ + LinphoneContent *ct = linphone_content_from_sal_body_handler(body_handler); + linphone_core_notify_subscribe_received(lc,lev,eventname,ct); + if (ct) + linphone_content_unref(ct); + } else { /*subscribe refresh, unhandled*/ } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index a46771707..81ff23cd8 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -53,6 +53,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "chat/chat-room/client-group-chat-room-p.h" #include "chat/chat-room/client-group-to-basic-chat-room.h" #include "chat/chat-room/server-group-chat-room-p.h" +#include "conference/handlers/local-conference-list-event-handler.h" #include "conference/handlers/remote-conference-event-handler.h" #include "content/content-manager.h" #include "content/content-type.h" @@ -367,6 +368,14 @@ void linphone_core_cbs_set_notify_received(LinphoneCoreCbs *cbs, LinphoneCoreCbs cbs->vtable->notify_received = cb; } +LinphoneCoreCbsSubscribeReceivedCb linphone_core_cbs_get_subscribe_received(LinphoneCoreCbs *cbs) { + return cbs->vtable->subscribe_received; +} + +void linphone_core_cbs_set_subscribe_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsSubscribeReceivedCb cb) { + cbs->vtable->subscribe_received = cb; +} + LinphoneCoreCbsPublishStateChangedCb linphone_core_cbs_get_rpublish_state_changed(LinphoneCoreCbs *cbs) { return cbs->vtable->publish_state_changed; } @@ -2153,29 +2162,34 @@ static void linphone_core_internal_notify_received(LinphoneCore *lc, LinphoneEve } } -static void _linphone_core_conference_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) { - if ( - linphone_event_get_subscription_dir(lev) == LinphoneSubscriptionIncoming && - state == LinphoneSubscriptionIncomingReceived - ) { - const LinphoneAddress *resource = linphone_event_get_resource(lev); - shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(LinphonePrivate::ChatRoomId( - IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(resource)), - IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(resource)) - )); - if (chatRoom) { - linphone_event_accept_subscription(lev); - L_GET_PRIVATE(static_pointer_cast(chatRoom))->subscribeReceived(lev); - } else - linphone_event_deny_subscription(lev, LinphoneReasonDeclined); +static void _linphone_core_conference_subscribe_received(LinphoneCore *lc, LinphoneEvent *lev, const LinphoneContent *body) { + if (body) { + // List subscription + L_GET_PRIVATE_FROM_C_OBJECT(lc)->localListEventHandler->subscribeReceived(lev, body); + return; + } + + const LinphoneAddress *resource = linphone_event_get_resource(lev); + shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(LinphonePrivate::ChatRoomId( + IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(resource)), + IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(resource)) + )); + if (chatRoom) { + linphone_event_accept_subscription(lev); + L_GET_PRIVATE(static_pointer_cast(chatRoom))->subscribeReceived(lev); + } else + linphone_event_deny_subscription(lev, LinphoneReasonDeclined); +} + +static void linphone_core_internal_subscribe_received(LinphoneCore *lc, LinphoneEvent *lev, const char *subscribe_event, const LinphoneContent *body) { + if (strcmp(linphone_event_get_name(lev), "conference") == 0) { + _linphone_core_conference_subscribe_received(lc, lev, body); } } static void linphone_core_internal_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) { if (strcasecmp(linphone_event_get_name(lev), "Presence") == 0) { linphone_friend_list_subscription_state_changed(lc, lev, state); - } else if (strcmp(linphone_event_get_name(lev), "conference") == 0) { - _linphone_core_conference_subscription_state_changed(lc, lev, state); } } @@ -2254,6 +2268,7 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig _linphone_core_init_account_creator_service(lc); linphone_core_cbs_set_notify_received(internal_cbs, linphone_core_internal_notify_received); + linphone_core_cbs_set_subscribe_received(internal_cbs, linphone_core_internal_subscribe_received); linphone_core_cbs_set_subscription_state_changed(internal_cbs, linphone_core_internal_subscription_state_changed); linphone_core_cbs_set_publish_state_changed(internal_cbs, linphone_core_internal_publish_state_changed); _linphone_core_add_callbacks(lc, internal_cbs, TRUE); diff --git a/coreapi/private_functions.h b/coreapi/private_functions.h index 9ab4e447f..70d5b2beb 100644 --- a/coreapi/private_functions.h +++ b/coreapi/private_functions.h @@ -498,6 +498,7 @@ void linphone_core_notify_configuring_status(LinphoneCore *lc, LinphoneConfiguri void linphone_core_notify_network_reachable(LinphoneCore *lc, bool_t reachable); void linphone_core_notify_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *notified_event, const LinphoneContent *body); +void linphone_core_notify_subscribe_received(LinphoneCore *lc, LinphoneEvent *lev, const char *subscribe_event, const LinphoneContent *body); void linphone_core_notify_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state); void linphone_core_notify_publish_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphonePublishState state); void linphone_core_notify_log_collection_upload_state_changed(LinphoneCore *lc, LinphoneCoreLogCollectionUploadState state, const char *info); diff --git a/coreapi/vtables.c b/coreapi/vtables.c index 13472609c..cb564860c 100644 --- a/coreapi/vtables.c +++ b/coreapi/vtables.c @@ -253,6 +253,11 @@ void linphone_core_notify_notify_received(LinphoneCore *lc, LinphoneEvent *lev, cleanup_dead_vtable_refs(lc); } +void linphone_core_notify_subscribe_received(LinphoneCore *lc, LinphoneEvent *lev, const char *subscribe_event, const LinphoneContent *body) { + NOTIFY_IF_EXIST_INTERNAL(subscribe_received, linphone_event_is_internal(lev), lc, lev, subscribe_event, body); + cleanup_dead_vtable_refs(lc); +} + void linphone_core_notify_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) { NOTIFY_IF_EXIST_INTERNAL(subscription_state_changed,linphone_event_is_internal(lev), lc,lev,state); cleanup_dead_vtable_refs(lc); diff --git a/include/linphone/callbacks.h b/include/linphone/callbacks.h index 7511a1d97..2d8473aa8 100644 --- a/include/linphone/callbacks.h +++ b/include/linphone/callbacks.h @@ -424,6 +424,16 @@ typedef void (*LinphoneCoreCbsNotifyReceivedCb)(LinphoneCore *lc, LinphoneEvent */ typedef LinphoneCoreCbsNotifyReceivedCb LinphoneCoreNotifyReceivedCb; +/** + * Callback prototype for notifying the application about subscription received from the network. +**/ +typedef void (*LinphoneCoreCbsSubscribeReceivedCb)(LinphoneCore *lc, LinphoneEvent *lev, const char *subscribe_event, const LinphoneContent *body); + +/** + * Old name of #LinphoneCoreCbsSubscribeReceivedCb. + */ +typedef LinphoneCoreCbsSubscribeReceivedCb LinphoneCoreSubscribeReceivedCb; + /** * Callback prototype for notifying the application about changes of subscription states, including arrival of new subscriptions. **/ diff --git a/include/linphone/core.h b/include/linphone/core.h index 7ee26c5d0..e45c272bc 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -180,6 +180,7 @@ typedef struct _LinphoneCoreVTable{ LinphoneCoreInfoReceivedCb info_received; /** A text message has been received */ @@ -547,6 +548,20 @@ LINPHONE_PUBLIC void linphone_core_cbs_set_notify_received(LinphoneCoreCbs *cbs, */ LINPHONE_PUBLIC LinphoneCoreCbsNotifyReceivedCb linphone_core_cbs_get_notify_received(LinphoneCoreCbs *cbs); +/** + * Set the #LinphoneCoreCbsSubscribeReceivedCb callback. + * @param[in] cbs A #LinphoneCoreCbs. + * @param[in] cb The callback. + */ +LINPHONE_PUBLIC void linphone_core_cbs_set_subscribe_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsSubscribeReceivedCb cb); + +/** + * Get the #LinphoneCoreCbsSubscribeReceivedCb callback. + * @param[in] cbs A #LinphoneCoreCbs. + * @return The callback. + */ +LINPHONE_PUBLIC LinphoneCoreCbsSubscribeReceivedCb linphone_core_cbs_get_subscribe_received(LinphoneCoreCbs *cbs); + /** * Set the #LinphoneCoreCbsPublishStateChangedCb callback. * @param[in] cbs A #LinphoneCoreCbs. diff --git a/src/conference/handlers/local-conference-list-event-handler.cpp b/src/conference/handlers/local-conference-list-event-handler.cpp index b08ea059a..d6eb2cb28 100644 --- a/src/conference/handlers/local-conference-list-event-handler.cpp +++ b/src/conference/handlers/local-conference-list-event-handler.cpp @@ -36,6 +36,9 @@ #include "xml/resource-lists.h" #include "xml/rlmi.h" +// TODO: Remove me later. +#include "private.h" + // ============================================================================= using namespace std; @@ -48,7 +51,11 @@ namespace { // ----------------------------------------------------------------------------- -void LocalConferenceListEventHandler::subscribeReceived (LinphoneEvent *lev) { +void LocalConferenceListEventHandler::subscribeReceived (LinphoneEvent *lev, const LinphoneContent *body) { + const string &xmlBody = string(linphone_content_get_string_buffer(body)); + if (xmlBody.empty()) + return; + const LinphoneAddress *lAddr = linphone_event_get_from(lev); char *addrStr = linphone_address_as_string(lAddr); IdentityAddress participantAddr(addrStr); @@ -59,31 +66,6 @@ void LocalConferenceListEventHandler::subscribeReceived (LinphoneEvent *lev) { IdentityAddress deviceAddr(deviceAddrStr); bctbx_free(deviceAddrStr); - for (const auto &handler : handlers) { - shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(linphone_event_get_core(lev))->findChatRoom(handler->getChatRoomId()); - if (!chatRoom) { - lError() << "Received subscribe for unknown chat room: " << handler->getChatRoomId(); - continue; - } - - shared_ptr participant = chatRoom->findParticipant(participantAddr); - if (!participant) { - lError() << "Received subscribe for unknown participant: " << participantAddr << " for chat room: " << handler->getChatRoomId(); - continue; - } - - shared_ptr device = participant->getPrivate()->findDevice(deviceAddr); - if (!device) { - lError() << "Received subscribe for unknown device: " << deviceAddr << " for participant: " - << participantAddr << " for chat room: " << handler->getChatRoomId(); - return; - } - - device->setConferenceSubscribeEvent((linphone_event_get_subscription_state(lev) == LinphoneSubscriptionActive) ? lev : nullptr); - } -} - -void LocalConferenceListEventHandler::parseBody (const string &xmlBody) { list contents; Content rlmiContent; rlmiContent.setContentType(ContentType::Rlmi); @@ -112,6 +94,24 @@ void LocalConferenceListEventHandler::parseBody (const string &xmlBody) { if (notifyBody.empty()) continue; + shared_ptr chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(linphone_event_get_core(lev))->findChatRoom(chatRoomId); + if (!chatRoom) { + lError() << "Received subscribe for unknown chat room: " << chatRoomId; + continue; + } + shared_ptr participant = chatRoom->findParticipant(participantAddr); + if (!participant) { + lError() << "Received subscribe for unknown participant: " << participantAddr << " for chat room: " << chatRoomId; + continue; + } + shared_ptr device = participant->getPrivate()->findDevice(deviceAddr); + if (!device) { + lError() << "Received subscribe for unknown device: " << deviceAddr << " for participant: " + << participantAddr << " for chat room: " << chatRoomId; + continue; + } + device->setConferenceSubscribeEvent((linphone_event_get_subscription_state(lev) == LinphoneSubscriptionActive) ? lev : nullptr); + Content content; if (notifyId > 0) { ContentType contentType(ContentType::Multipart); @@ -149,11 +149,7 @@ void LocalConferenceListEventHandler::parseBody (const string &xmlBody) { contents.push_front(rlmiContent); Content multipart = ContentManager::contentListToMultipart(contents, MultipartBoundaryListEventHandler); - (void) multipart; -} - -void LocalConferenceListEventHandler::notify () { - + linphone_event_notify(lev, multipart.toLinphoneContent()); } // ----------------------------------------------------------------------------- diff --git a/src/conference/handlers/local-conference-list-event-handler.h b/src/conference/handlers/local-conference-list-event-handler.h index 1e5c0ad7c..0240fb615 100644 --- a/src/conference/handlers/local-conference-list-event-handler.h +++ b/src/conference/handlers/local-conference-list-event-handler.h @@ -24,6 +24,7 @@ #include #include "linphone/event.h" +#include "linphone/content.h" #include "chat/chat-room/chat-room-id.h" #include "linphone/utils/general.h" @@ -36,9 +37,7 @@ class LocalConferenceEventHandler; class LocalConferenceListEventHandler { public: - void subscribeReceived (LinphoneEvent *lev); - void parseBody (const std::string &xmlBody); - void notify (); + void subscribeReceived (LinphoneEvent *lev, const LinphoneContent *body); void addHandler (std::shared_ptr handler); std::shared_ptr findHandler (const ChatRoomId &chatRoomId) const; const std::list> &getHandlers () const; diff --git a/src/sal/sal.h b/src/sal/sal.h index 3e48bc481..41e2f86f7 100644 --- a/src/sal/sal.h +++ b/src/sal/sal.h @@ -58,7 +58,7 @@ public: typedef void (*OnNotifyReferCb)(SalOp *op, SalReferStatus state); typedef void (*OnSubscribeResponseCb)(SalOp *op, SalSubscribeStatus status, int will_retry); typedef void (*OnNotifyCb)(SalSubscribeOp *op, SalSubscribeStatus status, const char *event, SalBodyHandler *body); - typedef void (*OnSubscribeReceivedCb)(SalSubscribeOp *salop, const char *event, const SalBodyHandler *body); + typedef void (*OnSubscribeReceivedCb)(SalSubscribeOp *salop, const char *event, SalBodyHandler *body); typedef void (*OnIncomingSubscribeClosedCb)(SalOp *salop); typedef void (*OnParsePresenceRequestedCb)(SalOp *salop, const char *content_type, const char *content_subtype, const char *content, SalPresenceModel **result); typedef void (*OnConvertPresenceToXMLRequestedCb)(SalOp *salop, SalPresenceModel *presence, const char *contact, char **content); @@ -89,7 +89,7 @@ public: OnRegisterFailureCb register_failure; OnVfuRequestCb vfu_request; OnDtmfReceivedCb dtmf_received; - + OnMessageReceivedCb message_received; OnMessageDeliveryUpdateCb message_delivery_update; OnNotifyReferCb notify_refer;