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");
131 return BT_STATUS_FAIL;
133 return BT_STATUS_SUCCESS;
136 static void __bt_av_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 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 Disconnect successful for Device: %s", address);
162 DBG("A2DP Disconnect un-successful for Device: %s", address);
164 if (result == BT_STATUS_FAIL) {
165 /* Prepare to send AV Disconnected event */
166 memset(&ev, 0, sizeof(ev));
167 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
168 ev.state = HAL_EV_A2DP_STATE_DISCONNECTED;
170 ERR("HF DBUS handler callback not registered");
172 event_cb(HAL_EV_A2DP_CONN_STATE, (void *)&ev, sizeof(ev));
174 /* Prepare to send AV Disconnecting event */
175 memset(&ev, 0, sizeof(ev));
176 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
177 ev.state = HAL_EV_A2DP_STATE_DISCONNECTING;
179 ERR("HF DBUS handler callback not registered");
181 event_cb(HAL_EV_A2DP_CONN_STATE, (void *)&ev, sizeof(ev));
187 bt_status_t _bt_hal_dbus_handler_av_disconnect(bt_bdaddr_t *bd_addr)
190 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_SINK_UUID,
212 __bt_av_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_source(void)
226 GError *error = NULL;
228 GDBusConnection *gconn;
232 if (_bt_hal_is_service_enabled(A2DP_SOURCE_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)", "source"),
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;