Use message port for streaming audio data 45/221645/1
authorJi-hoon Lee <dalton.lee@samsung.com>
Mon, 6 Jan 2020 08:33:59 +0000 (17:33 +0900)
committerJi-hoon Lee <dalton.lee@samsung.com>
Mon, 6 Jan 2020 12:00:38 +0000 (21:00 +0900)
Change-Id: I4772bb18bd1db9cacb5fac7a179127fef2ac52d6

CMakeLists.txt
client/ma.c
client/ma_dbus.c
packaging/multi-assistant.spec

index c1bcadd4d7dff312c860deeefd215c10b6500206..6a442b9c29ff9c1e6593a5bd2ea9d651ffff8588 100644 (file)
@@ -44,11 +44,11 @@ INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include")
 INCLUDE(FindPkgConfig)
 IF("${_TV_PRODUCT}" STREQUAL "TRUE")
 pkg_check_modules(pkgs REQUIRED
-    capi-base-common ecore-wayland capi-network-bluetooth capi-network-bluetooth-tv capi-system-info cynara-client cynara-session dbus-1 dlog ecore glib-2.0 json-glib-1.0 libgum libtzplatform-config libxml-2.0 vconf
+    capi-base-common ecore-wayland capi-network-bluetooth capi-network-bluetooth-tv capi-system-info cynara-client cynara-session dbus-1 dlog ecore capi-message-port glib-2.0 json-glib-1.0 libgum libtzplatform-config libxml-2.0 vconf
 )
 ELSE()
 pkg_check_modules(pkgs REQUIRED
-    capi-base-common ecore-wayland capi-system-info cynara-client cynara-session dbus-1 dlog ecore glib-2.0 json-glib-1.0 libgum libtzplatform-config libxml-2.0 vconf
+    capi-base-common ecore-wayland capi-system-info cynara-client cynara-session dbus-1 dlog ecore capi-message-port glib-2.0 json-glib-1.0 libgum libtzplatform-config libxml-2.0 vconf
 )
 ENDIF()
 
index 12ea135636e1a29f113f7d12d320a22d59789a84..46ecc05482794905aaaf2bc0e1a14793dd20c4ac 100644 (file)
@@ -2212,4 +2212,4 @@ int ma_unset_service_state_changed_cb(void)
        return MA_ERROR_NONE;
 }
 
-//LCOV_EXCL_STOP
\ No newline at end of file
+//LCOV_EXCL_STOP
index c1f9ae65a96e0265fa238953861fe57c43ca6667..97cb7e29b09cd470fc7fcab10c0dd90395bb0180 100644 (file)
@@ -20,6 +20,7 @@
 #include "ma_main.h"
 #include "ma_client.h"
 
+#include <message_port.h>
 
 static int g_waiting_time = 3000;
 
@@ -37,6 +38,108 @@ extern int __ma_cb_preprocessing_information_changed(const char* app_id);
 extern int __ma_cb_audio_streaming_data_section_changed(ma_audio_streaming_data_section_e section);
 extern int __ma_cb_preprocessing_result_received(bool result);
 
+#define STREAMING_BUFFER_SIZE 4096
+
+typedef enum {
+       streaming_data_type_audio_data,
+       streaming_data_type_streaming_section
+} streaming_data_type_e;
+
+typedef struct {
+       unsigned int streaming_data_size;
+       int streaming_data_type;
+       int streaming_data_serial;
+} streaming_data_header;
+
+typedef struct {
+       int event;
+       unsigned int data_size;
+} streaming_data_audio_data_header;
+
+typedef struct {
+       int section;
+} streaming_data_streaming_section_header;
+
+const char *message_port = "ma_streaming_port";
+static int g_local_port_id = -1;
+
+static void message_port_cb(int local_port_id,
+       const char *remote_app_id, const char *remote_port,
+       bool trusted_remote_port, bundle *message, void *user_data)
+{
+       static char pending_buffer[STREAMING_BUFFER_SIZE * 2];
+       static unsigned int pending_buffer_size = 0;
+
+       char buffer[STREAMING_BUFFER_SIZE];
+       size_t size;
+
+       unsigned char *v = NULL;
+       bundle_get_byte(message, "content", (void**)(&v), &size);
+
+       if (size > STREAMING_BUFFER_SIZE) {
+               MA_SLOGE("[ERROR] bundle contains data bigger than %d : %d", STREAMING_BUFFER_SIZE, size);
+               return;
+       } else {
+               memcpy(buffer, v, size);
+       }
+
+       memcpy(pending_buffer + pending_buffer_size, buffer, size);
+       pending_buffer_size += size;
+
+       if (pending_buffer_size >= sizeof(streaming_data_header)) {
+               streaming_data_header header;
+               memcpy(&header, pending_buffer, sizeof(streaming_data_header));
+               if (pending_buffer_size >= header.streaming_data_size) {
+                       static int last_serial = 0;
+                       if (header.streaming_data_serial != last_serial + 1) {
+                               MA_SLOGE("[ERROR] SERIAL MISMATCH in [%d] : %d => %d",
+                                       header.streaming_data_type, last_serial, header.streaming_data_serial);
+                       }
+                       last_serial = header.streaming_data_serial;
+
+                       if (streaming_data_type_audio_data == header.streaming_data_type) {
+                               streaming_data_audio_data_header audio_data_header;
+                               memcpy(&audio_data_header, pending_buffer + sizeof(streaming_data_header),
+                                       sizeof(streaming_data_audio_data_header));
+
+                               __ma_cb_audio_streaming(audio_data_header.event,
+                                       pending_buffer + sizeof(streaming_data_header) + sizeof(streaming_data_audio_data_header),
+                                       audio_data_header.data_size);
+                       } else if (streaming_data_type_streaming_section == header.streaming_data_type) {
+                               streaming_data_streaming_section_header streaming_section_header;
+                               memcpy(&streaming_section_header, pending_buffer + sizeof(streaming_data_header),
+                                       sizeof(streaming_data_streaming_section_header));
+
+                               __ma_cb_audio_streaming_data_section_changed(streaming_section_header.section);
+                       }
+
+                       memmove(pending_buffer + header.streaming_data_size, pending_buffer,
+                               sizeof(pending_buffer) - header.streaming_data_size);
+                       pending_buffer_size -= header.streaming_data_size;
+               }
+       }
+}
+
+static int streaming_ipc_initialize()
+{
+       int port_id = message_port_register_local_port(message_port, message_port_cb, NULL);
+       if (port_id < 0) {
+               MA_SLOGD("Port register error: %d", port_id);
+       } else {
+               MA_SLOGD("port_id: %d", port_id);
+               g_local_port_id = port_id;
+       }
+
+       return 0;
+}
+
+static int streaming_ipc_deinitialize()
+{
+       if (-1 != g_local_port_id) message_port_unregister_local_port(g_local_port_id);
+       g_local_port_id = -1;
+       return 0;
+}
+
 static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler* fd_handler)
 {
        if (NULL == g_conn_listener)
@@ -103,7 +206,6 @@ static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler* fd_handle
                        int len;
                        static int count = 0;
                        static bool start_received = false;
-
                        dbus_message_get_args(msg, &err,
                                        DBUS_TYPE_INT32, &event,
                                        DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
@@ -438,11 +540,15 @@ int ma_dbus_open_connection()
                return MA_ERROR_OPERATION_FAILED;
        }
 
+       streaming_ipc_initialize();
+
        return 0;
 }
 
 int ma_dbus_close_connection()
 {
+       streaming_ipc_deinitialize();
+
        DBusError err;
        dbus_error_init(&err);
 
index 787a1b20990c421c7ff5671a8a3fcc64699b6339..aff56f00f33e9659cd80cd1dcd0731247732b51e 100644 (file)
@@ -17,6 +17,7 @@ BuildRequires:  pkgconfig(cynara-session)
 BuildRequires:  pkgconfig(dbus-1)
 BuildRequires:  pkgconfig(dlog)
 BuildRequires:  pkgconfig(ecore)
+BuildRequires:  pkgconfig(capi-message-port)
 BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  pkgconfig(json-glib-1.0)
 BuildRequires:  pkgconfig(libgum)