aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt14
-rw-r--r--src/audiomanager_proxy.c697
-rw-r--r--src/audiomanager_proxy.h97
-rw-r--r--src/dbus/command_interface.xml2
-rw-r--r--src/dbus/routing_interface.xml52
-rw-r--r--src/dbus/sound_manager_interface.xml58
-rw-r--r--src/sm-def.h70
-rw-r--r--src/sm-error.c71
-rw-r--r--src/sm-error.h91
-rw-r--r--src/sm-helper.c163
-rw-r--r--src/sm-helper.h76
-rw-r--r--src/sm-pending.c76
-rw-r--r--src/sm-pending.h38
-rw-r--r--src/soundmanager.c965
-rw-r--r--src/soundmanager.h49
15 files changed, 1667 insertions, 852 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index a9e0e7b..66e640f 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -16,7 +16,7 @@
cmake_minimum_required(VERSION 2.8)
-set(TARGETS_SMBINDER soundmanager-service)
+set(TARGETS_SMBINDER agl-service-audio-soundmanager)
INCLUDE(FindThreads)
FIND_PACKAGE(Threads)
@@ -25,8 +25,18 @@ pkg_check_modules(sm_binding_depends afb-daemon glib-2.0 gio-2.0 gio-unix-2.0 js
set(binding_sm_sources
soundmanager.c
sm-helper.c
+ sm-error.c
+ sm-pending.c
+ audiomanager_proxy.c
dbus/audio_manager_interface.c)
+option(ENABLE_AGL_AHL "Implement AGL High Level API" ON)
+
+if(ENABLE_AGL_AHL)
+ message(STATUS "Adopt high level API of AGL")
+ add_definitions(-DENABLE_AGL_AHL)
+endif()
+
include_directories(dbus)
link_libraries(-Wl,--as-needed -Wl,--gc-sections -Wl,--no-undefined)
@@ -56,5 +66,5 @@ add_custom_command(TARGET ${TARGETS_SMBINDER} POST_BUILD
)
add_custom_target(package DEPENDS ${PROJECT_BINARY_DIR}/package/root
- COMMAND wgtpkg-pack -f -o ${PROJECT_BINARY_DIR}/package/${TARGETS_SMBINDER}-2017.wgt ${PROJECT_BINARY_DIR}/package/root
+ COMMAND wgtpkg-pack -f -o ${PROJECT_BINARY_DIR}/package/${TARGETS_SMBINDER}.wgt ${PROJECT_BINARY_DIR}/package/root
)
diff --git a/src/audiomanager_proxy.c b/src/audiomanager_proxy.c
new file mode 100644
index 0000000..d1ace2c
--- /dev/null
+++ b/src/audiomanager_proxy.c
@@ -0,0 +1,697 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <glib.h>
+#include <assert.h>
+#include <pthread.h>
+#include "audiomanager_proxy.h"
+#include "sm-helper.h"
+#include "dbus/audio_manager_interface.h"
+
+static AudiomanagerCommandinterface *am_cmd_bus;
+static AudiomanagerRoutinginterface *am_route_bus;
+static AudiomanagerRoutingSoundmanager *sm_adapter;
+static AudiomanagerRoutingSoundmanagerIface* sm_itf;
+static GDBusConnection* system_conn = NULL;
+
+static am_event _am_event = {0};
+static am_instruction _am_instruction = {0};
+static void *dbus_event_loop_run(void *args);
+
+/*
+********** Callback Function invoked by Audio Manager Command Interface**********
+*/
+static void _on_new_main_connection(AudiomanagerCommandinterface* interface,
+ GVariant* mainConnection)
+{
+ AFB_DEBUG("%s is called",__FUNCTION__);
+
+ guint16 mcid, srcid, sinkid;
+ gint16 delay, constate;
+ g_variant_get(
+ mainConnection,"(qqqnn)", &mcid, &srcid, &sinkid, &delay, &constate);
+
+ _am_event.on_new_main_connection(mcid, srcid, sinkid, delay, constate);
+}
+
+static void _on_removed_main_connection(
+ AudiomanagerCommandinterface* interface, guint16 mainConnectionID)
+{
+ AFB_DEBUG("%s is called",__FUNCTION__);
+
+ _am_event.on_removed_main_connection(mainConnectionID);
+}
+
+static void _on_main_connection_state_changed(
+ AudiomanagerCommandinterface* interface, guint16 connectionID, gint16 connectionState)
+{
+ AFB_DEBUG("%s is called",__FUNCTION__);
+ _am_event.on_main_connection_state_changed(connectionID, connectionState);
+}
+
+static void _on_volume_changed(
+ AudiomanagerCommandinterface* interface, guint16 sinkID, gint16 volume)
+{
+ AFB_DEBUG("%s is called",__FUNCTION__);
+ _am_event.on_volume_changed(sinkID, volume);
+}
+
+static void _on_sink_mute_state_changed(
+ AudiomanagerCommandinterface* interface, guint16 sinkID, gint16 mute)
+{
+ AFB_DEBUG("%s is called",__FUNCTION__);
+ _am_event.on_sink_mute_state_changed(sinkID, mute);
+}
+
+/*
+********** Callback Function invoked by Audio Manager Routing Interface**********
+*/
+static void _on_set_routing_ready(
+ AudiomanagerRoutinginterface* interface)
+{
+ AFB_DEBUG("%s is called",__FUNCTION__);
+ _am_event.on_set_routing_ready();
+}
+
+static void _on_set_routing_rundown(
+ AudiomanagerRoutinginterface* interface)
+{
+ AFB_DEBUG("%s is called",__FUNCTION__);
+ _am_event.on_set_routing_rundown();
+}
+
+static ErrorCode check_send_error(GError *err, guint16 result){
+ if(err != NULL){
+ return UNABLE_SEND;
+ }
+ return result;
+}
+
+static gboolean _on_async_abort(
+ AudiomanagerRoutingSoundmanager *object,
+ GDBusMethodInvocation *invocation,
+ guint16 arg_handle)
+{
+ AFB_DEBUG( "%s called", __FUNCTION__);
+ _am_instruction.on_async_abort((int)arg_handle);
+ return TRUE;
+}
+
+static gboolean _on_async_connect(
+ AudiomanagerRoutingSoundmanager *object,
+ GDBusMethodInvocation *invocation,
+ guint16 arg_handle,
+ guint16 arg_connectionID,
+ guint16 arg_sourceID,
+ guint16 arg_sinkID,
+ gint arg_connectionFormat)
+{
+ AFB_DEBUG( "%s called", __FUNCTION__);
+ int handle = (int)arg_handle;
+ int connection = (int)arg_connectionID;
+ int source = (int)arg_sourceID;
+ int sink = (int)arg_sinkID;
+ int connection_format = (int)arg_connectionFormat;
+ _am_instruction.on_async_connect(handle, connection,
+ source, sink, connection_format);
+ int ack_ok = 0;
+ ErrorCode ec = am_proxy_ack_connect(handle, connection, ack_ok);
+ if(ec == UNABLE_SEND)
+ {
+ AFB_ERROR( "Can't send ackConnect", __FUNCTION__);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean _on_async_disconnect(
+ AudiomanagerRoutingSoundmanager *object,
+ GDBusMethodInvocation *invocation,
+ guint16 arg_handle,
+ guint16 arg_connectionID)
+{
+ AFB_DEBUG( "%s called", __FUNCTION__);
+ int handle = (int)arg_handle;
+ int connection = (int)arg_connectionID;
+ _am_instruction.on_async_disconnect(handle, connection);
+ GError* err = NULL;
+ int ack_ok = 0;
+
+ ErrorCode ec = am_proxy_ack_disconnect(handle, connection, ack_ok);
+ if(ec == UNABLE_SEND)
+ {
+ AFB_ERROR( "Can't send ack to sound manager adapter %s", __FUNCTION__);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean _on_async_set_sink_volume(
+ AudiomanagerRoutingSoundmanager *object,
+ GDBusMethodInvocation *invocation,
+ guint16 arg_handle,
+ guint16 arg_sinkID,
+ gint16 arg_volume,
+ gint16 arg_ramp,
+ guint16 arg_time)
+{
+ AFB_DEBUG( "%s called", __FUNCTION__);
+ int handle = (int)arg_handle;
+ int sink = (int)arg_sinkID;
+ int volume = (int)arg_volume;
+ int ramp = (int)arg_ramp;
+ int time = (int)arg_time;
+ GError* err = NULL;
+ int ack_ok = 0;
+ ErrorCode ec = audiomanager_routinginterface_call_ack_set_sink_volume_sync(
+ am_route_bus,
+ arg_handle,
+ arg_volume,
+ ack_ok, NULL, &err);
+ if(ec == UNABLE_SEND);{
+ AFB_ERROR( "Can't send ack to sound manager adapter %s", __FUNCTION__);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean _on_async_set_source_state(
+ AudiomanagerRoutingSoundmanager *object,
+ GDBusMethodInvocation *invocation,
+ guint16 arg_handle,
+ guint16 arg_sourceID,
+ gint arg_sourceState)
+{
+ int handle = (int)arg_handle;
+ int source = (int)arg_sourceID;
+ int source_state = (int)arg_sourceState;
+ AFB_DEBUG( "%s called", __FUNCTION__);
+ _am_instruction.on_async_set_source_state(handle, source, source_state);
+ return TRUE;
+}
+
+/*
+********** API which calls audio manager API **********
+*/
+ErrorCode am_proxy_connect(int source, int sink, int *main_connection_id){
+ if(is_range_over_guint16(source) == OUT_RANGE || is_range_over_guint16(sink) == OUT_RANGE){
+ return OUT_RANGE;
+ }
+ AFB_DEBUG("Call %s: source:%d sink:%d", __FUNCTION__, source, sink);
+
+ guint16 connection_id = 0, ret = 0;
+ ErrorCode ec;
+ GError *err = NULL;
+
+ assert(am_cmd_bus != NULL);
+
+ audiomanager_commandinterface_call_connect_sync(
+ am_cmd_bus,
+ (guint16)source, (guint16)sink,
+ &ret, &connection_id,
+ NULL, &err);
+ *main_connection_id = (int)connection_id;
+ ec = check_send_error(err, ret);
+ return ec;
+}
+
+ErrorCode am_proxy_disconnect(int main_connection_id){
+ AFB_DEBUG("Call %s: mainConnectionID:%d", __FUNCTION__, main_connection_id);
+ if(is_range_over_guint16(main_connection_id) == OUT_RANGE){
+ return OUT_RANGE;
+ }
+ guint16 ret = 0;
+ ErrorCode ec;
+ GError *err = NULL;
+
+ assert(am_cmd_bus != NULL);
+ audiomanager_commandinterface_call_disconnect_sync(
+ am_cmd_bus,
+ (guint16)main_connection_id,
+ &ret,
+ NULL, &err);
+ ec = check_send_error(err, ret);
+ return ec;
+}
+
+ErrorCode am_proxy_set_volume(int sink, int volume){
+ AFB_DEBUG("Call %s: sink:%d volume:%d", __FUNCTION__, sink, volume);
+ if(is_range_over_guint16(sink) == OUT_RANGE && is_range_over_gint16(volume) == OUT_RANGE){
+ return OUT_RANGE;
+ }
+ guint16 ret = 0;
+ ErrorCode ec;
+ GError *err = NULL;
+
+ assert(am_cmd_bus != NULL);
+ audiomanager_commandinterface_call_set_volume_sync(
+ am_cmd_bus,
+ (guint16)sink,
+ (gint16)volume,
+ &ret, NULL, &err);
+ ec = check_send_error(err, ret);
+ return ec;
+}
+
+ErrorCode am_proxy_volume_step(int sink, int volume){
+ AFB_DEBUG("Call %s: sink:%d volume:%d", __FUNCTION__, sink, volume);
+ if(is_range_over_guint16(sink) == OUT_RANGE && is_range_over_gint16(volume) == OUT_RANGE){
+ return OUT_RANGE;
+ }
+ guint16 ret = 0;
+ ErrorCode ec;
+ GError *err = NULL;
+
+ assert(am_cmd_bus != NULL);
+ audiomanager_commandinterface_call_volume_step_sync(
+ am_cmd_bus,
+ (guint16)sink,
+ (gint16)volume,
+ &ret, NULL, &err);
+ ec = check_send_error(err, ret);
+ return ec;
+}
+
+ErrorCode am_proxy_set_sink_mute_state(int sink, int mute_state){
+ AFB_DEBUG("Call %s: sink:%d mute_state:%d", __FUNCTION__, sink, mute_state);
+ if(is_range_over_guint16(sink) == OUT_RANGE || is_range_over_gint16(mute_state) == OUT_RANGE){
+ return OUT_RANGE;
+ }
+ guint16 ret = 0;
+ ErrorCode ec;
+ GError *err = NULL;
+
+ assert(am_cmd_bus != NULL);
+ audiomanager_commandinterface_call_set_sink_mute_state_sync(
+ am_cmd_bus,
+ (guint16)sink, (gint16)mute_state,
+ &ret, NULL, &err);
+ ec = check_send_error(err, ret);
+ return ec;
+}
+
+ErrorCode am_proxy_get_list_main_connections(GVariant** connection_list){
+ guint16 ret = 0;
+ ErrorCode ec;
+ GError *err = NULL;
+
+ AFB_DEBUG("Call %s", __FUNCTION__);
+ assert(am_cmd_bus != NULL);
+ audiomanager_commandinterface_call_get_list_main_connections_sync(
+ am_cmd_bus,
+ &ret,
+ connection_list,
+ NULL,
+ &err
+ );
+ ec = check_send_error(err, ret);
+ return ec;
+}
+
+ErrorCode am_proxy_get_list_main_sources(GVariant** source_list){
+ guint16 ret = 0;
+ ErrorCode ec;
+ GError *err = NULL;
+
+ AFB_DEBUG("Call %s", __FUNCTION__);
+ assert(am_cmd_bus != NULL);
+ audiomanager_commandinterface_call_get_list_main_sources_sync(
+ am_cmd_bus,
+ &ret,
+ source_list,
+ NULL,
+ &err
+ );
+ ec = check_send_error(err, ret);
+ return ec;
+}
+
+ErrorCode am_proxy_get_list_main_sinks(GVariant** sink_list){
+ guint16 ret = 0;
+ ErrorCode ec;
+ GError *err = NULL;
+
+ AFB_DEBUG("Call %s", __FUNCTION__);
+ assert(am_cmd_bus != NULL);
+ audiomanager_commandinterface_call_get_list_main_sinks_sync(
+ am_cmd_bus,
+ &ret,
+ sink_list,
+ NULL,
+ &err
+ );
+ ec = check_send_error(err, ret);
+ return ec;
+}
+
+ErrorCode am_proxy_ack_connect(int handle, int connection_id, int usr_err){
+ AFB_DEBUG("Call %s handle:%d connectionID:%d error:%d", __FUNCTION__, handle, connection_id, usr_err);
+ if(is_range_over_guint16(handle) == OUT_RANGE ||
+ is_range_over_guint16(connection_id) == OUT_RANGE ||
+ is_range_over_guint16(usr_err) == OUT_RANGE){
+ return OUT_RANGE;
+ }
+
+ assert(am_route_bus != NULL);
+ GError *err = NULL;
+
+ audiomanager_routinginterface_call_ack_connect_sync(
+ am_route_bus,
+ (guint16)handle,
+ (guint16)connection_id,
+ (guint16)usr_err, NULL, &err);
+ return OK;
+}
+
+ErrorCode am_proxy_ack_disconnect(int handle, int connection_id, int usr_err){
+ AFB_DEBUG("Call %s handle:%d connectionID:%d error:%d", __FUNCTION__, handle, connection_id, usr_err);
+ if(is_range_over_guint16(handle) == OUT_RANGE ||
+ is_range_over_guint16(connection_id) == OUT_RANGE ||
+ is_range_over_guint16(usr_err) == OUT_RANGE){
+ return OUT_RANGE;
+ }
+ assert(am_route_bus != NULL);
+ GError *err = NULL;
+ audiomanager_routinginterface_call_ack_disconnect_sync(
+ am_route_bus,
+ (guint16)handle,
+ (guint16)connection_id,
+ (guint16)usr_err,NULL, &err);
+ return OK;
+}
+
+ErrorCode am_proxy_ack_set_source_state(int handle, int usr_err){
+ AFB_DEBUG("Call %s handle:%d error:%d", __FUNCTION__, handle, usr_err);
+ if(is_range_over_guint16(handle) == OUT_RANGE ||
+ is_range_over_guint16(usr_err) == OUT_RANGE){
+ return OUT_RANGE;
+ }
+
+ assert(am_route_bus != NULL);
+ GError *err = NULL;
+ audiomanager_routinginterface_call_ack_set_source_state_sync(
+ am_route_bus,
+ (guint16)handle,
+ (guint16)usr_err,
+ NULL, &err);
+ return OK;
+}
+
+ErrorCode am_proxy_register_source(GVariant *source_data, int *source){
+ AFB_DEBUG("Call %s", __FUNCTION__);
+ assert(am_route_bus != NULL);
+ guint16 ret = 0, g_source = 0;
+ ErrorCode ec;
+ GError *err = NULL;
+
+ audiomanager_routinginterface_call_register_source_sync(
+ am_route_bus,
+ source_data,
+ &g_source,
+ &ret,
+ NULL, &err);
+
+ *source = (int)g_source;
+ ec = check_send_error(err, ret);
+ return ec;
+}
+
+ErrorCode am_proxy_deregister_source(int source){
+ AFB_DEBUG("Call %s source:%d", __FUNCTION__, source);
+ if(is_range_over_guint16(source) == OUT_RANGE){
+ return OUT_RANGE;
+ }
+ guint16 ret = 0;
+ ErrorCode ec;
+ GError *err = NULL;
+
+ assert(am_route_bus != NULL);
+ audiomanager_routinginterface_call_deregister_source_sync(
+ am_route_bus,
+ (guint16)source,
+ &ret,
+ NULL, &err
+ );
+ ec = check_send_error(err, ret);
+ return ec;
+}
+
+ErrorCode am_proxy_register_domain(GVariant* domain_data, int *domain){
+ guint16 ret = 0, g_domain = 0;
+ ErrorCode ec;
+ GError *err = NULL;
+
+ assert(am_route_bus != NULL);
+ assert(domain_data);
+ AFB_DEBUG("Call %s", __FUNCTION__);
+ audiomanager_routinginterface_call_register_domain_sync(
+ am_route_bus,
+ domain_data,
+ SOUND_MANAGER_BUS_NAME,
+ SOUND_MANAGER_PATH,
+ SOUND_MANAGER_RETURN_INTERFACE,
+ &g_domain, &ret,
+ NULL, &err);
+
+ *domain = (int)g_domain;
+ ec = check_send_error(err, ret);
+ return ec;
+}
+
+GVariant* create_domain_data(struct domain_data* domain){
+ /*
+ * This function doesn't check the range of guint32 or gint16
+ * Soundmanager must keep the input data is between the size of type.
+ * This function is considered to be only used by soundmanager.
+ */
+ GVariantBuilder builder;
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("(qsssbbn)"));
+ g_variant_builder_add (&builder, "q", (guint16)domain->domainID);
+ g_variant_builder_add (&builder, "s", domain->name);
+ g_variant_builder_add (&builder, "s", domain->busname);
+ g_variant_builder_add (&builder, "s", domain->nodename);
+ g_variant_builder_add (&builder, "b", (gboolean)domain->early);
+ g_variant_builder_add (&builder, "b", (gboolean)domain->complete);
+ g_variant_builder_add (&builder, "n", (gint16)domain->state);
+ AFB_DEBUG("create domainData");
+ return g_variant_builder_end (&builder);
+}
+
+GVariant* create_source_data(int sourceID, int domainID, const char* appname, int sourceClassID,
+ int sourceState, int volume, bool visible, struct availability_s availables,
+ int interrupt, struct sound_property_s soundPropertyList, int connectionFormatList,
+ struct main_sound_property_s mainPropertyList, struct notification_config_s NConfRouting,
+ struct notification_config_s NConfCommand)
+{
+ GVariantBuilder builder;
+ if(is_range_over_guint16(sourceID) == OUT_RANGE ||
+ is_range_over_guint16(domainID) == OUT_RANGE ||
+ is_range_over_gint16(volume) == OUT_RANGE ||
+ is_range_over_guint16(interrupt) == OUT_RANGE ||
+ is_range_over_gint16(soundPropertyList.value) == OUT_RANGE ||
+ is_range_over_gint16(mainPropertyList.value) == OUT_RANGE ||
+ is_range_over_gint16(NConfRouting.parameter) == OUT_RANGE ||
+ is_range_over_gint16(NConfCommand.parameter) == OUT_RANGE)
+ {
+ return NULL;
+ }
+ g_variant_builder_init (&builder, G_VARIANT_TYPE ("(qqsqinb(ii)qa(in)aia(in)a(iin)a(iin))"));
+ g_variant_builder_add (&builder, "q", (guint16)sourceID);
+ g_variant_builder_add (&builder, "q", (guint16)domainID);
+ g_variant_builder_add (&builder, "s", appname);
+ g_variant_builder_add (&builder, "q", (guint16)sourceClassID);
+ g_variant_builder_add (&builder, "i", (gint32)sourceState);
+ g_variant_builder_add (&builder, "n", (gint16)volume);
+ g_variant_builder_add (&builder, "b", (gboolean)visible);
+ g_variant_builder_add (&builder, "(ii)", (gint32)availables.availability, (gint32)availables.avalilable_reason);
+ g_variant_builder_add (&builder, "q", (guint16)interrupt);
+
+ g_variant_builder_open(&builder, G_VARIANT_TYPE("a(in)"));
+ g_variant_builder_open(&builder, G_VARIANT_TYPE("(in)"));
+ g_variant_builder_add (&builder, "i", (gint32)soundPropertyList.type);
+ g_variant_builder_add (&builder, "n", (gint16)soundPropertyList.value);
+ g_variant_builder_close(&builder);
+ g_variant_builder_close (&builder);
+
+ g_variant_builder_open(&builder, G_VARIANT_TYPE("ai"));
+ g_variant_builder_add (&builder, "i", (gint32)connectionFormatList);
+ g_variant_builder_close (&builder);
+
+ g_variant_builder_open(&builder, G_VARIANT_TYPE("a(in)"));
+ g_variant_builder_open(&builder, G_VARIANT_TYPE("(in)"));
+ g_variant_builder_add (&builder, "i", (gint32)mainPropertyList.type);
+ g_variant_builder_add (&builder, "n", (gint16)mainPropertyList.value);
+ g_variant_builder_close (&builder);
+ g_variant_builder_close(&builder);
+
+ g_variant_builder_open(&builder, G_VARIANT_TYPE("a(iin)"));
+ g_variant_builder_open(&builder, G_VARIANT_TYPE("(iin)"));
+ g_variant_builder_add (&builder, "i", (gint32)NConfRouting.type);
+ g_variant_builder_add (&builder, "i", (gint32)NConfRouting.status);
+ g_variant_builder_add (&builder, "n", (gint16)NConfRouting.parameter);
+ g_variant_builder_close(&builder);
+ g_variant_builder_close (&builder);
+
+
+ g_variant_builder_open(&builder, G_VARIANT_TYPE("a(iin)"));
+ g_variant_builder_open(&builder, G_VARIANT_TYPE("(iin)"));
+ g_variant_builder_add (&builder, "i", (gint32)NConfCommand.type);
+ g_variant_builder_add (&builder, "i", (gint32)NConfCommand.status);
+ g_variant_builder_add (&builder, "n", (gint16)NConfCommand.parameter);
+ g_variant_builder_close(&builder);
+ g_variant_builder_close (&builder);
+
+ AFB_DEBUG("create sourceData");
+ return g_variant_builder_end (&builder);
+}
+
+static void *dbus_event_loop_run(void *args)
+{
+ GMainLoop* loop = g_main_loop_new(NULL, FALSE);
+ g_main_loop_run(loop);
+}
+
+ErrorCode initialize_proxy(){
+ if(am_cmd_bus || am_route_bus)
+ {
+ return NOT_INITIALIZED;
+ }
+ am_cmd_bus = audiomanager_commandinterface_proxy_new_for_bus_sync(
+ G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ AM_NAME,
+ AM_CMD_PATH,
+ NULL,
+ NULL
+ );
+ if(!am_cmd_bus){
+ AFB_ERROR("Failed to create command interface");
+ }
+ am_route_bus = audiomanager_routinginterface_proxy_new_for_bus_sync(
+ G_BUS_TYPE_SYSTEM,
+ G_DBUS_PROXY_FLAGS_NONE,
+ AM_NAME,
+ AM_ROUTE_PATH,
+ NULL,
+ NULL
+ );
+ if(!am_route_bus){
+ AFB_ERROR("Failed to create routing interface");
+ }
+ return (am_cmd_bus && am_route_bus) ? OK : UNABLE_SEND;
+}
+
+void close_proxy(){
+ if(am_cmd_bus) free(am_cmd_bus);
+ if(am_route_bus) free(am_route_bus);
+}
+
+void set_event_callback(const am_event* callback){
+ assert(am_cmd_bus != NULL);
+ assert(am_route_bus != NULL);
+ /* initialize signal from audio manager command interface */
+ _am_event.on_main_connection_state_changed = callback->on_main_connection_state_changed;
+ _am_event.on_new_main_connection = callback->on_new_main_connection;
+ _am_event.on_removed_main_connection = callback->on_removed_main_connection;
+ _am_event.on_set_routing_ready = callback->on_set_routing_ready;
+ _am_event.on_set_routing_rundown = callback->on_set_routing_rundown;
+ _am_event.on_sink_mute_state_changed = callback->on_sink_mute_state_changed;
+ _am_event.on_volume_changed = callback->on_volume_changed;
+
+ g_signal_connect(am_cmd_bus, "volume_changed",
+ G_CALLBACK(_on_volume_changed), NULL);
+ g_signal_connect(am_cmd_bus, "new_main_connection",
+ G_CALLBACK(_on_new_main_connection), NULL);
+ g_signal_connect(am_cmd_bus, "removed_main_connection",
+ G_CALLBACK(_on_removed_main_connection),NULL);
+ g_signal_connect(am_cmd_bus, "sink_mute_state_changed",
+ G_CALLBACK(_on_sink_mute_state_changed),NULL);
+ g_signal_connect(am_cmd_bus, "main_connection_state_changed",
+ G_CALLBACK(_on_main_connection_state_changed), NULL);
+ g_signal_connect(am_route_bus, "set_routing_ready",
+ G_CALLBACK(_on_set_routing_ready), NULL);
+ g_signal_connect(am_route_bus, "set_routing_rundown",
+ G_CALLBACK(_on_set_routing_rundown), NULL);
+}
+
+static void on_bus_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data){
+ GError* error = NULL;
+ AFB_DEBUG("%s is called", __FUNCTION__);
+
+ sm_adapter = audiomanager_routing_soundmanager_skeleton_new();
+ sm_itf = AUDIOMANAGER_ROUTING_SOUNDMANAGER_GET_IFACE(sm_adapter);
+
+ /* initialize sound manager adapter */
+ sm_itf->handle_async_abort = _on_async_abort;
+ sm_itf->handle_async_connect = _on_async_connect;
+ sm_itf->handle_async_disconnect = _on_async_disconnect;
+ sm_itf->handle_async_set_sink_volume = _on_async_set_sink_volume;
+ sm_itf->handle_async_set_source_state = _on_async_set_source_state;
+
+ int sigret = g_signal_connect(sm_adapter, "handle-async-abort", G_CALLBACK(_on_async_abort),NULL);
+ sigret = g_signal_connect(sm_adapter, "handle-async-connect", G_CALLBACK(_on_async_connect),NULL);
+ sigret = g_signal_connect(sm_adapter, "handle-async-disconnect", G_CALLBACK(_on_async_disconnect),NULL);
+ sigret = g_signal_connect(sm_adapter, "handle-async-set-sink-volume", G_CALLBACK(_on_async_set_sink_volume),NULL);
+ sigret = g_signal_connect(sm_adapter, "handle-async-set-source-state", G_CALLBACK(_on_async_set_source_state),NULL);
+
+ AFB_DEBUG("register %s", AUDIOMANAGER_ROUTING_SOUNDMANAGER_SKELETON(sm_adapter));
+
+ gboolean rc = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(sm_adapter), connection, SOUND_MANAGER_PATH, &error);
+ AFB_DEBUG("export soundmanager path result: %d", rc);
+ if (FALSE == rc)
+ {
+ AFB_ERROR( "failed to export");
+ g_error_free(error);
+ g_object_unref(connection);
+ }
+}
+
+static void on_name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data){
+ AFB_DEBUG("%s is called", __FUNCTION__);
+}
+
+static void on_name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data){
+ AFB_DEBUG("bus name is lost");
+ // TODO: soundmanager should register current status?
+}
+
+ErrorCode open_soundmanager_interface(const am_instruction *callback){
+ _am_instruction.on_async_abort = callback->on_async_abort;
+ _am_instruction.on_async_connect = callback->on_async_connect;
+ _am_instruction.on_async_disconnect = callback->on_async_disconnect;
+ _am_instruction.on_async_set_sink_volume = callback->on_async_set_sink_volume;
+ _am_instruction.on_async_set_source_state = callback->on_async_set_source_state;
+
+ guint owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, SOUND_MANAGER_BUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE,
+ on_bus_acquired, on_name_acquired, on_name_lost, NULL/* (gpointer)callback */, NULL);
+ // see https://developer.gnome.org/gio/stable/gio-Owning-Bus-Names.html#g-bus-own-name
+
+ pthread_t thread_id;
+ int ret = pthread_create(&thread_id, NULL, dbus_event_loop_run, NULL);
+ if(ret != 0)
+ {
+ AFB_ERROR("Failed to create thread");
+ g_bus_unown_name(owner_id);
+ close_soundmanager_inerface();
+ close_proxy();
+ return NOT_INITIALIZED;
+ }
+ return OK;
+}
+
+void close_soundmanager_inerface(){
+ g_dbus_interface_skeleton_unexport(G_DBUS_INTERFACE_SKELETON(sm_adapter));
+}
diff --git a/src/audiomanager_proxy.h b/src/audiomanager_proxy.h
new file mode 100644
index 0000000..5a2427b
--- /dev/null
+++ b/src/audiomanager_proxy.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef AUDIO_MANAGER_PROXY_H
+#define AUDIO_MANAGER_PROXY_H
+#include <glib.h>
+#include <stdbool.h>
+#include "sm-def.h"
+
+typedef struct audiomanager_event{
+ void (*on_new_main_connection)(int connection, int source, int sink, int delay, int connection_state);
+ void (*on_removed_main_connection)(int connection);
+ void (*on_main_connection_state_changed)(int connection, int connection_state);
+ void (*on_volume_changed)(int sink, int volume);
+ void (*on_sink_mute_state_changed)(int sink, int mute);
+ void (*on_set_routing_ready)(void);
+ void (*on_set_routing_rundown)(void);
+} am_event;
+
+typedef struct audiomanager_instruction{
+ void (*on_async_abort)(int handle);
+ void (*on_async_connect)(int handle, int connection, int source, int sink, int connection_format);
+ void (*on_async_disconnect)(int handle, int connection);
+ void (*on_async_set_sink_volume)(int handle, int sink, int volume, int ramp, int time);
+ void (*on_async_set_source_state)(int handle, int source, int source_state);
+} am_instruction;
+
+struct domain_data{
+ int domainID;
+ char* name;
+ char* busname;
+ char* nodename;
+ bool early;
+ bool complete;
+ int state;
+};
+
+struct sound_property_s{
+ int type;
+ int value;
+};
+struct availability_s{
+ int availability;
+ int avalilable_reason;
+};
+struct notification_config_s{
+ int type;
+ int status;
+ int parameter;
+};
+struct main_sound_property_s{
+ int type; /* am_CustomMainSoundPropertyType_t */
+ int value;
+};
+
+ErrorCode am_proxy_connect(int source, int sink, int *main_connection_id);
+ErrorCode am_proxy_disconnect(int main_connection_id);
+ErrorCode am_proxy_set_volume(int sink, int volume);
+ErrorCode am_proxy_volume_step(int sink, int volume);
+ErrorCode am_proxy_set_sink_mute_state(int sink, int mute_state);
+ErrorCode am_proxy_get_list_main_connections(GVariant** connection_list);
+ErrorCode am_proxy_get_list_main_sources(GVariant** source_list);
+ErrorCode am_proxy_get_list_main_sinks(GVariant** sink_list);
+ErrorCode am_proxy_ack_connect(int handle, int connection_id, int usr_err);
+ErrorCode am_proxy_ack_disconnect(int handle, int connection_id, int usr_err);
+ErrorCode am_proxy_ack_set_source_state(int handle, int usr_err);
+ErrorCode am_proxy_register_source(GVariant *source_data, int *source);
+ErrorCode am_proxy_deregister_source(int source);
+ErrorCode am_proxy_register_domain(GVariant* domain_data, int *domain);
+
+GVariant* create_domain_data(struct domain_data* domain);
+GVariant* create_source_data(int sourceID, int domainID, const char* appname, int sourceClassID,
+ int sourceState, int volume, bool visible, struct availability_s availables,
+ int interrupt, struct sound_property_s soundPropertyList, int connectionFormatList,
+ struct main_sound_property_s mainPropertyList, struct notification_config_s NConfRouting,
+ struct notification_config_s NConfCommand);
+
+ErrorCode initialize_proxy();
+void set_event_callback(const am_event *callback);
+void close_proxy();
+ErrorCode open_soundmanager_interface(const am_instruction *callback);
+void close_soundmanager_inerface();
+
+#endif //AUDIO_MANAGER_PROXY_H \ No newline at end of file
diff --git a/src/dbus/command_interface.xml b/src/dbus/command_interface.xml
index 244553c..2be9ba2 100644
--- a/src/dbus/command_interface.xml
+++ b/src/dbus/command_interface.xml
@@ -32,7 +32,7 @@
</method>
<method name="GetListMainSinks">
<arg type="n" name="result" direction="out"/> <!-- method return code (am_Error_e) -->
- <arg type="a(qs(nn)nnq)" name="listMainSinks" direction="out"/>
+ <arg type="a(qs(nn)nnq)" name="listMainSinks" direction="out"/>
<!-- uint16 sinkID; std::string name; am_Availability_s availability; am_mainVolume_t volume; am_MuteState_e muteState; am_sinkClass_t sinkClassID; -->
</method>
<method name="GetListMainSources">
diff --git a/src/dbus/routing_interface.xml b/src/dbus/routing_interface.xml
index a91d6eb..f82b456 100644
--- a/src/dbus/routing_interface.xml
+++ b/src/dbus/routing_interface.xml
@@ -3,11 +3,11 @@
"-//freedesktop//DTD D-Bus Object Introspection 1.0//EN"
"http://standards.freedesktop.org/dbus/1.0/introspect.dtd">
-<node>
- <interface name="org.genivi.audiomanager.routinginterface">
- <method name="ackConnect">
- <arg name="handle" type="q" direction="in" />
- <arg name="connectionID" type="q" direction="in" />
+<node>
+ <interface name="org.genivi.audiomanager.routinginterface">
+ <method name="ackConnect">
+ <arg name="handle" type="q" direction="in" />
+ <arg name="connectionID" type="q" direction="in" />
<arg name="error" type="q" direction="in" />
</method>
<method name="ackDisconnect">
@@ -24,23 +24,23 @@
<arg name="volume" type="n" direction="in" />
<arg name="error" type="q" direction="in" />
</method>
- <method name="registerSink">
- <arg name="sinkData" type="(qsqinb(ii)nna(in)aia(in)a(iin)a(iin))" direction="in" /> <!-- am_sinkID_t sinkID; std::string name; am_domainID_t domainID; am_sinkClass_t sinkClassID; am_volume_t volume; bool visible; am_Availability_s available; am_MuteState_e muteState;am_mainVolume_t mainVolume; std::vector<am_SoundProperty_s> listSoundProperties; std::vector<am_CustomAvailabilityReason_t> listConnectionFormats; std::vector<am_MainSoundProperty_s> listMainSoundProperties; -->
- <arg name="sinkID" type="q" direction="out" />
+ <method name="registerSink">
+ <arg name="sinkData" type="(qsqinb(ii)nna(in)aia(in)a(iin)a(iin))" direction="in" /> <!-- am_sinkID_t sinkID; std::string name; am_domainID_t domainID; am_sinkClass_t sinkClassID; am_volume_t volume; bool visible; am_Availability_s available; am_MuteState_e muteState;am_mainVolume_t mainVolume; std::vector<am_SoundProperty_s> listSoundProperties; std::vector<am_CustomAvailabilityReason_t> listConnectionFormats; std::vector<am_MainSoundProperty_s> listMainSoundProperties; -->
+ <arg name="sinkID" type="q" direction="out" />
<arg name="error" type="q" direction="out" />
</method>
<method name="deregisterSink">
- <arg name="sinkID" type="q" direction="in" />
+ <arg name="sinkID" type="q" direction="in" />
<arg name="error" type="i" direction="out" />
- </method>
- <method name="registerSource">
- <arg name="sourceData" type="(qqsqinb(ii)qa(in)aia(in)a(iin)a(iin))" direction="in" /> <!-- am_sourceID_t sourceID; am_domainID_t domainID; std::string name; am_sourceClass_t sourceClassID; am_SourceState_e sourceState; am_volume_t volume; bool visible; am_Availability_s available; am_InterruptState_e interruptState; std::vector<am_SoundProperty_s> listSoundProperties; std::vector<am_CustomAvailabilityReason_t> listConnectionFormats; std::vector<am_MainSoundProperty_s> listMainSoundProperties; -->
- <arg name="sourceID" type="q" direction="out" />
+ </method>
+ <method name="registerSource">
+ <arg name="sourceData" type="(qqsqinb(ii)qa(in)aia(in)a(iin)a(iin))" direction="in" /> <!-- am_sourceID_t sourceID; am_domainID_t domainID; std::string name; am_sourceClass_t sourceClassID; am_SourceState_e sourceState; am_volume_t volume; bool visible; am_Availability_s available; am_InterruptState_e interruptState; std::vector<am_SoundProperty_s> listSoundProperties; std::vector<am_CustomAvailabilityReason_t> listConnectionFormats; std::vector<am_MainSoundProperty_s> listMainSoundProperties; -->
+ <arg name="sourceID" type="q" direction="out" />
<arg name="error" type="q" direction="out" />
</method>
<method name="deregisterSource">
- <arg name="sourceID" type="q" direction="in" />
- <arg name="error" type="q" direction="out" />
+ <arg name="sourceID" type="q" direction="in" />
+ <arg name="error" type="q" direction="out" />
</method>
<method name="hookInterruptStatusChange">
<arg name="sourceID" type="q" direction="in" />
@@ -48,24 +48,24 @@
</method>
<method name="hookSourceAvailablityStatusChange">
<arg name="sourceID" type="q" direction="in" />
- <arg name="availability" type="(nn)" direction="in"/>
+ <arg name="availability" type="(nn)" direction="in"/>
</method>
- <method name="confirmRoutingReady">
+ <method name="confirmRoutingReady">
<arg name="domainID" type="q" direction="in" />
</method>
- <method name="confirmRoutingRundown">
+ <method name="confirmRoutingRundown">
<arg name="domainID" type="q" direction="in" />
</method>
- <method name="ackSetVolumes">
+ <method name="ackSetVolumes">
<arg name="handle" type="q" direction="in" />
<arg name="listvolumes" type="a(nqqnq)" direction="in" />
- <arg name="error" type="q" direction="in" />
- </method>
- <method name="ackSinkNotificationConfiguration">
+ <arg name="error" type="q" direction="in" />
+ </method>
+ <method name="ackSinkNotificationConfiguration">
<arg name="handle" type="q" direction="in" />
<arg name="error" type="q" direction="in" />
- </method>
- <method name="ackSourceNotificationConfiguration">
+ </method>
+ <method name="ackSourceNotificationConfiguration">
<arg name="handle" type="q" direction="in" />
<arg name="error" type="q" direction="in" />
</method>
@@ -78,8 +78,8 @@
<arg name="error" type="q" direction="out" />
</method>
<signal name="setRoutingReady">
- </signal>
+ </signal>
<signal name="setRoutingRundown">
- </signal>
+ </signal>
</interface>
</node>
diff --git a/src/dbus/sound_manager_interface.xml b/src/dbus/sound_manager_interface.xml
index df7df04..de528f9 100644
--- a/src/dbus/sound_manager_interface.xml
+++ b/src/dbus/sound_manager_interface.xml
@@ -3,34 +3,34 @@
"-//freedesktop//DTD D-Bus Object Introspection 1.0//EN"
"http://standards.freedesktop.org/dbus/1.0/introspect.dtd">
-<node>
- <interface name='org.genivi.audiomanager.routing.soundmanager'>
- <method name='asyncAbort'>
- <arg name='handle' type='q' direction='in' />
+<node>
+ <interface name='org.genivi.audiomanager.routing.soundmanager'>
+ <method name='asyncAbort'>
+ <arg name='handle' type='q' direction='in' />
<arg name='error' type='n' direction='out' />
- </method>
- <method name='asyncConnect'>
- <arg name='handle' type='q' direction='in' />
- <arg name='connectionID' type='q' direction='in' />
- <arg name='sourceID' type='q' direction='in' />
- <arg name='sinkID' type='q' direction='in' />
- <arg name='connectionFormat' type='i' direction='in' />
- </method>
- <method name='asyncDisconnect'>
- <arg name='handle' type='q' direction='in' />
- <arg name='connectionID' type='q' direction='in' />
- </method>
- <method name='asyncSetSinkVolume'>
- <arg name='handle' type='q' direction='in' />
- <arg name='sinkID' type='q' direction='in' />
- <arg name='volume' type='n' direction='in' />
- <arg name='ramp' type='n' direction='in' />
- <arg name='time' type='q' direction='in' />
- </method>
- <method name='asyncSetSourceState'>
- <arg name='handle' type='q' direction='in' />
- <arg name='sourceID' type='q' direction='in' />
- <arg name='sourceState' type='i' direction='in' />
- </method>
- </interface>
+ </method>
+ <method name='asyncConnect'>
+ <arg name='handle' type='q' direction='in' />
+ <arg name='connectionID' type='q' direction='in' />
+ <arg name='sourceID' type='q' direction='in' />
+ <arg name='sinkID' type='q' direction='in' />
+ <arg name='connectionFormat' type='i' direction='in' />
+ </method>
+ <method name='asyncDisconnect'>
+ <arg name='handle' type='q' direction='in' />
+ <arg name='connectionID' type='q' direction='in' />
+ </method>
+ <method name='asyncSetSinkVolume'>
+ <arg name='handle' type='q' direction='in' />
+ <arg name='sinkID' type='q' direction='in' />
+ <arg name='volume' type='n' direction='in' />
+ <arg name='ramp' type='n' direction='in' />
+ <arg name='time' type='q' direction='in' />
+ </method>
+ <method name='asyncSetSourceState'>
+ <arg name='handle' type='q' direction='in' />
+ <arg name='sourceID' type='q' direction='in' />
+ <arg name='sourceState' type='i' direction='in' />
+ </method>
+ </interface>
</node>
diff --git a/src/sm-def.h b/src/sm-def.h
index 9d4acb5..bd565d5 100644
--- a/src/sm-def.h
+++ b/src/sm-def.h
@@ -1,3 +1,18 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
#ifndef SOUNDMANAGER_DEFINE_H
#define SOUNDMANAGER_DEFINE_H
@@ -38,7 +53,7 @@
#define KEY_DOMAIN_ID "domainID"
#define KEY_HANDLE "handle"
-#define KEY_APPNAME "appname"
+#define KEY_APPNAME "audio_role"
#define KEY_RAMP "ramp"
#define KEY_TIME "time"
#define KEY_SOURCE_STATE "sourceState"
@@ -55,15 +70,64 @@
#define KEY_CONNECTION_FORMAT "connectionFormat"
#define KEY_EVENT "event"
+#define KEY_RESPONSE "response"
+
+#define SM_EVENT_VOLUME_CHANGED "volumeChanged"
+#define SM_EVENT_NEW_MAIN_CONNECTION "newMainConnection"
+#define SM_EVENT_REMOVED_MAIN_CONNECTION "removedMainConnection"
+#define SM_EVENT_SINK_MUTE_STATE_CHANGED "sinkMuteStateChanged"
+#define SM_EVENT_MAIN_CONNECTION_STATE_CHANGED "mainConnectionStateChanged"
+/* Routing event*/
+#define SM_EVENT_SET_ROUTING_READY "setRoutingReady"
+#define SM_EVENT_SET_ROUTING_RUNDOWN "setRoutingRundown"
+#define SM_EVENT_ASYNC_CONNECT "asyncConnect"
+#define SM_EVENT_ASYNC_SET_SOURCE_STATE "asyncSetSourceState"
+#define SM_EVENT_ASYNC_DISCONNECT "asyncDisconnect"
+#define SM_EVENT_STREAM_STATE_EVENT "stream_state_event"
+
+#ifdef ENABLE_AGL_AHL
#define KEY_AHL_AUDIO_ROLE "audio_role"
#define KEY_AHL_ENDPOINT_ID "endpoint_id"
#define KEY_AHL_ENDPOINT_TYPE "endpoint_type"
+#define KEY_AHL_REP_STREAM_ID "stream_id"
+#define KEY_AHL_EVENT_NAME "event_name"
+#define KEY_AHL_STATE_EVENT "state_event"
+#define AHL_EVENT_NAME "ahl_stream_state_event"
+#define KEY_AHL_MUTE "mute"
+#define AHL_STREAM_UNMUTE 0
+#define AHL_STREAM_MUTE 1
typedef enum {
ENDPOINT_SINK,
ENDPOINT_SOURCE,
} EndPointType;
+#endif
+
+typedef enum {
+ NOT_INITIALIZED = -2,
+ UNABLE_SEND,
+ OK = 0,
+ UNKNOWN,
+ OUT_RANGE,
+ NOT_USED,
+ DATABASE_ERR,
+ OBJECT_ALREADY_EXIST,
+ NO_CHANGE,
+ ACTION_IMPOSSIBLE,
+ OBJECT_NOT_EXIST,
+ ASYNC_ACTION_ABORTED,
+ CONNECTION_FORMAT_ERR,
+ COMMUNICATION_ERR,
+ EVENT_NOT_EXIST = 100
+} ErrorCode;
+
+typedef enum {
+ REQ_FAIL,
+ OUT_OF_RANGE,
+ NOT_NUMBER,
+ REQ_OK
+} REQ_ERROR;
-#define MAX_LENGTH_STRING 256
+#define MAX_LENGTH_STR 256
-#endif // SOUNDMANAGER_DEFINE_H
+#endif // SOUNDMANAGER_DEFINE_H \ No newline at end of file
diff --git a/src/sm-error.c b/src/sm-error.c
new file mode 100644
index 0000000..79a2009
--- /dev/null
+++ b/src/sm-error.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "sm-error.h"
+#include "sm-def.h"
+
+const char* get_response_audiomanager_massage_error(int am_error_code)
+{
+ switch (am_error_code){
+ case UNABLE_SEND:
+ return "Unable to send request to audiomanager";
+ case NOT_INITIALIZED:
+ return "soundmanager is not initialized";
+ case OK:
+ return "OK";
+ case UNKNOWN:
+ return "unknown error";
+ case OUT_RANGE:
+ return "value out of range";
+ case NOT_USED:
+ return "not used";
+ case DATABASE_ERR:
+ return "database error occured";
+ case OBJECT_ALREADY_EXIST:
+ return "the desired object already exists";
+ case NO_CHANGE:
+ return "there is no change";
+ case ACTION_IMPOSSIBLE:
+ return "the desired action is not possible";
+ case OBJECT_NOT_EXIST:
+ return "the desired object is non existent";
+ case ASYNC_ACTION_ABORTED:
+ return "the asynchronous action was aborted";
+ case CONNECTION_FORMAT_ERR:
+ return "connectionFormat is not selected";
+ case COMMUNICATION_ERR:
+ return "communication error";
+ case EVENT_NOT_EXIST:
+ return "desired event doesn't exist";
+ default:
+ return "Audio Manager responsed unknown error number";
+ }
+}
+
+const char* get_source_state_key(int am_source_state){
+ switch (am_source_state){
+ case 0:
+ return "unknown";
+ case 1:
+ return "on";
+ case 2:
+ return "off";
+ case 3:
+ return "paused";
+ default:
+ return "";
+ }
+} \ No newline at end of file
diff --git a/src/sm-error.h b/src/sm-error.h
index bc60175..521fca2 100644
--- a/src/sm-error.h
+++ b/src/sm-error.h
@@ -1,73 +1,20 @@
-#ifndef SM_ERROR_H
-#define SM_ERROR_H
-#include <glib.h>
-#define _GNU_SOURCE
-#define AFB_BINDING_VERSION 2
-#include <afb/afb-binding.h>
-#define IS_SEND_ERROR(...) is_send_error(__VA_ARGS__, __FUNCTION__)
-#define IS_SEND_ERROR_WITHOUT_RETURN(...) is_send_error_without_return(__VA_ARGS__, __FUNCTION__)
-
-char* get_response_audiomanager_massage_error(int am_error_code)
-{
- switch (am_error_code){
- case 0:
- return "OK";
- case 1:
- return "unknown error";
- case 2:
- return "value out of range";
- case 3:
- return "not used";
- case 4:
- return "database error occured";
- case 5:
- return "the desired object already exists";
- case 6:
- return "there is no change";
- case 7:
- return "the desired action is not possible";
- case 8:
- return "the desired object is non existent";
- case 9:
- return "the asynchronous action was aborted";
- case 10:
- return "connectionFormat is not selected";
- case 11:
- return "communication error";
- case 100:
- return "desired event doesn't exist";
- default:
- return "Audio Manager responsed unknown error number";
- }
-}
-
-char* get_source_state_key(int am_source_state){
- switch (am_source_state){
- case 0:
- return "unknown";
- case 1:
- return "on";
- case 2:
- return "off";
- case 3:
- return "paused";
- default:
- return "";
- }
-}
-
-void is_send_error_without_return(GError* result_of_send, const char* function){
- if(result_of_send != NULL){
- AFB_ERROR("Unable to call %s", function);
- }
-}
-
-int is_send_error(GError* result_of_send, struct afb_req req, const char* function){
- if(result_of_send != NULL)
- {
- afb_req_fail_f(req, "failed", "Unable to call %s", function);
- return 0;
- }
- return -1;
-}
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef SOUNDMANAGER_ERROR_H
+#define SOUNDMANAGER_ERROR_H
+const char* get_response_audiomanager_massage_error(int am_error_code);
+const char* get_source_state_key(int am_source_state);
#endif
diff --git a/src/sm-helper.c b/src/sm-helper.c
index 02de95a..9f78414 100644
--- a/src/sm-helper.c
+++ b/src/sm-helper.c
@@ -14,13 +14,15 @@
* limitations under the License.
*/
-#include "sm-helper.h"
-#include "sm-def.h"
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <json-c/json.h>
#include <stdarg.h>
+#include "sm-helper.h"
+#include "sm-error.h"
+
+static int default_sinkID = DEFAULT_SINK;
REQ_ERROR get_value_uint16(const struct afb_req request, const char *source, uint16_t *out_id)
{
@@ -35,7 +37,7 @@ REQ_ERROR get_value_uint16(const struct afb_req request, const char *source, uin
/* error check of range */
if( (tmp_id > UINT16_MAX) || (tmp_id < 0) )
{
- return OUT_RANGE;
+ return OUT_OF_RANGE;
}
if(*endptr != '\0')
{
@@ -59,7 +61,7 @@ REQ_ERROR get_value_int16(const struct afb_req request, const char *source, int1
/* error check of range */
if( (tmp_id > INT16_MAX) || (tmp_id < INT16_MIN) )
{
- return OUT_RANGE;
+ return OUT_OF_RANGE;
}
if(*endptr != '\0')
{
@@ -83,7 +85,7 @@ REQ_ERROR get_value_int32(const struct afb_req request, const char *source, int3
/* error check of range */
if( (tmp_id > INT32_MAX) || (tmp_id < INT32_MIN) )
{
- return OUT_RANGE;
+ return OUT_OF_RANGE;
}
if(*endptr != '\0')
{
@@ -94,6 +96,35 @@ REQ_ERROR get_value_int32(const struct afb_req request, const char *source, int3
return REQ_OK;
}
+REQ_ERROR get_sink_id(const afb_req request, const char* key, uint16_t* out_sink_id){
+ AFB_DEBUG("");
+ REQ_ERROR result = REQ_FAIL;
+ const char* requested_sink_str = afb_req_value (request, key);
+ json_object* test = afb_req_json(request);
+ AFB_DEBUG("%s", json_object_to_json_string_ext(test, JSON_C_TO_STRING_PRETTY));
+
+ if(0 == strcmp(requested_sink_str, "default")){
+ *out_sink_id = default_sinkID;
+ AFB_INFO("sinkID(endpointID) is attached as default sinkID as %d", DEFAULT_SINK);
+ result = REQ_OK;
+ }
+ else{
+ result = get_value_uint16(request, key, out_sink_id);
+ AFB_INFO("sinkID(endpointID) is %d", *out_sink_id);
+ }
+
+ if(REQ_OK != result){
+ AFB_INFO("can't parse %s, result %d", key, result);
+ afb_req_fail_f(request,"wrong-request","can't parse %s, result: %d", key, result);
+ return result;
+ }
+ return REQ_OK;
+}
+
+void set_default_sinkID(int sinkID){
+ default_sinkID = sinkID;
+}
+
void sm_add_object_to_json_object(struct json_object* j_obj, int count,...)
{
va_list args;
@@ -157,102 +188,40 @@ int sm_search_routing_event_name_index(const char* value)
return ret;
}
-GVariant* create_source_data(guint16 sourceID, guint16 domainID, const char* appname, guint16 sourceClassID,
- gint32 sourceState, gint16 volume, gboolean visible, struct availability_s availables,
- guint16 interrupt, struct sound_property_s soundPropertyList, gint32 connectionFormatList,
- struct main_sound_property_s mainPropertyList, struct notification_config_s NConfRouting,
- struct notification_config_s NConfCommand)
-{
- GVariantBuilder builder;
-
- AFB_DEBUG("create sourceData %d", __LINE__);
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("(qqsqinb(ii)qa(in)aia(in)a(iin)a(iin))"));
- g_variant_builder_add (&builder, "q", sourceID);
- g_variant_builder_add (&builder, "q", domainID);
- g_variant_builder_add (&builder, "s", appname);
- g_variant_builder_add (&builder, "q", sourceClassID);
- g_variant_builder_add (&builder, "i", sourceState);
- g_variant_builder_add (&builder, "n", volume);
- g_variant_builder_add (&builder, "b", visible);
- g_variant_builder_add (&builder, "(ii)", availables.availability, availables.avalilable_reason);
- g_variant_builder_add (&builder, "q", interrupt);
-
- g_variant_builder_open(&builder, G_VARIANT_TYPE("a(in)"));
- g_variant_builder_open(&builder, G_VARIANT_TYPE("(in)"));
- g_variant_builder_add (&builder, "i", soundPropertyList.type);
- g_variant_builder_add (&builder, "n", soundPropertyList.value);
- g_variant_builder_close(&builder);
- g_variant_builder_close (&builder);
-
- g_variant_builder_open(&builder, G_VARIANT_TYPE("ai"));
- g_variant_builder_add (&builder, "i", connectionFormatList);
- g_variant_builder_close (&builder);
-
- g_variant_builder_open(&builder, G_VARIANT_TYPE("a(in)"));
- g_variant_builder_open(&builder, G_VARIANT_TYPE("(in)"));
- g_variant_builder_add (&builder, "i", mainPropertyList.type);
- g_variant_builder_add (&builder, "n", mainPropertyList.value);
- g_variant_builder_close (&builder);
- g_variant_builder_close(&builder);
-
- g_variant_builder_open(&builder, G_VARIANT_TYPE("a(iin)"));
- g_variant_builder_open(&builder, G_VARIANT_TYPE("(iin)"));
- g_variant_builder_add (&builder, "i", NConfRouting.type);
- g_variant_builder_add (&builder, "i", NConfRouting.status);
- g_variant_builder_add (&builder, "n", NConfRouting.parameter);
- g_variant_builder_close(&builder);
- g_variant_builder_close (&builder);
-
-
- g_variant_builder_open(&builder, G_VARIANT_TYPE("a(iin)"));
- g_variant_builder_open(&builder, G_VARIANT_TYPE("(iin)"));
- g_variant_builder_add (&builder, "i", NConfCommand.type);
- g_variant_builder_add (&builder, "i", NConfCommand.status);
- g_variant_builder_add (&builder, "n", NConfCommand.parameter);
- g_variant_builder_close(&builder);
- g_variant_builder_close (&builder);
-
- AFB_DEBUG("created sourceData %d", __LINE__);
- return g_variant_builder_end (&builder);
+bool send_result(ErrorCode ec, struct afb_req req, const char* function){
+ /* GError = NULL means success in case of gdbus request */
+ if(ec == UNABLE_SEND)
+ {
+ AFB_ERROR("Unable to call : %s", function);
+ afb_req_fail_f(req, "failed", "%s : %s", function,
+ get_response_audiomanager_massage_error(ec));
+ return false;
+ }
+ return true;
}
-GVariant* create_domain_data(struct domain_data* data)
-{
- GVariantBuilder builder;
- g_variant_builder_init (&builder, G_VARIANT_TYPE ("(qsssbbn)"));
- g_variant_builder_add (&builder, "q", data->domainID);
- g_variant_builder_add (&builder, "s", data->name);
- g_variant_builder_add (&builder, "s", data->busname);
- g_variant_builder_add (&builder, "s", data->nodename);
- g_variant_builder_add (&builder, "b", data->early);
- g_variant_builder_add (&builder, "b", data->complete);
- g_variant_builder_add (&builder, "n", data->state);
- AFB_DEBUG("created domainData %d", __LINE__);
- return g_variant_builder_end (&builder);
+bool send_result_no_resp(ErrorCode ec, const char* function){
+ if(ec == UNABLE_SEND){
+ AFB_ERROR("Unable to call : %s", function);
+ return false;
+ }
+ return true;
}
-int get_sink_id(struct afb_req req, const char* key){
- const char* default_sink = afb_req_value (req, key);
- int sink_id;
- REQ_ERROR result = REQ_FAIL;
- if(default_sink == NULL) {
- afb_req_fail(req, "wrong request", NULL);
- return -1;
- }
- else{
- if((strlen("default") == strlen(default_sink)) &&
- (0 == strncmp("default", default_sink, strlen("default")))){
- sink_id = DEFAULT_SINK;
- result = REQ_OK;
- }
- else{
- result = get_value_uint16(req, key, &sink_id);
- }
+ErrorCode is_range_over_guint16(int source){
+ /* error check of range */
+ if( (source > UINT16_MAX) || (source < 0) )
+ {
+ return OUT_RANGE;
}
- if(REQ_OK != result){
- AFB_INFO("can't parse %s, result %d", key, result);
- afb_req_fail_f(req,"wrong-request","can't parse %s, result: %d", result);
- return -1
+ return OK;
+}
+
+ErrorCode is_range_over_gint16(int source){
+ /* error check of range */
+ if( (source > INT16_MAX) || (source < INT16_MIN) )
+ {
+ return OUT_RANGE;
}
- return sink_id;
+ return OK;
} \ No newline at end of file
diff --git a/src/sm-helper.h b/src/sm-helper.h
index f6a3601..ec35ad2 100644
--- a/src/sm-helper.h
+++ b/src/sm-helper.h
@@ -20,75 +20,41 @@
#define AFB_BINDING_VERSION 2
#include <afb/afb-binding.h>
#include <stdint.h>
+#include <stdbool.h>
#include <glib.h>
-//#include <errno.h>
-
-typedef enum REQ_ERROR
-{
- REQ_FAIL = -1,
- REQ_OK=0,
- NOT_NUMBER,
- OUT_RANGE
-}REQ_ERROR;
+#include "sm-def.h"
+#define SEND_RESULT(...) send_result(__VA_ARGS__, __FUNCTION__)
+#define SEND_RESULT_NO_RESP(...) send_result_no_resp(__VA_ARGS__, __FUNCTION__)
static const char* cmd_evlist[] = {
- "volumeChanged",
- "newMainConnection",
- "removedMainConnection",
- "sinkMuteStateChanged",
- "mainConnectionStateChanged"
+ SM_EVENT_VOLUME_CHANGED,
+ SM_EVENT_NEW_MAIN_CONNECTION,
+ SM_EVENT_REMOVED_MAIN_CONNECTION,
+ SM_EVENT_SINK_MUTE_STATE_CHANGED,
+ SM_EVENT_MAIN_CONNECTION_STATE_CHANGED
};
static const char* route_evlist[] = {
/* Routing event*/
- "setRoutingReady",
- "setRoutingRundown",
- "asyncConnect",
- "asyncSetSourceState",
- "asyncDisconnect"
-};
-
-struct sound_property_s{
- guint16 type;
- gint16 value;
-};
-struct availability_s{
- gint32 availability;
- gint32 avalilable_reason;
-};
-struct notification_config_s{
- gint32 type;
- gint32 status;
- gint16 parameter;
-};
-struct main_sound_property_s{
- gint32 type; /* am_CustomMainSoundPropertyType_t */
- gint16 value;
-};
-
-struct domain_data{
- guint16 domainID;
- gchar* name;
- gchar* busname;
- gchar* nodename;
- gboolean early;
- gboolean complete;
- gint16 state;
+ SM_EVENT_SET_ROUTING_READY,
+ SM_EVENT_SET_ROUTING_RUNDOWN,
+ SM_EVENT_ASYNC_CONNECT,
+ SM_EVENT_ASYNC_SET_SOURCE_STATE,
+ SM_EVENT_ASYNC_DISCONNECT,
+ SM_EVENT_STREAM_STATE_EVENT
};
REQ_ERROR get_value_uint16(const struct afb_req request, const char *source, uint16_t *out_id);
REQ_ERROR get_value_int16(const struct afb_req request, const char *source, int16_t *out_id);
REQ_ERROR get_value_int32(const struct afb_req request, const char *source, int32_t *out_id);
+REQ_ERROR get_sink_id(const struct afb_req request, const char* key, uint16_t *out_sink_id);
+void set_default_sinkID(int sinkID);
void sm_add_object_to_json_object(struct json_object* j_obj, int count, ...);
void sm_add_object_to_json_object_func(struct json_object* j_obj, const char* verb_name, int count, ...);
int sm_search_event_name_index(const char* value);
int sm_search_routing_event_name_index(const char* value);
-GVariant* create_source_data(guint16 sourceID, guint16 domainID, const char* appname, guint16 sourceClassID,
- gint32 sourceState, gint16 volume, gboolean visible, struct availability_s availables,
- guint16 interrupt, struct sound_property_s soundPropertyList, gint32 connectionFormatList,
- struct main_sound_property_s mainPropertyList, struct notification_config_s NConfRouting,
- struct notification_config_s NConfCommand);
-GVariant* create_domain_data(struct domain_data*);
-
-
+bool send_result_no_resp(ErrorCode ec, const char* function);
+bool send_result(ErrorCode ec, struct afb_req req, const char* function);
+ErrorCode is_range_over_guint16(int source);
+ErrorCode is_range_over_gint16(int source);
#endif /*AM_HELPER_H*/ \ No newline at end of file
diff --git a/src/sm-pending.c b/src/sm-pending.c
new file mode 100644
index 0000000..28a2382
--- /dev/null
+++ b/src/sm-pending.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <stdlib.h>
+#include "sm-pending.h"
+
+struct pending* add_pending(struct pending *list, int source_id)
+{
+ struct pending* pd;
+
+ if(list == NULL){
+ pd = malloc(sizeof(struct pending));
+ if(NULL == pd){
+ AFB_WARNING("memory allocation error");
+ return NULL;
+ }
+ pd->source.sourceID = source_id;
+ pd->next = NULL;
+ return pd;
+ }
+ else{
+ list->next = add_pending(list->next, source_id);
+ return list;
+ }
+}
+
+struct pending* get_pending(struct pending *list, int source_id){
+ if(list == NULL){
+ return NULL;
+ }
+ if(list->source.sourceID == source_id){
+ return list;
+ }
+ else{
+ struct pending* pd = get_pending(list->next, source_id);
+ return pd;
+ }
+}
+
+struct pending* del_pending(struct pending* list, int source_id){
+ struct pending* tmp;
+ if(list == NULL){
+ return NULL;
+ }
+
+ if(list->source.sourceID == source_id){
+ tmp = list->next;
+ free(list);
+ return tmp;
+ }
+ else{
+ list->next = del_pending(list->next, source_id);
+ return list;
+ }
+}
+
+void del_all_pendings(struct pending *list){
+ struct pending* tmp;
+ if(list != NULL){
+ tmp = list->next;
+ free(list);
+ del_all_pendings(tmp);
+ }
+} \ No newline at end of file
diff --git a/src/sm-pending.h b/src/sm-pending.h
new file mode 100644
index 0000000..ab753cd
--- /dev/null
+++ b/src/sm-pending.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 TOYOTA MOTOR CORPORATION
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SOUNDMANAGER_PENDING_H
+#define SOUNDMANAGER_PENDING_H
+
+#define _GNU_SOURCE
+#define AFB_BINDING_VERSION 2
+#include <afb/afb-binding.h>
+
+struct pending_source{
+ int sourceID;
+};
+struct pending{
+ struct pending_source source;
+ struct pending* next;
+};
+
+
+struct pending* add_pending(struct pending *list, int source_id);
+struct pending* get_pending(struct pending *list, int source_id);
+struct pending* del_pending(struct pending* list, int source_id);
+void del_all_pendings(struct pending *list);
+
+#endif //SOUNDMANAGER_PENDING_H \ No newline at end of file
diff --git a/src/soundmanager.c b/src/soundmanager.c
index 2df7bd3..b499a06 100644
--- a/src/soundmanager.c
+++ b/src/soundmanager.c
@@ -22,18 +22,20 @@
#include <json-c/json.h>
#include <glib.h>
#include "soundmanager.h"
+#include "audiomanager_proxy.h"
#include "sm-def.h"
#include "sm-error.h"
#include "sm-helper.h"
+#include "sm-pending.h"
-const static struct afb_binding_interface *afbitf;
-static AudiomanagerCommandinterface *am_cmd_bus;
-static AudiomanagerRoutinginterface *am_route_bus;
-static AudiomanagerRoutingSoundmanager *sm_adapter;
-static AudiomanagerRoutingSoundmanagerIface* sm_itf;
-static GDBusConnection* system_conn = NULL;
+struct event{
+ char* name;
+ struct afb_event* event;
+ };
+
+static struct pending* pending_list = NULL;
-static guint16 SOUNDMANAGER_DOMAIN_ID;
+static int SOUNDMANAGER_DOMAIN_ID;
static struct event command_event_list[COMMAND_EVENT_NUM];
static struct event routing_event_list[ROUTING_EVENT_NUM];
@@ -49,6 +51,33 @@ static struct afb_event ev_set_routing_rundown;
static struct afb_event ev_async_connect;
static struct afb_event ev_async_disconnect;
static struct afb_event ev_async_set_source_state;
+static struct afb_event ev_stream_state_event;
+
+/* Client context */
+typedef struct source {
+ int sourceID;
+ int mainConnectionID;
+} source;
+
+typedef struct sink {
+ int endpointID;
+ int endpointType;
+ int sinkID;
+} sink;
+
+typedef struct events {
+ afb_event asyncSetSourceState;
+} events;
+
+typedef struct smClientCtxt{
+ char* appname;
+ source source;
+ sink sink;
+ events events;
+} smClientCtxt;
+
+static void on_client_context_terminated(void *data);
+static void create_client_context(afb_req request, guint16 source_id, guint16 sink_id, int endpoint_type);
/*
********** Method of Sound Manager (API) **********
@@ -58,11 +87,9 @@ void connect (struct afb_req request)
{
AFB_DEBUG("call %s", __FUNCTION__);
guint16 source_id = 0, sink_id = 0;
- guint16 main_connectionID = 0;
- gint16 ret = -1;
+ int main_connectionID = 0;
REQ_ERROR req_err1 = REQ_FAIL;
REQ_ERROR req_err2 = REQ_FAIL;
- GError *err = NULL;
req_err1 = get_value_uint16(request, KEY_SOURCE_ID, &source_id);
/* ToDo: Hardware abstraction for application user is needed.
@@ -88,24 +115,18 @@ void connect (struct afb_req request)
return;
}
- audiomanager_commandinterface_call_connect_sync(
- am_cmd_bus,
- source_id,
- sink_id,
- &ret,
- &main_connectionID,
- NULL, &err);
+ ErrorCode ec = am_proxy_connect(source_id, sink_id, &main_connectionID);
- if(IS_SEND_ERROR(err, request) == 0) return;
+ if(!SEND_RESULT(ec, request)) return;
/* ToDo Remember appname(key) and tie to sourceID(value) */
/*create response json object*/
struct json_object *res = json_object_new_object();
sm_add_object_to_json_object_func(res, __FUNCTION__, 4,
- "error", ret,
+ "error", ec,
KEY_MAIN_CONNECTION_ID, main_connectionID);
- char *info = get_response_audiomanager_massage_error(ret);
+ const char* info = get_response_audiomanager_massage_error(ec);
afb_req_success(request, res, info);
}
@@ -113,32 +134,26 @@ void disconnect (struct afb_req request)
{
AFB_DEBUG("call %s", __FUNCTION__);
- guint16 id;
- gint16 ret;
+ guint16 main_connection_id;
REQ_ERROR req_err;
- GError *err = NULL;
- req_err = get_value_uint16(request, KEY_MAIN_CONNECTION_ID, &id);
- AFB_DEBUG( "requested %s = %d", KEY_MAIN_CONNECTION_ID, id);
+ req_err = get_value_uint16(request, KEY_MAIN_CONNECTION_ID, &main_connection_id);
+ AFB_DEBUG( "requested %s = %d", KEY_MAIN_CONNECTION_ID, main_connection_id);
if(req_err != REQ_OK)
{
afb_req_fail(request,"wrong-request",afb_req_value (request, KEY_MAIN_CONNECTION_ID));
return;
}
- audiomanager_commandinterface_call_disconnect_sync(
- am_cmd_bus,
- id,
- &ret,
- NULL, &err);
- AFB_DEBUG( "ret = %d", ret);
+ ErrorCode ec = am_proxy_disconnect(main_connection_id);
+ AFB_DEBUG( "ret = %d", ec);
- if(IS_SEND_ERROR(err, request) == 0) return;
+ if(!SEND_RESULT(ec, request)) return;
struct json_object* res_obj = json_object_new_object();
sm_add_object_to_json_object_func(res_obj, __FUNCTION__, 2,
- KEY_ERROR, ret);
- char *info = get_response_audiomanager_massage_error(ret);
+ KEY_ERROR, ec);
+ const char* info = get_response_audiomanager_massage_error(ec);
afb_req_success(request, res_obj, info); /* return error num as status */
}
@@ -148,9 +163,7 @@ void setVolume (struct afb_req request)
AFB_DEBUG("call %s", __FUNCTION__);
guint16 sink_id, vol;
- gint16 ret;
REQ_ERROR req_err1, req_err2;
- GError *err = NULL;
req_err1 = get_value_uint16(request, KEY_SINK_ID, &sink_id);
req_err2 = get_value_int16(request, KEY_VOLUME, &vol);
@@ -161,20 +174,15 @@ void setVolume (struct afb_req request)
return;
}
- audiomanager_commandinterface_call_set_volume_sync(
- am_cmd_bus,
- sink_id,
- vol,
- &ret,
- NULL, &err);
- AFB_DEBUG( "ret = %d", ret);
+ ErrorCode ec = am_proxy_set_volume(sink_id, vol);
+ AFB_DEBUG( "ret = %d", ec);
- if(IS_SEND_ERROR(err, request) == 0) return;
+ if(!SEND_RESULT(ec, request)) return;
struct json_object* res_obj = json_object_new_object();
sm_add_object_to_json_object_func(res_obj, __FUNCTION__, 2,
- "error", ret);
- char *info = get_response_audiomanager_massage_error(ret);
+ "error", ec);
+ const char* info = get_response_audiomanager_massage_error(ec);
afb_req_success(request, res_obj, info); /* return error num as status */
}
@@ -184,9 +192,7 @@ void volumeStep (struct afb_req request)
AFB_DEBUG("call %s", __FUNCTION__);
guint16 sink_id, vol;
- gint16 ret;
REQ_ERROR req_err1, req_err2;
- GError *err = NULL;
req_err1 = get_value_uint16(request, KEY_SINK_ID, &sink_id);
req_err2 = get_value_int16(request, KEY_VOLUME_STEP, &vol);
@@ -197,20 +203,15 @@ void volumeStep (struct afb_req request)
return;
}
- audiomanager_commandinterface_call_volume_step_sync(
- am_cmd_bus,
- sink_id,
- vol,
- &ret,
- NULL, &err);
- AFB_DEBUG( "ret = %d", ret);
+ ErrorCode ec = am_proxy_volume_step(sink_id, vol);
+ AFB_DEBUG( "ret = %d", ec);
- if(IS_SEND_ERROR(err, request) == 0) return;
+ if(!SEND_RESULT(ec, request)) return;
struct json_object* res_obj = json_object_new_object();
sm_add_object_to_json_object_func(res_obj, __FUNCTION__, 2,
- "error", ret);
- char *info = get_response_audiomanager_massage_error(ret);
+ "error", ec);
+ const char* info = get_response_audiomanager_massage_error(ec);
afb_req_success(request, res_obj, info); /* return error num as status */
}
@@ -220,33 +221,27 @@ void setSinkMuteState(struct afb_req request)
AFB_DEBUG("call %s", __FUNCTION__);
guint16 sink_id, mute;
- gint16 ret;
REQ_ERROR req_err1, req_err2;
- GError *err = NULL;
req_err1 = get_value_uint16(request, KEY_SINK_ID, &sink_id);
req_err2 = get_value_int16(request, KEY_MUTE_STATE, &mute);
AFB_DEBUG( "requested %s = %d, %s = %d",KEY_SINK_ID, sink_id, KEY_MUTE_STATE, mute);
+
if((req_err1 != REQ_OK) || (req_err2 != REQ_OK))
{
afb_req_fail(request,"wrong-request", NULL);
return;
}
- audiomanager_commandinterface_call_set_sink_mute_state_sync(
- am_cmd_bus,
- sink_id,
- mute,
- &ret,
- NULL, &err);
- AFB_DEBUG( "ret = %d", ret);
+ ErrorCode ec = am_proxy_set_sink_mute_state(sink_id, mute);
+ AFB_DEBUG( "ret = %d", ec);
- if(IS_SEND_ERROR(err, request) == 0) return;
+ if(!SEND_RESULT(ec, request)) return;
struct json_object* res_obj = json_object_new_object();
sm_add_object_to_json_object_func(res_obj, __FUNCTION__, 2,
- "error", ret);
- char *info = get_response_audiomanager_massage_error(ret);
+ "error", ec);
+ const char* info = get_response_audiomanager_massage_error(ec);
afb_req_success(request, res_obj, info); /* return error num as status */
}
@@ -254,32 +249,24 @@ void setSinkMuteState(struct afb_req request)
void getListMainConnections(struct afb_req request)
{
AFB_DEBUG("call getListMainConnections");
- guint16 ret;
+
GVariant* mainConnectionList;
- GError *err = NULL;
- audiomanager_commandinterface_call_get_list_main_connections_sync(
- am_cmd_bus,
- &ret,
- &mainConnectionList,
- NULL,
- &err
- );
+ ErrorCode ec = am_proxy_get_list_main_connections(&mainConnectionList);
- if(IS_SEND_ERROR(err, request) == 0) return;
+ if(!SEND_RESULT(ec, request)) return;
/* create response */
- struct json_object *array_res = json_object_new_array();
+ struct json_object *response = json_object_new_object();
gsize size = g_variant_n_children(mainConnectionList);
AFB_DEBUG("mainConnectionList size is %u",(uint16_t)size);
- struct json_object *verb_obj = json_object_new_object();
- sm_add_object_to_json_object_func(verb_obj, __FUNCTION__, 0);
- json_object_array_add(array_res, verb_obj);
+ sm_add_object_to_json_object_func(response, __FUNCTION__, 0);
if(size <= 0)
{
AFB_NOTICE( "mainConnectionList size is 0");
}
else{
+ struct json_object *array_res = json_object_new_array();
for(int i = 0; i < size; ++i)
{
guint16 mcid, srcid, sinkid;
@@ -299,27 +286,22 @@ void getListMainConnections(struct afb_req request)
);
json_object_array_add(array_res,res_obj);
}
+ json_object_object_add(response, "connections", array_res);
}
- AFB_DEBUG("json object :%s:",json_object_to_json_string(array_res));
- afb_req_success(request, array_res, "Success to get main connection list");
+ AFB_DEBUG("json object :%s:",json_object_to_json_string(response));
+ afb_req_success(request, response, "Success to get main connection list");
+ g_variant_unref(mainConnectionList);
}
void getListMainSources(struct afb_req request)
{
AFB_DEBUG("call %s", __FUNCTION__);
- guint16 ret;
+
GVariant* mainSourceList;
- GError *err = NULL;
- audiomanager_commandinterface_call_get_list_main_sources_sync(
- am_cmd_bus,
- &ret,
- &mainSourceList,
- NULL,
- &err
- );
+ ErrorCode ec = am_proxy_get_list_main_sources(&mainSourceList);
- if(IS_SEND_ERROR(err, request) == 0) return;
+ if(!SEND_RESULT(ec, request)) return;
/* create response */
struct json_object *response = json_object_new_object();
@@ -356,7 +338,7 @@ void getListMainSources(struct afb_req request)
json_object_array_add(array_res,res_obj);
g_variant_unref(child);
}
- json_object_object_add(response, "sinks", array_res);
+ json_object_object_add(response, "sources", array_res);
}
afb_req_success(request, response, "Success to get main source list");
g_variant_unref(mainSourceList);
@@ -365,19 +347,12 @@ void getListMainSources(struct afb_req request)
void getListMainSinks(struct afb_req request)
{
AFB_DEBUG("call %s", __FUNCTION__);
- guint16 ret;
+
GVariant* mainSinkList;
- GError *err = NULL;
- audiomanager_commandinterface_call_get_list_main_sinks_sync(
- am_cmd_bus,
- &ret,
- &mainSinkList,
- NULL,
- &err
- );
+ ErrorCode ec = am_proxy_get_list_main_sinks(&mainSinkList);
- if(IS_SEND_ERROR(err, request) == 0) return;
+ if(!SEND_RESULT(ec, request)) return;
/* create response */
struct json_object *response = json_object_new_object();
@@ -436,7 +411,6 @@ void ackConnect(struct afb_req request)
guint16 handle, connection_id, error;
guint16 ret = 0;
REQ_ERROR req_err1, req_err2 , req_err3;
- GError *err = NULL;
req_err1 = get_value_uint16(request, KEY_HANDLE, &handle);
req_err2 = get_value_uint16(request, KEY_CONNECTION_ID, &connection_id);
@@ -453,19 +427,15 @@ void ackConnect(struct afb_req request)
return;
}
- audiomanager_routinginterface_call_ack_connect_sync(
- am_route_bus,
- handle,
- connection_id,
- error,
- NULL, &err);
+ ErrorCode ec = am_proxy_ack_connect(handle, connection_id, error);
+
+ if(!SEND_RESULT(ec, request)) return;
- if(IS_SEND_ERROR(err, request) == 0) return;
/*create response json object*/
struct json_object *res = json_object_new_object();
sm_add_object_to_json_object_func(res, __FUNCTION__, 2,
KEY_ERROR, ret);
- char *info = get_response_audiomanager_massage_error(ret);
+ const char* info = get_response_audiomanager_massage_error(ret);
afb_req_success(request, res, info);
}
@@ -476,7 +446,6 @@ void ackDisconnect(struct afb_req request)
guint16 handle, connection_id, error;
guint16 ret = 0;
REQ_ERROR req_err1, req_err2 , req_err3;
- GError *err = NULL;
req_err1 = get_value_uint16(request, KEY_HANDLE, &handle);
req_err2 = get_value_uint16(request, KEY_CONNECTION_ID, &connection_id);
@@ -493,20 +462,15 @@ void ackDisconnect(struct afb_req request)
return;
}
- audiomanager_routinginterface_call_ack_disconnect_sync(
- am_route_bus,
- handle,
- connection_id,
- error,
- NULL, &err);
+ ErrorCode ec = am_proxy_ack_disconnect(handle, connection_id, error);
- if(IS_SEND_ERROR(err, request) == 0) return;
+ if(!SEND_RESULT(ec, request)) return;
/*create response json object*/
struct json_object *res = json_object_new_object();
sm_add_object_to_json_object_func(res, __FUNCTION__, 2,
KEY_ERROR, ret);
- char *info = get_response_audiomanager_massage_error(ret);
+ const char* info = get_response_audiomanager_massage_error(ret);
afb_req_success(request, res, info);
}
@@ -516,7 +480,6 @@ void ackSetSourceState(struct afb_req request)
guint16 handle, error;
guint16 ret = 0;
REQ_ERROR req_err1, req_err2;
- GError *err = NULL;
req_err1 = get_value_uint16(request, KEY_HANDLE, &handle);
req_err2 = get_value_uint16(request, KEY_ERROR, &error);
@@ -528,27 +491,21 @@ void ackSetSourceState(struct afb_req request)
return;
}
- audiomanager_routinginterface_call_ack_set_source_state_sync(
- am_route_bus,
- handle,
- error,
- NULL, &err);
+ ErrorCode ec = am_proxy_ack_set_source_state(handle, error);
- if(IS_SEND_ERROR(err, request) == 0) return;
+ if(!SEND_RESULT(ec, request)) return;
/*create response json object*/
struct json_object *res = json_object_new_object();
sm_add_object_to_json_object_func(res, __FUNCTION__, 2,
- KEY_ERROR, ret);
- char *info = get_response_audiomanager_massage_error(ret);
+ KEY_ERROR, ec);
+ const char* info = get_response_audiomanager_massage_error(ec);
afb_req_success(request, res, info);
}
void registerSource(struct afb_req request)
{
AFB_DEBUG("call %s", __FUNCTION__);
- GError *err = NULL;
-
guint16 source_id; /* q 0 is for dynamic id*/
guint16 domain_id; /* q */
@@ -578,8 +535,8 @@ void registerSource(struct afb_req request)
const gchar* name = afb_req_value(request, KEY_APPNAME); /* s */
if(!name)
{
- char* info = "Must specify the name. Please input json arg such as {\"appname\":\"radio\"}";
- afb_req_fail(request, NULL, info);
+ char* info = "Must specify the name. Please input json arg such as {\"audio_role\":\"radio\"}";
+ afb_req_fail(request, "wrong-request", info);
return;
}
if(REQ_OK != get_value_uint16(request, KEY_SOURCE_CLASS_ID, &source_class_id)){
@@ -620,57 +577,44 @@ void registerSource(struct afb_req request)
nconf_command.parameter = 0;
/* acquire data */
- guint16 acquire_source_id;
- guint16 ret;
+ int acquire_source_id;
+
GVariant* sourceData = create_source_data (source_id, domain_id, name, source_class_id,
source_state, volume, visible, available, interrupt,
sound_property_list, connection_format_list, main_property_list,
nconf_routing, nconf_command);
- GVariant* input = g_variant_ref_sink(sourceData);
- audiomanager_routinginterface_call_register_source_sync(
- am_route_bus,
- input,
- &acquire_source_id,
- &ret,
- NULL, &err);
- g_variant_unref(input);
+ ErrorCode ec = am_proxy_register_source(sourceData, &acquire_source_id);
- if(IS_SEND_ERROR(err, request) == 0) return;
+ if(!SEND_RESULT(ec, request)) return;
/*create response json object*/
struct json_object *res = json_object_new_object();
sm_add_object_to_json_object_func(res, __FUNCTION__, 4,
- KEY_ERROR, ret,
+ KEY_ERROR, ec,
KEY_SOURCE_ID, acquire_source_id);
- char *info = get_response_audiomanager_massage_error(ret);
+ const char* info = get_response_audiomanager_massage_error(ec);
afb_req_success(request, res, info);
}
void deregisterSource(struct afb_req request)
{
guint16 source_id;
- guint16 ret;
GError *err = NULL;
if(REQ_OK != get_value_uint16(request, KEY_SOURCE_ID, &source_id)){
afb_req_fail(request, "wrong-request", NULL);
}
- audiomanager_routinginterface_call_deregister_source_sync(
- am_route_bus,
- source_id,
- &ret,
- NULL, &err
- );
- if(IS_SEND_ERROR(err, request) == 0) return;
+ ErrorCode ec = am_proxy_deregister_source(source_id);
+ if(!SEND_RESULT(ec, request)) return;
/*create response json object*/
struct json_object *res = json_object_new_object();
sm_add_object_to_json_object_func(res, __FUNCTION__, 2,
- KEY_ERROR, ret);
- char *info = get_response_audiomanager_massage_error(ret);
+ KEY_ERROR, ec);
+ const char* info = get_response_audiomanager_massage_error(ec);
afb_req_success(request, res, info);
}
@@ -708,7 +652,7 @@ void subscribe(struct afb_req request)
struct json_object *res = json_object_new_object();
sm_add_object_to_json_object_func(res, __FUNCTION__, 2,
KEY_ERROR, ret);
- char *info = get_response_audiomanager_massage_error(ret);
+ const char* info = get_response_audiomanager_massage_error(ret);
afb_req_success(request, res, info);
}
@@ -745,7 +689,7 @@ void unsubscribe(struct afb_req request)
struct json_object *res = json_object_new_object();
sm_add_object_to_json_object_func(res, __FUNCTION__, 2,
KEY_ERROR, ret);
- char *info = get_response_audiomanager_massage_error(ret);
+ const char* info = get_response_audiomanager_massage_error(ret);
afb_req_success(request, res, info);
}
@@ -754,159 +698,203 @@ void unsubscribe(struct afb_req request)
****** High Level API ***********
*
*/
-void streamOpen(struct afb_req req){
+
+
+#ifdef ENABLE_AGL_AHL
+
+void stream_open(struct afb_req request){
AFB_DEBUG("call %s", __FUNCTION__);
// register audio role and endpoint
+ // get audio_role
const gchar* audio_role = afb_req_value(request, KEY_AHL_AUDIO_ROLE); /* s */
if(!audio_role)
{
afb_req_fail(request, "wrong request", "Please input 'audio_role' as key");
return;
}
- guint16 endpoint_type = 0, endpoint_id = 0;
-
- endpoint_id = get_sink_id(request, KEY_AHL_ENDPOINT_ID);
- if(-1 == endpoint_id) return;
-
+ // get endpoint
+ guint16 endpoint_type = ENDPOINT_SOURCE, endpoint_id = 0;
+ if(REQ_OK != get_sink_id(request, KEY_AHL_ENDPOINT_ID, &endpoint_id)){return;}
get_value_uint16(request, KEY_AHL_ENDPOINT_TYPE, &endpoint_type);
- if(endpoint_type == ENDPOINT_SINK){
+
+ if(endpoint_type != ENDPOINT_SOURCE){
AFB_WARNING("register sink from application is not supported");
- afb_req_fail(request,"wrong-request", "register sink from application is not supported");
+ afb_req_fail(request,"wrong-request", "register source from application is only supported");
return;
}
// call registerSource
- json_object *jreq = afb_req_json(req);
+ json_object *jreq = afb_req_json(request);
json_object *response = json_object_new_object();
- json_object_object_add(jreq, KEY_SOURCE_ID, json_object_new_string(audio_role));
- afb_service_call_sync("soundmanager", "registerSource", jreq, &response);
+ json_object_object_add(jreq, KEY_APPNAME, json_object_new_string(audio_role));
- json_object j_sid = NULL;
- if(!json_object_object_get_ex(response, KEY_ERROR, &j_sid) {
- afb_req_fail(request, NULL, "Failed streamOpen");
+ afb_service_call_sync("soundmanager", "registerSource", jreq, &response);
+ // jreq is released by afb_service_call_sync then don't release jreq here.
+
+ AFB_DEBUG("request result :%s", json_object_to_json_string_ext(response, JSON_C_TO_STRING_PRETTY));
+
+ json_object *j_resp, *j_sid, *j_err;
+ int sid = -1, ret = -1;
+ if(json_object_object_get_ex(response, KEY_RESPONSE, &j_resp)){
+ AFB_DEBUG("Get response success: %s", json_object_to_json_string_ext(j_resp, JSON_C_TO_STRING_PRETTY));
+ json_object_object_get_ex(j_resp, KEY_SOURCE_ID, &j_sid);
+ json_object_object_get_ex(j_resp, KEY_ERROR, &j_err);
+ // registerSource must return sourceID and error then I don't check whether sid and ret is in json_object.
+ sid = json_object_get_int(j_sid);
+ ret = json_object_get_int(j_err);
+ json_object_put(j_resp);
+ json_object_put(j_sid);
+ json_object_put(j_err);
+ json_object_put(response);
+ }else {
+ afb_req_fail(request, "unknown-error", "Failed stream_open");
+ json_object_put(response);
return;
}
- int sid = json_object_get_int(j_sid);
-
- // create client context
- smClientCtxt* ctxt = (smClientCtxt*)malloc(sizeof smClientCtxt);
- char* appid = afb_req_get_application_id((req);
- ctxt->appname = malloc(MAX_LENGTH_STRING * sizeof(char));
- strcpy(ctxt->appname, appid, MAX_LENGTH_STRING);
- ctxt->source->sourceID = sid;
- ctxt->sink->sinkID = endpoint_id;
- ctxt->type = endpoint_type;
- ctxt->event->asyncSetSourceState = afb_daemon_make_event("asyncSetSourceState");
- afb_req_context_set(req, ctxt, on_client_context_terminated);
-
- // response
+
json_object *res = json_object_new_object();
sm_add_object_to_json_object_func(res, __FUNCTION__, 4,
KEY_ERROR, ret,
- KEY_CONNECTION_ID);
- char *info = get_response_audiomanager_massage_error(ret);
+ KEY_AHL_REP_STREAM_ID, sid);
+ const char* info = get_response_audiomanager_massage_error(ret);
+ create_client_context(request, sid, endpoint_id, endpoint_type);
+ int index = sm_search_routing_event_name_index(SM_EVENT_STREAM_STATE_EVENT);
+ afb_req_subscribe(request, *routing_event_list[index].event);
afb_req_success(request, res, info);
-
}
-void streamClose(struct afb_req req){
-// TODO : wtite function
-}
-
-void setStreamState(struct afb_req req){
-// TODO : wtite function
-}
-
-/*
-********** Callback Function invoked by Audio Manager **********
-*/
-
-typedef struct source {
- struct source* next;
- int sourceID;
- int mainConnectionID;
-} source;
-
-typedef struct sink {
- struct sink* next;
- int sinkID;
-} sink;
-
-typedef struct events {
- struct afb_event asyncSetSourceState;
+void stream_close(struct afb_req request){
+ ErrorCode ec;
+ gint16 source_id = 0;
+ smClientCtxt* ctxt = afb_req_context_get(request);
+ if(NULL == ctxt){
+ AFB_ERROR("Context is not registered");
+ afb_req_fail(request, "wrong-request", "call stream_open at first");
+ return;
+ }
+ if(REQ_OK != get_value_uint16(request, KEY_SOURCE_ID, &source_id)){
+ if(REQ_OK != get_value_uint16(request, KEY_AHL_REP_STREAM_ID, &source_id)){
+ afb_req_fail(request, "wrong-request", "Unable to find sourceID");
+ return;
+ }
+ }
+ if(source_id != ctxt->source.sourceID){
+ AFB_ERROR("requested sourceID is %d, but your sourceID is %d", source_id, ctxt->source.sourceID);
+ afb_req_fail(request, "wrong-request", "sourceID is not yours");
+ return;
+ }
+ if(ctxt->source.mainConnectionID > 0){
+ pending_list = add_pending(pending_list, source_id);
+ ec = am_proxy_disconnect(ctxt->source.mainConnectionID);
+ if(!SEND_RESULT(ec, request)) {
+ del_pending(pending_list, source_id);
+ return;
+ }
+ ctxt->source.mainConnectionID = -1;
+ }
+ else{
+ AFB_NOTICE("Stream %d doesn't have connection. Ignore disconnect", ctxt->source.sourceID);
+ return;
+ }
+ /*create response json object*/
+ struct json_object *res = json_object_new_object();
+ sm_add_object_to_json_object_func(res, __FUNCTION__, 2,
+ KEY_ERROR, ec);
+ const char* info = get_response_audiomanager_massage_error(ec);
+ afb_req_success(request, res, info);
}
-typedef struct smClientCtxt{
- char* appname;
- struct source source;
- struct sink sink;
- struct events events;
-}
+void set_stream_state(struct afb_req request){
+ gint16 source_id = 0;
+ int main_connection_id = -1;
+ ErrorCode ec = OK;
+ int mute_state;
+ smClientCtxt* ctxt = afb_req_context_get(request);
+ if(NULL == ctxt){
+ AFB_ERROR("Context is not registered");
+ afb_req_fail(request, "wrong-request", "call stream_open at first");
+ return;
+ }
-static void on_client_context_terminated(void *data){
- smClientCtxt ctxt = (smClientCtxt*)data;
- source* source_deleted;
- if(ctxt == NULL){
+ // get sourceID from request
+ if(REQ_OK != get_value_uint16(request, KEY_SOURCE_ID, &source_id)){
+ if(REQ_OK != get_value_uint16(request, KEY_AHL_REP_STREAM_ID, &source_id)){
+ afb_req_fail(request, "wrong-request", "Unable to find sourceID");
+ return;
+ }
+ }
+ if(source_id != ctxt->source.sourceID){
+ AFB_ERROR("requested sourceID is %d, but your sourceID is %d", source_id, ctxt->source.sourceID);
+ afb_req_fail(request, "wrong-request", "sourceID is not yours");
return;
}
- AFB_DEBUG("Client %s session is closed", ctxt->appname);
- while(ctxt->source->next != NULL){
- gint16 ret;
- GError *err = NULL;
- audiomanager_routinginterface_call_deregister_source_sync(
- am_route_bus,
- ctxt->source->sourceID,
- &ret, NULL, &err
- );
- source = ctxt->source->next;
- free(ctxt->source->source);
- if(err != NULL){
- AFB_ERROR("failed to call deregisterSource");
+ if(REQ_OK != get_value_int32(request, KEY_AHL_MUTE, &mute_state)){
+ mute_state = AHL_STREAM_UNMUTE;
+ AFB_INFO("Mute state is not set. Set mute state %d(unmute) as default.", mute_state);
+ }
+ AFB_INFO("souceID: %d , mute : %d", source_id, mute_state);
+
+ if(AHL_STREAM_MUTE == mute_state){
+ if(ctxt->source.mainConnectionID > 0){
+ pending_list = add_pending(pending_list, source_id);
+ ec = am_proxy_disconnect(ctxt->source.mainConnectionID);
+ if(!SEND_RESULT(ec, request)){
+ del_pending(pending_list, source_id);
+ return;
+ }
+ ctxt->source.mainConnectionID = -1;
+ }
+ else{
+ AFB_NOTICE("Stream %d doesn't have connection. Ignore disconnect", ctxt->source.sourceID);
+ ec = ACTION_IMPOSSIBLE;
}
- else if(ret != NULL)
- ++(ctxt->source);
- AFB_DEBUG("ret = %d", ret);
}
- free(ctxt->appname);
- free(ctxt->event);
- free(ctxt);
+ else{
+ pending_list = add_pending(pending_list, source_id);
+ ec = am_proxy_connect(source_id, ctxt->sink.sinkID, &main_connection_id);
+ ctxt->source.mainConnectionID = main_connection_id;
+ if(!SEND_RESULT(ec, request)) {
+ del_pending(pending_list, source_id);
+ return;
+ }
+ }
+ /*create response json object*/
+ struct json_object *res = json_object_new_object();
+ sm_add_object_to_json_object_func(res, __FUNCTION__, 2,
+ KEY_ERROR, ec);
+ const char* info = get_response_audiomanager_massage_error(ec);
+ afb_req_success(request, res, info);
}
+#endif
-static void on_new_main_connection(AudiomanagerCommandinterface* interface,
- GVariant* mainConnection)
+/*
+********** Callback Function invoked by Audio Manager **********
+*/
+
+static void on_new_main_connection(int mainConnectioID,
+ int sourceID, int sinkID, int delay, int connectionState)
{
AFB_DEBUG("%s is called",__FUNCTION__);
- guint16 mcid, srcid, sinkid;
- gint16 delay, constate;
- g_variant_get(
- mainConnection,"(qqqnn)", &mcid, &srcid, &sinkid, &delay, &constate);
-
struct json_object* res_obj = json_object_new_object();
sm_add_object_to_json_object(res_obj,10,
- KEY_MAIN_CONNECTION_ID, mcid,
- KEY_SOURCE_ID, srcid,
- KEY_SINK_ID, sinkid,
+ KEY_MAIN_CONNECTION_ID, mainConnectioID,
+ KEY_SOURCE_ID, sourceID,
+ KEY_SINK_ID, sinkID,
KEY_DELAY, delay,
- KEY_CONNECTION_STATE, constate
- );
- AFB_DEBUG("json object :%s:",json_object_to_json_string(res_obj));
-
+ KEY_CONNECTION_STATE, connectionState);
afb_event_push(ev_new_connection, res_obj);
}
-static void on_removed_main_connection(
- AudiomanagerCommandinterface* interface, guint16 mainConnectionID)
+static void on_removed_main_connection(int mainConnectionID)
{
AFB_DEBUG("%s is called",__FUNCTION__);
struct json_object* res_obj = json_object_new_object();
- sm_add_object_to_json_object(res_obj, 2,
- KEY_MAIN_CONNECTION_ID, mainConnectionID);
+ json_object_object_add(res_obj, KEY_MAIN_CONNECTION_ID, json_object_new_int(mainConnectionID));
afb_event_push(ev_removed_main_connection, res_obj);
}
-static void on_main_connection_state_changed(
- AudiomanagerCommandinterface* interface, guint16 connectionID, gint16 connectionState)
+static void on_main_connection_state_changed(int connectionID, int connectionState)
{
AFB_DEBUG("%s is called",__FUNCTION__);
@@ -917,8 +905,7 @@ static void on_main_connection_state_changed(
afb_event_push(ev_main_connection_state_changed, res_obj);
}
-static void on_volume_changed(
- AudiomanagerCommandinterface* interface, guint16 sinkID, gint16 volume)
+static void on_volume_changed(int sinkID, int volume)
{
AFB_DEBUG("%s is called",__FUNCTION__);
struct json_object* res_obj = json_object_new_object();
@@ -928,8 +915,7 @@ static void on_volume_changed(
afb_event_push(ev_volume_changed, res_obj);
}
-static void on_sink_mute_state_changed(
- AudiomanagerCommandinterface* interface, guint16 sinkID, gint16 mute)
+static void on_sink_mute_state_changed(int sinkID, int mute)
{
AFB_DEBUG("%s is called",__FUNCTION__);
struct json_object* res_obj = json_object_new_object();
@@ -942,15 +928,28 @@ static void on_sink_mute_state_changed(
/*
********** Callback Function invoked by Audio Manager Routing Interface**********
*/
-static void on_set_routing_ready(
- AudiomanagerRoutinginterface* interface)
+static void on_set_routing_ready(void)
{
AFB_DEBUG("%s is called",__FUNCTION__);
+ struct domain_data ddata = {
+ .domainID = DYNAMIC_DOMAIN_ID,
+ .name = "SoundManager",
+ .busname = SOUND_MANAGER_BUS_NAME,
+ .nodename = "soundmanager",
+ .early = FALSE,
+ .complete = TRUE,
+ .state = DS_CONTROLLED
+ };
+ ErrorCode ec = am_proxy_register_domain(create_domain_data(&ddata) , &SOUNDMANAGER_DOMAIN_ID);
+ if(!SEND_RESULT_NO_RESP(ec)){
+ AFB_WARNING("Failed to re-gisterDomain when asyncAbort");
+ return;
+ }
+ AFB_NOTICE("Sound Manager re-register domain, the old infomation may be lost");
afb_event_push(ev_set_routing_ready, NULL);
}
-static void on_set_routing_rundown(
- AudiomanagerRoutinginterface* interface)
+static void on_set_routing_rundown(void)
{
AFB_DEBUG("%s is called",__FUNCTION__);
afb_event_push(ev_set_routing_ready, NULL);
@@ -965,122 +964,71 @@ static void on_set_routing_rundown(
* Sound Manager just sends ack to Audio Manager in charge of applications.
*
*/
-static gboolean on_async_abort(
- AudiomanagerRoutingSoundmanager *object,
- GDBusMethodInvocation *invocation,
- guint16 arg_handle)
+static void on_async_abort(int handle)
{
AFB_DEBUG( "%s called", __FUNCTION__);
/* Nothing To Do. If it is better to implement something, I will implement */
- return TRUE;
}
-static gboolean on_async_connect(
- AudiomanagerRoutingSoundmanager *object,
- GDBusMethodInvocation *invocation,
- guint16 arg_handle,
- guint16 arg_connectionID,
- guint16 arg_sourceID,
- guint16 arg_sinkID,
- gint arg_connectionFormat)
+static void on_async_connect(int handle, int connectionID,
+ int sourceID, int sinkID, int connectionFormat)
{
AFB_DEBUG( "%s called", __FUNCTION__);
struct json_object* ev_obj = json_object_new_object();
sm_add_object_to_json_object(ev_obj, 10,
- KEY_HANDLE, arg_handle,
- KEY_CONNECTION_ID, arg_connectionID,
- KEY_SOURCE_ID, arg_sourceID,
- KEY_SINK_ID, arg_sinkID,
- KEY_CONNECTION_FORMAT, arg_connectionFormat);
+ KEY_HANDLE, handle,
+ KEY_CONNECTION_ID, connectionID,
+ KEY_SOURCE_ID, sourceID,
+ KEY_SINK_ID, sinkID,
+ KEY_CONNECTION_FORMAT, connectionFormat);
afb_event_push(ev_async_connect, ev_obj);
-
- /* GError must be initialized here because it is same as grobal errno,
- so if afb_event_push is failed due to something, number will be changed */
- GError* err = NULL;
- audiomanager_routinginterface_call_ack_connect_sync(
- am_route_bus,
- arg_handle,
- arg_connectionID,
- 0,
- NULL, &err);
- if(err != NULL)
- {
- AFB_ERROR( "Can't send ack to sound manager adapter %s", __FUNCTION__);
- return FALSE;
- }
- return TRUE;
}
-static gboolean on_async_disconnect(
- AudiomanagerRoutingSoundmanager *object,
- GDBusMethodInvocation *invocation,
- guint16 arg_handle,
- guint16 arg_connectionID)
+static void on_async_disconnect(int handle, int connectionID)
{
AFB_DEBUG( "%s called", __FUNCTION__);
struct json_object* ev_obj = json_object_new_object();
sm_add_object_to_json_object(ev_obj, 4,
- KEY_HANDLE, arg_handle,
- KEY_CONNECTION_ID, arg_connectionID);
+ KEY_HANDLE, handle,
+ KEY_CONNECTION_ID, connectionID);
afb_event_push(ev_async_disconnect, ev_obj);
- GError* err = NULL;
- audiomanager_routinginterface_call_ack_disconnect_sync(
- am_route_bus,
- arg_handle,
- arg_connectionID,
- 0,
- NULL, &err);
- if(err != NULL)
- {
- AFB_ERROR( "Can't send ack to sound manager adapter %s", __FUNCTION__);
- return FALSE;
- }
- return TRUE;
}
-static gboolean on_async_set_sink_volume(
- AudiomanagerRoutingSoundmanager *object,
- GDBusMethodInvocation *invocation,
- guint16 arg_handle,
- guint16 arg_sinkID,
- gint16 arg_volume,
- gint16 arg_ramp,
- guint16 arg_time)
+static void on_async_set_sink_volume(int handle, int sinkID,
+ int volume, int ramp, int time)
{
AFB_DEBUG( "%s called", __FUNCTION__);
- GError* err = NULL;
- audiomanager_routinginterface_call_ack_set_sink_volume_sync(
- am_route_bus,
- arg_handle,
- arg_volume,
- 0, NULL, &err);
- if(err != NULL);{
- AFB_ERROR( "Can't send ack to sound manager adapter %s", __FUNCTION__);
- return FALSE;
- }
- return TRUE;
}
-static gboolean on_async_set_source_state(
- AudiomanagerRoutingSoundmanager *object,
- GDBusMethodInvocation *invocation,
- guint16 arg_handle,
- guint16 arg_sourceID,
- gint arg_sourceState)
+static void on_async_set_source_state(int handle, int sourceID, int sourceState)
{
- AFB_DEBUG( "%s called", __FUNCTION__);
+ AFB_INFO( "%s called. handle : %d, sourceID: %d, state: %s", __FUNCTION__, handle, sourceID, get_source_state_key(sourceState));
struct json_object* ev_obj = json_object_new_object();
- char* ss_key = get_source_state_key(arg_sourceState);
+ const char* ss_key = get_source_state_key(sourceState);
sm_add_object_to_json_object(ev_obj, 4,
- KEY_HANDLE, arg_handle,
- KEY_SOURCE_ID, arg_sourceID);
+ KEY_HANDLE, handle,
+ KEY_SOURCE_ID, sourceID);
json_object_object_add(ev_obj, KEY_SOURCE_STATE, json_object_new_string(ss_key));
+#ifdef ENABLE_AGL_AHL
+ struct pending* pd = get_pending(pending_list, sourceID);
+ if(pd != NULL){
+ int ack_ok = 0;
+ am_proxy_ack_set_source_state(handle, ack_ok);
+ pending_list = del_pending(pending_list, sourceID);
+ }
+ json_object_object_add(ev_obj, KEY_AHL_EVENT_NAME, json_object_new_string(AHL_EVENT_NAME));
+ sm_add_object_to_json_object(ev_obj, 4,
+ KEY_AHL_REP_STREAM_ID, sourceID,
+ KEY_AHL_STATE_EVENT, sourceState);
+ json_object_get(ev_obj);
+ afb_event_push(ev_stream_state_event, ev_obj);
+#endif
afb_event_push(ev_async_set_source_state, ev_obj);
/* Applications must return ackSetSourceState to look sourceID, then Sound Manager doen't return ackSetSourceState */
/*audiomanager_routinginterface_call_ack_set_source_state_sync(
am_route_bus,
- arg_handle,
+ handle,
NULL,
NULL, &err);*/
}
@@ -1091,139 +1039,93 @@ static gboolean on_async_set_source_state(
*
*/
-static int registerDomain()
-{
- /* Default Setting of Sound Manager Domain */
- struct domain_data ddata = {
- .domainID = DYNAMIC_DOMAIN_ID,
- .name = "SoundManager",
- .busname = SOUND_MANAGER_BUS_NAME,
- .nodename = "soundmanager",
- .early = FALSE,
- .complete = TRUE,
- .state = DS_CONTROLLED
- };
- GVariant* domainData = create_domain_data(&ddata);
- gchar* retBusName = SOUND_MANAGER_BUS_NAME;
- gchar* retPath = SOUND_MANAGER_PATH;
- gchar* retInterface = SOUND_MANAGER_RETURN_INTERFACE;
- guint16 domain_id;
- GError *err = NULL;
- guint16 error;
+static void on_client_context_terminated(void *data){
+ smClientCtxt* ctxt = (smClientCtxt*)data;
+ if(NULL == ctxt){
+ return;
+ }
+ AFB_DEBUG("Client %s session is closed", ctxt->appname);
+ free(ctxt->appname);
+ free(ctxt);
+ // TODO : After application is terminated, what should we do?
+}
- audiomanager_routinginterface_call_register_domain_sync(
- am_route_bus,
- domainData,
- retBusName,
- retPath,
- retInterface,
- &domain_id, &error,
- NULL, &err);
- if(err != NULL){
- AFB_ERROR( "Failed to call %s", __FUNCTION__);
- return -1;
+static void create_client_context(afb_req request, guint16 source_id, guint16 sink_id, int endpoint_type){
+ AFB_DEBUG("");
+ static int applicationID_debug = 0;
+ smClientCtxt* ctxt = malloc(sizeof(smClientCtxt));
+ ctxt->appname = malloc(MAX_LENGTH_STR * sizeof(char));
+ char *appid = afb_req_get_application_id(request);
+ if(NULL == appid){
+ char debug[MAX_LENGTH_STR];
+ //char* debug;
+ snprintf(debug, MAX_LENGTH_STR, "%s%d", "applicationID_debug", ++applicationID_debug);
+ AFB_INFO("application id is not set. Define as %s", debug);
+ strncpy(ctxt->appname, debug, MAX_LENGTH_STR);
}
- if(error != 0)
- {
- AFB_ERROR( "Failed to register domain");
- return error;
+ else{
+ strncpy(ctxt->appname, appid, MAX_LENGTH_STR);
}
- SOUNDMANAGER_DOMAIN_ID = domain_id;
- AFB_NOTICE( "Complete registered domain id:%d",SOUNDMANAGER_DOMAIN_ID);
- return 0;
+ ctxt->source.sourceID = source_id;
+ ctxt->sink.endpointID = sink_id;
+ ctxt->sink.sinkID = sink_id;
+ ctxt->sink.endpointType = endpoint_type;
+ afb_req_context_set(request, ctxt, on_client_context_terminated);
}
-static int create_adapter()
-{
- GError *error = NULL;
- gboolean ret;
- GVariant *value;
- system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
- if (error)
- {
- g_error_free(error);
- return -1;
+void set_default_sink(){
+ GVariant *mainSinkList;
+ ErrorCode ec = am_proxy_get_list_main_sinks(&mainSinkList);
+ if(ec != OK){
+ return;
}
- sm_adapter = audiomanager_routing_soundmanager_skeleton_new();
- sm_itf = AUDIOMANAGER_ROUTING_SOUNDMANAGER_GET_IFACE(sm_adapter);
-
- /* initialize sound manager adapter */
- sm_itf->handle_async_abort = on_async_abort;
- sm_itf->handle_async_connect = on_async_connect;
- sm_itf->handle_async_disconnect = on_async_disconnect;
- sm_itf->handle_async_set_sink_volume = on_async_set_sink_volume;
- sm_itf->handle_async_set_source_state = on_async_set_source_state;
-
- int sigret = g_signal_connect(sm_adapter, "handle-async-abort", G_CALLBACK(on_async_abort),NULL);
- sigret = g_signal_connect(sm_adapter, "handle-async-connect", G_CALLBACK(on_async_connect),NULL);
- sigret = g_signal_connect(sm_adapter, "handle-async-disconnect", G_CALLBACK(on_async_disconnect),NULL);
- sigret = g_signal_connect(sm_adapter, "handle-async-set-sink-volume", G_CALLBACK(on_async_set_sink_volume),NULL);
- sigret = g_signal_connect(sm_adapter, "handle-async-set-source-state", G_CALLBACK(on_async_set_source_state),NULL);
- ret = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(sm_adapter), system_conn, SOUND_MANAGER_PATH, &error);
- if (FALSE == ret)
- {
- AFB_ERROR( "failed to export");
- g_error_free(error);
- g_object_unref(system_conn);
- return -1;
+ gsize size = g_variant_n_children(mainSinkList);
+
+ if(0 == size){
+ AFB_NOTICE("Sink is not registered in Audio Manaager then can't set default sinkID, then set as %d", DEFAULT_SINK);
+ return;
}
- return 0;
-}
+ guint16 sinkid, sinkclassid;
+ gchar* sinkname;
+ gint16 av, avr, volume, mutestate;
+ // Take the first one as default sinkID
+ GVariant* child = g_variant_get_child_value(mainSinkList, 0);
+ g_variant_get(
+ child,"(qs(nn)nnq)",
+ &sinkid, &sinkname, &av, &avr, &volume, &mutestate, &sinkclassid);
+ AFB_DEBUG( "sinkID: %d, sinkName: %s, availability: %d, availableReason: %d, volume: %d, muteState: %d, sinkClassID: %d",
+ sinkid, sinkname, av, avr, volume, mutestate, sinkclassid);
+ g_variant_unref(child);
+ g_variant_unref(mainSinkList);
-static void on_name_lost(GDBusServer *server, GDBusConnection *conn, gpointer data)
-{
- AFB_WARNING("%s called", __FUNCTION__);
+ set_default_sinkID(sinkid);
}
int preinit()
{
- int ret;
AFB_INFO("Initialize Dbus object");
- /* Initialize Dbus interface */
- if(am_cmd_bus || am_route_bus)
- {
- AFB_ERROR( "Dbus object to Audio Manager is already created");
- goto out;
- }
- am_cmd_bus = audiomanager_commandinterface_proxy_new_for_bus_sync(
- G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_NONE,
- AM_NAME,
- AM_CMD_PATH,
- NULL,
- NULL
- );
- am_route_bus = audiomanager_routinginterface_proxy_new_for_bus_sync(
- G_BUS_TYPE_SYSTEM,
- G_DBUS_PROXY_FLAGS_NONE,
- AM_NAME,
- AM_ROUTE_PATH,
- NULL,
- NULL
- );
- if(!am_cmd_bus || !am_route_bus)
- {
- goto out;
+ /* Initialize Dbus interface */
+ ErrorCode ec = initialize_proxy();
+ if(ec == NOT_INITIALIZED){
+ AFB_ERROR("Failed to initialize");
+ return -1;
}
AFB_NOTICE( "Finish Initialize");
return 0;
-out:
- AFB_ERROR("Failed to initialize");
- return -1;
}
int sm_init()
{
AFB_NOTICE("Initialize event receive setting");
- printf("Initialize event receive setting");
- int ret;
+
/* Initialize make event */
size_t size = sizeof cmd_evlist / sizeof *cmd_evlist;
+ ErrorCode ec;
/*create event*/
/*ToDo Hash table is better. And event should be created in the loop
@@ -1233,15 +1135,15 @@ int sm_init()
ev_removed_main_connection = afb_daemon_make_event(cmd_evlist[2]);
ev_sink_mute_state_changed = afb_daemon_make_event(cmd_evlist[3]);
ev_main_connection_state_changed = afb_daemon_make_event(cmd_evlist[4]);
- command_event_list[0].name = cmd_evlist[0];
+ command_event_list[0].name = strdup(cmd_evlist[0]);
command_event_list[0].event = &ev_volume_changed;
- command_event_list[1].name = cmd_evlist[1];
+ command_event_list[1].name = strdup(cmd_evlist[1]);
command_event_list[1].event = &ev_new_connection;
- command_event_list[2].name = cmd_evlist[2];
+ command_event_list[2].name = strdup(cmd_evlist[2]);
command_event_list[2].event = &ev_removed_main_connection;
- command_event_list[3].name = cmd_evlist[3];
+ command_event_list[3].name = strdup(cmd_evlist[3]);
command_event_list[3].event = &ev_sink_mute_state_changed;
- command_event_list[4].name = cmd_evlist[4];
+ command_event_list[4].name = strdup(cmd_evlist[4]);
command_event_list[4].event = &ev_main_connection_state_changed;
/* create routing event */
@@ -1250,89 +1152,72 @@ int sm_init()
ev_async_connect = afb_daemon_make_event(route_evlist[2]);
ev_async_set_source_state = afb_daemon_make_event(route_evlist[3]);
ev_async_disconnect = afb_daemon_make_event(route_evlist[4]);
+#ifdef ENABLE_AGL_AHL
+ ev_stream_state_event = afb_daemon_make_event(route_evlist[5]);
+#endif
- routing_event_list[0].name = route_evlist[0];
+ routing_event_list[0].name = strdup(route_evlist[0]);
routing_event_list[0].event = &ev_set_routing_ready;
- routing_event_list[1].name = route_evlist[1];
+ routing_event_list[1].name = strdup(route_evlist[1]);
routing_event_list[1].event = &ev_set_routing_rundown;
- routing_event_list[2].name = route_evlist[2];
+ routing_event_list[2].name = strdup(route_evlist[2]);
routing_event_list[2].event = &ev_async_connect;
- routing_event_list[3].name = route_evlist[3];
+ routing_event_list[3].name = strdup(route_evlist[3]);
routing_event_list[3].event = &ev_async_set_source_state;
- routing_event_list[4].name = route_evlist[4];
+ routing_event_list[4].name = strdup(route_evlist[4]);
routing_event_list[4].event = &ev_async_disconnect;
- /*for(size_t i = 0; i < size; ++i)
- {
- struct afb_event afbev = afb_daemon_make_event(afbitf->daemon, cmd_evlist[i]));
- size_t afbev_size = sizeof afbev;
- size_t key_size = sizeof cmd_evlist[i];
-
- struct event ev = {cmd_evlist[i],afbev};
- command_event_list[i] = malloc(key_size + afbev_size);
- command_event_list[i] = ev;
- search_result = hsearch(entry, FIND);
- if(search_result)
- AFB_NOTICE( "event name is %s", search_result->key);
- }*/
-
- /* Initialize dbus event thread */
- if(!am_cmd_bus || !am_route_bus)
- {
- goto ev_init_out;
- }
- /* initialize signal from audio manager command interface */
- g_signal_connect(am_cmd_bus,
- "volume_changed",
- G_CALLBACK(on_volume_changed),
- NULL);
- g_signal_connect(am_cmd_bus,
- "new_main_connection",
- G_CALLBACK(on_new_main_connection),
- NULL);
- g_signal_connect(am_cmd_bus,
- "removed_main_connection",
- G_CALLBACK(on_removed_main_connection),
- NULL);
- g_signal_connect(am_cmd_bus,
- "sink_mute_state_changed",
- G_CALLBACK(on_sink_mute_state_changed),
- NULL);
- g_signal_connect(am_cmd_bus,
- "main_connection_state_changed",
- G_CALLBACK(on_main_connection_state_changed),
- NULL);
- g_signal_connect(am_route_bus,
- "set_routing_ready",
- G_CALLBACK(on_set_routing_ready),
- NULL);
- g_signal_connect(am_route_bus,
- "set_routing_rundown",
- G_CALLBACK(on_set_routing_rundown),
- NULL);
+#ifdef ENABLE_AGL_AHL
+ routing_event_list[5].name = strdup(route_evlist[5]);
+ routing_event_list[5].event = &ev_stream_state_event;
+#endif
+
+ am_event callback = {
+ .on_new_main_connection = on_new_main_connection,
+ .on_removed_main_connection = on_removed_main_connection,
+ .on_main_connection_state_changed = on_main_connection_state_changed,
+ .on_volume_changed = on_volume_changed,
+ .on_sink_mute_state_changed = on_sink_mute_state_changed,
+ .on_set_routing_ready = on_set_routing_ready,
+ .on_set_routing_rundown = on_set_routing_rundown
+ };
+ set_event_callback(&callback);
/* Get soundmanager adapter bus */
- ret = g_bus_own_name(G_BUS_TYPE_SYSTEM, SOUND_MANAGER_BUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE,
- NULL,NULL, NULL, NULL, NULL);
- AFB_DEBUG( "g_bus_own_name ret: %d", ret);
- ret = create_adapter();
- if(ret != 0)
- {
- goto ev_init_out;
+ am_instruction instruction = {
+ .on_async_abort = on_async_abort,
+ .on_async_connect = on_async_connect,
+ .on_async_disconnect = on_async_disconnect,
+ .on_async_set_sink_volume = on_async_set_sink_volume,
+ .on_async_set_source_state = on_async_set_source_state
+ };
+ ec = open_soundmanager_interface(&instruction);
+ if(ec != OK){
+ AFB_ERROR("Failed to create sound manager interface");
+ return -1;
}
- ret = registerDomain();
- if(ret != 0)
- {
- AFB_ERROR("registerDomain error: %s",get_response_audiomanager_massage_error(ret));
- goto ev_init_out;
+ GError* err = NULL;
+ struct domain_data ddata = {
+ .domainID = DYNAMIC_DOMAIN_ID,
+ .name = "SoundManager",
+ .busname = SOUND_MANAGER_BUS_NAME,
+ .nodename = "soundmanager",
+ .early = FALSE,
+ .complete = TRUE,
+ .state = DS_CONTROLLED
+ };
+ ec = am_proxy_register_domain(create_domain_data(&ddata) , &SOUNDMANAGER_DOMAIN_ID);
+ if(!SEND_RESULT_NO_RESP(ec)){
+ return -1;
}
+ if(ec != OK){
+ AFB_ERROR("Failed to registerDomain : %s", get_response_audiomanager_massage_error(ec));
+ return -1;
+ }
+ AFB_DEBUG("domainID : %d", SOUNDMANAGER_DOMAIN_ID);
- AFB_INFO("Finish Initialize event receive setting");
+ set_default_sink();
return 0;
-
-ev_init_out:
- AFB_WARNING( "DBus connection is not created");
- return -1;
}
void onevent(const char *event, struct json_object *object)
diff --git a/src/soundmanager.h b/src/soundmanager.h
index e9e65ea..f79643b 100644
--- a/src/soundmanager.h
+++ b/src/soundmanager.h
@@ -13,23 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
-/**
- * @file soundmanager.h
- * @brief Sound Manager API
- */
#ifndef SOUNDMANAGER_H
#define SOUNDMANAGER_H
#define _GNU_SOURCE
#define AFB_BINDING_VERSION 2
#include <afb/afb-binding.h>
-#include "dbus/audio_manager_interface.h"
-
-struct event{
- char* name;
- struct afb_event* event;
- };
/*
********** Method of Sound Manager (API) **********
@@ -315,6 +304,8 @@ void subscribe(struct afb_req request);
*/
void unsubscribe(struct afb_req request);
+#ifdef ENABLE_AGL_AHL
+
/**
* Application High Level API for AGL
* This function opens "stream".
@@ -337,7 +328,7 @@ void unsubscribe(struct afb_req request);
* #### Note
* TODO : write note
*/
-void streamOpen(struct afb_req req);
+void stream_open(struct afb_req req);
/**
* Application High Level API for AGL
@@ -353,28 +344,30 @@ void streamOpen(struct afb_req req);
* #### Note
* TODO : write note
*/
-void streamClose(struct afb_req req);
+void stream_close(struct afb_req req);
/**
* Application High Level API for AGL
* This function set stream state.
- * This function set the availability and calls connect function of Audio Manager
- * and returns the result of policy check.
+ * This function set the availability and calls connect function of Audio Manager.
+ * Policy check result will be notified by event..
*
* #### Parameters
* - stream_id : Stream id which is returned in stream_open.
- * - mute : Stream state as int
+ * - mute : Stream state as int. 0 is unmute, and 1 is mute. Sound manager set this parameter as unmute as default
* #### Return
* - error : Error status number. If error is 0, it means the request is accepted, otherwise error message is attached with error code in reply message.
* #### Note
- * TODO : write note
+ * After set unmute, then 'asyncSetSourceState' and 'stream_state_event' is pushed. These events contains information of state judged by AudioManager.
*/
-void setStreamState(struct afb_req req);
+void set_stream_state(struct afb_req req);
/*
********** Event list from Sound Manager **********
*/
+#endif
+
/*
********** Application Framework Imprement **********
@@ -384,13 +377,15 @@ void setStreamState(struct afb_req req);
* array of the verbs exported to afb-daemon
*/
const struct afb_verb_v2 binding_verbs[]= {
+#ifdef ENABLE_AGL_AHL
// High Level API of AGL
-{ .verb = "stream_open", .callback = streamOpen, .auth = NULL,
- .info = "Open stream." , .session = AFB_SESSION_NONE},
-{ .verb = "stream_close", .callback = streamClose, .auth = NULL,
+{ .verb = "stream_open", .callback = stream_open, .auth = NULL,
+ .info = "Open stream." , .session = AFB_SESSION_NONE},
+{ .verb = "stream_close", .callback = stream_close, .auth = NULL,
.info = "Close stream" , .session = AFB_SESSION_NONE},
-{ .verb = "set_stream_state", .callback = setStreamState, .auth = NULL,
- .info = "Set stream state" , .session = AFB_SESSION_NONE},
+{ .verb = "set_stream_state", .callback = set_stream_state, .auth = NULL,
+ .info = "Set stream state" , .session = AFB_SESSION_NONE},
+#endif
// Adaption API of Audio Manager
{ .verb = "connect", .callback = connect, .auth = NULL,
.info = "Connect source id and sink id" , .session = AFB_SESSION_NONE},
@@ -407,11 +402,11 @@ const struct afb_verb_v2 binding_verbs[]= {
{ .verb = "getListMainSinks", .callback = getListMainSinks, .auth = NULL,
.info = "Get MainSink List" , .session = AFB_SESSION_NONE},
{ .verb = "getListMainSources", .callback = getListMainSources, .auth = NULL,
- .info = "Get MainSource List" , .session = AFB_SESSION_NONE},
+ .info = "Get MainSource List" , .session = AFB_SESSION_NONE},
{ .verb = "registerSource", .callback = registerSource, .auth = NULL,
- .info = "Register autio role" , .session = AFB_SESSION_NONE},
+ .info = "Register autio role" , .session = AFB_SESSION_NONE},
{ .verb = "deregisterSource", .callback = deregisterSource, .auth = NULL,
- .info = "Deregister audio role" , .session = AFB_SESSION_NONE},
+ .info = "Deregister audio role" , .session = AFB_SESSION_NONE},
{ .verb = "ackConnect", .callback = ackConnect, .auth = NULL,
.info = "Acknowledge of asyncConnect" , .session = AFB_SESSION_NONE},
{ .verb = "ackDisconnect", .callback = ackDisconnect, .auth = NULL,
@@ -437,4 +432,4 @@ const struct afb_binding_v2 afbBindingV2 = {
.onevent = onevent
};
-#endif //SOUNDMANAGER_H
+#endif //SOUNDMANAGER_H \ No newline at end of file