Fix the issue that can not send device event
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / oal-avrcp-tg.c
1 /*
2  * Open Adaptation Layer (OAL)
3  *
4  * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *              http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <dlog.h>
21 #include <string.h>
22 #include <stdio.h>
23
24 #include "bluetooth.h"
25 #include "bt_rc.h"
26
27 #include "oal-event.h"
28 #include "oal-internal.h"
29 #include "oal-common.h"
30 #include "oal-manager.h"
31 #include "oal-avrcp-tg.h"
32
33 #define NUM_MEDIA_ATTR_MAX (BTRC_MEDIA_ATTR_PLAYING_TIME)
34
35 #define CHECK_OAL_AVRCP_ENABLED() \
36         do { \
37                 if (avrcp_api == NULL) { \
38                         BT_ERR("AVRCP Not Enabled"); \
39                         return OAL_STATUS_NOT_READY; \
40                 } \
41         } while (0)
42
43 static void remove_pos_timer();
44
45 #ifdef TIZEN_BT_HAL
46 static void cb_connection_state(bt_bdaddr_t* bd_addr, btrc_connection_state_t state);
47 #endif
48
49 static void cb_avrcp_remote_features(bt_bdaddr_t* bd_addr, btrc_remote_features_t features);
50
51 static void cb_avrcp_get_play_status();
52 static void cb_avrcp_set_player_app_value(btrc_player_settings_t *p_vals, bt_bdaddr_t *bd_addr);
53 static void cb_avrcp_get_element_attr(uint8_t num_attr, btrc_media_attr_t *p_attrs, bt_bdaddr_t *bd_addr);
54 static void cb_avrcp_register_notification(btrc_event_id_t event_id, uint32_t param, bt_bdaddr_t *bd_addr);
55 static void cb_avrcp_volume_change(uint8_t volume, uint8_t ctype, bt_bdaddr_t *bd_addr);
56 static void cb_avrcp_delay_change(uint16_t delay, bt_bdaddr_t *bd_addr);
57 static void cb_avrcp_passthrough_command(int id, int pressed, bt_bdaddr_t *bd_addr);
58
59 typedef struct {
60         int play_status:1;
61         int track_change:1;
62         int track_end:1;
63         int track_start:1;
64         int pos_change:1;
65         int setting_change:1;
66         int interval;
67 } notif_t;
68
69 typedef struct {
70         int equalizer;
71         btrc_player_repeat_val_t repeat;
72         btrc_player_shuffle_val_t shuffle;
73         int scan;
74         btrc_play_status_t status;
75         unsigned int volume;
76 } player_settings_t;
77
78 typedef struct {
79         uint32_t song_pos;
80         uint32_t playing_time;
81         uint8_t title[BTRC_MAX_ATTR_STR_LEN];
82         uint8_t artist[BTRC_MAX_ATTR_STR_LEN];
83         uint8_t album[BTRC_MAX_ATTR_STR_LEN];
84         uint8_t genre[BTRC_MAX_ATTR_STR_LEN];
85         unsigned int num_tracks;
86         uint32_t cur_track;
87 } track_info_t;
88
89 typedef enum {
90         STATUS_STOPPED = 0x00,
91         STATUS_PLAYING,
92         STATUS_PAUSED,
93         STATUS_FORWARD_SEEK,
94         STATUS_REVERSE_SEEK,
95         STATUS_ERROR,
96         STATUS_INVALID
97 } media_player_status;
98
99 static track_info_t track_info;
100 static player_settings_t player_setting;
101
102 static guint send_pos_timer = 0;
103
104 static notif_t registered_notifications;
105 static const btrc_interface_t *avrcp_api;
106
107 static btrc_callbacks_t sBluetoothAvrcpCallbacks = {
108         .size = sizeof(sBluetoothAvrcpCallbacks),
109 #ifdef TIZEN_BT_HAL
110         .connection_state_cb = cb_connection_state,
111 #endif
112         .remote_features_cb = cb_avrcp_remote_features,
113         .get_play_status_cb = cb_avrcp_get_play_status,
114         .list_player_app_attr_cb = NULL,
115         .list_player_app_values_cb = NULL,
116         .get_player_app_value_cb = NULL,
117         .get_player_app_attrs_text_cb = NULL,
118         .get_player_app_values_text_cb = NULL,
119         .set_player_app_value_cb = cb_avrcp_set_player_app_value,
120         .get_element_attr_cb = cb_avrcp_get_element_attr,
121         .register_notification_cb = cb_avrcp_register_notification,
122         .volume_change_cb = cb_avrcp_volume_change,
123         .delay_change_cb = cb_avrcp_delay_change,
124         .passthrough_cmd_cb = cb_avrcp_passthrough_command,
125         .set_addressed_player_cb = NULL,
126         .set_browsed_player_cb = NULL,
127         .get_folder_items_cb = NULL,
128         .change_path_cb = NULL,
129         .get_item_attr_cb = NULL,
130         .play_item_cb = NULL,
131         .get_total_num_of_items_cb = NULL,
132         .search_cb = NULL,
133         .add_to_now_playing_cb = NULL,
134 };
135
136 static void send_pos_changed(void)
137 {
138         BT_DBG("Pos changed");
139
140         if (avrcp_api == NULL) {
141                 BT_ERR("AVRCP Not Enabled");
142                 return ;
143         }
144
145         if (registered_notifications.pos_change) {
146                 int ret;
147                 btrc_register_notification_t response;
148
149                 BT_DBG("Song Pos: %d", track_info.song_pos);
150                 response.song_pos = track_info.song_pos;
151                 ret = avrcp_api->register_notification_rsp(
152                         BTRC_EVT_PLAY_POS_CHANGED, BTRC_NOTIFICATION_TYPE_CHANGED, &response);
153
154                 if (ret != BT_STATUS_SUCCESS)
155                         BT_ERR("Notif send failed: %s", status2string(ret));
156         }
157 }
158
159 static gboolean send_pos_timeout(gpointer  param)
160 {
161         BT_DBG("pos timeout");
162
163         if (!registered_notifications.pos_change)
164                 return FALSE;
165
166         send_pos_changed();
167
168         if (player_setting.status != BTRC_PLAYSTATE_PLAYING &&
169                 player_setting.status != BTRC_PLAYSTATE_FWD_SEEK &&
170                 player_setting.status != BTRC_PLAYSTATE_REV_SEEK)
171                 return FALSE;
172
173         return TRUE;
174 }
175
176 static void remove_pos_timer()
177 {
178
179         if (send_pos_timer > 0) {
180                 g_source_remove(send_pos_timer);
181                 send_pos_timer = 0;
182         }
183 }
184
185 static void send_track_boundary_reached(void)
186 {
187         int ret = BT_STATUS_SUCCESS;
188
189         if (avrcp_api == NULL) {
190                 BT_ERR("AVRCP Not Enabled");
191                 return;
192         }
193
194         if (track_info.song_pos == 0 &&
195                 registered_notifications.track_start)
196                 ret = avrcp_api->register_notification_rsp(
197                         BTRC_EVT_TRACK_REACHED_START, BTRC_NOTIFICATION_TYPE_CHANGED, NULL);
198         else if ((track_info.playing_time == track_info.song_pos) &&
199                         registered_notifications.track_end) {
200                 ret = avrcp_api->register_notification_rsp(
201                         BTRC_EVT_TRACK_REACHED_END, BTRC_NOTIFICATION_TYPE_CHANGED, NULL);
202         }
203
204         if (ret != BT_STATUS_SUCCESS)
205                 BT_ERR("Notif send failed: %s", status2string(ret));
206 }
207
208 gboolean avrcp_tg_enable_state(void)
209 {
210         if (avrcp_api == NULL)
211                 return FALSE;
212         else
213                 return TRUE;
214 }
215
216 oal_status_t avrcp_enable(void)
217 {
218         const bt_interface_t * blued_api = NULL;
219         int ret;
220
221         API_TRACE();
222
223         /*TODO: Need to check below logic */
224 #if 0
225         if (a2dp_sink_enable_state() == TRUE || avrcp_ct_enable_state() == TRUE) {
226                 BT_ERR("AVRCP_CT Role Enabled, cannot enable AVRCP_TG Role");
227                 return OAL_STATUS_BUSY;
228         }
229 #endif
230
231         blued_api = adapter_get_stack_interface();
232         if (blued_api == NULL) {
233                 BT_ERR("Stack is not initialized");
234                 return OAL_STATUS_NOT_READY;
235         }
236
237         if (avrcp_api) {
238                 BT_WARN("avrcp tg Interface is already initialized...");
239                 return OAL_STATUS_ALREADY_DONE;
240         }
241
242         avrcp_api = (const btrc_interface_t *)blued_api->get_profile_interface(BT_PROFILE_AV_RC_ID);
243         if (avrcp_api == NULL) {
244                 BT_ERR("AVRCP interface failed");
245                 return OAL_STATUS_INTERNAL_ERROR;
246         }
247
248         memset(&registered_notifications, 0x00, sizeof(registered_notifications));
249         memset(&track_info, 0x00, sizeof(track_info));
250         memset(&player_setting, 0, sizeof(player_settings_t));
251
252         /* Handle failure if return value is anything other than Success or Already done */
253         ret = avrcp_api->init(&sBluetoothAvrcpCallbacks);
254         if (ret != BT_STATUS_SUCCESS && ret != BT_STATUS_DONE) {
255                 BT_ERR("AVRCP Init failed %s", status2string(ret));
256                 avrcp_api->cleanup();
257                 avrcp_api = NULL;
258                 return convert_to_oal_status(ret);
259         }
260
261         return OAL_STATUS_SUCCESS;
262 }
263
264 oal_status_t avrcp_disable(void)
265 {
266
267         API_TRACE();
268
269         CHECK_OAL_AVRCP_ENABLED();
270
271         remove_pos_timer();
272         avrcp_api->cleanup();
273         avrcp_api = NULL;
274
275         return OAL_STATUS_SUCCESS;
276 }
277
278 void avrcp_tg_cleanup(void)
279 {
280
281         BT_DBG();
282
283         remove_pos_timer();
284         avrcp_api = NULL;
285 }
286
287 oal_status_t avrcp_tg_connect(bt_address_t *rem_addr)
288 {
289         int result = OAL_STATUS_SUCCESS;
290         bt_status_t status;
291         bdstr_t bdstr;
292
293         API_TRACE();
294
295         CHECK_OAL_AVRCP_ENABLED();
296         OAL_CHECK_PARAMETER(rem_addr, return);
297
298         BT_INFO("BT Audio Address: %s", bdt_bd2str(rem_addr, &bdstr));
299
300 #ifdef TIZEN_BT_HAL
301         status = avrcp_api->connect((bt_bdaddr_t *)rem_addr);
302         if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
303                 BT_ERR("Connection could not be established, err: %s", status2string(status));;
304                 result =  convert_to_oal_status(status);
305         }
306 #else
307         BT_INFO("Not Supported");
308         result = OAL_STATUS_NOT_SUPPORT;
309 #endif
310
311         return result;
312 }
313
314 oal_status_t avrcp_tg_disconnect(bt_address_t *rem_addr)
315 {
316         int result = OAL_STATUS_SUCCESS;
317         bdstr_t bdstr;
318         bt_status_t status;
319
320         API_TRACE();
321
322         CHECK_OAL_AVRCP_ENABLED();
323         OAL_CHECK_PARAMETER(rem_addr, return);
324
325         BT_INFO("BT Audio Address: %s", bdt_bd2str(rem_addr, &bdstr));
326
327 #ifdef TIZEN_BT_HAL
328         status = avrcp_api->disconnect((bt_bdaddr_t *)rem_addr);
329         if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
330                 BT_ERR("OAL, Disconnection failed err: %s", status2string(status));
331                 result =  convert_to_oal_status(status);
332         }
333 #else
334         BT_INFO("Not Supported");
335         result = OAL_STATUS_NOT_SUPPORT;
336 #endif
337
338         return result;
339 }
340
341 oal_status_t avrcp_set_track_info(oal_media_metadata_attributes_t *meta_data)
342 {
343         API_TRACE();
344
345         CHECK_OAL_AVRCP_ENABLED();
346
347         retv_if(meta_data == NULL, OAL_STATUS_INTERNAL_ERROR);
348
349         /********* Update media attribs **********/
350         g_strlcpy((char*)track_info.title, meta_data->title, BTRC_MAX_ATTR_STR_LEN);
351         g_strlcpy((char*)track_info.artist, meta_data->artist, BTRC_MAX_ATTR_STR_LEN);
352         g_strlcpy((char*)track_info.album, meta_data->album, BTRC_MAX_ATTR_STR_LEN);
353         g_strlcpy((char*)track_info.genre, meta_data->genre, BTRC_MAX_ATTR_STR_LEN);
354
355         track_info.num_tracks = meta_data->total_tracks;
356         track_info.playing_time = meta_data->duration;
357
358         if (registered_notifications.track_change &&
359                         track_info.cur_track != meta_data->number) {
360                 int ret;
361                 btrc_register_notification_t response;
362
363                 memset(&response, 0x00, sizeof(btrc_register_notification_t));
364
365                 track_info.cur_track = meta_data->number;
366
367                 /* Send Track Change notification */
368                 memcpy(&response.track, &track_info.cur_track, sizeof(uint32_t));
369                 ret = avrcp_api->register_notification_rsp(
370                         BTRC_EVT_TRACK_CHANGE, BTRC_NOTIFICATION_TYPE_CHANGED, &response);
371                 if (ret != BT_STATUS_SUCCESS)
372                         BT_ERR("Notif send failed: %s",  status2string(ret));
373
374                 send_pos_changed();
375         }
376
377         track_info.cur_track = meta_data->number;
378         return OAL_STATUS_SUCCESS;
379 }
380
381 oal_status_t avrcp_set_property(int type, unsigned int value)
382 {
383         btrc_register_notification_t response;
384         int ret;
385
386         API_TRACE("type: %d, value: %d", type, value);
387         CHECK_OAL_AVRCP_ENABLED();
388
389         switch (type) {
390         case AVRCP_EQUALIZER: {
391                 if (value == player_setting.equalizer &&
392                         !registered_notifications.setting_change)
393                         break;
394
395                 response.player_setting.num_attr = 1;
396                 response.player_setting.attr_ids[0] = BTRC_PLAYER_ATTR_EQUALIZER;
397                 response.player_setting.attr_values[0] = value;
398                 ret = avrcp_api->register_notification_rsp(BTRC_EVT_APP_SETTINGS_CHANGED,
399                                 BTRC_NOTIFICATION_TYPE_CHANGED, &response);
400                 if (ret != BT_STATUS_SUCCESS)
401                         BT_ERR("Notif send failed: %s", status2string(ret));
402
403                 player_setting.equalizer = value;
404                 break;
405         }
406         case AVRCP_REPEAT: {
407                 if (value == player_setting.repeat &&
408                         !registered_notifications.setting_change)
409                         break;
410
411                 response.player_setting.num_attr = 1;
412                 response.player_setting.attr_ids[0] = BTRC_PLAYER_ATTR_REPEAT;
413                 response.player_setting.attr_values[0] = value;
414                 ret = avrcp_api->register_notification_rsp(BTRC_EVT_APP_SETTINGS_CHANGED,
415                                 BTRC_NOTIFICATION_TYPE_CHANGED, &response);
416                 if (ret != BT_STATUS_SUCCESS)
417                         BT_ERR("Notif send failed: %s", status2string(ret));
418
419                 player_setting.repeat = value;
420                 break;
421         }
422         case AVRCP_SHUFFLE: {
423                 if (value == player_setting.shuffle &&
424                         !registered_notifications.setting_change)
425                         break;
426
427                 response.player_setting.num_attr = 1;
428                 response.player_setting.attr_ids[0] = BTRC_PLAYER_ATTR_SHUFFLE;
429                 response.player_setting.attr_values[0] = value;
430                 ret = avrcp_api->register_notification_rsp(BTRC_EVT_APP_SETTINGS_CHANGED,
431                                 BTRC_NOTIFICATION_TYPE_CHANGED, &response);
432                 if (ret != BT_STATUS_SUCCESS)
433                         BT_ERR("Notif send failed: %s", status2string(ret));
434
435                 player_setting.shuffle = value;
436                 break;
437         }
438         case AVRCP_SCAN: {
439                 if (value == player_setting.scan &&
440                         !registered_notifications.setting_change)
441                         break;
442
443                 response.player_setting.num_attr = 1;
444                 response.player_setting.attr_ids[0] = BTRC_PLAYER_ATTR_SCAN;
445                 response.player_setting.attr_values[0] = value;
446                 ret = avrcp_api->register_notification_rsp(BTRC_EVT_APP_SETTINGS_CHANGED,
447                                 BTRC_NOTIFICATION_TYPE_CHANGED, &response);
448                 if (ret != BT_STATUS_SUCCESS)
449                         BT_ERR("Notif send failed: %s", status2string(ret));
450
451                 player_setting.scan = value;
452                 break;
453         }
454         case AVRCP_STATUS:
455                 if (value != player_setting.status) {
456                         player_setting.status = (value == STATUS_ERROR) ? BTRC_PLAYSTATE_ERROR : value;
457
458                         if (registered_notifications.play_status) {
459                                 response.play_status = player_setting.status;
460                                 ret = avrcp_api->register_notification_rsp(BTRC_EVT_PLAY_STATUS_CHANGED,
461                                                 BTRC_NOTIFICATION_TYPE_CHANGED, &response);
462                                 if (ret != BT_STATUS_SUCCESS)
463                                         BT_ERR("Notif send failed: %s", status2string(ret));
464                         }
465                 }
466                 break;
467         case AVRCP_POSITION:
468                 if (value != track_info.song_pos) {
469                         track_info.song_pos = value;
470                         send_pos_changed();
471                         send_track_boundary_reached();
472                 }
473                 break;
474         default:
475                 BT_ERR("Invalid Type\n");
476                 return OAL_STATUS_INTERNAL_ERROR;
477         }
478
479         return OAL_STATUS_SUCCESS;
480 }
481
482 oal_status_t avrcp_tg_set_volume(bt_address_t *rem_addr, unsigned int volume)
483 {
484         int result = OAL_STATUS_SUCCESS;
485         bt_status_t status;
486         bdstr_t bdstr;
487
488         API_TRACE();
489
490         CHECK_OAL_AVRCP_ENABLED();
491         OAL_CHECK_PARAMETER(rem_addr, return);
492
493         BT_INFO("BT Audio Address: %s", bdt_bd2str(rem_addr, &bdstr));
494
495 #ifdef TIZEN_BT_HAL
496         status = avrcp_api->set_volume((bt_bdaddr_t *)rem_addr, volume);
497         if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
498                 BT_ERR("set volume failed, err: %s", status2string(status));;
499                 result = convert_to_oal_status(status);
500         }
501 #else
502         BT_INFO("Not Supported");
503         result = OAL_STATUS_NOT_SUPPORT;
504 #endif
505
506         return result;
507 }
508
509 oal_status_t avrcp_tg_get_volume(bt_address_t *rem_addr, unsigned int *volume)
510 {
511         int result = OAL_STATUS_SUCCESS;
512         bt_status_t status;
513         bdstr_t bdstr;
514
515         API_TRACE();
516
517         CHECK_OAL_AVRCP_ENABLED();
518         OAL_CHECK_PARAMETER(rem_addr, return);
519
520         BT_INFO("BT Audio Address: %s", bdt_bd2str(rem_addr, &bdstr));
521
522 #ifdef TIZEN_BT_HAL
523         status = avrcp_api->get_volume((bt_bdaddr_t *)rem_addr, volume);
524         if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
525                 BT_ERR("set volume failed, err: %s", status2string(status));;
526                 result = convert_to_oal_status(status);
527         }
528 #else
529         BT_INFO("Not Supported");
530         result = OAL_STATUS_NOT_SUPPORT;
531 #endif
532
533         return result;
534 }
535
536
537 #ifdef TIZEN_BT_HAL
538 static void cb_connection_state(bt_bdaddr_t* bd_addr, btrc_connection_state_t state)
539 {
540         bt_address_t * event_data = NULL;
541         int event;
542
543         BT_DBG("%d", state);
544
545         event_data = g_new0(bt_address_t, 1);
546         memcpy(event_data->addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
547
548         switch (state) {
549         case BTRC_CONNECTION_STATE_DISCONNECTED:
550                 event = OAL_EVENT_AVRCP_DISCONNECTED;
551                 break;
552         case BTRC_CONNECTION_STATE_CONNECTED:
553                 event = OAL_EVENT_AVRCP_CONNECTED;
554                 break;
555         default:
556                 BT_ERR("Unhandled Connection state %d", state);
557                 return;
558         }
559
560         send_event_bda_trace(event, event_data, sizeof(bt_address_t), (bt_address_t*)bd_addr);
561
562 }
563 #endif
564
565 static void cb_avrcp_remote_features(bt_bdaddr_t* bd_addr, btrc_remote_features_t features)
566 {
567         remote_feature *avrcp_rem_feature = g_new0(remote_feature, 1);
568
569         /* Reset variables */
570         memset(&registered_notifications, 0, sizeof(notif_t));
571         memset(&track_info, 0, sizeof(track_info_t));
572         memset(&player_setting, 0, sizeof(player_settings_t));
573         player_setting.volume =  0xFFFFFFFF/2;
574
575         /* TODO: need to check if this feature mask is useful */
576         BT_INFO("Remore features Mask: 0x%x", features);
577
578         avrcp_rem_feature->avrcp_feature = features;
579         memcpy(avrcp_rem_feature->address.addr, bd_addr->address, 6);
580
581         send_event_bda_trace(OAL_EVENT_AVRCP_REMOTE_FEATURES,
582                 avrcp_rem_feature, sizeof(remote_feature), (bt_address_t *)bd_addr);
583 }
584
585 static void cb_avrcp_get_play_status(bt_bdaddr_t *bd_addr)
586 {
587         int ret;
588
589         BT_DBG("");
590
591         if (avrcp_api == NULL) {
592                 BT_ERR("AVRCP Not Enabled");
593                 return ;
594         }
595
596         ret = avrcp_api->get_play_status_rsp(bd_addr, player_setting.status,
597                         track_info.playing_time, track_info.song_pos);
598         if (ret != BT_STATUS_SUCCESS)
599                 BT_ERR("Play Status send failed: %s", status2string(ret));
600 }
601
602 static void cb_avrcp_set_player_app_value(btrc_player_settings_t *p_vals, bt_bdaddr_t *bd_addr)
603 {
604         int i;
605         uint8_t *value ;
606         oal_event_t event;
607
608         BT_DBG("");
609
610         for (i = 0; i < p_vals->num_attr; i++) {
611                 event = 0xffff;
612
613                 switch (p_vals->attr_ids[i]) {
614                 case BTRC_PLAYER_ATTR_EQUALIZER:
615                         event = OAL_EVENT_AVRCP_SETTING_EQUALIZER_STATUS;
616                         break;
617                 case BTRC_PLAYER_ATTR_REPEAT:
618                         event = OAL_EVENT_AVRCP_SETTING_REPEAT_STATUS;
619                         break;
620                 case BTRC_PLAYER_ATTR_SHUFFLE:
621                         event = OAL_EVENT_AVRCP_SETTING_SHUFFLE_STATUS;
622                         break;
623                 case BTRC_PLAYER_ATTR_SCAN:
624                         event = OAL_EVENT_AVRCP_SETTING_SCAN_STATUS;
625                         break;
626                 default:
627                         BT_ERR("Inavlid attr id= %d", p_vals->attr_ids[i]);
628                 }
629
630                 if (event != 0xffff) {
631                         value = g_new0(uint8_t, 1);
632                         *value = p_vals->attr_values[i];
633                         send_event(event, value, sizeof(*value));
634                 }
635         }
636 }
637
638 static void cb_avrcp_get_element_attr(uint8_t num_attr, btrc_media_attr_t *p_attrs, bt_bdaddr_t *bd_addr)
639 {
640         btrc_element_attr_val_t *p_attrs_vals;
641         int ret;
642         int i;
643
644         if (avrcp_api == NULL) {
645                 BT_ERR("AVRCP Not Enabled");
646                 return;
647         }
648
649         if (p_attrs == NULL) {
650                 BT_ERR("p_attrs is NULL");
651                 return;
652         }
653
654         BT_DBG("num_attr: %d", num_attr);
655         p_attrs_vals = g_malloc0(num_attr * sizeof(btrc_element_attr_val_t));
656
657         for (i = 0; i < num_attr; i++) {
658                 p_attrs_vals[i].attr_id = p_attrs[i];
659
660                 switch (p_attrs[i]) {
661                 case BTRC_MEDIA_ATTR_TITLE:
662                         g_strlcpy((char*)p_attrs_vals[i].text,
663                                 (const char *)track_info.title, BTRC_MAX_ATTR_STR_LEN);
664                         break;
665                 case BTRC_MEDIA_ATTR_ARTIST:
666                         g_strlcpy((char*)p_attrs_vals[i].text,
667                                 (const char *)track_info.artist, BTRC_MAX_ATTR_STR_LEN);
668                         break;
669                 case BTRC_MEDIA_ATTR_ALBUM:
670                         g_strlcpy((char*)p_attrs_vals[i].text,
671                                 (const char *)track_info.album, BTRC_MAX_ATTR_STR_LEN);
672                         break;
673                 case BTRC_MEDIA_ATTR_TRACK_NUM:
674                         snprintf((char*)p_attrs_vals[i].text, BTRC_MAX_ATTR_STR_LEN, "%u", track_info.cur_track);
675                         break;
676                 case BTRC_MEDIA_ATTR_NUM_TRACKS:
677                         snprintf((char*)p_attrs_vals[i].text, BTRC_MAX_ATTR_STR_LEN, "%u", track_info.num_tracks);
678                         break;
679                 case BTRC_MEDIA_ATTR_GENRE:
680                         g_strlcpy((char*)p_attrs_vals[i].text,
681                                 (const char *)track_info.genre, BTRC_MAX_ATTR_STR_LEN);
682                         break;
683                 case BTRC_MEDIA_ATTR_PLAYING_TIME:
684                         snprintf((char*)p_attrs_vals[i].text, BTRC_MAX_ATTR_STR_LEN, "%u", track_info.playing_time);
685                         break;
686                 default:
687                         BT_ERR("Inavlid attr id= %d", p_attrs[i]);
688                 }
689         }
690
691         ret = avrcp_api->get_element_attr_rsp(bd_addr, num_attr, p_attrs_vals);
692         if (ret != BT_STATUS_SUCCESS)
693                 BT_ERR("Element attr send failed: %s", status2string(ret));
694
695         g_free(p_attrs_vals);
696 }
697
698 static void cb_avrcp_register_notification(btrc_event_id_t event_id, uint32_t param, bt_bdaddr_t *bd_addr)
699 {
700         btrc_register_notification_t response;
701         int ret;
702
703         BT_DBG("event_id: 0x%x", event_id);
704
705         if (avrcp_api == NULL) {
706                 BT_ERR("AVRCP Not Enabled");
707                 return ;
708         }
709         memset(&response, 0x00, sizeof(btrc_register_notification_t));
710
711         switch (event_id) {
712         case BTRC_EVT_PLAY_STATUS_CHANGED:
713                 registered_notifications.play_status = 1;
714                 response.play_status = player_setting.status;
715                 ret = avrcp_api->register_notification_rsp(
716                         BTRC_EVT_PLAY_STATUS_CHANGED, BTRC_NOTIFICATION_TYPE_INTERIM, &response);
717                 break;
718         case BTRC_EVT_TRACK_CHANGE:
719                 registered_notifications.track_change = 1;
720                 memcpy(response.track, &track_info.cur_track, sizeof(uint32_t));
721                 ret = avrcp_api->register_notification_rsp(
722                         BTRC_EVT_TRACK_CHANGE, BTRC_NOTIFICATION_TYPE_INTERIM, &response);
723                 break;
724         case BTRC_EVT_TRACK_REACHED_END:
725                 registered_notifications.track_end = 1;
726                 ret = avrcp_api->register_notification_rsp(
727                         BTRC_EVT_TRACK_REACHED_END, BTRC_NOTIFICATION_TYPE_INTERIM, NULL);
728                 break;
729         case BTRC_EVT_TRACK_REACHED_START:
730                 registered_notifications.track_start = 1;
731                 ret = avrcp_api->register_notification_rsp(
732                         BTRC_EVT_TRACK_REACHED_START, BTRC_NOTIFICATION_TYPE_INTERIM, NULL);
733                 break;
734         case BTRC_EVT_PLAY_POS_CHANGED:
735                 registered_notifications.pos_change = 1;
736                 registered_notifications.interval = param;
737                 BT_DBG("Pos will be notified every %d secs", param);
738                 /*
739                  * start a timer with value of interval and send rsp on each timer fire.
740                  * Other then this in below situations also send the response:
741                  *      - Change in Play status
742                  *      - Change in current track
743                  *      - Reach end or beginning of track
744                  */
745                 response.song_pos = track_info.song_pos;
746                 ret = avrcp_api->register_notification_rsp(
747                         BTRC_EVT_PLAY_POS_CHANGED, BTRC_NOTIFICATION_TYPE_INTERIM, &response);
748                 remove_pos_timer();
749                 send_pos_timer = g_timeout_add(param * 1000, send_pos_timeout, NULL);
750                 break;
751         case BTRC_EVT_APP_SETTINGS_CHANGED:
752                 registered_notifications.setting_change = 1;
753                 ret = avrcp_api->register_notification_rsp(
754                         BTRC_EVT_APP_SETTINGS_CHANGED, BTRC_NOTIFICATION_TYPE_INTERIM, &response);
755                 break;
756         default:
757                 BT_ERR("Invalid event id: 0x%x", event_id);
758                 ret = BT_STATUS_FAIL;
759         }
760
761         if (ret != BT_STATUS_SUCCESS)
762                 BT_ERR("Notif send failed: %s", status2string(ret));
763 }
764
765 static void cb_avrcp_volume_change(uint8_t volume, uint8_t ctype, bt_bdaddr_t *bd_addr)
766 {
767
768         oal_avrcp_volume_mute_t *avrcp_volume_mute = g_new0(oal_avrcp_volume_mute_t, 1);
769
770         BT_INFO("volume: %d, ctype: %d", volume, ctype);
771         player_setting.volume = volume;
772
773         avrcp_volume_mute->volume = volume;
774         if (0 == volume)
775                 avrcp_volume_mute->mute_status = TRUE;
776         else
777                 avrcp_volume_mute->mute_status = FALSE;
778
779         send_event(OAL_EVENT_AVRCP_VOLUME_MUTE_CHANGED,
780                         avrcp_volume_mute, sizeof(oal_avrcp_volume_mute_t));
781 }
782
783 static void cb_avrcp_delay_change(uint16_t delay, bt_bdaddr_t *bd_addr)
784 {
785         BT_INFO("Delay : %d", delay);
786         oal_avrcp_delay_t *avrcp_delay = g_new0(oal_avrcp_delay_t, 1);
787         avrcp_delay->delay = delay;
788
789         send_event(OAL_EVENT_AVRCP_DELAY_CHANGED,
790                         avrcp_delay, sizeof(oal_avrcp_delay_t));
791 }
792
793 static void cb_avrcp_passthrough_command(int id, int key_state, bt_bdaddr_t *bd_addr)
794 {
795         BT_DBG("id: %d, key_state: %d", id, key_state);
796         //TODO: need to check
797 }