Fixed gatt char read value when length of value is zero
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / oal-avrcp-ctrl.c
1 /*
2  * Open Adaptation Layer (OAL)
3  *
4  * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd.
5  *
6  * Contact: Nilesh Trimbake <t.shripati@samsung.com>
7  *
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
11  *
12  *              http://www.apache.org/licenses/LICENSE-2.0
13  *
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.
19  *
20  */
21
22 #include <stdio.h>
23 #include <sys/un.h>
24 #include <sys/socket.h>
25 #include <sys/errno.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <dlog.h>
29 #include <glib.h>
30
31 #include <bluetooth.h>
32 #include <bt_rc.h>
33
34 #include "oal-internal.h"
35 #include "oal-avrcp-ct.h"
36 #include "oal-utils.h"
37 #include "oal-common.h"
38
39 #define CHECK_OAL_AVRCP_CTRL_ENABLED() \
40         do { \
41                 if (avrcp_ct_interface == NULL) { \
42                         BT_ERR("OAL, Audio Not Enabled"); \
43                         return OAL_STATUS_NOT_READY; \
44                 } \
45         } while (0)
46
47 #define NO_OF_ATTRIBUTE 1
48
49 typedef struct {
50         long int song_pos;
51         long int playing_time;
52         uint8_t title_info[BTRC_MAX_ATTR_STR_LEN];
53         uint8_t artist_info[BTRC_MAX_ATTR_STR_LEN];
54         uint8_t album_info[BTRC_MAX_ATTR_STR_LEN];
55         uint8_t genre_info[BTRC_MAX_ATTR_STR_LEN];
56         long int total_track;
57         uint32_t track_number;
58 } avrcp_ct_track_info_t;
59
60 typedef struct {
61         bdstr_t bdstr;
62         int equalizer;
63         btrc_player_repeat_val_t repeat;
64         btrc_player_shuffle_val_t shuffle;
65         int scan;
66         btrc_play_status_t status;
67         unsigned int volume;
68 } avrcp_ct_player_settings_t;
69
70 typedef struct {
71         char address[BT_ADDRESS_STR_LEN];
72         avrcp_ct_player_settings_t player_setting;
73         avrcp_ct_track_info_t track_info;
74 } avrcp_ct_player_info_t;
75
76 static GSList *player_list = NULL;
77
78 const btrc_ctrl_interface_t * _bt_get_stack_interface(void);
79 static const btrc_ctrl_interface_t *avrcp_ct_interface = NULL;
80
81 static void cb_avrcp_ct_connection_state(bool rc_connect, bool bt_connect, bt_bdaddr_t* bd_addr);
82 static void cb_avrcp_ct_btrc_playerapplicationsetting_changed(bt_bdaddr_t *bd_addr, btrc_player_settings_t *p_vals);
83 static void cb_avrcp_ct_btrc_play_position_changed(bt_bdaddr_t *bd_addr, uint32_t song_len, uint32_t song_pos);
84 static void cb_avrcp_ct_btrc_play_status_changed(bt_bdaddr_t *bd_addr, btrc_play_status_t play_status);
85 static void cb_avrcp_ct_trak_info_chnaged(bt_bdaddr_t *bd_address, uint8_t num_attr, btrc_element_attr_val_t *p_attrs);
86 static void cb_avrcp_ct_btrc_passthrough_rsp(bt_bdaddr_t *bd_addr, int id, int key_state);
87 static void cb_avrcp_ct_btrc_setplayerapplicationsetting_rsp(bt_bdaddr_t *bd_addr, uint8_t accepted);
88
89 /** AVRCP Controller callback structure. */
90 static btrc_ctrl_callbacks_t avrcp_ct_cb = {
91         /** set to sizeof(BtRcCallbacks) */
92         sizeof(avrcp_ct_cb),
93         cb_avrcp_ct_btrc_passthrough_rsp,
94         NULL, //cb_avrcp_ct_btrc_groupnavigation_rsp,
95         cb_avrcp_ct_connection_state,
96         NULL,/*btrc_ct_getrcfeatures_callback*/
97         cb_avrcp_ct_btrc_setplayerapplicationsetting_rsp,
98         NULL, /*btrc_ct_playerapplicationsetting_callback*/
99         cb_avrcp_ct_btrc_playerapplicationsetting_changed,
100         NULL, /*btrc_ct_setabsvol_cmd_callback*/
101         NULL, /*btrc_ct_registernotification_abs_vol_callback*/
102         cb_avrcp_ct_trak_info_chnaged,
103         cb_avrcp_ct_btrc_play_position_changed,
104         cb_avrcp_ct_btrc_play_status_changed,
105         NULL, /*btrc_ct_get_folder_items_callback*/
106         NULL, /*btrc_ct_change_path_callback*/
107         NULL, /*btrc_ct_set_browsed_player_callback*/
108         NULL /*btrc_ct_set_addressed_player_callback*/
109 };
110
111 static void __add_device_to_avrcp_list(bt_address_t *address)
112 {
113         avrcp_ct_player_info_t *player_info;
114         avrcp_ct_player_settings_t *player_setting;
115         bdstr_t bdstr;
116         GSList *l;
117
118         bdt_bd2str(address, &bdstr);
119         BT_INFO("Address: %s", bdstr);
120         for (l = player_list; NULL != l; l = g_slist_next(l)) {
121                 player_info = (avrcp_ct_player_info_t *)l->data;
122
123                 if (!player_info)
124                         continue;
125
126                 if (!strncmp(bdstr, player_info->address, BT_ADDRESS_STR_LEN)) {
127                         BT_INFO("Already added");
128                         return;
129                 }
130         }
131
132         player_info = g_new0(avrcp_ct_player_info_t, 1);
133
134         /* Copy address to player_info->address */
135         g_strlcpy(player_info->address, bdstr, BT_ADDRESS_STR_LEN);
136
137         /* Init player settings with default values */
138         player_setting = &player_info->player_setting;
139         player_setting->equalizer = 0;
140         player_setting->repeat = BTRC_PLAYER_VAL_OFF_REPEAT;
141         player_setting->shuffle = BTRC_PLAYER_VAL_OFF_SHUFFLE;
142         player_setting->scan = 0;
143         player_setting->status = BTRC_PLAYSTATE_STOPPED;
144         player_setting->volume = 0;
145
146         /* Nothing to do for track_info as values are already initialized to 0 */
147
148         /* Add player_info to player_list */
149         player_list = g_slist_append(player_list, player_info);
150 }
151
152 static void __remove_device_from_avrcp_list(bt_address_t *address)
153 {
154         avrcp_ct_player_info_t *player_info = NULL;
155         bdstr_t bdstr;
156         GSList *l;
157
158         bdt_bd2str(address, &bdstr);
159         BT_INFO("Address: %s", bdstr);
160         for (l = player_list; NULL != l; l = g_slist_next(l)) {
161                 player_info = (avrcp_ct_player_info_t *)l->data;
162
163                 if (!player_info)
164                         continue;
165
166                 if (!strncmp(bdstr, player_info->address, BT_ADDRESS_STR_LEN)) {
167                         BT_INFO("Found");
168                         break;
169                 }
170
171                 player_info = NULL;
172         }
173
174         if (!player_info)
175                 return;
176
177         player_list = g_slist_remove(player_list, player_info);
178         g_free(player_info);
179 }
180
181 static avrcp_ct_player_info_t *__get_player_info_from_list(bt_address_t *address)
182 {
183         avrcp_ct_player_info_t *player_info;
184         bdstr_t bdstr;
185         GSList *l;
186
187         bdt_bd2str(address, &bdstr);
188         BT_INFO("Address: %s", bdstr);
189         for (l = player_list; NULL != l; l = g_slist_next(l)) {
190                 player_info = (avrcp_ct_player_info_t *)l->data;
191
192                 if (!player_info)
193                         continue;
194
195                 if (!strncmp(bdstr, player_info->address, BT_ADDRESS_STR_LEN)) {
196                         BT_INFO("Found");
197                         return player_info;
198                 }
199         }
200
201         return NULL;
202 }
203
204 oal_status_t avrcp_ct_enable(void)
205 {
206         const bt_interface_t* blued_inf;
207         int ret;
208
209         API_TRACE("AVRCP Controller Enable");
210
211         if ((blued_inf = adapter_get_stack_interface()) == NULL) {
212                 BT_ERR("Bluetooth module is not loaded");
213                 return OAL_STATUS_NOT_READY;
214         }
215
216         if (avrcp_ct_interface != NULL) {
217                 BT_WARN("AVRCP Controller Interface is already initialized...");
218                 return OAL_STATUS_ALREADY_DONE;
219         }
220
221         if ((avrcp_ct_interface = (const btrc_ctrl_interface_t *)blued_inf->get_profile_interface(BT_PROFILE_AV_RC_CTRL_ID)) == NULL) {
222                 BT_ERR("OAL, Failed to get Bluetooth AVRCP Controller Interface");
223                 return OAL_STATUS_INTERNAL_ERROR;
224         }
225
226         BT_DBG("Got profile interface");
227         if ((ret = avrcp_ct_interface->init(&avrcp_ct_cb)) != BT_STATUS_SUCCESS) {
228                 BT_ERR("Failed to initialize Bluetooth AVRCP Controller, status: %s", status2string(ret));
229                 avrcp_ct_interface = NULL;
230                 return convert_to_oal_status(ret);
231         }
232         BT_DBG("OAL, Bluetooth avrcp controller interface initialised");
233
234         return OAL_STATUS_SUCCESS;
235 }
236
237 /* Audio deinit: Resets all the audio information
238  * Note: Adapter should be disabled before calling deinit
239  * */
240 oal_status_t avrcp_ct_disable(void)
241 {
242         API_TRACE("AVRCP Controller Disable");
243
244         CHECK_OAL_AVRCP_CTRL_ENABLED();
245
246         avrcp_ct_interface->cleanup();
247         avrcp_ct_interface = NULL;
248
249         return OAL_STATUS_SUCCESS;
250 }
251
252 void avrcp_ct_cleanup(void)
253 {
254         BT_DBG();
255         avrcp_ct_interface = NULL;
256 }
257
258
259 oal_status_t avrcp_ct_connect(bt_address_t *device_address)
260 {
261         int result = OAL_STATUS_SUCCESS;
262         bt_status_t status;
263         bdstr_t bdstr;
264
265         API_TRACE();
266
267         CHECK_OAL_AVRCP_CTRL_ENABLED();
268         OAL_CHECK_PARAMETER(device_address, return);
269
270         BT_INFO("BT Audio Address: %s", bdt_bd2str(device_address, &bdstr));
271
272 #ifdef TIZEN_BT_HAL
273         status = avrcp_ct_interface->connect((bt_bdaddr_t *)device_address);
274         if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
275                 BT_ERR("Connection could not be established, err: %s", status2string(status));;
276                 result =  convert_to_oal_status(status);
277         }
278 #else
279         BT_INFO("Not Supported");
280         result = OAL_STATUS_NOT_SUPPORT;
281 #endif
282         return result;
283 }
284
285 oal_status_t avrcp_ct_disconnect(bt_address_t *device_address)
286 {
287         int result = OAL_STATUS_SUCCESS;
288         bdstr_t bdstr;
289         bt_status_t status;
290
291         API_TRACE();
292
293         CHECK_OAL_AVRCP_CTRL_ENABLED();
294         OAL_CHECK_PARAMETER(device_address, return);
295
296         BT_INFO("BT Audio Address: %s", bdt_bd2str(device_address, &bdstr));
297
298 #ifdef TIZEN_BT_HAL
299         status = avrcp_ct_interface->disconnect((bt_bdaddr_t *)device_address);
300         if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
301                 BT_ERR("OAL, Disconnection failed err: %s", status2string(status));
302                 result =  convert_to_oal_status(status);
303         }
304 #else
305         BT_INFO("Not Supported");
306         result = OAL_STATUS_NOT_SUPPORT;
307 #endif
308         return result;
309 }
310
311 static void cb_avrcp_ct_connection_state(bool rc_connect, bool bt_connect, bt_bdaddr_t* bd_addr)
312 {
313         bt_address_t *event_data = NULL;
314         bdstr_t bdstr;
315         oal_event_t event;
316
317         ret_if(bd_addr == NULL);
318         BT_INFO("rc_connect = %d, bt_connect = %d, BT Address = %s",
319                         rc_connect, bt_connect, bdt_bd2str((bt_address_t*)bd_addr, &bdstr));
320
321         event_data = g_new0(bt_address_t, 1);
322         memcpy(event_data->addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
323
324         if (rc_connect) {
325                 event = OAL_EVENT_AVRCP_CT_CONNECTED;
326                 __add_device_to_avrcp_list(event_data);
327         } else {
328                 event = OAL_EVENT_AVRCP_CT_DISCONNECTED;
329                 __remove_device_from_avrcp_list(event_data);
330         }
331
332         send_event_bda_trace(event, event_data, sizeof(bt_address_t), (bt_address_t*)bd_addr);
333 }
334
335 notif_event_avrcp_ct_play_status_t __hal_to_oal_play_status(btrc_play_status_t play_status)
336 {
337         notif_event_avrcp_ct_play_status_t status = OAL_PLAY_STATUS_ERROR;
338
339         switch (play_status) {
340         case BTRC_PLAYSTATE_STOPPED:
341                 status = OAL_PLAY_STATUS_STOPPED;
342                 break;
343         case BTRC_PLAYSTATE_PLAYING:
344                 status = OAL_PLAY_STATUS_PLAYING;
345                 break;
346         case BTRC_PLAYSTATE_PAUSED:
347                 status = OAL_PLAY_STATUS_PAUSED;
348                 break;
349         case BTRC_PLAYSTATE_FWD_SEEK:
350                 status = OAL_PLAY_STATUS_FWD_SEEK;
351                 break;
352         case BTRC_PLAYSTATE_REV_SEEK:
353                 status = OAL_PLAY_STATUS_REV_SEEK;
354                 break;
355         default:
356                 BT_INFO("Incorrect Play status");
357                 break;
358         }
359
360         return status;
361 }
362
363 static avrcp_ct_player_settings_t *__get_player_setting(bt_address_t *address)
364 {
365         avrcp_ct_player_info_t *player_info;
366
367         BT_INFO("");
368         player_info = __get_player_info_from_list(address);
369         if (!player_info)
370                 return NULL;
371
372         return &player_info->player_setting;
373 }
374
375 static void cb_avrcp_ct_btrc_playerapplicationsetting_changed(
376                 bt_bdaddr_t *bd_addr, btrc_player_settings_t *p_vals)
377 {
378         avrcp_ct_property_value_t *event_data = NULL;
379         oal_event_t event;
380         int i;
381         bdstr_t bdstr;
382         avrcp_ct_player_settings_t *player_setting;
383
384         bdt_bd2str((bt_address_t *)bd_addr, &bdstr);
385         player_setting = __get_player_setting((bt_address_t *)bd_addr);
386         if (!player_setting) {
387                 BT_INFO("player_setting is NULL");
388                 /* Player info not yet added to player_list, first add it to list */
389                 __add_device_to_avrcp_list((bt_address_t *)bd_addr);
390                 player_setting = __get_player_setting((bt_address_t *)bd_addr);
391         }
392
393         for (i = 0; i < p_vals->num_attr; i++) {
394                 event_data = g_new0(avrcp_ct_property_value_t, 1);
395
396                 switch (p_vals->attr_ids[i]) {
397                 case BTRC_PLAYER_ATTR_EQUALIZER:
398                         event = OAL_EVENT_AVRCP_CT_EQUALIZER_STATUS;
399                         event_data->type = OAL_EQUALIZER;
400                         event_data->value = p_vals->attr_values[i];
401                         player_setting->equalizer = p_vals->attr_values[i];
402                         break;
403                 case BTRC_PLAYER_ATTR_REPEAT:
404                         event = OAL_EVENT_AVRCP_CT_REPEAT_STATUS;
405                         event_data->type = OAL_REPEAT;
406                         event_data->value = p_vals->attr_values[i];
407                         player_setting->repeat = p_vals->attr_values[i];
408                         break;
409                 case BTRC_PLAYER_ATTR_SHUFFLE:
410                         event = OAL_EVENT_AVRCP_CT_SHUFFLE_STATUS;
411                         event_data->type = OAL_SHUFFLE;
412                         event_data->value = p_vals->attr_values[i];
413                         player_setting->shuffle = p_vals->attr_values[i];
414                         break;
415                 case BTRC_PLAYER_ATTR_SCAN:
416                         event = OAL_EVENT_AVRCP_CT_SCAN_STATUS;
417                         event_data->type = OAL_SCAN;
418                         event_data->value = p_vals->attr_values[i];
419                         player_setting->scan = p_vals->attr_values[i];
420                         break;
421                 default:
422                         event = OAL_EVENT_END;
423                         g_free(event_data);
424                         break;
425                 }
426
427                 if (OAL_EVENT_END != event)
428                         send_event(event, event_data, sizeof(avrcp_ct_property_value_t));
429         }
430 }
431
432 static avrcp_ct_track_info_t *__get_track_info(bt_address_t *address)
433 {
434         avrcp_ct_player_info_t *player_info;
435
436         BT_INFO("");
437         player_info = __get_player_info_from_list(address);
438         if (!player_info)
439                 return NULL;
440
441         return &player_info->track_info;
442 }
443
444 static void cb_avrcp_ct_btrc_play_position_changed(
445                 bt_bdaddr_t *bd_addr, uint32_t song_len, uint32_t song_pos)
446 {
447         event_notif_avrcp_ct_notif_info_t *event_data = NULL;
448         avrcp_ct_track_info_t *track_info;
449
450         track_info = __get_track_info((bt_address_t *)bd_addr);
451         if (!track_info) {
452                 BT_INFO("track_info is NULL");
453                 /* Player info not yet added to player_list, first add it to list */
454                 __add_device_to_avrcp_list((bt_address_t *)bd_addr);
455                 track_info = __get_track_info((bt_address_t *)bd_addr);
456         }
457         track_info->song_pos = song_pos;
458
459         event_data = g_new0(event_notif_avrcp_ct_notif_info_t, 1);
460         event_data->song_pos = song_pos;
461         send_event(OAL_EVENT_AVRCP_CT_NOTIF_PLAY_POS_CHANGED,
462                         event_data, sizeof(event_notif_avrcp_ct_notif_info_t));
463 }
464
465 static void cb_avrcp_ct_btrc_play_status_changed(
466                 bt_bdaddr_t *bd_addr, btrc_play_status_t play_status)
467 {
468         event_notif_avrcp_ct_notif_info_t *event_data = NULL;
469         avrcp_ct_player_settings_t *player_setting;
470
471         player_setting = __get_player_setting((bt_address_t *)bd_addr);
472         if (!player_setting) {
473                 BT_INFO("player_setting is NULL");
474                 /* Player info not yet added to player_list, first add it to list */
475                 __add_device_to_avrcp_list((bt_address_t *)bd_addr);
476                 player_setting = __get_player_setting((bt_address_t *)bd_addr);
477         }
478
479         player_setting->status = play_status;
480
481         event_data = g_new0(event_notif_avrcp_ct_notif_info_t, 1);
482         event_data->play_status = __hal_to_oal_play_status(play_status);
483         send_event(OAL_EVENT_AVRCP_CT_NOTIF_PLAY_STATUS_CHANGED,
484                         event_data, sizeof(event_notif_avrcp_ct_notif_info_t));
485 }
486
487 static void cb_avrcp_ct_btrc_passthrough_rsp(bt_bdaddr_t *bd_addr, int id, int state)
488 {
489         avrcp_ct_pass_cmd_key_code_t key_code;
490         avrcp_ct_pass_state_t key_state;
491         avrcp_ct_pass_cmd_t *event_data;
492
493         event_data = g_new0(avrcp_ct_pass_cmd_t, 1);
494
495         key_code = id;
496         key_state = state;
497         if (key_code) {
498                 event_data->key_code = key_code;
499                 event_data->key_state = key_state;
500                 send_event(OAL_EVENT_AVRCP_CT_PASS_CMD_RES,
501                                 event_data, sizeof(avrcp_ct_pass_cmd_t));
502         } else {
503                 BT_ERR("Invalid pass through command key code");
504                 g_free(event_data);
505         }
506 }
507
508 static void cb_avrcp_ct_btrc_setplayerapplicationsetting_rsp(
509                 bt_bdaddr_t *bd_addr, uint8_t accepted)
510 {
511         avrcp_ct_playersetting_t *event_data;
512
513         event_data = g_new0(avrcp_ct_playersetting_t, 1);
514
515         event_data->accepted = accepted;
516         send_event(OAL_EVENT_AVRCP_CT_PLAYER_SETTING_RES,
517                         event_data, sizeof(avrcp_ct_playersetting_t));
518 }
519
520 static void cb_avrcp_ct_trak_info_chnaged(bt_bdaddr_t *device_address,
521                 uint8_t num_attr, btrc_element_attr_val_t *p_attrs)
522 {
523         int idx = 0;
524         avrcp_ct_track_info_t *track_info;
525         event_avrcp_ct_media_info_t *event_data = NULL;
526
527         track_info = __get_track_info((bt_address_t *)device_address);
528         if (!track_info) {
529                 BT_INFO("track_info is NULL");
530                 /* Player info not yet added to player_list, first add it to list */
531                 __add_device_to_avrcp_list((bt_address_t *)device_address);
532                 track_info = __get_track_info((bt_address_t *)device_address);
533         }
534
535         event_data = g_new0(event_avrcp_ct_media_info_t, 1);
536         for (idx = 0; idx < num_attr; idx++) {
537                 BT_INFO("idx [%d]", p_attrs[idx].attr_id);
538
539                 switch (p_attrs[idx].attr_id) {
540                 case BTRC_MEDIA_ATTR_ID_TITLE:
541                         g_strlcpy((char *)track_info->title_info, (const char *)&p_attrs[idx].text,
542                                         MEDIA_ATTIRBUTE_STRING_LENGTH);
543                         g_strlcpy((char *)event_data->title_info, (const char *)&p_attrs[idx].text,
544                                         MEDIA_ATTIRBUTE_STRING_LENGTH);
545                         break;
546                 case BTRC_MEDIA_ATTR_ID_ARTIST:
547                         g_strlcpy((char *)track_info->artist_info, (const char *)&p_attrs[idx].text,
548                                         MEDIA_ATTIRBUTE_STRING_LENGTH);
549                         g_strlcpy((char *)event_data->artist_info, (const char *)&p_attrs[idx].text,
550                                         MEDIA_ATTIRBUTE_STRING_LENGTH);
551                         break;
552                 case BTRC_MEDIA_ATTR_ID_ALBUM:
553                         g_strlcpy((char *)track_info->album_info, (const char *)&p_attrs[idx].text,
554                                         MEDIA_ATTIRBUTE_STRING_LENGTH);
555                         g_strlcpy((char *)event_data->album_info, (const char *)&p_attrs[idx].text,
556                                         MEDIA_ATTIRBUTE_STRING_LENGTH);
557                         break;
558                 case BTRC_MEDIA_ATTR_ID_GENRE:
559                         g_strlcpy((char *)track_info->genre_info, (const char *)&p_attrs[idx].text,
560                                         MEDIA_ATTIRBUTE_STRING_LENGTH);
561                         g_strlcpy((char *)event_data->genre_info, (const char *)&p_attrs[idx].text,
562                                         MEDIA_ATTIRBUTE_STRING_LENGTH);
563                         break;
564                 case BTRC_MEDIA_ATTR_ID_NUM_TRACKS:
565                         if (p_attrs[idx].text != NULL) {
566                                 track_info->total_track = g_ascii_strtoll(
567                                                 (const gchar *)p_attrs[idx].text, NULL, 10);
568                                 event_data->total_track = track_info->total_track;
569                         }
570                         break;
571                 case BTRC_MEDIA_ATTR_ID_TRACK_NUM:
572                         if (p_attrs[idx].text != NULL) {
573                                 track_info->track_number = g_ascii_strtoll(
574                                                 (const gchar *)p_attrs[idx].text, NULL, 10);
575                                 event_data->track_number = track_info->track_number;
576                         }
577                         break;
578                 case BTRC_MEDIA_ATTR_ID_PLAYING_TIME:
579                                 track_info->playing_time = g_ascii_strtoll(
580                                                 (const gchar *)p_attrs[idx].text, NULL, 10);
581                                 event_data->playing_time = (uint64_t) track_info->playing_time;
582                         break;
583                 default:
584                         break;
585                 }
586         }
587
588         send_event(OAL_EVENT_AVRCP_CT_NOTIF_TRACK_CHANGE,
589                         event_data, sizeof(event_avrcp_ct_media_info_t));
590         return;
591 }
592
593 oal_status_t __avrcp_ct_send_pass_through_cmd(bt_address_t *device_address,
594                 avrcp_ct_pass_cmd_key_code_t key_code, avrcp_ct_pass_state_t key_state)
595 {
596         int result = OAL_STATUS_SUCCESS;
597         bt_status_t status;
598         bdstr_t bdstr;
599
600         API_TRACE();
601
602         CHECK_OAL_AVRCP_CTRL_ENABLED();
603
604         BT_INFO("BT Audio Address: %s", bdt_bd2str(device_address, &bdstr));
605
606         status = avrcp_ct_interface->send_pass_through_cmd((bt_bdaddr_t *)device_address,
607                         key_code, key_state);
608         if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
609                 BT_ERR("OAL, send pass through cmd failed err: %s", status2string(status));
610                 result =  convert_to_oal_status(status);
611         }
612         return result;
613 }
614
615 oal_status_t avrcp_ct_play(bt_address_t *device_address)
616 {
617         oal_status_t result = OAL_STATUS_SUCCESS;
618
619         API_TRACE();
620
621         result = __avrcp_ct_send_pass_through_cmd(device_address,
622                         OAL_RC_PASS_CMD_PLAY, PRESS_STATE);
623
624         return result;
625 }
626
627 oal_status_t avrcp_ct_pause(bt_address_t *device_address)
628 {
629         oal_status_t result = OAL_STATUS_SUCCESS;
630
631         API_TRACE();
632
633         result = __avrcp_ct_send_pass_through_cmd(device_address,
634                         OAL_RC_PASS_CMD_PAUSE, PRESS_STATE);
635
636         return result;
637 }
638
639 oal_status_t avrcp_ct_stop(bt_address_t *device_address)
640 {
641         oal_status_t result = OAL_STATUS_SUCCESS;
642
643         API_TRACE();
644
645         result = __avrcp_ct_send_pass_through_cmd(device_address,
646                         OAL_RC_PASS_CMD_STOP, PRESS_STATE);
647
648         return result;
649 }
650
651 oal_status_t avrcp_ct_next_track(bt_address_t *device_address)
652 {
653         oal_status_t result = OAL_STATUS_SUCCESS;
654
655         API_TRACE();
656
657         result = __avrcp_ct_send_pass_through_cmd(device_address,
658                         OAL_RC_PASS_CMD_NEXT, PRESS_STATE);
659
660         return result;
661 }
662
663 oal_status_t avrcp_ct_prev_track(bt_address_t *device_address)
664 {
665         oal_status_t result = OAL_STATUS_SUCCESS;
666
667         API_TRACE();
668
669         result = __avrcp_ct_send_pass_through_cmd(device_address,
670                         OAL_RC_PASS_CMD_PREVIOUS, PRESS_STATE);
671
672         return result;
673 }
674
675 oal_status_t avrcp_ct_fforward(bt_address_t *device_address, avrcp_ct_pass_state_t press_state)
676 {
677         oal_status_t result = OAL_STATUS_SUCCESS;
678
679         API_TRACE();
680         switch (press_state) {
681         case PRESS_STATE:
682                 result = __avrcp_ct_send_pass_through_cmd(device_address,
683                                 OAL_RC_PASS_CMD_PRESS_FAST_FORWARD, press_state);
684                 break;
685         case RELEASE_STATE:
686                 result = __avrcp_ct_send_pass_through_cmd(device_address,
687                                 OAL_RC_PASS_CMD_RELEASE_FAST_FORWARD, press_state);
688                 break;
689         default:
690                 result = OAL_STATUS_INVALID_PARAM;
691                 break;
692         }
693
694         return result;
695 }
696
697 oal_status_t avrcp_ct_rewind(bt_address_t *device_address, avrcp_ct_pass_state_t press_state)
698 {
699         oal_status_t result = OAL_STATUS_SUCCESS;
700
701         API_TRACE();
702         switch (press_state) {
703         case PRESS_STATE:
704                 result = __avrcp_ct_send_pass_through_cmd(device_address,
705                                 OAL_RC_PASS_CMD_PRESS_REWIND, press_state);
706                 break;
707         case RELEASE_STATE:
708                 result = __avrcp_ct_send_pass_through_cmd(device_address,
709                                 OAL_RC_PASS_CMD_RELEASE_REWIND, press_state);
710                 break;
711         default:
712                 result = OAL_STATUS_INVALID_PARAM;
713                 break;
714         }
715
716         return result;
717 }
718
719 uint8_t __oal_to_hal_property_type(avrcp_ct_player_property_type_t type)
720 {
721         uint8_t property_type = 0;
722
723         switch (type) {
724         case OAL_EQUALIZER:
725                 property_type = BTRC_PLAYER_ATTR_EQUALIZER;
726                 break;
727         case OAL_REPEAT:
728                 property_type = BTRC_PLAYER_ATTR_REPEAT;
729                 break;
730         case OAL_SHUFFLE:
731                 property_type = BTRC_PLAYER_ATTR_SHUFFLE;
732                 break;
733         case OAL_SCAN:
734                 property_type = BTRC_PLAYER_ATTR_SCAN;
735                 break;
736         default:
737                 BT_ERR(" Invalid Property type[%d]", type);
738                 break;
739         }
740
741         return property_type;
742 }
743
744 oal_status_t avrcp_ct_set_property(bt_address_t *device_address, avrcp_ct_player_property_type_t type, uint32_t value)
745 {
746         int result = OAL_STATUS_SUCCESS;
747         uint8_t property_type;
748         bt_status_t status;
749         bdstr_t bdstr;
750
751         API_TRACE();
752
753         CHECK_OAL_AVRCP_CTRL_ENABLED();
754         BT_INFO("BT Audio Address: %s", bdt_bd2str(device_address, &bdstr));
755
756         property_type = __oal_to_hal_property_type(type);
757         if (property_type) {
758                 status = avrcp_ct_interface->set_player_app_setting_cmd((bt_bdaddr_t *)device_address, NO_OF_ATTRIBUTE,
759                                 (uint8_t*)&property_type, (uint8_t*)&value);
760                 if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
761                         BT_ERR("OAL, Set property failed err: %s", status2string(status));
762                         result =  convert_to_oal_status(status);
763                 }
764         } else {
765                 result = OAL_STATUS_INTERNAL_ERROR;
766         }
767         return result;
768 }
769
770 oal_status_t avrcp_transport_set_property(bt_address_t *device_address, int type, unsigned int value)
771 {
772         int result = OAL_STATUS_SUCCESS;
773         bt_status_t status;
774         bdstr_t bdstr;
775
776         API_TRACE();
777
778         CHECK_OAL_AVRCP_CTRL_ENABLED();
779         BT_INFO("BT Audio Address: %s", bdt_bd2str(device_address, &bdstr));
780
781         if (type) {
782                 status = avrcp_ct_interface->set_transport_setting_cmd((bt_bdaddr_t *)device_address, NO_OF_ATTRIBUTE,
783                                 &type, &value);
784                 if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
785                         BT_ERR("OAL, Set property failed err: %s", status2string(status));
786                         result =  convert_to_oal_status(status);
787                 }
788         } else {
789                 result = OAL_STATUS_INTERNAL_ERROR;
790         }
791         return result;
792 }
793
794 static gboolean __send_avrcp_property_event(gpointer data)
795 {
796         avrcp_ct_property_value_t *event_data = (avrcp_ct_property_value_t *)data;
797
798         send_event(OAL_EVENT_AVRCP_CT_GET_PROPERTY_RES,
799                         event_data, sizeof(avrcp_ct_property_value_t));
800         return FALSE;
801 }
802
803 oal_status_t avrcp_ct_get_property(bt_address_t *device_address, avrcp_ct_player_property_type_t type)
804 {
805         avrcp_ct_player_info_t *player_info;
806         avrcp_ct_player_settings_t *player_setting;
807         avrcp_ct_track_info_t *track_info;
808         avrcp_ct_property_value_t *event_data;
809
810         API_TRACE();
811         CHECK_OAL_AVRCP_CTRL_ENABLED();
812
813         player_info = __get_player_info_from_list(device_address);
814         if (!player_info) {
815                 BT_ERR("Player info not found");
816                 return OAL_STATUS_INVALID_PARAM;
817         }
818
819         player_setting = &player_info->player_setting;
820         track_info = &player_info->track_info;
821
822         event_data = g_new0(avrcp_ct_property_value_t, 1);
823         event_data->type = type;
824
825         switch (type) {
826         case OAL_EQUALIZER:
827                 event_data->value = player_setting->equalizer;
828                 break;
829         case OAL_REPEAT:
830                 event_data->value = player_setting->repeat;
831                 break;
832         case OAL_SHUFFLE:
833                 event_data->value = player_setting->shuffle;
834                 break;
835         case OAL_SCAN:
836                 event_data->value = player_setting->scan;
837                 break;
838         case OAL_PLAY_POSITION:
839                 event_data->value = track_info->song_pos;
840                 break;
841         default:
842                 BT_ERR("Invalid Type [%d]", type);
843                 g_free(event_data);
844                 return OAL_STATUS_INVALID_PARAM;
845         }
846
847         g_idle_add(__send_avrcp_property_event, (gpointer)event_data);
848         return OAL_STATUS_SUCCESS;
849 }
850
851 static gboolean __send_avrcp_play_status_event(gpointer data)
852 {
853         event_avrcp_ct_play_status_t *event_data = (event_avrcp_ct_play_status_t *)data;
854
855         send_event(OAL_EVENT_AVRCP_CT_PLAY_STATUS,
856                         event_data, sizeof(event_avrcp_ct_play_status_t));
857
858         return FALSE;
859 }
860
861 oal_status_t avrcp_ct_get_play_status(bt_address_t *device_address)
862 {
863         avrcp_ct_player_info_t *player_info;
864         avrcp_ct_player_settings_t *player_setting;
865         avrcp_ct_track_info_t *track_info;
866         event_avrcp_ct_play_status_t *event_data = NULL;
867
868         API_TRACE();
869         CHECK_OAL_AVRCP_CTRL_ENABLED();
870
871         player_info = __get_player_info_from_list(device_address);
872         if (!player_info) {
873                 BT_ERR("Player info not found");
874                 return OAL_STATUS_INVALID_PARAM;
875         }
876
877         player_setting = &player_info->player_setting;
878         track_info = &player_info->track_info;
879
880         event_data = g_new0(event_avrcp_ct_play_status_t, 1);
881         event_data->song_len = track_info->playing_time;
882         event_data->song_pos = track_info->song_pos;
883
884         switch (player_setting->status) {
885         case BTRC_PLAYSTATE_STOPPED:
886                 event_data->play_status = OAL_PLAY_STATUS_STOPPED;
887                 break;
888         case BTRC_PLAYSTATE_PLAYING:
889                 event_data->play_status = OAL_PLAY_STATUS_PLAYING;
890                 break;
891         case BTRC_PLAYSTATE_PAUSED:
892                 event_data->play_status = OAL_PLAY_STATUS_PAUSED;
893                 break;
894         case BTRC_PLAYSTATE_FWD_SEEK:
895                 event_data->play_status = OAL_PLAY_STATUS_FWD_SEEK;
896                 break;
897         case BTRC_PLAYSTATE_REV_SEEK:
898                 event_data->play_status = OAL_PLAY_STATUS_REV_SEEK;
899                 break;
900         default:
901                 event_data->play_status = OAL_PLAY_STATUS_ERROR;
902                 break;
903         }
904
905         g_idle_add(__send_avrcp_play_status_event, (gpointer)event_data);
906         return OAL_STATUS_SUCCESS;
907 }
908
909 static gboolean __send_media_attribute_event(gpointer data)
910 {
911         event_avrcp_ct_media_info_t *event_data = (event_avrcp_ct_media_info_t *)data;
912
913         send_event(OAL_EVENT_AVRCP_CT_MEDIA_INFO,
914                         event_data, sizeof(event_avrcp_ct_media_info_t));
915
916         return FALSE;
917 }
918
919 oal_status_t avrcp_ct_get_media_attribute(bt_address_t *device_address)
920 {
921         avrcp_ct_track_info_t *track_info;
922         event_avrcp_ct_media_info_t *event_data;
923
924         API_TRACE();
925
926         CHECK_OAL_AVRCP_CTRL_ENABLED();
927
928         OAL_CHECK_PARAMETER(device_address, return);
929
930         track_info = __get_track_info(device_address);
931         if (!track_info) {
932                 BT_ERR("Player info not found");
933                 return OAL_STATUS_INVALID_PARAM;
934         }
935
936         event_data = g_new0(event_avrcp_ct_media_info_t, 1);
937         g_strlcpy((char *)event_data->title_info, (const char *)track_info->title_info,
938                                 MEDIA_ATTIRBUTE_STRING_LENGTH);
939         g_strlcpy((char *)event_data->album_info, (const char *)track_info->album_info,
940                                 MEDIA_ATTIRBUTE_STRING_LENGTH);
941         g_strlcpy((char *)event_data->genre_info, (const char *)track_info->genre_info,
942                                 MEDIA_ATTIRBUTE_STRING_LENGTH);
943         g_strlcpy((char *)event_data->artist_info, (const char *)track_info->artist_info,
944                                 MEDIA_ATTIRBUTE_STRING_LENGTH);
945         event_data->playing_time = (uint64_t)track_info->playing_time;
946         event_data->total_track = track_info->total_track;
947         event_data->track_number = track_info->track_number;
948
949         g_idle_add(__send_media_attribute_event, (gpointer)event_data);
950
951         return OAL_STATUS_SUCCESS;
952 }