From: Jaechul Lee Date: Wed, 22 Jul 2020 08:18:31 +0000 (+0900) Subject: add publish and allow remote access internal api X-Git-Tag: submit/tizen/20200818.081651^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=eb0cc73bb4174dded2e9819914db75dd6886c20f;p=platform%2Fcore%2Fapi%2Fsound-manager.git add publish and allow remote access internal api [Version] 0.6.27 [Issue Type] Improvement Change-Id: I715ffd51c837e01bd01dccd74936a6caa9425763 Signed-off-by: Jaechul Lee --- diff --git a/include/sound_manager_internal.h b/include/sound_manager_internal.h index c326ee0..8f00a13 100644 --- a/include/sound_manager_internal.h +++ b/include/sound_manager_internal.h @@ -1073,6 +1073,130 @@ typedef enum { */ int sound_manager_get_latest_stream_pid(int stream_type, unsigned int *pid); +/** + * @internal + * @brief Called when the remote client is connected or disconnected. + * @since_tizen 6.0 + * @remarks This callback indicates that the new remote client is connected or existing remote client is disconnected. \n + The parameters are the identification of the remote client such as unique id, name, description, and recording or not, \n + which can help the user to make a decision to allow access from the remote client using sound_manager_set_remote_permission(). + * @param[in] id The id of the remote client + * @param[in] name The name of the remote client + * @param[in] is_recording The flag indicating whether it's recording client or not + * @param[in] description The brief description of the remote client + * @param[in] is_connected The state of remote client connection: (@c true = connected, @c false = disconnected) + * @param[in] user_data The user data passed from the callback registration function + * @pre You should register this callback using sound_manager_publish_local_device(). + * @see sound_manager_publish_local_device() + * @see sound_manager_unpublish_local_device() + * @see sound_manager_set_allow_remote_access() + */ +typedef void (*sound_manager_remote_client_connected_cb) (int id, const char *name, bool is_recording, + const char *description, bool is_connected, void *user_data); + +/** + * @internal + * @brief Publishes device's built-in audio devices to the local network. + * @since_tizen 6.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/internet + * @remarks This function publishes the device's built-in audio devices such as speakers and microphones to the local network. \n + * The registered callback function will be invoked when the remote clients discover published audio devices and the connection established. + * @param[in] callback The remote client connection state changed callback function + * @param[in] user_data The user data to be passed to the callback function + * @return @c 0 on success, + * otherwise a negative error value + * @retval #SOUND_MANAGER_ERROR_NONE Success + * @retval #SOUND_MANAGER_ERROR_NOT_SUPPORTED Not supported + * @retval #SOUND_MANAGER_ERROR_PERMISSION_DENIED Permission denied + * @retval #SOUND_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SOUND_MANAGER_ERROR_INVALID_OPERATION Invalid operation + * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system + * @post sound_manager_remote_client_connected_cb() will be invoked. + * @see sound_manager_unpublish_local_device() + * @see sound_manager_set_remote_permission() + */ +int sound_manager_publish_local_device(sound_manager_remote_client_connected_cb callback, void *user_data); + +/** + * @internal + * @brief Unpublishes device's built-in audio devices to local network. + * @since_tizen 6.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/internet + * @remarks This function unpublishes the device's built-in audio devices to the local network. + * @return @c 0 on success, + * otherwise a negative error value + * @retval #SOUND_MANAGER_ERROR_NONE Success + * @retval #SOUND_MANAGER_ERROR_NOT_SUPPORTED Not supported + * @retval #SOUND_MANAGER_ERROR_PERMISSION_DENIED Permission denied + * @retval #SOUND_MANAGER_ERROR_INVALID_OPERATION Invalid operation + * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system + * @pre You should have already published using sound_manager_publish_local_device(). + * @see sound_manager_publish_local_device() + * @see sound_manager_set_remote_permission() + */ +int sound_manager_unpublish_local_device(void); + +/** + * @internal + * @brief Sets the permission of accessing the local device from the remote client. + * @since_tizen 6.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/internet + * @remarks + * @param[in] id The remote client id + * @param[in] allowed The permission to allow accessing from the remote client. + * @return @c 0 on success, + * otherwise a negative error value + * @retval #SOUND_MANAGER_ERROR_NONE Success + * @retval #SOUND_MANAGER_ERROR_NOT_SUPPORTED Not supported + * @retval #SOUND_MANAGER_ERROR_PERMISSION_DENIED Permission denied + * @retval #SOUND_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #SOUND_MANAGER_ERROR_INVALID_OPERATION Invalid operation + * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system + * @see sound_manager_publish_local_device() + * @see sound_manager_unpublish_local_device() + */ +int sound_manager_set_remote_permission(int id, bool allowed); + +/** + * @internal + * @brief Starts discovering of published remote devices on the local network. + * @since_tizen 6.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/internet + * @remarks + * @return @c 0 on success, + * otherwise a negative error value + * @retval #SOUND_MANAGER_ERROR_NONE Success + * @retval #SOUND_MANAGER_ERROR_NOT_SUPPORTED Not supported + * @retval #SOUND_MANAGER_ERROR_PERMISSION_DENIED Permission denied + * @retval #SOUND_MANAGER_ERROR_INVALID_OPERATION Invalid operation + * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system + * @see sound_manager_stop_discover_remote_device() + */ +int sound_manager_start_discover_remote_device(void); + +/** + * @internal + * @brief Stops discovering of published remote devices on the local network. + * @since_tizen 6.0 + * @privlevel public + * @privilege %http://tizen.org/privilege/internet + * @remark + * @return @c 0 on success, + * otherwise a negative error value + * @retval #SOUND_MANAGER_ERROR_NONE Success + * @retval #SOUND_MANAGER_ERROR_NOT_SUPPORTED Not supported + * @retval #SOUND_MANAGER_ERROR_PERMISSION_DENIED Permission denied + * @retval #SOUND_MANAGER_ERROR_INVALID_OPERATION Invalid operation + * @retval #SOUND_MANAGER_ERROR_INTERNAL Internal error inside the sound system + * @pre You should start discovering by sound_manager_start_discover_remote_device(). + * @see sound_manager_start_discover_remote_device() + */ +int sound_manager_stop_discover_remote_device(void); + /** * @} */ diff --git a/include/sound_manager_private.h b/include/sound_manager_private.h index f5f3b1c..40af984 100644 --- a/include/sound_manager_private.h +++ b/include/sound_manager_private.h @@ -356,6 +356,14 @@ int _create_virtual_stream(sound_stream_info_s *stream_info, virtual_sound_strea int _destroy_virtual_stream(virtual_sound_stream_info_s *virtual_stream); +int _discover_remote_device(bool enable); + +int _publish_local_device(sound_manager_remote_client_connected_cb callback, void *user_data); + +int _unpublish_local_device(void); + +int _set_remote_permission(int index, bool allowed); + int _start_virtual_stream(virtual_sound_stream_info_s *virtual_stream); int _stop_virtual_stream(virtual_sound_stream_info_s *virtual_stream); diff --git a/packaging/capi-media-sound-manager.spec b/packaging/capi-media-sound-manager.spec index c959b0f..764eecd 100644 --- a/packaging/capi-media-sound-manager.spec +++ b/packaging/capi-media-sound-manager.spec @@ -1,6 +1,6 @@ Name: capi-media-sound-manager Summary: Sound Manager library -Version: 0.6.26 +Version: 0.6.27 Release: 0 Group: Multimedia/API License: Apache-2.0 diff --git a/src/sound_manager_internal.c b/src/sound_manager_internal.c index dcc616c..ea65f07 100644 --- a/src/sound_manager_internal.c +++ b/src/sound_manager_internal.c @@ -866,3 +866,31 @@ int sound_manager_get_stream_preemptive_device(sound_stream_type_e stream_type, return _get_preemptive_device(stream_type, in_device_id, out_device_id); } + +int sound_manager_start_discover_remote_device(void) +{ + return _discover_remote_device(true); +} + +int sound_manager_stop_discover_remote_device(void) +{ + return _discover_remote_device(false); +} + +int sound_manager_publish_local_device(sound_manager_remote_client_connected_cb callback, void *user_data) +{ + SM_ARG_CHECK(callback); + + return _publish_local_device(callback, user_data); +} + +int sound_manager_unpublish_local_device(void) +{ + return _unpublish_local_device(); +} + +int sound_manager_set_remote_permission(int id, bool allowed) +{ + return _set_remote_permission(id, allowed); +} + diff --git a/src/sound_manager_private.c b/src/sound_manager_private.c index 9c3ad15..d333def 100644 --- a/src/sound_manager_private.c +++ b/src/sound_manager_private.c @@ -65,6 +65,11 @@ #define PA_STREAM_MANAGER_METHOD_NAME_ACTIVATE_DUCKING "ActivateDucking" #define PA_STREAM_MANAGER_METHOD_NAME_GET_DUCKING_STATE "GetDuckingState" #define PA_STREAM_MANAGER_METHOD_NAME_GET_LASTEST_STREAM_PID "GetPidOfLatestStream" +#define PA_STREAM_MANAGER_METHOD_NAME_PUBLISH_LOCAL_DEVICE "PublishLocalDevice" +#define PA_STREAM_MANAGER_METHOD_NAME_DISCOVER_REMOTE_DEVICE "DiscoverRemoteDevice" +#define PA_STREAM_MANAGER_METHOD_NAME_SET_REMOTE_PERMISSION "SetRemotePermission" + +#define PA_STREAM_MANAGER_SIGNAL_NAME_REMOTE_FOUND "RemoteFound" #define PA_DEVICE_MANAGER_OBJECT_PATH "/org/pulseaudio/DeviceManager" #define PA_DEVICE_MANAGER_INTERFACE "org.pulseaudio.DeviceManager" @@ -2243,6 +2248,212 @@ int _destroy_pa_connection_and_unregister_focus(sound_stream_info_s *stream_h) return ret; } +static int __dbus_method_call(const char *method, GVariant *param, GVariant **reply) +{ + GDBusConnection *conn = NULL; + GVariant *_reply = NULL; + GError *err = NULL; + int ret; + + if (!method || !param) { + LOGE("invalid parameter"); + ret = SOUND_MANAGER_ERROR_INVALID_PARAMETER; + goto error; + } + + if ((ret = __get_dbus_connection(&conn)) != SOUND_MANAGER_ERROR_NONE) { + ret = SOUND_MANAGER_ERROR_INVALID_OPERATION; + goto error; + } + + _reply = g_dbus_connection_call_sync(conn, PA_BUS_NAME, + PA_STREAM_MANAGER_OBJECT_PATH, + PA_STREAM_MANAGER_INTERFACE, + method, param, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err); + + g_object_unref(conn); + + if (!_reply) { + ret = _convert_dbus_error(err->message); + LOGE("g_dbus_connection_call_sync() method(%s), err-msg(%s)", method, err->message); + g_error_free(err); + return ret; + } + + if (reply) + *reply = _reply; + else + g_variant_unref(_reply); + + return SOUND_MANAGER_ERROR_NONE; + +error: + if (param) + g_variant_unref(param); + + return ret; +} + +// not thread-safe +static struct _publish_info { + GDBusConnection *conn; + guint subs_id; + struct _cb_info { + sound_manager_remote_client_connected_cb cb; + void *userdata; + } cb_info; +} publish_info; + +#define REMOTE_CLIENT_BIT_TYPE_MASK 0x80000000 +#define REMOTE_CLIENT_BIT_TYPE 31 + +static void __internal_cb(GDBusConnection *connection, const gchar *sender_name, + const gchar *object_path, const gchar *interface_name, + const gchar *signal_name,GVariant *params, gpointer userdata) +{ + struct _cb_info *cb_info = (struct _cb_info *)userdata; + + if (cb_info && cb_info->cb) { + gint32 type; + guint32 id; + gboolean is_connected; + gchar *name, *description; + + g_variant_get(params, "(iub&s&s)", &type, &id, &is_connected, &name, &description); + + LOGE("type(%d), id(%u), is_connected(%d), name(%s), description(%s)", + type, id, is_connected, name, description); + + /* MSB:input or output, others:index */ + id = id | (type << REMOTE_CLIENT_BIT_TYPE); + cb_info->cb(id, name, type, description, is_connected, cb_info->userdata); + } +} + +static int __subscribe_remote_devices(sound_manager_remote_client_connected_cb callback, void *userdata) +{ + int ret; + struct _cb_info *cb_info = &(publish_info.cb_info); + + if (publish_info.subs_id > 0) { + LOGE("already subscribed remote device"); + return SOUND_MANAGER_ERROR_INTERNAL; + } + + if ((ret = __get_dbus_connection(&publish_info.conn)) != SOUND_MANAGER_ERROR_NONE) + return ret; + + cb_info->cb = callback; + cb_info->userdata = userdata; + + publish_info.subs_id = g_dbus_connection_signal_subscribe(publish_info.conn, NULL, + PA_STREAM_MANAGER_INTERFACE, + PA_STREAM_MANAGER_SIGNAL_NAME_REMOTE_FOUND, + PA_STREAM_MANAGER_OBJECT_PATH, NULL, G_DBUS_SIGNAL_FLAGS_NONE, + __internal_cb, cb_info, NULL); + if (publish_info.subs_id == 0) { + g_object_unref(publish_info.conn); + LOGE("subscription failed"); + return SOUND_MANAGER_ERROR_INTERNAL; + } + + LOGI("subscribe remote devices. subs_id %d", publish_info.subs_id); + + return SOUND_MANAGER_ERROR_NONE; +} + +static int __unsubscribe_remote_devices(void) +{ + int ret; + + if (publish_info.subs_id == 0) { + LOGE("invalid subs_id(%d)", publish_info.subs_id); + return SOUND_MANAGER_ERROR_INTERNAL; + } + + if ((ret = __get_dbus_connection(&publish_info.conn)) != SOUND_MANAGER_ERROR_NONE) + return ret; + + g_dbus_connection_signal_unsubscribe(publish_info.conn, publish_info.subs_id); + + if (publish_info.conn) { + g_object_unref(publish_info.conn); + publish_info.conn = NULL; + } + + publish_info.subs_id = 0; + + LOGI("unsubscribe remote devices state subs_id %d", publish_info.subs_id); + + return SOUND_MANAGER_ERROR_NONE; +} + +int _publish_local_device(sound_manager_remote_client_connected_cb callback, void *user_data) +{ + int ret; + + LOGI("publish local device callback(%p), userdata(%p)", callback, user_data); + + ret = __subscribe_remote_devices(callback, user_data); + if (ret != SOUND_MANAGER_ERROR_NONE) { + LOGE("subscribe failed"); + return ret; + } + + ret = __dbus_method_call(PA_STREAM_MANAGER_METHOD_NAME_PUBLISH_LOCAL_DEVICE, g_variant_new("(b)", TRUE), NULL); + if (ret != SOUND_MANAGER_ERROR_NONE) { + if (__unsubscribe_remote_devices()) + LOGE("unsubscribe failed"); + + LOGE("publish local device failed"); + + return ret; + } + + return ret; +} + +int _unpublish_local_device(void) +{ + int ret; + + ret = __dbus_method_call(PA_STREAM_MANAGER_METHOD_NAME_PUBLISH_LOCAL_DEVICE, g_variant_new("(b)", FALSE), NULL); + if (ret != SOUND_MANAGER_ERROR_NONE) { + LOGE("unpublish local device failed"); + return ret; + } + + ret = __unsubscribe_remote_devices(); + if (ret != SOUND_MANAGER_ERROR_NONE) { + LOGE("unsubscribe failed"); + return ret; + } + + return ret; +} + +int _discover_remote_device(bool enable) +{ + return __dbus_method_call(PA_STREAM_MANAGER_METHOD_NAME_DISCOVER_REMOTE_DEVICE, + g_variant_new("(b)", (gboolean)enable), NULL); +} + +int _set_remote_permission(int id, bool allowed) +{ + int ret; + int index = (id << 1) >> 1; + char *type = id & REMOTE_CLIENT_BIT_TYPE_MASK ? "source-output" : "sink-input"; + + LOGI("id(%d), allowed(%d), index(%d), type(%s)", id, allowed, index, type); + + ret = __dbus_method_call(PA_STREAM_MANAGER_METHOD_NAME_SET_REMOTE_PERMISSION, + g_variant_new("(sub)", type, index, (gboolean)allowed), NULL); + if (ret != SOUND_MANAGER_ERROR_NONE) + LOGE("update proplist failed"); + + return ret; +} + static int __check_manual_route_type(sound_stream_info_s *stream_info) { SM_ARG_CHECK(stream_info); diff --git a/test/sound_manager_test.c b/test/sound_manager_test.c index e79ee4e..5abb753 100644 --- a/test/sound_manager_test.c +++ b/test/sound_manager_test.c @@ -117,6 +117,9 @@ enum { CURRENT_STATUS_ACTIVATE_DUCKING, CURRENT_STATUS_DEACTIVATE_DUCKING, CURRENT_STATUS_GET_DUCKING_STATE, + CURRENT_STATUS_DISCOVER_REMOTE_DEVICE, + CURRENT_STATUS_PUBLISH_REMOTE_DEVICE, + CURRENT_STATUS_SET_REMOTE_PERMISSION, }; @@ -385,6 +388,12 @@ void _interpret_main_menu(char *cmd) g_menu_state = CURRENT_STATUS_DEACTIVATE_DUCKING; else if (strncmp(cmd, "gds", MAX_CMD_LEN) == 0) g_menu_state = CURRENT_STATUS_GET_DUCKING_STATE; + else if (strncmp(cmd, "dis", MAX_CMD_LEN) == 0) + g_menu_state = CURRENT_STATUS_DISCOVER_REMOTE_DEVICE; + else if (strncmp(cmd, "pub", MAX_CMD_LEN) == 0) + g_menu_state = CURRENT_STATUS_PUBLISH_REMOTE_DEVICE; + else if (strncmp(cmd, "alw", MAX_CMD_LEN) == 0) + g_menu_state = CURRENT_STATUS_SET_REMOTE_PERMISSION; else if (strncmp(cmd, "q", MAX_CMD_LEN) == 0) { g_print("closing the test suite\n"); quit_program(); @@ -495,6 +504,9 @@ void display_sub_basic() #ifndef TIZEN_FEATURE_TV_PROD g_print("acm. *Set ACM Master mode\n"); #endif + g_print("dis. *Discover remote devices\n"); + g_print("pub. *Publish remote devices\n"); + g_print("alw. *Allow remote device\n"); g_print(" * is for internal usage.\n"); g_print("=========================================================================================\n"); } @@ -689,6 +701,12 @@ static void displaymenu() g_print("*** press enter to deactivate ducking\n"); else if (g_menu_state == CURRENT_STATUS_GET_DUCKING_STATE) g_print("*** press enter to get ducking state\n"); + else if (g_menu_state == CURRENT_STATUS_DISCOVER_REMOTE_DEVICE) + g_print("*** press enter 0:disable, 1:enable\n"); + else if (g_menu_state == CURRENT_STATUS_PUBLISH_REMOTE_DEVICE) + g_print("*** press enter 0:disable, 1:enable\n"); + else if (g_menu_state == CURRENT_STATUS_SET_REMOTE_PERMISSION) + g_print("*** press enter number num, allow(0,1)\n"); else { g_print("*** unknown status.\n"); quit_program(); @@ -767,7 +785,7 @@ void _volume_changed_cb_internal(sound_type_internal_e type, unsigned int volume /* If failed to get some property, just give some default value */ void _get_device_props_simple(sound_device_h device, int *id, const char **type, char **name, - const char **direc, const char **state, int *vendor_id, int *product_id, bool *is_running) + const char **direction, const char **state, int *vendor_id, int *product_id, bool *is_running) { int ret; sound_device_type_e _type; @@ -804,9 +822,9 @@ void _get_device_props_simple(sound_device_h device, int *id, const char **type, if ((ret = sound_manager_get_device_io_direction(device, &_direc))) { g_print("failed to get device io direction, ret[0x%x]\n", ret); - *direc = NOT_AVAIL; + *direction = NOT_AVAIL; } else { - *direc = g_device_direction_str[_direc]; + *direction = g_device_direction_str[_direc]; } if ((ret = sound_manager_get_device_state(device, &_state))) { @@ -830,23 +848,14 @@ void _device_connected_cb(sound_device_h device, bool is_connected, void *user_d int vendor_id = -1; int product_id = -1; char *name; - const char *type, *direc, *state; + const char *type, *direction, *state; bool is_running = false; - int ret; - sound_device_type_e device_type; - - _get_device_props_simple(device, &id, &type, &name, &direc, &state, &vendor_id, &product_id, &is_running); - g_print("[ Device #%d %s %s ] %s\n", id, type, name, is_connected ? "Connected" : "Disconnected"); - g_print(" Direc[ %-4s ] State[ %-12s ] Running[ %d ] VendorID[ %04x ], ProductID[ %04x ]\n", - direc, state, is_running, vendor_id, product_id); + _get_device_props_simple(device, &id, &type, &name, &direction, &state, &vendor_id, &product_id, &is_running); - - ret = sound_manager_get_current_media_playback_device_type(&device_type); - if (ret) - g_print("fail to sound_manager_get_current_media_playback_device_type, ret(0x%x)\n", ret); - else - g_print("current media playback device type is [%s]\n", g_device_type_str[device_type]); + g_print("\n[ Device #%d %20s %s ] %15s : ", id, type, name, is_connected ? "Connected" : "Disconnected"); + g_print(" Direction[ %-4s ] State[ %-12s ] Running[ %d ] VendorID[ %04x ], ProductID[ %04x ]\n", + direction, state, is_running, vendor_id, product_id); } void _device_running_changed_cb(sound_device_h device, bool is_running, void *user_data) @@ -855,14 +864,14 @@ void _device_running_changed_cb(sound_device_h device, bool is_running, void *us int vendor_id = -1; int product_id = -1; char *name; - const char *type, *direc, *state; + const char *type, *direction, *state; bool _is_running = false; - _get_device_props_simple(device, &id, &type, &name, &direc, &state, &vendor_id, &product_id, &_is_running); + _get_device_props_simple(device, &id, &type, &name, &direction, &state, &vendor_id, &product_id, &_is_running); - g_print("[Device #%d %s %s] running changed to [ %d ]\n", id, type, name, is_running); - g_print(" Direc[ %-4s ] State[ %-12s ] Running[ %d ] VendorID[ %04x ], ProductID[ %04x ]\n", - direc, state, _is_running, vendor_id, product_id); + g_print("\n[ Device #%d %20s %s ] running changed to [ %d ] : ", id, type, name, is_running); + g_print(" Direction[ %-4s ] State[ %-12s ] Running[ %d ] VendorID[ %04x ], ProductID[ %04x ]\n", + direction, state, _is_running, vendor_id, product_id); } void reset_menu_state(void) @@ -1138,7 +1147,7 @@ static void interpret(char *cmd) int product_id = -1; char *name; const char *type; - const char *direc; + const char *direction; const char *state; bool is_running; unsigned int num; @@ -1148,9 +1157,10 @@ static void interpret(char *cmd) if (!(ret = sound_manager_get_device_list(g_device_mask, &device_list))) { g_print("success to get current device list\n"); while (!sound_manager_get_next_device(device_list, &device)) { - _get_device_props_simple(device, &id, &type, &name, &direc, &state, &vendor_id, &product_id, &is_running); - g_print("[ Device #%d %s %s ]\n", id, type, name); - g_print(" Direc[ %-4s ] State[ %-12s ] Running[ %d ] VendorID[ %04x ] ProductID[ %04x ]\n", direc, state, is_running, vendor_id, product_id); + _get_device_props_simple(device, &id, &type, &name, &direction, &state, &vendor_id, &product_id, &is_running); + g_print("[ Device #%d %20s %s ] : ", id, type, name); + g_print(" Direction[ %-4s ] State[ %-12s ] Running[ %d ] VendorID[ %04x ] ProductID[ %04x ]\n", + direction, state, is_running, vendor_id, product_id); if (!(ret = sound_manager_get_supported_sample_formats(device, &formats, &num))) { while (num--) @@ -2755,6 +2765,61 @@ static void interpret(char *cmd) reset_menu_state(); break; } + case CURRENT_STATUS_DISCOVER_REMOTE_DEVICE: { + int ret; + int discover = atoi(cmd); + + if (discover) + ret = sound_manager_start_discover_remote_device(); + else + ret = sound_manager_stop_discover_remote_device(); + + if (!ret) + g_print("success to discover devices\n"); + else + g_print("fail to discover devices\n"); + + reset_menu_state(); + break; + } + case CURRENT_STATUS_PUBLISH_REMOTE_DEVICE: { + int ret = SOUND_MANAGER_ERROR_NONE; + int publish = atoi(cmd); + + void remote_client_connected_cb(int id, const char *name, bool is_recording, const char *description, bool is_connected, void *user_data) { + g_print("\nid %u, name %s, is_recording %d, description %s, connected %d\n", + id, name, is_recording, description, is_connected); + } + + if (publish) + ret = sound_manager_publish_local_device(remote_client_connected_cb, NULL); + else + ret = sound_manager_unpublish_local_device(); + + if (!ret) + g_print("success to publish devices\n"); + else + g_print("fail to publish devices\n"); + + reset_menu_state(); + break; + } + case CURRENT_STATUS_SET_REMOTE_PERMISSION: { + int ret; + unsigned int id; + int allow; + + ret = sscanf(cmd, "%u %d", &id, &allow); + + ret = sound_manager_set_remote_permission(id, !!allow); + if (!ret) + g_print("allow id %u, allow %d\n", id, allow); + else + g_print("sound_manager_set_allow_remote_device failed\n"); + + reset_menu_state(); + break; + } } end: g_timeout_add(100, timeout_menu_display, 0);