4 * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Nilesh Trimbake <t.shripati@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
32 #include "bt-hal-a2dp-sink-dbus-handler.h"
33 #include "bt-hal-dbus-common-utils.h"
34 #include "bt-hal-internal.h"
37 static handle_stack_msg event_cb = NULL;
39 /* To send stack event to hal-a2dp-sink handler */
40 void _bt_hal_register_a2dp_sink_dbus_handler_cb(handle_stack_msg cb)
45 /* To send stack event to hal-a2dp-sink handler */
46 void _bt_hal_unregister_a2dp_sink_dbus_handler_cb()
51 static void __bt_a2dp_sink_connect_cb(GDBusProxy *proxy, GAsyncResult *res,
54 GError *g_error = NULL;
55 struct hal_ev_a2dp_conn_state ev;
56 GVariant *reply = NULL;
57 char *address = user_data;
58 int result = BT_STATUS_SUCCESS;
62 reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
63 g_object_unref(proxy);
65 ERR("A2DP Source Connect Dbus Call Error");
67 ERR("Error: %s\n", g_error->message);
68 g_clear_error(&g_error);
70 result = BT_STATUS_FAIL;
72 g_variant_unref(reply);
74 DBG("Address: %s", address);
76 * If result is success, Send connecting event
78 if (result == BT_STATUS_SUCCESS) {
79 /* Prepare to send A2DP Source connecting event */
80 memset(&ev, 0, sizeof(ev));
81 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
82 ev.state = HAL_EV_A2DP_STATE_CONNECTING;
84 ERR("A2DP SINK DBUS handler callback not registered");
86 event_cb(HAL_EV_A2DP_SOURCE_CONN_STATE, (void *)&ev, sizeof(ev));
88 /* Prepare to send A2DP Source disconnected event */
89 memset(&ev, 0, sizeof(ev));
90 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
91 ev.state = HAL_EV_A2DP_STATE_DISCONNECTED;
93 ERR("A2DP SINK DBUS handler callback not registered");
95 event_cb(HAL_EV_A2DP_SOURCE_CONN_STATE, (void *)&ev, sizeof(ev));
100 bt_status_t _bt_hal_dbus_handler_a2dp_sink_connect(bt_bdaddr_t *bd_addr)
103 GDBusConnection *conn;
108 ERR("bd_addr is NULL, return");
109 return BT_STATUS_PARM_INVALID;
112 conn = _bt_hal_get_system_gconn();
114 ERR("_bt_hal_get_system_gconn returned NULL, return");
115 return BT_STATUS_FAIL;
118 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE * sizeof(char));
120 ERR("Memory allocation failed");
121 return BT_STATUS_NOMEM;
123 _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
125 ret = _bt_hal_connect_profile(address, A2DP_SOURCE_UUID,
126 __bt_a2dp_sink_connect_cb, address);
128 if (ret != BT_HAL_ERROR_NONE) {
129 ERR("_bt_hal_connect_profile(A2DP source) Error");
130 return BT_STATUS_FAIL;
133 return BT_STATUS_SUCCESS;
136 static void __bt_a2dp_source_disconnect_cb(GDBusProxy *proxy, GAsyncResult *res,
139 GError *g_error = NULL;
140 struct hal_ev_a2dp_conn_state ev;
141 GVariant *reply = NULL;
142 char *address = user_data;
143 int result = BT_STATUS_SUCCESS;
147 reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
148 g_object_unref(proxy);
150 ERR("A2DP Source Disconnect Dbus Call Error");
152 ERR("Error: %s\n", g_error->message);
153 g_clear_error(&g_error);
155 result = BT_STATUS_FAIL;
157 g_variant_unref(reply);
159 if (result != BT_STATUS_FAIL)
160 DBG("A2DP Source Disconnect successful for Device: %s", address);
162 DBG("A2DP Source Disconnect un-successful for Device: %s", address);
163 if (result == BT_STATUS_FAIL) {
164 /* Prepare to send AV source disconnected state event */
165 memset(&ev, 0, sizeof(ev));
166 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
167 ev.state = HAL_EV_A2DP_STATE_DISCONNECTED;
169 ERR("A2DP SINK DBUS handler callback not registered");
171 event_cb(HAL_EV_A2DP_SOURCE_CONN_STATE, (void *)&ev, sizeof(ev));
173 /* Prepare to send AV source disconnecting state event */
174 memset(&ev, 0, sizeof(ev));
175 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
176 ev.state = HAL_EV_A2DP_STATE_DISCONNECTING;
178 ERR("A2DP SINK DBUS handler callback not registered");
180 event_cb(HAL_EV_A2DP_SOURCE_CONN_STATE, (void *)&ev, sizeof(ev));
186 bt_status_t _bt_hal_dbus_handler_a2dp_sink_disconnect(bt_bdaddr_t *bd_addr)
189 GDBusConnection *conn;
194 ERR("bd_addr is NULL, return");
195 return BT_STATUS_PARM_INVALID;
198 conn = _bt_hal_get_system_gconn();
200 ERR("_bt_hal_get_system_gconn returned NULL, return");
201 return BT_STATUS_FAIL;
204 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE * sizeof(char));
206 ERR("Memory allocation failed");
207 return BT_STATUS_NOMEM;
209 _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
211 ret = _bt_hal_disconnect_profile(address, A2DP_SOURCE_UUID,
212 __bt_a2dp_source_disconnect_cb, address);
214 if (ret != BT_HAL_ERROR_NONE) {
215 ERR("_bt_hal_connect_profile(AV) Error");
216 return BT_STATUS_FAIL;
219 return BT_STATUS_SUCCESS;
222 bt_status_t _bt_hal_dbus_handler_enable_a2dp_sink(void)
226 GError *error = NULL;
228 GDBusConnection *gconn;
232 if (_bt_hal_is_service_enabled(A2DP_SINK_UUID)) {
233 ERR("Audio sink role already enabled, return");
234 return BT_STATUS_SUCCESS;
237 gconn = _bt_hal_get_system_gconn();
239 ERR("_bt_hal_get_system_gconn returned NULL, return");
240 return BT_STATUS_FAIL;
243 adapter_path = _bt_hal_get_adapter_path();
245 ERR("adapter_path is NULL");
246 return BT_STATUS_FAIL;
249 proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE, NULL,
250 BT_HAL_BLUEZ_NAME, adapter_path, BT_HAL_MEDIA_INTERFACE, NULL, &error);
251 g_free(adapter_path);
253 ERR("Unable to create proxy");
256 ERR("Error: %s", error->message);
257 g_clear_error(&error);
259 return BT_STATUS_FAIL;
262 ret = g_dbus_proxy_call_sync(proxy, "SelectRole", g_variant_new("(s)", "sink"),
263 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
264 g_object_unref(proxy);
266 ERR("Call SelectRole Failed");
268 ERR("errCode[%x], message[%s]", error->code, error->message);
269 g_clear_error(&error);
271 return BT_STATUS_FAIL;
274 g_variant_unref(ret);
276 return BT_STATUS_SUCCESS;