diff options
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/audiomanager_proxy.c | 651 | ||||
-rw-r--r-- | src/audiomanager_proxy.h | 97 | ||||
-rw-r--r-- | src/sm-def.h | 40 | ||||
-rw-r--r-- | src/sm-error.h | 27 | ||||
-rw-r--r-- | src/sm-helper.c | 98 | ||||
-rw-r--r-- | src/sm-helper.h | 46 | ||||
-rw-r--r-- | src/soundmanager.c | 528 | ||||
-rw-r--r-- | src/soundmanager.h | 1 |
10 files changed, 954 insertions, 536 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 695186d..b758124 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ set(PROJECT_DESCRIPTION " Sound Manager binding and client library Binder commu set(PROJECT_INCLUDEDIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}) set(PROJECT_LIBDIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}) set(PROJECT_BINDINGDIR ${binding_install_dir}) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # get pkgconfig INCLUDE(FindPkgConfig) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 30adbd8..96d906b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -25,6 +25,7 @@ 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 + audiomanager_proxy.c dbus/audio_manager_interface.c) option(ENABLE_AGL_AHL "Implement AGL High Level API" ON) diff --git a/src/audiomanager_proxy.c b/src/audiomanager_proxy.c new file mode 100644 index 0000000..cdf5b4c --- /dev/null +++ b/src/audiomanager_proxy.c @@ -0,0 +1,651 @@ +/* + * 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 "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 _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(NULL, 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(NULL, 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(NULL, connectionID, connectionState); +} + +static void _on_volume_changed( + AudiomanagerCommandinterface* interface, guint16 sinkID, gint16 volume) +{ + AFB_DEBUG("%s is called",__FUNCTION__); + _am_event.on_volume_changed(NULL, 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(NULL, 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(NULL); +} + +static void _on_set_routing_rundown( + AudiomanagerRoutinginterface* interface) +{ + AFB_DEBUG("%s is called",__FUNCTION__); + _am_event.on_set_routing_rundown(NULL); +} + +static ErrorCode check_send_error(GError *err, guint16 result){ + if(err != NULL){ + return UNABLE_SEND; + } + return result; +} + +/* +********** Callback Function invoked by Sound Manager Adapter Interface********** +* +* For now, there may be no need to send events to applications from these invocation. +* Sound Manager just sends ack to Audio Manager in charge of applications. +* +*/ +static gboolean _on_async_abort( + AudiomanagerRoutingSoundmanager *object, + GDBusMethodInvocation *invocation, + guint16 arg_handle) +{ + AFB_DEBUG( "%s called", __FUNCTION__); + _am_instruction.on_async_abort(NULL, (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(NULL, handle, connection, + source, sink, connection_format); + + /* 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 */ + + 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(NULL, 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(NULL, handle, source, source_state); + return TRUE; +} + + +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; + } + guint16 connection_id = -1, ret = UNABLE_SEND; + ErrorCode ec; + GError *err = NULL; + + assert(!am_cmd_bus); + + 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){ + if(is_range_over_guint16(main_connection_id) == OUT_RANGE){ + return OUT_RANGE; + } + guint16 ret = UNABLE_SEND; + ErrorCode ec; + GError *err = NULL; + + assert(!am_cmd_bus); + 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){ + if(is_range_over_guint16(sink) == OUT_RANGE && is_range_over_gint16(volume) == OUT_RANGE){ + return OUT_RANGE; + } + guint16 ret = UNABLE_SEND; + ErrorCode ec; + GError *err = NULL; + + assert(!am_cmd_bus); + 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){ + if(is_range_over_guint16(sink) == OUT_RANGE && is_range_over_gint16(volume) == OUT_RANGE){ + return OUT_RANGE; + } + guint16 ret = UNABLE_SEND; + ErrorCode ec; + GError *err = NULL; + + assert(!am_cmd_bus); + 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){ + if(is_range_over_guint16(sink) == OUT_RANGE || is_range_over_gint16(mute_state) == OUT_RANGE){ + return OUT_RANGE; + } + guint16 ret = UNABLE_SEND; + ErrorCode ec; + GError *err = NULL; + + assert(!am_cmd_bus); + 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 = UNABLE_SEND; + ErrorCode ec; + GError *err = NULL; + + assert(!am_cmd_bus); + 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 = UNABLE_SEND; + ErrorCode ec; + GError *err = NULL; + + assert(!am_cmd_bus); + 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 = UNABLE_SEND; + ErrorCode ec; + GError *err = NULL; + + assert(!am_cmd_bus); + audiomanager_commandinterface_call_get_list_main_sources_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){ + 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); + 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){ + 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); + 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){ + if(is_range_over_guint16(handle) == OUT_RANGE || + is_range_over_guint16(usr_err) == OUT_RANGE){ + return OUT_RANGE; + } + + assert(!am_route_bus); + 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){ + assert(!am_route_bus); + guint16 ret = UNABLE_SEND; + ErrorCode ec; + GError *err = NULL; + + audiomanager_routinginterface_call_register_source_sync( + am_route_bus, + source_data, + source, + &ret, + NULL, &err); + g_variant_unref(source_data); + ec = check_send_error(err, ret); + return ec; +} + +ErrorCode am_proxy_deregister_source(int source){ + if(is_range_over_guint16(source) == OUT_RANGE){ + return OUT_RANGE; + } + guint16 ret = UNABLE_SEND; + ErrorCode ec; + GError *err = NULL; + + assert(!am_route_bus); + 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 = UNABLE_SEND; + ErrorCode ec; + GError *err = NULL; + + assert(!am_route_bus); + audiomanager_routinginterface_call_register_domain_sync( + am_route_bus, + domain_data, + SOUND_MANAGER_BUS_NAME, + SOUND_MANAGER_PATH, + SOUND_MANAGER_RETURN_INTERFACE, + domain, &ret, + NULL, &err); + + SEND_RESULT_NO_RESP(err); + g_variant_unref(domain_data); + 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 only used by soundmanager. + */ + GVariantBuilder builder; + 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); + 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("created sourceData %d", __LINE__); + return g_variant_builder_end (&builder); +} + +ErrorCode initialize_proxy(){ + if(am_cmd_bus || am_route_bus) + { + return UNABLE_SEND; + } + 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 + ); + 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); + assert(!am_route_bus); + /* 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_removed_main_connection; + _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); +} + +ErrorCode open_soundmanager_interface(const am_instruction *callback){ + guint 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); + GError *error = NULL;; + GVariant *value; + system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (error) + { + g_error_free(error); + return NOT_INITIALIZED; + } + sm_adapter = audiomanager_routing_soundmanager_skeleton_new(); + sm_itf = AUDIOMANAGER_ROUTING_SOUNDMANAGER_GET_IFACE(sm_adapter); + + _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; + + /* 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); + gboolean rc = g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(sm_adapter), system_conn, SOUND_MANAGER_PATH, &error); + if (FALSE == rc) + { + AFB_ERROR( "failed to export"); + g_error_free(error); + g_object_unref(system_conn); + + return NOT_INITIALIZED; + } + return OK; +} + +void close_soundmanager_inerface(){ + g_dbus_interface_skeleton_unexport(sm_adapter); +} diff --git a/src/audiomanager_proxy.h b/src/audiomanager_proxy.h new file mode 100644 index 0000000..e0c6b3d --- /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)(void* closure, int connection, int source, int sink, int delay, int connection_state); + void (*on_removed_main_connection)(void* closure, int connection); + void (*on_main_connection_state_changed)(void* closure, int connection, int connection_state); + void (*on_volume_changed)(void* closure, int sink, int volume); + void (*on_sink_mute_state_changed)(void* closure, int sink, int mute); + void (*on_set_routing_ready)(void* closure); + void (*on_set_routing_rundown)(void* closure); +} am_event; + +typedef struct audiomanager_instruction{ + void (*on_async_abort)(void* closure, int handle); + void (*on_async_connect)(void* closure, int handle, int connection, int source, int sink, int connection_format); + void (*on_async_disconnect)(void* closure, int handle, int connection); + void (*on_async_set_sink_volume)(void* closure, int handle, int sink, int volume, int ramp, int time); + void (*on_async_set_source_state)(void* closure, 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/sm-def.h b/src/sm-def.h index ce25b5e..17e31ff 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 @@ -68,6 +83,31 @@ typedef enum { } 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_STR 256 #endif // SOUNDMANAGER_DEFINE_H
\ No newline at end of file diff --git a/src/sm-error.h b/src/sm-error.h index 34d36b3..afaaed8 100644 --- a/src/sm-error.h +++ b/src/sm-error.h @@ -1,34 +1,35 @@ #ifndef SM_ERROR_H #define SM_ERROR_H +#include "sm-def.h" char* get_response_audiomanager_massage_error(int am_error_code) { switch (am_error_code){ - case 0: + case OK: return "OK"; - case 1: + case UNKNOWN: return "unknown error"; - case 2: + case OUT_RANGE: return "value out of range"; - case 3: + case NOT_USED: return "not used"; - case 4: + case DATABASE_ERR: return "database error occured"; - case 5: + case OBJECT_ALREADY_EXIST: return "the desired object already exists"; - case 6: + case NO_CHANGE: return "there is no change"; - case 7: + case ACTION_IMPOSSIBLE: return "the desired action is not possible"; - case 8: + case OBJECT_NOT_EXIST: return "the desired object is non existent"; - case 9: + case ASYNC_ACTION_ABORTED: return "the asynchronous action was aborted"; - case 10: + case CONNECTION_FORMAT_ERR: return "connectionFormat is not selected"; - case 11: + case COMMUNICATION_ERR: return "communication error"; - case 100: + case EVENT_NOT_EXIST: return "desired event doesn't exist"; default: return "Audio Manager responsed unknown error number"; diff --git a/src/sm-helper.c b/src/sm-helper.c index a02d772..0ccd1c7 100644 --- a/src/sm-helper.c +++ b/src/sm-helper.c @@ -35,7 +35,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 +59,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 +83,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') { @@ -187,80 +187,6 @@ 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); -} - -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(const GError* result_of_send, struct afb_req req, const char* function){ /* GError = NULL means success in case of gdbus request */ if(result_of_send != NULL) @@ -278,4 +204,22 @@ bool send_result_no_resp(const GError* result_of_send, const char* function){ return false; } return true; +} + +ErrorCode is_range_over_guint16(int source){ + /* error check of range */ + if( (source > UINT16_MAX) || (source < 0) ) + { + return OUT_RANGE; + } + return OK; +} + +ErrorCode is_range_over_gint16(int source){ + /* error check of range */ + if( (source > INT16_MAX) || (source < INT16_MIN) ) + { + return OUT_RANGE; + } + return OK; }
\ No newline at end of file diff --git a/src/sm-helper.h b/src/sm-helper.h index 8c87432..412551d 100644 --- a/src/sm-helper.h +++ b/src/sm-helper.h @@ -22,17 +22,10 @@ #include <stdint.h> #include <stdbool.h> #include <glib.h> +#include "sm-def.h" #define SEND_RESULT(...) send_result(__VA_ARGS__, __FUNCTION__) #define SEND_RESULT_NO_RESP(...) send_result_no_resp(__VA_ARGS__, __FUNCTION__) -typedef enum REQ_ERROR -{ - REQ_FAIL = -1, - REQ_OK=0, - NOT_NUMBER, - OUT_RANGE -}REQ_ERROR; - static const char* cmd_evlist[] = { "volumeChanged", "newMainConnection", @@ -50,34 +43,6 @@ static const char* route_evlist[] = { "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; -}; - 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); @@ -86,13 +51,8 @@ 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(const GError* result_of_send, const char* function); bool send_result(const GError* result_of_send, 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/soundmanager.c b/src/soundmanager.c index b887f25..1b7ad6d 100644 --- a/src/soundmanager.c +++ b/src/soundmanager.c @@ -22,6 +22,7 @@ #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" @@ -31,14 +32,7 @@ struct event{ struct afb_event* event; }; -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; - -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]; @@ -90,8 +84,7 @@ 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; @@ -120,13 +113,7 @@ 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, source_id, &main_connectionID); if(!SEND_RESULT(err, request)) return; @@ -135,9 +122,9 @@ void connect (struct afb_req request) /*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); + char *info = get_response_audiomanager_massage_error(ec); afb_req_success(request, res, info); } @@ -145,32 +132,27 @@ 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(!SEND_RESULT(err, 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); + char *info = get_response_audiomanager_massage_error(ec); afb_req_success(request, res_obj, info); /* return error num as status */ } @@ -180,7 +162,6 @@ 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; @@ -193,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(!SEND_RESULT(err, 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); + char *info = get_response_audiomanager_massage_error(ec); afb_req_success(request, res_obj, info); /* return error num as status */ } @@ -216,7 +192,6 @@ 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; @@ -229,20 +204,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(!SEND_RESULT(err, 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); + char *info = get_response_audiomanager_massage_error(ec); afb_req_success(request, res_obj, info); /* return error num as status */ } @@ -252,7 +222,6 @@ 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; @@ -266,20 +235,15 @@ void setSinkMuteState(struct afb_req request) 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(!SEND_RESULT(err, 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); + char *info = get_response_audiomanager_massage_error(ec); afb_req_success(request, res_obj, info); /* return error num as status */ } @@ -287,17 +251,11 @@ 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(!SEND_RESULT(err, request)) return; @@ -340,17 +298,11 @@ void getListMainConnections(struct afb_req request) 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(!SEND_RESULT(err, request)) return; @@ -398,17 +350,11 @@ 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(!SEND_RESULT(err, request)) return; @@ -486,12 +432,7 @@ 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(err, request)) return; @@ -526,12 +467,7 @@ 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(!SEND_RESULT(err, request)) return; @@ -561,19 +497,15 @@ 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(!SEND_RESULT(err, 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); + char *info = get_response_audiomanager_massage_error(ec); afb_req_success(request, res, info); } @@ -654,56 +586,43 @@ void registerSource(struct afb_req request) /* acquire data */ guint16 acquire_source_id; - guint16 ret; + 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(!SEND_RESULT(err, 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); + 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 - ); + ErrorCode ec = am_proxy_deregister_source(source_id); if(!SEND_RESULT(err, 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); + char *info = get_response_audiomanager_massage_error(ec); afb_req_success(request, res, info); } @@ -851,6 +770,15 @@ void streamOpen(struct afb_req request){ void streamClose(struct afb_req request){ // TODO : wtite function + // unpack request + /* json_object* response = json_object_new_object(); + smClientCtxt* ctxt = afb_req_context_get(request); + if(ctxt->source.mainConnectionID > 0){ + json_object* jreq = json_object_new_object(); + json_object_object_add(jreq, KEY_MAIN_CONNECTION_ID, ctxt->source.mainConnectionID); + afb_service_call_sync("soundmanager", "disconnect", jreq, &response); + json_object_object_get_ex(response, KEY_RESPONSE, &j_resp); + } */ } void setStreamState(struct afb_req request){ @@ -862,31 +790,24 @@ void setStreamState(struct afb_req request){ ********** Callback Function invoked by Audio Manager ********** */ -static void on_new_main_connection(AudiomanagerCommandinterface* interface, - GVariant* mainConnection) +static void on_new_main_connection(void* closure, 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 - ); + KEY_CONNECTION_STATE, connectionState); AFB_DEBUG("json object :%s:",json_object_to_json_string(res_obj)); afb_event_push(ev_new_connection, res_obj); } -static void on_removed_main_connection( - AudiomanagerCommandinterface* interface, guint16 mainConnectionID) +static void on_removed_main_connection(void* closure, int mainConnectionID) { AFB_DEBUG("%s is called",__FUNCTION__); @@ -896,8 +817,7 @@ static void on_removed_main_connection( 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(void* closure, int connectionID, int connectionState) { AFB_DEBUG("%s is called",__FUNCTION__); @@ -908,8 +828,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(void* closure, int sinkID, int volume) { AFB_DEBUG("%s is called",__FUNCTION__); struct json_object* res_obj = json_object_new_object(); @@ -919,8 +838,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(void* closure, int sinkID, int mute) { AFB_DEBUG("%s is called",__FUNCTION__); struct json_object* res_obj = json_object_new_object(); @@ -933,15 +851,13 @@ 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* closure) { AFB_DEBUG("%s is called",__FUNCTION__); afb_event_push(ev_set_routing_ready, NULL); } -static void on_set_routing_rundown( - AudiomanagerRoutinginterface* interface) +static void on_set_routing_rundown(void* closure) { AFB_DEBUG("%s is called",__FUNCTION__); afb_event_push(ev_set_routing_ready, NULL); @@ -956,122 +872,57 @@ 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(void *closure, 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(void *closure, 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 gboolean on_async_disconnect(void *closure, 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 gboolean on_async_set_sink_volume(void *closure, 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 gboolean on_async_set_source_state(void *closure, int handle, int sourceID, int sourceState) { AFB_DEBUG( "%s called", __FUNCTION__); struct json_object* ev_obj = json_object_new_object(); - char* ss_key = get_source_state_key(arg_sourceState); + 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)); 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);*/ } @@ -1117,138 +968,25 @@ static void create_client_context(afb_req request, guint16 source_id, guint16 si afb_req_context_set(request, ctxt, on_client_context_terminated); } -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; - - 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; - } - if(error != 0) - { - AFB_ERROR( "Failed to register domain"); - return error; - } - SOUNDMANAGER_DOMAIN_ID = domain_id; - AFB_NOTICE( "Complete registered domain id:%d",SOUNDMANAGER_DOMAIN_ID); - return 0; -} - -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; - } - 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; - } - - return 0; -} - - -static void on_name_lost(GDBusServer *server, GDBusConnection *conn, gpointer data) -{ - // TODO: when the dbus name is lost, what should we do? - AFB_WARNING("%s called", __FUNCTION__); -} - 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 err = initialize_proxy(); + if(err != OK){ + 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; @@ -1302,64 +1040,50 @@ int sm_init() 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); + am_event callback = { + .on_new_main_connection = on_new_main_connection, + .on_removed_main_connection = on_removed_main_connection, + .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 + }; + ErrorCode ret = open_soundmanager_interface(&instruction); + if(ret != 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 + }; + ret = am_proxy_register_domain( create_domain_data(&ddata), &SOUNDMANAGER_DOMAIN_ID); + if(!SEND_RESULT_NO_RESP(err)){ + return -1; } - - AFB_INFO("Finish Initialize event receive setting"); + if(ret != OK){ + AFB_ERROR("Failed to registerDomain : %s", get_response_audiomanager_massage_error(ret)); + return -1; + } + AFB_DEBUG("domainID : %d", SOUNDMANAGER_DOMAIN_ID); 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 c03f718..3666473 100644 --- a/src/soundmanager.h +++ b/src/soundmanager.h @@ -19,7 +19,6 @@ #define _GNU_SOURCE #define AFB_BINDING_VERSION 2 #include <afb/afb-binding.h> -#include "dbus/audio_manager_interface.h" /* ********** Method of Sound Manager (API) ********** |