4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Atul Kumar Rai <a.rai@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.
29 #include "bt-hal-log.h"
30 #include "bt-hal-msg.h"
31 #include "bt-hal-utils.h"
33 #include "bt-hal-event-receiver.h"
34 #include "bt-hal-avrcp-tg-dbus-handler.h"
36 static const btrc_callbacks_t *bt_hal_avrcp_tg_cbacks;
38 static bool interface_ready(void)
40 return bt_hal_avrcp_tg_cbacks != NULL;
43 bt_status_t get_play_status_rsp(bt_bdaddr_t *bd_addr, btrc_play_status_t play_status,
44 uint32_t song_len, uint32_t song_pos)
46 return BT_STATUS_UNSUPPORTED;
49 bt_status_t list_player_app_attr_rsp(bt_bdaddr_t *bd_addr, int num_attr,
50 btrc_player_attr_t *p_attrs)
52 return BT_STATUS_UNSUPPORTED;
55 bt_status_t list_player_app_value_rsp(bt_bdaddr_t *bd_addr, int num_val, uint8_t *p_vals)
57 return BT_STATUS_UNSUPPORTED;
60 bt_status_t get_player_app_value_rsp(bt_bdaddr_t *bd_addr, btrc_player_settings_t *p_vals)
62 return BT_STATUS_UNSUPPORTED;
65 bt_status_t get_player_app_attr_text_rsp(bt_bdaddr_t *bd_addr, int num_attr,
66 btrc_player_setting_text_t *p_attrs)
68 return BT_STATUS_UNSUPPORTED;
71 bt_status_t get_player_app_value_text_rsp(bt_bdaddr_t *bd_addr, int num_val,
72 btrc_player_setting_text_t *p_vals)
74 return BT_STATUS_UNSUPPORTED;
77 bt_status_t get_element_attr_rsp(bt_bdaddr_t *bd_addr, uint8_t num_attr,
78 btrc_element_attr_val_t *p_attrs)
80 if (num_attr > 0 && !p_attrs)
81 return BT_STATUS_PARM_INVALID;
83 return _bt_hal_dbus_handler_avrcp_tg_set_track_info(num_attr, p_attrs);
86 bt_status_t set_player_app_value_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status)
88 return BT_STATUS_UNSUPPORTED;
91 gboolean __fetch_track_info(gpointer data)
93 if (bt_hal_avrcp_tg_cbacks->get_element_attr_cb) {
95 btrc_media_attr_t attrs[] = {
96 BTRC_MEDIA_ATTR_TITLE, BTRC_MEDIA_ATTR_ARTIST,
97 BTRC_MEDIA_ATTR_ALBUM, BTRC_MEDIA_ATTR_TRACK_NUM,
98 BTRC_MEDIA_ATTR_NUM_TRACKS, BTRC_MEDIA_ATTR_GENRE,
99 BTRC_MEDIA_ATTR_PLAYING_TIME};
101 num_attr = sizeof(attrs) / sizeof(btrc_media_attr_t);
103 bt_hal_avrcp_tg_cbacks->get_element_attr_cb(num_attr, attrs, NULL);
109 bt_status_t register_notification_rsp(btrc_event_id_t event_id,
110 btrc_notification_type_t type,
111 btrc_register_notification_t *p_param)
113 if (BTRC_NOTIFICATION_TYPE_INTERIM == type)
114 return BT_STATUS_SUCCESS;
117 case BTRC_EVT_PLAY_STATUS_CHANGED:
118 _bt_hal_dbus_handler_avrcp_tg_play_status_changed(p_param->play_status);
120 case BTRC_EVT_TRACK_CHANGE:
121 g_idle_add(__fetch_track_info, NULL);
123 case BTRC_EVT_PLAY_POS_CHANGED:
124 _bt_hal_dbus_handler_avrcp_tg_play_pos_changed(p_param->song_pos);
126 case BTRC_EVT_APP_SETTINGS_CHANGED:
127 _bt_hal_dbus_handler_avrcp_tg_app_setting_changed(&(p_param->player_setting));
130 ERR("Unknown event Id: %d", event_id);
133 return BT_STATUS_SUCCESS;
136 bt_status_t set_volume(uint8_t volume)
138 return BT_STATUS_UNSUPPORTED;
141 bt_status_t set_addressed_player_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status)
143 return BT_STATUS_UNSUPPORTED;
146 bt_status_t set_browsed_player_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status,
147 uint32_t num_items, uint16_t charset_id, uint8_t folder_depth,
148 btrc_br_folder_name_t *p_folders)
150 return BT_STATUS_UNSUPPORTED;
153 bt_status_t get_folder_items_list_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status,
154 uint16_t uid_counter, uint8_t num_items, btrc_folder_items_t *p_items)
156 return BT_STATUS_UNSUPPORTED;
159 bt_status_t change_path_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status,
162 return BT_STATUS_UNSUPPORTED;
165 bt_status_t get_item_attr_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status,
166 uint8_t num_attr, btrc_element_attr_val_t *p_attrs)
168 return BT_STATUS_UNSUPPORTED;
171 bt_status_t play_item_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status)
173 return BT_STATUS_UNSUPPORTED;
176 bt_status_t get_total_num_of_items_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status,
177 uint32_t uid_counter, uint32_t num_items)
179 return BT_STATUS_UNSUPPORTED;
182 bt_status_t search_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status, uint32_t uid_counter,
185 return BT_STATUS_UNSUPPORTED;
188 bt_status_t add_to_now_playing_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status)
190 return BT_STATUS_UNSUPPORTED;
193 static gboolean __bt_avrcp_register_notifications(gpointer user_data)
195 bt_bdaddr_t *bdaddr = user_data;
197 if (!bt_hal_avrcp_tg_cbacks->register_notification_cb)
200 bt_hal_avrcp_tg_cbacks->register_notification_cb(BTRC_EVT_PLAY_STATUS_CHANGED, 0, bdaddr);
201 bt_hal_avrcp_tg_cbacks->register_notification_cb(BTRC_EVT_TRACK_CHANGE, 0, bdaddr);
202 bt_hal_avrcp_tg_cbacks->register_notification_cb(BTRC_EVT_PLAY_POS_CHANGED, 1, bdaddr);
203 bt_hal_avrcp_tg_cbacks->register_notification_cb(BTRC_EVT_APP_SETTINGS_CHANGED, 0, bdaddr);
208 static void __handle_player_property(void *buf, uint16_t len)
210 btrc_player_settings_t player_setting;
211 struct hal_ev_avrcp_tg_player_property *ev = buf;
213 if (!bt_hal_avrcp_tg_cbacks->set_player_app_value_cb)
216 memset(&player_setting, 0, sizeof(btrc_player_settings_t));
217 player_setting.num_attr = 1;
219 switch (ev->prop_type) {
220 case HAL_AVRCP_TG_PLAYER_PROP_REPEAT:
221 player_setting.attr_ids[0] = BTRC_PLAYER_ATTR_REPEAT;
222 player_setting.attr_values[0] = ev->value;
224 case HAL_AVRCP_TG_PLAYER_PROP_SHUFFLE:
225 player_setting.attr_ids[0] = BTRC_PLAYER_ATTR_SHUFFLE;
226 player_setting.attr_values[0] = ev->value;
228 case HAL_AVRCP_TG_PLAYER_PROP_SCAN:
229 player_setting.attr_ids[0] = BTRC_PLAYER_ATTR_SCAN;
230 player_setting.attr_values[0] = ev->value;
232 case HAL_AVRCP_TG_PLAYER_PROP_EQUALIZER:
233 player_setting.attr_ids[0] = BTRC_PLAYER_ATTR_EQUALIZER;
234 player_setting.attr_values[0] = ev->value;
237 INFO("Player property not handled: %d", ev->prop_type);
241 bt_hal_avrcp_tg_cbacks->set_player_app_value_cb(&player_setting, NULL);
244 static void __bt_hal_handle_avrcp_tg_events(int message, void *buf, uint16_t len)
250 case HAL_EV_AVRCP_TG_CONN_STATE:
252 struct hal_ev_avrcp_tg_conn_state *ev = buf;
254 if (!bt_hal_avrcp_tg_cbacks->connection_state_cb)
257 bt_hal_avrcp_tg_cbacks->connection_state_cb(
258 (bt_bdaddr_t *)ev->bdaddr, ev->state);
260 * To retrieve various player properties, callbacks are invoked from bluedroid to
261 * upper layers (in our case OAL). But in case of BlueZ, these properties are
262 * cached in stack and replied from within. For this, BlueZ relies on property
263 * changed signals from upper layer, to keep its cache updated. To handle the above
264 * case in BlueZ HAL, we register notifications (internal to HAL) and send property
265 * changed signals to bluez on receiving notifications from upper layer (OAL).
267 if (HAL_AVRCP_TG_STATE_CONNECTED == ev->state)
268 g_idle_add(__bt_avrcp_register_notifications, ev->bdaddr);
271 case HAL_EV_AVRCP_TG_DELAY_CHANGE:
273 DBG("avrcp tg delay change");
274 struct hal_ev_avrcp_tg_delay_changed *ev = buf;
275 bt_hal_avrcp_tg_cbacks->delay_change_cb(
276 ev->value, (bt_bdaddr_t *)ev->bdaddr);
280 case HAL_EV_AVRCP_TG_SET_PLAYER_PROPERTY:
281 __handle_player_property(buf, len);
284 ERR("Unknown event: 0x%.2X", message);
291 bt_status_t hal_avrcp_tg_connect(bt_bdaddr_t *rem_addr)
293 return _bt_hal_dbus_handler_avrcp_tg_connect(rem_addr);
296 bt_status_t hal_avrcp_tg_disconnect(bt_bdaddr_t *rem_addr)
298 return _bt_hal_dbus_handler_avrcp_tg_disconnect(rem_addr);
302 static bt_status_t init(btrc_callbacks_t *callbacks)
308 if (interface_ready())
309 return BT_STATUS_DONE;
312 return BT_STATUS_PARM_INVALID;
314 /* Register AVRCP Media player */
315 ret = _bt_hal_dbus_handler_register_media_player();
316 if (BT_STATUS_SUCCESS != ret)
317 ERR("_bt_hal_dbus_handler_register_media_player failed");
319 /* Register AVRCP event callback */
320 _bt_hal_register_avrcp_tg_dbus_handler_cb(
321 __bt_hal_handle_avrcp_tg_events);
322 _bt_hal_register_event_handler_cb(HAL_AVRCP_TG,
323 __bt_hal_handle_avrcp_tg_events);
325 bt_hal_avrcp_tg_cbacks = callbacks;
327 return BT_STATUS_SUCCESS;
330 static void cleanup(void)
334 if (!interface_ready())
337 /* Un-register AVRCP Media player */
338 _bt_hal_dbus_handler_unregister_media_player();
340 /* Un-register AVRCP event callback */
341 _bt_hal_unregister_avrcp_tg_dbus_handler_cb();
342 _bt_hal_unregister_event_handler_cb(HAL_AVRCP_TG);
344 bt_hal_avrcp_tg_cbacks = NULL;
347 static btrc_interface_t avrcp_tg_if = {
348 .size = sizeof(avrcp_tg_if),
351 .connect = hal_avrcp_tg_connect,
352 .disconnect = hal_avrcp_tg_disconnect,
354 .get_play_status_rsp = get_play_status_rsp,
355 .list_player_app_attr_rsp = list_player_app_attr_rsp,
356 .list_player_app_value_rsp = list_player_app_value_rsp,
357 .get_player_app_attr_text_rsp = get_player_app_attr_text_rsp,
358 .get_player_app_value_text_rsp = get_player_app_value_text_rsp,
359 .get_element_attr_rsp = get_element_attr_rsp,
360 .set_player_app_value_rsp = set_player_app_value_rsp,
361 .register_notification_rsp = register_notification_rsp,
362 .set_volume = set_volume,
363 .set_addressed_player_rsp = set_addressed_player_rsp,
364 .set_browsed_player_rsp = set_browsed_player_rsp,
365 .get_folder_items_list_rsp = get_folder_items_list_rsp,
366 .change_path_rsp = change_path_rsp,
367 .get_item_attr_rsp = get_item_attr_rsp,
368 .play_item_rsp = play_item_rsp,
369 .get_total_num_of_items_rsp = get_total_num_of_items_rsp,
370 .search_rsp = search_rsp,
371 .add_to_now_playing_rsp = add_to_now_playing_rsp,
375 btrc_interface_t *bt_get_avrcp_tg_interface(void)