diff --git a/coreapi/bellesip_sal/sal_op_message.c b/coreapi/bellesip_sal/sal_op_message.c index 05f1199b8..c346347d0 100644 --- a/coreapi/bellesip_sal/sal_op_message.c +++ b/coreapi/bellesip_sal/sal_op_message.c @@ -92,6 +92,11 @@ void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *eve || (external_body=is_external_body(content_type)))) { SalMessage salmsg; char message_id[256]={0}; + + if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans); + op->pending_server_trans=server_transaction; + belle_sip_object_ref(op->pending_server_trans); + address=belle_sip_header_address_create(belle_sip_header_address_get_displayname(BELLE_SIP_HEADER_ADDRESS(from_header)) ,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(from_header))); from=belle_sip_object_to_string(BELLE_SIP_OBJECT(address)); @@ -120,6 +125,8 @@ void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *eve saliscomposing.from=from; saliscomposing.text=belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)); op->base.root->callbacks.is_composing_received(op,&saliscomposing); + resp = belle_sip_response_create_from_request(req,200); + belle_sip_server_transaction_send_response(server_transaction,resp); belle_sip_object_unref(address); belle_sip_free(from); } else { @@ -130,14 +137,11 @@ void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *eve belle_sip_server_transaction_send_response(server_transaction,resp); return; } - resp = belle_sip_response_create_from_request(req,200); - belle_sip_server_transaction_send_response(server_transaction,resp); } static void process_request_event(void *op_base, const belle_sip_request_event_t *event) { SalOp* op = (SalOp*)op_base; sal_process_incoming_message(op,event); - sal_op_release(op); } int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg){ @@ -171,6 +175,17 @@ int sal_message_send(SalOp *op, const char *from, const char *to, const char* co } +int sal_message_reply(SalOp *op, SalReason reason){ + if (op->pending_server_trans){ + int code=sal_reason_to_sip_code(reason); + belle_sip_response_t *resp = belle_sip_response_create_from_request( + belle_sip_transaction_get_request((belle_sip_transaction_t*)op->pending_server_trans),code); + belle_sip_server_transaction_send_response(op->pending_server_trans,resp); + return 0; + }else ms_error("sal_message_reply(): no server transaction"); + return -1; +} + int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg) { return sal_message_send(op,from,to,"text/plain",msg); } diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index f7a1fa363..0daf09cd2 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -878,9 +878,12 @@ static bool_t is_duplicate_msg(LinphoneCore *lc, const char *msg_id){ static void text_received(SalOp *op, const SalMessage *msg){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); - if (is_duplicate_msg(lc,msg->message_id)==FALSE){ + LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op); + if (lc->chat_deny_code==LinphoneReasonNone && is_duplicate_msg(lc,msg->message_id)==FALSE){ linphone_core_message_received(lc,op,msg); } + sal_message_reply(op,lc->chat_deny_code); + if (!call) sal_op_release(op); } static void is_composing_received(SalOp *op, const SalIsComposing *is_composing) { diff --git a/coreapi/chat.c b/coreapi/chat.c index 264d6d768..ef01b8b11 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -37,6 +37,31 @@ * @{ */ +/** + * Inconditionnaly disable incoming chat messages. + * @param lc the core + * @param deny_reason the deny reason (#LinphoneReasonNone has no effect). +**/ +void linphone_core_disable_chat(LinphoneCore *lc, LinphoneReason deny_reason){ + lc->chat_deny_code=deny_reason; +} + +/** + * Enable reception of incoming chat messages. + * By default it is enabled but it can be disabled with linphone_core_disable_chat(). + * @param lc the core +**/ +void linphone_core_enable_chat(LinphoneCore *lc){ + lc->chat_deny_code=LinphoneReasonNone; +} + +/** + * Returns whether chat is enabled. +**/ +bool_t linphone_core_chat_enabled(const LinphoneCore *lc){ + return lc->chat_deny_code!=LinphoneReasonNone; +} + /** * Returns an array of chat rooms * @param lc #LinphoneCore object diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index f2d4b2514..927b46a43 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -1038,6 +1038,9 @@ LINPHONE_PUBLIC void linphone_core_set_chat_database_path(LinphoneCore *lc, cons LINPHONE_PUBLIC LinphoneChatRoom * linphone_core_create_chat_room(LinphoneCore *lc, const char *to); LINPHONE_PUBLIC LinphoneChatRoom * linphone_core_get_or_create_chat_room(LinphoneCore *lc, const char *to); LINPHONE_PUBLIC LinphoneChatRoom *linphone_core_get_chat_room(LinphoneCore *lc, const LinphoneAddress *addr); +LINPHONE_PUBLIC void linphone_core_disable_chat(LinphoneCore *lc, LinphoneReason deny_reason); +LINPHONE_PUBLIC void linphone_core_enable_chat(LinphoneCore *lc); +LINPHONE_PUBLIC bool_t linphone_core_chat_enabled(const LinphoneCore *lc); LINPHONE_PUBLIC void linphone_chat_room_destroy(LinphoneChatRoom *cr); LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message(LinphoneChatRoom *cr,const char* message); LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message_2(LinphoneChatRoom *cr, const char* message, const char* external_body_url, LinphoneChatMessageState state, time_t time, bool_t is_read, bool_t is_incoming); diff --git a/coreapi/private.h b/coreapi/private.h index 18de67587..a9bd1f0bf 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -681,6 +681,7 @@ struct _LinphoneCore #endif //BUILD_UPNP belle_http_provider_t *http_provider; MSList *tones; + LinphoneReason chat_deny_code; }; diff --git a/include/sal/sal.h b/include/sal/sal.h index f508484ec..9990d099e 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -618,6 +618,7 @@ int sal_unregister(SalOp *h); /*Messaging */ int sal_text_send(SalOp *op, const char *from, const char *to, const char *text); int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg); +int sal_message_reply(SalOp *op, SalReason reason); /*presence Subscribe/notify*/ int sal_subscribe_presence(SalOp *op, const char *from, const char *to, int expires); diff --git a/tester/message_tester.c b/tester/message_tester.c index 5cf1b54a8..259727715 100644 --- a/tester/message_tester.c +++ b/tester/message_tester.c @@ -263,6 +263,25 @@ static void text_message_with_send_error(void) { linphone_core_manager_destroy(pauline); } +static void text_message_denied(void) { + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + char* to = linphone_address_as_string(pauline->identity); + LinphoneChatRoom* chat_room = linphone_core_create_chat_room(marie->lc,to); + LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu"); + + /*pauline doesn't want to be disturbed*/ + linphone_core_disable_chat(pauline->lc,LinphoneReasonDoNotDisturb); + + linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,marie->lc); + + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageNotDelivered,1)); + CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageReceived,0); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + static const char *info_content="blabla"; void info_message_received(LinphoneCore *lc, LinphoneCall* call, const LinphoneInfoMessage *msg){ @@ -360,6 +379,7 @@ test_t message_tests[] = { { "Text message with ack", text_message_with_ack }, { "Text message with send error", text_message_with_send_error }, { "Text message with external body", text_message_with_external_body }, + { "Text message denied", text_message_denied }, { "Info message", info_message }, { "Info message with body", info_message_with_body }, { "IsComposing notification", is_composing_notification }