978166f68bb2af50fc404d48ae3cce59ff765b71
[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                         break;
424                 }
425
426                 if (OAL_EVENT_END != event)
427                         send_event(event, event_data, sizeof(avrcp_ct_property_value_t));
428         }
429 }
430
431 static avrcp_ct_track_info_t *__get_track_info(bt_address_t *address)
432 {
433         avrcp_ct_player_info_t *player_info;
434
435         BT_INFO("");
436         player_info = __get_player_info_from_list(address);
437         if (!player_info)
438                 return NULL;
439
440         return &player_info->track_info;
441 }
442
443 static void cb_avrcp_ct_btrc_play_position_changed(
444                 bt_bdaddr_t *bd_addr, uint32_t song_len, uint32_t song_pos)
445 {
446         event_notif_avrcp_ct_notif_info_t *event_data = NULL;
447         avrcp_ct_track_info_t *track_info;
448
449         track_info = __get_track_info((bt_address_t *)bd_addr);
450         if (!track_info) {
451                 BT_INFO("track_info is NULL");
452                 /* Player info not yet added to player_list, first add it to list */
453                 __add_device_to_avrcp_list((bt_address_t *)bd_addr);
454                 track_info = __get_track_info((bt_address_t *)bd_addr);
455         }
456         track_info->song_pos = song_pos;
457
458         event_data = g_new0(event_notif_avrcp_ct_notif_info_t, 1);
459         event_data->song_pos = song_pos;
460         send_event(OAL_EVENT_AVRCP_CT_NOTIF_PLAY_POS_CHANGED,
461                         event_data, sizeof(event_notif_avrcp_ct_notif_info_t));
462 }
463
464 static void cb_avrcp_ct_btrc_play_status_changed(
465                 bt_bdaddr_t *bd_addr, btrc_play_status_t play_status)
466 {
467         event_notif_avrcp_ct_notif_info_t *event_data = NULL;
468         avrcp_ct_player_settings_t *player_setting;
469
470         player_setting = __get_player_setting((bt_address_t *)bd_addr);
471         if (!player_setting) {
472                 BT_INFO("player_setting is NULL");
473                 /* Player info not yet added to player_list, first add it to list */
474                 __add_device_to_avrcp_list((bt_address_t *)bd_addr);
475                 player_setting = __get_player_setting((bt_address_t *)bd_addr);
476         }
477
478         player_setting->status = play_status;
479
480         event_data = g_new0(event_notif_avrcp_ct_notif_info_t, 1);
481         event_data->play_status = __hal_to_oal_play_status(play_status);
482         send_event(OAL_EVENT_AVRCP_CT_NOTIF_PLAY_STATUS_CHANGED,
483                         event_data, sizeof(event_notif_avrcp_ct_notif_info_t));
484 }
485
486 static void cb_avrcp_ct_btrc_passthrough_rsp(bt_bdaddr_t *bd_addr, int id, int state)
487 {
488         avrcp_ct_pass_cmd_key_code_t key_code;
489         avrcp_ct_pass_state_t key_state;
490         avrcp_ct_pass_cmd_t *event_data;
491
492         event_data = g_new0(avrcp_ct_pass_cmd_t, 1);
493
494         key_code = id;
495         key_state = state;
496         if (key_code) {
497                 event_data->key_code = key_code;
498                 event_data->key_state = key_state;
499                 send_event(OAL_EVENT_AVRCP_CT_PASS_CMD_RES,
500                                 event_data, sizeof(avrcp_ct_pass_cmd_t));
501         } else {
502                 BT_ERR("Invalid pass through command key code");
503         }
504 }
505
506 static void cb_avrcp_ct_btrc_setplayerapplicationsetting_rsp(
507                 bt_bdaddr_t *bd_addr, uint8_t accepted)
508 {
509         avrcp_ct_playersetting_t *event_data;
510
511         event_data = g_new0(avrcp_ct_playersetting_t, 1);
512
513         event_data->accepted = accepted;
514         send_event(OAL_EVENT_AVRCP_CT_PLAYER_SETTING_RES,
515                         event_data, sizeof(avrcp_ct_playersetting_t));
516 }
517
518 static void cb_avrcp_ct_trak_info_chnaged(bt_bdaddr_t *device_address,
519                 uint8_t num_attr, btrc_element_attr_val_t *p_attrs)
520 {
521         int idx = 0;
522         avrcp_ct_track_info_t *track_info;
523         event_avrcp_ct_media_info_t *event_data = NULL;
524
525         track_info = __get_track_info((bt_address_t *)device_address);
526         if (!track_info) {
527                 BT_INFO("track_info is NULL");
528                 /* Player info not yet added to player_list, first add it to list */
529                 __add_device_to_avrcp_list((bt_address_t *)device_address);
530                 track_info = __get_track_info((bt_address_t *)device_address);
531         }
532
533         event_data = g_new0(event_avrcp_ct_media_info_t, 1);
534         for (idx = 0; idx < num_attr; idx++) {
535                 BT_INFO("idx [%d]", p_attrs[idx].attr_id);
536
537                 switch (p_attrs[idx].attr_id) {
538                 case BTRC_MEDIA_ATTR_ID_TITLE:
539                         g_strlcpy((char *)track_info->title_info, (const char *)&p_attrs[idx].text,
540                                         MEDIA_ATTIRBUTE_STRING_LENGTH);
541                         g_strlcpy((char *)event_data->title_info, (const char *)&p_attrs[idx].text,
542                                         MEDIA_ATTIRBUTE_STRING_LENGTH);
543                         break;
544                 case BTRC_MEDIA_ATTR_ID_ARTIST:
545                         g_strlcpy((char *)track_info->artist_info, (const char *)&p_attrs[idx].text,
546                                         MEDIA_ATTIRBUTE_STRING_LENGTH);
547                         g_strlcpy((char *)event_data->artist_info, (const char *)&p_attrs[idx].text,
548                                         MEDIA_ATTIRBUTE_STRING_LENGTH);
549                         break;
550                 case BTRC_MEDIA_ATTR_ID_ALBUM:
551                         g_strlcpy((char *)track_info->album_info, (const char *)&p_attrs[idx].text,
552                                         MEDIA_ATTIRBUTE_STRING_LENGTH);
553                         g_strlcpy((char *)event_data->album_info, (const char *)&p_attrs[idx].text,
554                                         MEDIA_ATTIRBUTE_STRING_LENGTH);
555                         break;
556                 case BTRC_MEDIA_ATTR_ID_GENRE:
557                         g_strlcpy((char *)track_info->genre_info, (const char *)&p_attrs[idx].text,
558                                         MEDIA_ATTIRBUTE_STRING_LENGTH);
559                         g_strlcpy((char *)event_data->genre_info, (const char *)&p_attrs[idx].text,
560                                         MEDIA_ATTIRBUTE_STRING_LENGTH);
561                         break;
562                 case BTRC_MEDIA_ATTR_ID_NUM_TRACKS:
563                         if (p_attrs[idx].text != NULL) {
564                                 track_info->total_track = g_ascii_strtoll(
565                                                 (const gchar *)p_attrs[idx].text, NULL, 10);
566                                 event_data->total_track = track_info->total_track;
567                         } else {
568                                 BT_WARN("string is null!!!!!!!");
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                         } else {
577                                 BT_WARN("string is null!!!!!!!");
578                         }
579                         break;
580                 case BTRC_MEDIA_ATTR_ID_PLAYING_TIME:
581                         if (p_attrs[idx].text != NULL) {
582                                 track_info->playing_time = g_ascii_strtoll(
583                                                 (const gchar *)p_attrs[idx].text, NULL, 10);
584                                 event_data->playing_time = track_info->playing_time;
585                         } else {
586                                 BT_WARN("string is null!!!!!!!");
587                         }
588                         break;
589                 default:
590                         break;
591                 }
592         }
593
594         send_event(OAL_EVENT_AVRCP_CT_NOTIF_TRACK_CHANGE,
595                         event_data, sizeof(event_avrcp_ct_media_info_t));
596         return;
597 }
598
599 oal_status_t __avrcp_ct_send_pass_through_cmd(bt_address_t *device_address,
600                 avrcp_ct_pass_cmd_key_code_t key_code, avrcp_ct_pass_state_t key_state)
601 {
602         int result = OAL_STATUS_SUCCESS;
603         bt_status_t status;
604         bdstr_t bdstr;
605
606         API_TRACE();
607
608         CHECK_OAL_AVRCP_CTRL_ENABLED();
609
610         BT_INFO("BT Audio Address: %s", bdt_bd2str(device_address, &bdstr));
611
612         status = avrcp_ct_interface->send_pass_through_cmd((bt_bdaddr_t *)device_address,
613                         key_code, key_state);
614         if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
615                 BT_ERR("OAL, send pass through cmd failed err: %s", status2string(status));
616                 result =  convert_to_oal_status(status);
617         }
618         return result;
619 }
620
621 oal_status_t avrcp_ct_play(bt_address_t *device_address)
622 {
623         oal_status_t result = OAL_STATUS_SUCCESS;
624
625         API_TRACE();
626
627         result = __avrcp_ct_send_pass_through_cmd(device_address,
628                         OAL_RC_PASS_CMD_PLAY, PRESS_STATE);
629
630         return result;
631 }
632
633 oal_status_t avrcp_ct_pause(bt_address_t *device_address)
634 {
635         oal_status_t result = OAL_STATUS_SUCCESS;
636
637         API_TRACE();
638
639         result = __avrcp_ct_send_pass_through_cmd(device_address,
640                         OAL_RC_PASS_CMD_PAUSE, PRESS_STATE);
641
642         return result;
643 }
644
645 oal_status_t avrcp_ct_stop(bt_address_t *device_address)
646 {
647         oal_status_t result = OAL_STATUS_SUCCESS;
648
649         API_TRACE();
650
651         result = __avrcp_ct_send_pass_through_cmd(device_address,
652                         OAL_RC_PASS_CMD_STOP, PRESS_STATE);
653
654         return result;
655 }
656
657 oal_status_t avrcp_ct_next_track(bt_address_t *device_address)
658 {
659         oal_status_t result = OAL_STATUS_SUCCESS;
660
661         API_TRACE();
662
663         result = __avrcp_ct_send_pass_through_cmd(device_address,
664                         OAL_RC_PASS_CMD_NEXT, PRESS_STATE);
665
666         return result;
667 }
668
669 oal_status_t avrcp_ct_prev_track(bt_address_t *device_address)
670 {
671         oal_status_t result = OAL_STATUS_SUCCESS;
672
673         API_TRACE();
674
675         result = __avrcp_ct_send_pass_through_cmd(device_address,
676                         OAL_RC_PASS_CMD_PREVIOUS, PRESS_STATE);
677
678         return result;
679 }
680
681 oal_status_t avrcp_ct_fforward(bt_address_t *device_address, avrcp_ct_pass_state_t press_state)
682 {
683         oal_status_t result = OAL_STATUS_SUCCESS;
684
685         API_TRACE();
686         switch (press_state) {
687         case PRESS_STATE:
688                 result = __avrcp_ct_send_pass_through_cmd(device_address,
689                                 OAL_RC_PASS_CMD_PRESS_FAST_FORWARD, press_state);
690                 break;
691         case RELEASE_STATE:
692                 result = __avrcp_ct_send_pass_through_cmd(device_address,
693                                 OAL_RC_PASS_CMD_RELEASE_FAST_FORWARD, press_state);
694                 break;
695         default:
696                 result = OAL_STATUS_INVALID_PARAM;
697                 break;
698         }
699
700         return result;
701 }
702
703 oal_status_t avrcp_ct_rewind(bt_address_t *device_address, avrcp_ct_pass_state_t press_state)
704 {
705         oal_status_t result = OAL_STATUS_SUCCESS;
706
707         API_TRACE();
708         switch (press_state) {
709         case PRESS_STATE:
710                 result = __avrcp_ct_send_pass_through_cmd(device_address,
711                                 OAL_RC_PASS_CMD_PRESS_REWIND, press_state);
712                 break;
713         case RELEASE_STATE:
714                 result = __avrcp_ct_send_pass_through_cmd(device_address,
715                                 OAL_RC_PASS_CMD_RELEASE_REWIND, press_state);
716                 break;
717         default:
718                 result = OAL_STATUS_INVALID_PARAM;
719                 break;
720         }
721
722         return result;
723 }
724
725 uint8_t __oal_to_hal_property_type(avrcp_ct_player_property_type_t type)
726 {
727         uint8_t property_type = 0;
728
729         switch (type) {
730         case OAL_EQUALIZER:
731                 property_type = BTRC_PLAYER_ATTR_EQUALIZER;
732                 break;
733         case OAL_REPEAT:
734                 property_type = BTRC_PLAYER_ATTR_REPEAT;
735                 break;
736         case OAL_SHUFFLE:
737                 property_type = BTRC_PLAYER_ATTR_SHUFFLE;
738                 break;
739         case OAL_SCAN:
740                 property_type = BTRC_PLAYER_ATTR_SCAN;
741                 break;
742         default:
743                 BT_ERR(" Invalid Property type[%d]", type);
744                 break;
745         }
746
747         return property_type;
748 }
749
750 oal_status_t avrcp_ct_set_property(bt_address_t *device_address, avrcp_ct_player_property_type_t type, uint32_t value)
751 {
752         int result = OAL_STATUS_SUCCESS;
753         uint8_t property_type;
754         bt_status_t status;
755         bdstr_t bdstr;
756
757         API_TRACE();
758
759         CHECK_OAL_AVRCP_CTRL_ENABLED();
760         BT_INFO("BT Audio Address: %s", bdt_bd2str(device_address, &bdstr));
761
762         property_type = __oal_to_hal_property_type(type);
763         if (property_type) {
764                 status = avrcp_ct_interface->set_player_app_setting_cmd((bt_bdaddr_t *)device_address, NO_OF_ATTRIBUTE,
765                                 (uint8_t*)&property_type, (uint8_t*)&value);
766                 if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
767                         BT_ERR("OAL, Set property failed err: %s", status2string(status));
768                         result =  convert_to_oal_status(status);
769                 }
770         } else {
771                 result = OAL_STATUS_INTERNAL_ERROR;
772         }
773         return result;
774 }
775
776 static gboolean __send_avrcp_property_event(gpointer data)
777 {
778         avrcp_ct_property_value_t *event_data = (avrcp_ct_property_value_t *)data;
779
780         send_event(OAL_EVENT_AVRCP_CT_GET_PROPERTY_RES,
781                         event_data, sizeof(avrcp_ct_property_value_t));
782         return FALSE;
783 }
784
785 oal_status_t avrcp_ct_get_property(bt_address_t *device_address, avrcp_ct_player_property_type_t type)
786 {
787         avrcp_ct_player_info_t *player_info;
788         avrcp_ct_player_settings_t *player_setting;
789         avrcp_ct_track_info_t *track_info;
790         avrcp_ct_property_value_t *event_data;
791
792         API_TRACE();
793         CHECK_OAL_AVRCP_CTRL_ENABLED();
794
795         player_info = __get_player_info_from_list(device_address);
796         if (!player_info) {
797                 BT_ERR("Player info not found");
798                 return OAL_STATUS_INVALID_PARAM;
799         }
800
801         player_setting = &player_info->player_setting;
802         track_info = &player_info->track_info;
803
804         event_data = g_new0(avrcp_ct_property_value_t, 1);
805         event_data->type = type;
806
807         switch (type) {
808         case OAL_EQUALIZER:
809                 event_data->value = player_setting->equalizer;
810                 break;
811         case OAL_REPEAT:
812                 event_data->value = player_setting->repeat;
813                 break;
814         case OAL_SHUFFLE:
815                 event_data->value = player_setting->shuffle;
816                 break;
817         case OAL_SCAN:
818                 event_data->value = player_setting->scan;
819                 break;
820         case OAL_PLAY_POSITION:
821                 event_data->value = track_info->song_pos;
822                 break;
823         default:
824                 BT_ERR("Invalid Type [%d]", type);
825                 return OAL_STATUS_INVALID_PARAM;
826         }
827
828         g_idle_add(__send_avrcp_property_event, (gpointer)event_data);
829         return OAL_STATUS_SUCCESS;
830 }
831
832 static gboolean __send_avrcp_play_status_event(gpointer data)
833 {
834         event_avrcp_ct_play_status_t *event_data = (event_avrcp_ct_play_status_t *)data;
835
836         send_event(OAL_EVENT_AVRCP_CT_PLAY_STATUS,
837                         event_data, sizeof(event_avrcp_ct_play_status_t));
838
839         return FALSE;
840 }
841
842 oal_status_t avrcp_ct_get_play_status(bt_address_t *device_address)
843 {
844         avrcp_ct_player_info_t *player_info;
845         avrcp_ct_player_settings_t *player_setting;
846         avrcp_ct_track_info_t *track_info;
847         event_avrcp_ct_play_status_t *event_data = NULL;
848
849         API_TRACE();
850         CHECK_OAL_AVRCP_CTRL_ENABLED();
851
852         player_info = __get_player_info_from_list(device_address);
853         if (!player_info) {
854                 BT_ERR("Player info not found");
855                 return OAL_STATUS_INVALID_PARAM;
856         }
857
858         player_setting = &player_info->player_setting;
859         track_info = &player_info->track_info;
860
861         event_data = g_new0(event_avrcp_ct_play_status_t, 1);
862         event_data->song_len = track_info->playing_time;
863         event_data->song_pos = track_info->song_pos;
864
865         switch (player_setting->status) {
866         case BTRC_PLAYSTATE_STOPPED:
867                 event_data->play_status = OAL_PLAY_STATUS_STOPPED;
868                 break;
869         case BTRC_PLAYSTATE_PLAYING:
870                 event_data->play_status = OAL_PLAY_STATUS_PLAYING;
871                 break;
872         case BTRC_PLAYSTATE_PAUSED:
873                 event_data->play_status = OAL_PLAY_STATUS_PAUSED;
874                 break;
875         case BTRC_PLAYSTATE_FWD_SEEK:
876                 event_data->play_status = OAL_PLAY_STATUS_FWD_SEEK;
877                 break;
878         case BTRC_PLAYSTATE_REV_SEEK:
879                 event_data->play_status = OAL_PLAY_STATUS_REV_SEEK;
880                 break;
881         default:
882                 event_data->play_status = OAL_PLAY_STATUS_ERROR;
883                 break;
884         }
885
886         g_idle_add(__send_avrcp_play_status_event, (gpointer)event_data);
887         return OAL_STATUS_SUCCESS;
888 }
889
890 static gboolean __send_media_attribute_event(gpointer data)
891 {
892         event_avrcp_ct_media_info_t *event_data = (event_avrcp_ct_media_info_t *)data;
893
894         send_event(OAL_EVENT_AVRCP_CT_MEDIA_INFO,
895                         event_data, sizeof(event_avrcp_ct_media_info_t));
896
897         return FALSE;
898 }
899
900 oal_status_t avrcp_ct_get_media_attribute(bt_address_t *device_address)
901 {
902         avrcp_ct_track_info_t *track_info;
903         event_avrcp_ct_media_info_t *event_data;
904
905         API_TRACE();
906
907         CHECK_OAL_AVRCP_CTRL_ENABLED();
908
909         OAL_CHECK_PARAMETER(device_address, return);
910
911         track_info = __get_track_info(device_address);
912         if (!track_info) {
913                 BT_ERR("Player info not found");
914                 return OAL_STATUS_INVALID_PARAM;
915         }
916
917         event_data = g_new0(event_avrcp_ct_media_info_t, 1);
918         g_strlcpy((char *)event_data->title_info, (const char *)track_info->title_info,
919                                 MEDIA_ATTIRBUTE_STRING_LENGTH);
920         g_strlcpy((char *)event_data->album_info, (const char *)track_info->album_info,
921                                 MEDIA_ATTIRBUTE_STRING_LENGTH);
922         g_strlcpy((char *)event_data->genre_info, (const char *)track_info->genre_info,
923                                 MEDIA_ATTIRBUTE_STRING_LENGTH);
924         g_strlcpy((char *)event_data->artist_info, (const char *)track_info->artist_info,
925                                 MEDIA_ATTIRBUTE_STRING_LENGTH);
926         event_data->playing_time = track_info->playing_time;
927         event_data->total_track = track_info->total_track;
928         event_data->track_number = track_info->track_number;
929
930         g_idle_add(__send_media_attribute_event, (gpointer)event_data);
931
932         return OAL_STATUS_SUCCESS;
933 }