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);
279 case HAL_EV_AVRCP_TG_VOLUME_CHANGE:
281 DBG("avrcp tg volume change");
282 struct hal_ev_avrcp_tg_volume_changed *ev = buf;
283 bt_hal_avrcp_tg_cbacks->volume_change_cb(
284 ev->volume, 0, (bt_bdaddr_t *)ev->bdaddr);
288 case HAL_EV_AVRCP_TG_SET_PLAYER_PROPERTY:
289 __handle_player_property(buf, len);
292 ERR("Unknown event: 0x%.2X", message);
299 bt_status_t hal_avrcp_tg_connect(bt_bdaddr_t *rem_addr)
301 return _bt_hal_dbus_handler_avrcp_tg_connect(rem_addr);
304 bt_status_t hal_avrcp_tg_disconnect(bt_bdaddr_t *rem_addr)
306 return _bt_hal_dbus_handler_avrcp_tg_disconnect(rem_addr);
310 static bt_status_t init(btrc_callbacks_t *callbacks)
316 if (interface_ready())
317 return BT_STATUS_DONE;
320 return BT_STATUS_PARM_INVALID;
322 /* Register AVRCP Media player */
323 ret = _bt_hal_dbus_handler_register_media_player();
324 if (BT_STATUS_SUCCESS != ret)
325 ERR("_bt_hal_dbus_handler_register_media_player failed");
327 /* Register AVRCP event callback */
328 _bt_hal_register_avrcp_tg_dbus_handler_cb(
329 __bt_hal_handle_avrcp_tg_events);
330 _bt_hal_register_event_handler_cb(HAL_AVRCP_TG,
331 __bt_hal_handle_avrcp_tg_events);
333 bt_hal_avrcp_tg_cbacks = callbacks;
335 return BT_STATUS_SUCCESS;
338 static void cleanup(void)
342 if (!interface_ready())
345 /* Un-register AVRCP Media player */
346 _bt_hal_dbus_handler_unregister_media_player();
348 /* Un-register AVRCP event callback */
349 _bt_hal_unregister_avrcp_tg_dbus_handler_cb();
350 _bt_hal_unregister_event_handler_cb(HAL_AVRCP_TG);
352 bt_hal_avrcp_tg_cbacks = NULL;
355 static btrc_interface_t avrcp_tg_if = {
356 .size = sizeof(avrcp_tg_if),
359 .connect = hal_avrcp_tg_connect,
360 .disconnect = hal_avrcp_tg_disconnect,
362 .get_play_status_rsp = get_play_status_rsp,
363 .list_player_app_attr_rsp = list_player_app_attr_rsp,
364 .list_player_app_value_rsp = list_player_app_value_rsp,
365 .get_player_app_attr_text_rsp = get_player_app_attr_text_rsp,
366 .get_player_app_value_text_rsp = get_player_app_value_text_rsp,
367 .get_element_attr_rsp = get_element_attr_rsp,
368 .set_player_app_value_rsp = set_player_app_value_rsp,
369 .register_notification_rsp = register_notification_rsp,
370 .set_volume = set_volume,
371 .set_addressed_player_rsp = set_addressed_player_rsp,
372 .set_browsed_player_rsp = set_browsed_player_rsp,
373 .get_folder_items_list_rsp = get_folder_items_list_rsp,
374 .change_path_rsp = change_path_rsp,
375 .get_item_attr_rsp = get_item_attr_rsp,
376 .play_item_rsp = play_item_rsp,
377 .get_total_num_of_items_rsp = get_total_num_of_items_rsp,
378 .search_rsp = search_rsp,
379 .add_to_now_playing_rsp = add_to_now_playing_rsp,
383 btrc_interface_t *bt_get_avrcp_tg_interface(void)