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"
35 #include "bt-hal-avrcp-transport-dbus-handler.h"
37 static const btrc_callbacks_t *bt_hal_avrcp_tg_cbacks;
39 static bool interface_ready(void)
41 return bt_hal_avrcp_tg_cbacks != NULL;
44 bt_status_t get_play_status_rsp(bt_bdaddr_t *bd_addr, btrc_play_status_t play_status,
45 uint32_t song_len, uint32_t song_pos)
47 return BT_STATUS_UNSUPPORTED;
50 bt_status_t list_player_app_attr_rsp(bt_bdaddr_t *bd_addr, int num_attr,
51 btrc_player_attr_t *p_attrs)
53 return BT_STATUS_UNSUPPORTED;
56 bt_status_t list_player_app_value_rsp(bt_bdaddr_t *bd_addr, int num_val, uint8_t *p_vals)
58 return BT_STATUS_UNSUPPORTED;
61 bt_status_t get_player_app_value_rsp(bt_bdaddr_t *bd_addr, btrc_player_settings_t *p_vals)
63 return BT_STATUS_UNSUPPORTED;
66 bt_status_t get_player_app_attr_text_rsp(bt_bdaddr_t *bd_addr, int num_attr,
67 btrc_player_setting_text_t *p_attrs)
69 return BT_STATUS_UNSUPPORTED;
72 bt_status_t get_player_app_value_text_rsp(bt_bdaddr_t *bd_addr, int num_val,
73 btrc_player_setting_text_t *p_vals)
75 return BT_STATUS_UNSUPPORTED;
78 bt_status_t get_element_attr_rsp(bt_bdaddr_t *bd_addr, uint8_t num_attr,
79 btrc_element_attr_val_t *p_attrs)
81 if (num_attr > 0 && !p_attrs)
82 return BT_STATUS_PARM_INVALID;
84 return _bt_hal_dbus_handler_avrcp_tg_set_track_info(num_attr, p_attrs);
87 bt_status_t set_player_app_value_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status)
89 return BT_STATUS_UNSUPPORTED;
92 gboolean __fetch_track_info(gpointer data)
94 if (bt_hal_avrcp_tg_cbacks->get_element_attr_cb) {
96 btrc_media_attr_t attrs[] = {
97 BTRC_MEDIA_ATTR_TITLE, BTRC_MEDIA_ATTR_ARTIST,
98 BTRC_MEDIA_ATTR_ALBUM, BTRC_MEDIA_ATTR_TRACK_NUM,
99 BTRC_MEDIA_ATTR_NUM_TRACKS, BTRC_MEDIA_ATTR_GENRE,
100 BTRC_MEDIA_ATTR_PLAYING_TIME};
102 num_attr = sizeof(attrs) / sizeof(btrc_media_attr_t);
104 bt_hal_avrcp_tg_cbacks->get_element_attr_cb(num_attr, attrs, NULL);
110 bt_status_t register_notification_rsp(btrc_event_id_t event_id,
111 btrc_notification_type_t type,
112 btrc_register_notification_t *p_param)
114 if (BTRC_NOTIFICATION_TYPE_INTERIM == type)
115 return BT_STATUS_SUCCESS;
118 case BTRC_EVT_PLAY_STATUS_CHANGED:
119 _bt_hal_dbus_handler_avrcp_tg_play_status_changed(p_param->play_status);
121 case BTRC_EVT_TRACK_CHANGE:
122 g_idle_add(__fetch_track_info, NULL);
124 case BTRC_EVT_PLAY_POS_CHANGED:
125 _bt_hal_dbus_handler_avrcp_tg_play_pos_changed(p_param->song_pos);
127 case BTRC_EVT_APP_SETTINGS_CHANGED:
128 _bt_hal_dbus_handler_avrcp_tg_app_setting_changed(&(p_param->player_setting));
131 ERR("Unknown event Id: %d", event_id);
134 return BT_STATUS_SUCCESS;
137 bt_status_t set_volume(bt_bdaddr_t *bd_addr, uint32_t volume)
139 int ret = BT_STATUS_SUCCESS;
141 ret = _bt_hal_dbus_handler_avrcp_transport_set_property(bd_addr, BTRC_TRANSPORT_ATTR_VOLUME, volume);
146 bt_status_t get_volume(bt_bdaddr_t *bd_addr, uint32_t *volume)
148 int ret = BT_STATUS_SUCCESS;
150 ret = _bt_hal_dbus_handler_avrcp_transport_get_property(bd_addr, BTRC_TRANSPORT_ATTR_VOLUME, volume);
155 bt_status_t set_addressed_player_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status)
157 return BT_STATUS_UNSUPPORTED;
160 bt_status_t set_browsed_player_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status,
161 uint32_t num_items, uint16_t charset_id, uint8_t folder_depth,
162 btrc_br_folder_name_t *p_folders)
164 return BT_STATUS_UNSUPPORTED;
167 bt_status_t get_folder_items_list_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status,
168 uint16_t uid_counter, uint8_t num_items, btrc_folder_items_t *p_items)
170 return BT_STATUS_UNSUPPORTED;
173 bt_status_t change_path_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status,
176 return BT_STATUS_UNSUPPORTED;
179 bt_status_t get_item_attr_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status,
180 uint8_t num_attr, btrc_element_attr_val_t *p_attrs)
182 return BT_STATUS_UNSUPPORTED;
185 bt_status_t play_item_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status)
187 return BT_STATUS_UNSUPPORTED;
190 bt_status_t get_total_num_of_items_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status,
191 uint32_t uid_counter, uint32_t num_items)
193 return BT_STATUS_UNSUPPORTED;
196 bt_status_t search_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status, uint32_t uid_counter,
199 return BT_STATUS_UNSUPPORTED;
202 bt_status_t add_to_now_playing_rsp(bt_bdaddr_t *bd_addr, btrc_status_t rsp_status)
204 return BT_STATUS_UNSUPPORTED;
207 static gboolean __bt_avrcp_register_notifications(gpointer user_data)
209 bt_bdaddr_t *bdaddr = user_data;
211 if (!bt_hal_avrcp_tg_cbacks->register_notification_cb)
214 bt_hal_avrcp_tg_cbacks->register_notification_cb(BTRC_EVT_PLAY_STATUS_CHANGED, 0, bdaddr);
215 bt_hal_avrcp_tg_cbacks->register_notification_cb(BTRC_EVT_TRACK_CHANGE, 0, bdaddr);
216 bt_hal_avrcp_tg_cbacks->register_notification_cb(BTRC_EVT_PLAY_POS_CHANGED, 1, bdaddr);
217 bt_hal_avrcp_tg_cbacks->register_notification_cb(BTRC_EVT_APP_SETTINGS_CHANGED, 0, bdaddr);
222 static void __handle_player_property(void *buf, uint16_t len)
224 btrc_player_settings_t player_setting;
225 struct hal_ev_avrcp_tg_player_property *ev = buf;
227 if (!bt_hal_avrcp_tg_cbacks->set_player_app_value_cb)
230 memset(&player_setting, 0, sizeof(btrc_player_settings_t));
231 player_setting.num_attr = 1;
233 switch (ev->prop_type) {
234 case HAL_AVRCP_TG_PLAYER_PROP_REPEAT:
235 player_setting.attr_ids[0] = BTRC_PLAYER_ATTR_REPEAT;
236 player_setting.attr_values[0] = ev->value;
238 case HAL_AVRCP_TG_PLAYER_PROP_SHUFFLE:
239 player_setting.attr_ids[0] = BTRC_PLAYER_ATTR_SHUFFLE;
240 player_setting.attr_values[0] = ev->value;
242 case HAL_AVRCP_TG_PLAYER_PROP_SCAN:
243 player_setting.attr_ids[0] = BTRC_PLAYER_ATTR_SCAN;
244 player_setting.attr_values[0] = ev->value;
246 case HAL_AVRCP_TG_PLAYER_PROP_EQUALIZER:
247 player_setting.attr_ids[0] = BTRC_PLAYER_ATTR_EQUALIZER;
248 player_setting.attr_values[0] = ev->value;
251 INFO("Player property not handled: %d", ev->prop_type);
255 bt_hal_avrcp_tg_cbacks->set_player_app_value_cb(&player_setting, NULL);
258 static void __bt_hal_handle_avrcp_tg_events(int message, void *buf, uint16_t len)
264 case HAL_EV_AVRCP_TG_CONN_STATE:
266 struct hal_ev_avrcp_tg_conn_state *ev = buf;
268 if (!bt_hal_avrcp_tg_cbacks->connection_state_cb)
271 bt_hal_avrcp_tg_cbacks->connection_state_cb(
272 (bt_bdaddr_t *)ev->bdaddr, ev->state);
274 * To retrieve various player properties, callbacks are invoked from bluedroid to
275 * upper layers (in our case OAL). But in case of BlueZ, these properties are
276 * cached in stack and replied from within. For this, BlueZ relies on property
277 * changed signals from upper layer, to keep its cache updated. To handle the above
278 * case in BlueZ HAL, we register notifications (internal to HAL) and send property
279 * changed signals to bluez on receiving notifications from upper layer (OAL).
281 if (HAL_AVRCP_TG_STATE_CONNECTED == ev->state)
282 g_idle_add(__bt_avrcp_register_notifications, ev->bdaddr);
285 case HAL_EV_AVRCP_TG_DELAY_CHANGE:
287 DBG("avrcp tg delay change");
288 struct hal_ev_avrcp_tg_delay_changed *ev = buf;
289 bt_hal_avrcp_tg_cbacks->delay_change_cb(
290 ev->value, (bt_bdaddr_t *)ev->bdaddr);
293 case HAL_EV_AVRCP_TG_VOLUME_CHANGE:
295 DBG("avrcp tg volume change");
296 struct hal_ev_avrcp_tg_volume_changed *ev = buf;
297 bt_hal_avrcp_tg_cbacks->volume_change_cb(
298 ev->volume, 0, (bt_bdaddr_t *)ev->bdaddr);
302 case HAL_EV_AVRCP_TG_SET_PLAYER_PROPERTY:
303 __handle_player_property(buf, len);
306 ERR("Unknown event: 0x%.2X", message);
313 bt_status_t hal_avrcp_tg_connect(bt_bdaddr_t *rem_addr)
315 return _bt_hal_dbus_handler_avrcp_tg_connect(rem_addr);
318 bt_status_t hal_avrcp_tg_disconnect(bt_bdaddr_t *rem_addr)
320 return _bt_hal_dbus_handler_avrcp_tg_disconnect(rem_addr);
324 static bt_status_t init(btrc_callbacks_t *callbacks)
330 if (interface_ready())
331 return BT_STATUS_DONE;
334 return BT_STATUS_PARM_INVALID;
336 /* Register AVRCP Media player */
337 ret = _bt_hal_dbus_handler_register_media_player();
338 if (BT_STATUS_SUCCESS != ret)
339 ERR("_bt_hal_dbus_handler_register_media_player failed");
341 /* Register AVRCP event callback */
342 _bt_hal_register_avrcp_tg_dbus_handler_cb(
343 __bt_hal_handle_avrcp_tg_events);
344 _bt_hal_register_event_handler_cb(HAL_AVRCP_TG,
345 __bt_hal_handle_avrcp_tg_events);
347 bt_hal_avrcp_tg_cbacks = callbacks;
349 return BT_STATUS_SUCCESS;
352 static void cleanup(void)
356 if (!interface_ready())
359 /* Un-register AVRCP Media player */
360 _bt_hal_dbus_handler_unregister_media_player();
362 /* Un-register AVRCP event callback */
363 _bt_hal_unregister_avrcp_tg_dbus_handler_cb();
364 _bt_hal_unregister_event_handler_cb(HAL_AVRCP_TG);
366 bt_hal_avrcp_tg_cbacks = NULL;
369 static btrc_interface_t avrcp_tg_if = {
370 .size = sizeof(avrcp_tg_if),
373 .connect = hal_avrcp_tg_connect,
374 .disconnect = hal_avrcp_tg_disconnect,
376 .get_play_status_rsp = get_play_status_rsp,
377 .list_player_app_attr_rsp = list_player_app_attr_rsp,
378 .list_player_app_value_rsp = list_player_app_value_rsp,
379 .get_player_app_attr_text_rsp = get_player_app_attr_text_rsp,
380 .get_player_app_value_text_rsp = get_player_app_value_text_rsp,
381 .get_element_attr_rsp = get_element_attr_rsp,
382 .set_player_app_value_rsp = set_player_app_value_rsp,
383 .register_notification_rsp = register_notification_rsp,
384 .set_volume = set_volume,
385 .get_volume = get_volume,
386 .set_addressed_player_rsp = set_addressed_player_rsp,
387 .set_browsed_player_rsp = set_browsed_player_rsp,
388 .get_folder_items_list_rsp = get_folder_items_list_rsp,
389 .change_path_rsp = change_path_rsp,
390 .get_item_attr_rsp = get_item_attr_rsp,
391 .play_item_rsp = play_item_rsp,
392 .get_total_num_of_items_rsp = get_total_num_of_items_rsp,
393 .search_rsp = search_rsp,
394 .add_to_now_playing_rsp = add_to_now_playing_rsp,
398 btrc_interface_t *bt_get_avrcp_tg_interface(void)