3 * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
5 * Contact: Nilesh Trimbake <t.shripati@samsung.com>
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
31 #include "bt-hal-avrcp-ctrl-dbus-handler.h"
32 #include "bt-hal-dbus-common-utils.h"
33 #include "bt-hal-internal.h"
35 static bt_player_settinngs_t repeat_status[] = {
36 { REPEAT_MODE_OFF, "off" },
37 { REPEAT_SINGLE_TRACK, "singletrack" },
38 { REPEAT_ALL_TRACK, "alltracks" },
39 { REPEAT_GROUP, "group" },
40 { REPEAT_INVALID, "" }
43 static bt_player_settinngs_t equalizer_status[] = {
44 { EQUALIZER_OFF, "off" },
45 { EQUALIZER_ON, "on" },
46 { EQUALIZER_INVALID, "" },
49 static bt_player_settinngs_t scan_status[] = {
50 { SCAN_MODE_OFF, "off" },
51 { SCAN_ALL_TRACK, "alltracks" },
52 { SCAN_GROUP, "group" },
56 static bt_player_settinngs_t shuffle_settings[] = {
57 { SHUFFLE_MODE_OFF, "off" },
58 { SHUFFLE_ALL_TRACK, "alltracks" },
59 { SHUFFLE_GROUP, "group" },
60 { SHUFFLE_INVALID, "" }
63 static handle_stack_msg event_cb = NULL;
65 /* To send stack event to hal-avrcp-ctrl handler */
66 void _bt_hal_register_avrcp_ctrl_dbus_handler_cb(handle_stack_msg cb)
71 /* To send stack event to hal-avrcp-ctrl handler */
72 void _bt_hal_unregister_avrcp_ctrl_dbus_handler_cb()
77 static void __bt_avrcp_target_connect_cb(GDBusProxy *proxy, GAsyncResult *res,
80 struct hal_ev_avrcp_ctrl_conn_state ev;
81 char *address = user_data;
82 int result = BT_STATUS_SUCCESS;
83 GVariant *reply = NULL;
84 GError *g_error = NULL;
88 reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
89 g_object_unref(proxy);
91 ERR("AVRCP Target Connect Dbus Call Error");
93 ERR("Error: %s\n", g_error->message);
94 g_clear_error(&g_error);
96 result = BT_STATUS_FAIL;
98 g_variant_unref(reply);
100 DBG("Address: %s", address);
102 * If result is success, Remote device connected event will be triggered
103 * automatically from stack, so return from here.
105 if (result == BT_STATUS_SUCCESS)
108 /* Prepare to send AVRCP Target connection state event */
109 memset(&ev, 0, sizeof(ev));
110 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
111 ev.state = HAL_AVRCP_CTRL_STATE_DISCONNECTED;
113 ERR("AVRCP CTRL DBUS handler callback not registered");
115 event_cb(HAL_EV_AVRCP_CTRL_CONN_STATE, (void *)&ev, sizeof(ev));
121 bt_status_t _bt_hal_dbus_handler_avrcp_ctrl_connect(bt_bdaddr_t *bd_addr)
125 GDBusConnection *conn;
128 ERR("bd_addr is NULL, return");
129 return BT_STATUS_PARM_INVALID;
132 conn = _bt_hal_get_system_gconn();
134 ERR("_bt_hal_get_system_gconn returned NULL, return");
135 return BT_STATUS_FAIL;
138 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE * sizeof(char));
140 ERR("Memory allocation failed");
141 return BT_STATUS_NOMEM;
143 _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
145 ret = _bt_hal_connect_profile(address, AVRCP_TARGET_UUID,
146 __bt_avrcp_target_connect_cb, address);
148 if (ret != BT_HAL_ERROR_NONE) {
149 ERR("_bt_hal_connect_profile(AVRCP Target) Error");
151 return BT_STATUS_FAIL;
154 return BT_STATUS_SUCCESS;
157 static void __bt_avrcp_target_disconnect_cb(GDBusProxy *proxy, GAsyncResult *res,
160 struct hal_ev_avrcp_ctrl_conn_state ev;
161 char *address = user_data;
162 int result = BT_STATUS_SUCCESS;
163 GError *g_error = NULL;
164 GVariant *reply = NULL;
168 reply = g_dbus_proxy_call_finish(proxy, res, &g_error);
169 g_object_unref(proxy);
171 ERR("AVRCP Target Disconnect Dbus Call Error");
173 ERR("Error: %s\n", g_error->message);
174 g_clear_error(&g_error);
176 result = BT_STATUS_FAIL;
178 g_variant_unref(reply);
180 if (result != BT_STATUS_FAIL) {
181 DBG("AVRCP Target Disconnect successful for Device: %s", address);
185 DBG("AVRCP Target Disconnect un-successful for Device: %s", address);
189 * Prepare to send AVRCP Target connection state event indicating
190 * disconnection failed.
192 memset(&ev, 0, sizeof(ev));
193 _bt_hal_convert_addr_string_to_type(ev.bdaddr, address);
194 ev.state = HAL_AVRCP_CTRL_STATE_CONNECTED;
196 ERR("AVRCP Target DBUS handler callback not registered");
198 event_cb(HAL_EV_AVRCP_CTRL_CONN_STATE, (void *)&ev, sizeof(ev));
203 bt_status_t _bt_hal_dbus_handler_avrcp_ctrl_disconnect(bt_bdaddr_t *bd_addr)
207 GDBusConnection *conn;
210 ERR("bd_addr is NULL, return");
211 return BT_STATUS_PARM_INVALID;
214 conn = _bt_hal_get_system_gconn();
216 ERR("_bt_hal_get_system_gconn returned NULL, return");
217 return BT_STATUS_FAIL;
220 address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE * sizeof(char));
222 ERR("Memory allocation failed");
223 return BT_STATUS_NOMEM;
225 _bt_hal_convert_addr_type_to_string(address, bd_addr->address);
227 ret = _bt_hal_disconnect_profile(address, AVRCP_TARGET_UUID,
228 __bt_avrcp_target_disconnect_cb, address);
230 if (ret != BT_HAL_ERROR_NONE) {
231 ERR("_bt_hal_connect_profile(AVRCP Target) Error");
233 return BT_STATUS_FAIL;
236 return BT_STATUS_SUCCESS;
239 static int __bt_media_send_control_msg(bt_bdaddr_t *bd_addr, const char *name)
241 GVariant *reply = NULL;
243 GDBusProxy *proxy = NULL;
246 ERR("Command is NULL");
247 return BT_STATUS_FAIL;
249 DBG("Command [%s]", name);
250 proxy = _bt_hal_get_avrcp_ctrl_proxy(bd_addr);
252 ERR("Unable to allocate new proxy \n");
254 ERR("%s", err->message);
257 return BT_STATUS_FAIL;
259 reply = g_dbus_proxy_call_sync(proxy, name, NULL,
260 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
263 ERR("Error returned in method call");
265 ERR("%s", err->message);
268 return BT_STATUS_FAIL;
270 g_variant_unref(reply);
272 return BT_STATUS_SUCCESS;
275 bt_status_t _bt_hal_dbus_handler_avrcp_ctrl_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code, uint8_t key_state)
281 ret = __bt_media_send_control_msg(bd_addr, "Play");
285 ret = __bt_media_send_control_msg(bd_addr, "Pause");
289 ret = __bt_media_send_control_msg(bd_addr, "Stop");
293 ret = __bt_media_send_control_msg(bd_addr, "Next");
297 ret = __bt_media_send_control_msg(bd_addr, "Previous");
300 case PRESS_FAST_FORWARD: {
301 ret = __bt_media_send_control_msg(bd_addr, "PressFastForward");
304 case RELEASE_FAST_FORWARD: {
305 ret = __bt_media_send_control_msg(bd_addr, "ReleaseFastForward");
309 ret = __bt_media_send_control_msg(bd_addr, "PressRewind");
312 case RELEASE_REWIND: {
313 ret = __bt_media_send_control_msg(bd_addr, "ReleaseRewind");
317 ret = __bt_media_send_control_msg(bd_addr, "VolumeUp");
321 ret = __bt_media_send_control_msg(bd_addr, "VolumeDown");
325 DBG("Invalid Type\n");
326 return BT_STATUS_FAIL;
332 static const char *__bt_media_type_to_str(int type)
335 case BTRC_PLAYER_ATTR_EQUALIZER:
337 case BTRC_PLAYER_ATTR_REPEAT:
339 case BTRC_PLAYER_ATTR_SHUFFLE:
341 case BTRC_PLAYER_ATTR_SCAN:
351 static const char *__bt_transport_type_to_str(int type)
354 case BTRC_TRANSPORT_ATTR_DELAY:
356 case BTRC_TRANSPORT_ATTR_VOLUME:
366 bt_status_t _bt_hal_dbus_handler_avrcp_ctrl_set_property(bt_bdaddr_t *bd_addr, uint8_t type, uint8_t value)
368 GVariant *reply, *param = NULL;
370 GDBusProxy *proxy = NULL;
374 case BTRC_PLAYER_ATTR_EQUALIZER:
375 param = g_variant_new("s", equalizer_status[value].property);
376 INFO("equalizer_status %s", equalizer_status[value].property);
378 case BTRC_PLAYER_ATTR_REPEAT:
379 param = g_variant_new("s", repeat_status[value].property);
380 INFO("repeat_status %s", repeat_status[value].property);
382 case BTRC_PLAYER_ATTR_SHUFFLE:
383 param = g_variant_new("s", shuffle_settings[value].property);
384 INFO("shuffle_settings %s", shuffle_settings[value].property);
386 case BTRC_PLAYER_ATTR_SCAN:
387 param = g_variant_new("s", scan_status[value].property);
388 INFO("scan_status %s", scan_status[value].property);
391 ERR("Invalid property type: %d", type);
392 return BT_STATUS_FAIL;
395 proxy = _bt_hal_get_avrcp_ctrl_properties_proxy(bd_addr);
397 ERR("Unable to allocate new proxy \n");
399 ERR("%s", err->message);
402 return BT_STATUS_FAIL;
405 reply = g_dbus_proxy_call_sync(proxy,
406 "Set", g_variant_new("(ssv)",
407 BT_HAL_PLAYER_CONTROL_INTERFACE,
408 __bt_media_type_to_str(type), param),
409 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
410 g_object_unref(proxy);
412 ERR("Can't get managed objects");
414 ERR("SetProperty Fail: %s", err->message);
416 return BT_STATUS_FAIL;
420 g_variant_unref(reply);
422 return BT_STATUS_SUCCESS;
425 bt_status_t _bt_hal_dbus_handler_avrcp_transport_set_property(bt_bdaddr_t *bd_addr, int type, unsigned int value)
427 GVariant *reply, *param = NULL;
429 GDBusProxy *proxy = NULL;
430 uint16_t property_level = (uint16_t)value;
434 case BTRC_TRANSPORT_ATTR_DELAY:
435 param = g_variant_new("q", property_level);
436 INFO("delay level %d", property_level);
438 case BTRC_TRANSPORT_ATTR_VOLUME:
439 param = g_variant_new("q", property_level);
440 INFO("volume level %d", property_level);
443 ERR("Invalid property type: %d", type);
444 return BT_STATUS_FAIL;
447 proxy = _bt_hal_get_avrcp_transport_properties_proxy(bd_addr);
449 ERR("Unable to allocate new proxy \n");
451 ERR("%s", err->message);
454 return BT_STATUS_FAIL;
457 reply = g_dbus_proxy_call_sync(proxy,
458 "Set", g_variant_new("(ssv)",
459 BT_HAL_MEDIATRANSPORT_INTERFACE,
460 __bt_media_type_to_str(type), param),
461 G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
462 g_object_unref(proxy);
464 ERR("Can't get managed objects");
466 ERR("SetProperty Fail: %s", err->message);
468 return BT_STATUS_FAIL;
472 g_variant_unref(reply);
474 return BT_STATUS_SUCCESS;