4 * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Anupam Roy <anupam.r@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-av-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-av handler */
40 void _bt_hal_register_av_dbus_handler_cb(handle_stack_msg cb)
45 /* To send stack event to hal-av handler */
46 void _bt_hal_unregister_av_dbus_handler_cb()
51 static void __bt_av_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 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, AV Connecting event will be triggered
79 if (result == BT_STATUS_SUCCESS) {
80 /* Prepare to send AV connecting event */
81 memset(&ev, 0, sizeof(ev));
82 ev.state = HAL_EV_A2DP_STATE_CONNECTING;
83 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
85 ERR("A2DP dbus handler callback not registered");
87 event_cb(HAL_EV_A2DP_CONN_STATE, (void *)&ev, sizeof(ev));
89 /* Prepare to send AV disconnected event */
90 memset(&ev, 0, sizeof(ev));
91 ev.state = HAL_EV_A2DP_STATE_DISCONNECTED;
92 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
94 ERR("HF DBUS handler callback not registered");
96 event_cb(HAL_EV_A2DP_CONN_STATE, (void *)&ev, sizeof(ev));
102 bt_status_t _bt_hal_dbus_handler_av_connect(bt_bdaddr_t *bd_addr)
105 GDBusConnection *conn;
109 ERR("bd_addr is NULL, return");
110 return BT_STATUS_PARM_INVALID;
113 conn = _bt_hal_get_system_gconn();
115 ERR("_bt_hal_get_system_gconn returned NULL, return");
116 return BT_STATUS_FAIL;
119 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE * sizeof(char));
121 ERR("Memory allocation failed");
122 return BT_STATUS_NOMEM;
124 _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
126 ret = _bt_hal_connect_profile(address, A2DP_SINK_UUID,
127 __bt_av_connect_cb, address);
129 if (ret != BT_HAL_ERROR_NONE) {
130 ERR("_bt_hal_connect_profile(A2DP) Error");
132 return BT_STATUS_FAIL;
134 return BT_STATUS_SUCCESS;
137 static void __bt_av_disconnect_cb(GDBusProxy *proxy, GAsyncResult *res,
140 GError *g_error = NULL;
141 struct hal_ev_a2dp_conn_state ev;
142 GVariant *reply = NULL;
143 char *address = user_data;
144 int result = BT_STATUS_SUCCESS;
148 reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
149 g_object_unref(proxy);
151 ERR("A2DP Disconnect Dbus Call Error");
153 ERR("Error: %s\n", g_error->message);
154 g_clear_error(&g_error);
156 result = BT_STATUS_FAIL;
158 g_variant_unref(reply);
160 if (result != BT_STATUS_FAIL)
161 DBG("A2DP Disconnect successful for Device: %s", address);
163 DBG("A2DP Disconnect un-successful for Device: %s", address);
165 if (result == BT_STATUS_FAIL) {
166 /* Prepare to send AV Disconnected event */
167 memset(&ev, 0, sizeof(ev));
168 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
169 ev.state = HAL_EV_A2DP_STATE_DISCONNECTED;
171 ERR("HF DBUS handler callback not registered");
173 event_cb(HAL_EV_A2DP_CONN_STATE, (void *)&ev, sizeof(ev));
175 /* Prepare to send AV Disconnecting event */
176 memset(&ev, 0, sizeof(ev));
177 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
178 ev.state = HAL_EV_A2DP_STATE_DISCONNECTING;
180 ERR("HF DBUS handler callback not registered");
182 event_cb(HAL_EV_A2DP_CONN_STATE, (void *)&ev, sizeof(ev));
188 bt_status_t _bt_hal_dbus_handler_av_disconnect(bt_bdaddr_t *bd_addr)
191 GDBusConnection *conn;
195 ERR("bd_addr is NULL, return");
196 return BT_STATUS_PARM_INVALID;
199 conn = _bt_hal_get_system_gconn();
201 ERR("_bt_hal_get_system_gconn returned NULL, return");
202 return BT_STATUS_FAIL;
205 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE * sizeof(char));
207 ERR("Memory allocation failed");
208 return BT_STATUS_NOMEM;
210 _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
212 ret = _bt_hal_disconnect_profile(address, A2DP_SINK_UUID,
213 __bt_av_disconnect_cb, address);
215 if (ret != BT_HAL_ERROR_NONE) {
216 ERR("_bt_hal_connect_profile(AV) Error");
217 return BT_STATUS_FAIL;
220 return BT_STATUS_SUCCESS;
223 bt_status_t _bt_hal_dbus_handler_enable_a2dp_source(void)
227 GError *error = NULL;
229 GDBusConnection *gconn;
233 if (_bt_hal_is_service_enabled(A2DP_SOURCE_UUID)) {
234 ERR("Audio sink role already enabled, return");
235 return BT_STATUS_SUCCESS;
238 gconn = _bt_hal_get_system_gconn();
240 ERR("_bt_hal_get_system_gconn returned NULL, return");
241 return BT_STATUS_FAIL;
244 adapter_path = _bt_hal_get_adapter_path();
246 ERR("adapter_path is NULL");
247 return BT_STATUS_FAIL;
250 proxy = g_dbus_proxy_new_sync(gconn, G_DBUS_PROXY_FLAGS_NONE, NULL,
251 BT_HAL_BLUEZ_NAME, adapter_path, BT_HAL_MEDIA_INTERFACE, NULL, &error);
252 g_free(adapter_path);
254 ERR("Unable to create proxy");
257 ERR("Error: %s", error->message);
258 g_clear_error(&error);
260 return BT_STATUS_FAIL;
263 ret = g_dbus_proxy_call_sync(proxy, "SelectRole", g_variant_new("(s)", "source"),
264 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
265 g_object_unref(proxy);
267 ERR("Call SelectRole Failed");
269 ERR("errCode[%x], message[%s]", error->code, error->message);
270 g_clear_error(&error);
272 return BT_STATUS_FAIL;
275 g_variant_unref(ret);
277 return BT_STATUS_SUCCESS;