502364888f54c7042d57e110c5534c7b36314dd2
[platform/core/connectivity/bluetooth-frwk.git] / bt-service-adaptation / services / audio / avrcp / bt-service-avrcp-tg.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <gio/gio.h>
19 #include <glib.h>
20 #include <dlog.h>
21 #include <string.h>
22 #include <dbus/dbus.h>
23
24 #include <oal-avrcp-tg.h>
25
26 #include "bluetooth-api.h"
27 #include "bt-internal-types.h"
28 #include "bt-service-common.h"
29 #include "bt-service-avrcp-tg.h"
30 #include "bt-service-event.h"
31 #include "bt-service-event-receiver.h"
32 #include "bt-service-audio-common.h"
33 #include "bt-service-util.h"
34
35 static invocation_info_t* __bt_get_request_info(int service_function, char *address)
36 {
37         GSList *l;
38         invocation_info_t *req_info = NULL;
39
40         BT_DBG("+");
41
42         retv_if(NULL == address, FALSE);
43
44         /* Get method invocation context */
45         for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
46                 req_info = l->data;
47                 if (req_info == NULL || req_info->service_function != service_function)
48                         continue;
49
50                 if (!strncasecmp((char *)req_info->user_data, address, BT_ADDRESS_STRING_SIZE))
51                         return req_info;
52         }
53
54         return NULL;
55 }
56
57 static int __bt_avrcp_set_equalizer(media_player_equalizer_status equalizer)
58 {
59         unsigned int value;
60         oal_status_t result;
61
62         BT_DBG("+");
63
64         switch (equalizer) {
65         case EQUALIZER_ON:
66                 value = 0x01;
67                 break;
68         case EQUALIZER_OFF:
69                 value = 0x02;
70                 break;
71         default:
72                 BT_ERR("Invalid Equalizer state");
73                 return BLUETOOTH_ERROR_INTERNAL;
74         }
75
76         result = avrcp_set_property(AVRCP_EQUALIZER, value);
77         if (result != OAL_STATUS_SUCCESS) {
78                 BT_ERR("avrcp_set_property failed");
79                 return BLUETOOTH_ERROR_INTERNAL;
80         }
81
82         BT_DBG("-");
83         return BLUETOOTH_ERROR_NONE;
84 }
85
86 static int __bt_avrcp_set_repeat_status(media_player_repeat_status repeat_status)
87 {
88         unsigned int value;
89         oal_status_t result;
90
91         BT_DBG("+");
92
93         switch (repeat_status) {
94         case REPEAT_MODE_OFF:
95                 value = OAL_PLAYER_VAL_OFF_REPEAT;
96                 break;
97         case REPEAT_SINGLE_TRACK:
98                 value = OAL_PLAYER_VAL_SINGLE_REPEAT;
99                 break;
100         case REPEAT_ALL_TRACK:
101                 value = OAL_PLAYER_VAL_ALL_REPEAT;
102                 break;
103         case REPEAT_GROUP:
104                 value = OAL_PLAYER_VAL_GROUP_REPEAT;
105                 break;
106         default:
107                 BT_ERR("Invalid repeat status");
108                 return BLUETOOTH_ERROR_INTERNAL;
109         }
110
111         result = avrcp_set_property(AVRCP_REPEAT, value);
112         if (result != OAL_STATUS_SUCCESS) {
113                 BT_ERR("avrcp_set_property failed");
114                 return BLUETOOTH_ERROR_INTERNAL;
115         }
116
117         BT_DBG("-");
118         return BLUETOOTH_ERROR_NONE;
119 }
120
121 static int __bt_avrcp_set_shuffel_mode(media_player_shuffle_status shuffel)
122 {
123         unsigned int value;
124         oal_status_t result;
125
126         BT_DBG("+");
127
128         switch (shuffel) {
129         case SHUFFLE_MODE_OFF:
130                 value = OAL_PLAYER_VAL_OFF_SHUFFLE;
131                 break;
132         case SHUFFLE_ALL_TRACK:
133                 value = OAL_PLAYER_VAL_ALL_SHUFFLE;
134                 break;
135         case SHUFFLE_GROUP:
136                 value = OAL_PLAYER_VAL_GROUP_SHUFFLE;
137                 break;
138         default:
139                 BT_ERR("Invalid shuffel mode");
140                 return BLUETOOTH_ERROR_INTERNAL;
141         }
142
143         result = avrcp_set_property(AVRCP_SHUFFLE, value);
144         if (result != OAL_STATUS_SUCCESS) {
145                 BT_ERR("avrcp_set_property failed");
146                 return BLUETOOTH_ERROR_INTERNAL;
147         }
148
149         BT_DBG("-");
150         return BLUETOOTH_ERROR_NONE;
151 }
152
153 static int __bt_avrcp_set_scan_mode(media_player_scan_status scan_status)
154 {
155         unsigned int value;
156         oal_status_t result;
157
158         BT_DBG("+");
159
160         switch (scan_status) {
161         case SCAN_MODE_OFF:
162                 value = 0x01;
163                 break;
164         case SCAN_ALL_TRACK:
165                 value = 0x02;
166                 break;
167         case SCAN_GROUP:
168                 value = 0x03;
169                 break;
170         default:
171                 BT_ERR("Invalid scan mode");
172                 return BLUETOOTH_ERROR_INTERNAL;
173         }
174
175         result = avrcp_set_property(AVRCP_SCAN, value);
176         if (result != OAL_STATUS_SUCCESS) {
177                 BT_ERR("avrcp_set_property failed");
178                 return BLUETOOTH_ERROR_INTERNAL;
179         }
180
181         BT_DBG("-");
182         return BLUETOOTH_ERROR_NONE;
183 }
184
185 static int __bt_avrcp_set_player_status(media_player_status status)
186 {
187         unsigned int value;
188         oal_status_t result;
189
190         BT_DBG("+");
191
192         switch (status) {
193         case STATUS_STOPPED:
194                 value = OAL_PLAYSTATE_STOPPED;
195                 break;
196         case STATUS_PLAYING:
197                 value = OAL_PLAYSTATE_PLAYING;
198                 break;
199         case STATUS_PAUSED:
200                 value = OAL_PLAYSTATE_PAUSED;
201                 break;
202         case STATUS_FORWARD_SEEK:
203                 value = OAL_PLAYSTATE_FWD_SEEK;
204                 break;
205         case STATUS_REVERSE_SEEK:
206                 value = OAL_PLAYSTATE_REV_SEEK;
207                 break;
208         case STATUS_ERROR:
209                 value = OAL_PLAYSTATE_ERROR;
210                 break;
211         default:
212                 BT_ERR("Invalid ");
213                 return BLUETOOTH_ERROR_INTERNAL;
214         }
215
216         result = avrcp_set_property(AVRCP_STATUS, value);
217         if (result != OAL_STATUS_SUCCESS) {
218                 BT_ERR("avrcp_set_property failed");
219                 return BLUETOOTH_ERROR_INTERNAL;
220         }
221
222         BT_DBG("-");
223         return BLUETOOTH_ERROR_NONE;
224 }
225
226 static int __bt_avrcp_set_play_position(unsigned int position)
227 {
228         oal_status_t result;
229
230         BT_DBG("+");
231
232         result = avrcp_set_property(AVRCP_POSITION, position);
233         if (result != OAL_STATUS_SUCCESS) {
234                 BT_ERR("avrcp_set_property failed");
235                 return BLUETOOTH_ERROR_INTERNAL;
236         }
237
238         BT_DBG("-");
239         return BLUETOOTH_ERROR_NONE;
240 }
241
242 int _bt_avrcp_connect_remote_ctrl(bluetooth_device_address_t *address)
243 {
244         oal_status_t status = OAL_STATUS_SUCCESS;
245         int result = BLUETOOTH_ERROR_NONE;
246         bt_address_t bdaddr;
247
248         BT_DBG("+");
249
250         memcpy(bdaddr.addr, address->addr, BT_ADDRESS_BYTES_NUM);
251         status = avrcp_tg_connect(&bdaddr);
252         if (status != OAL_STATUS_SUCCESS) {
253                 BT_ERR("Connection could not be established, err: [%d]", status);
254                 result = BLUETOOTH_ERROR_INTERNAL;
255         }
256
257         BT_DBG("-");
258         return result;
259 }
260
261 int _bt_avrcp_disconnect_remote_ctrl(bluetooth_device_address_t *address)
262 {
263         oal_status_t status = OAL_STATUS_SUCCESS;
264         int result = BLUETOOTH_ERROR_NONE;
265         bt_address_t bdaddr;
266
267         BT_DBG("+");
268
269         memcpy(bdaddr.addr, address->addr, BT_ADDRESS_BYTES_NUM);
270         status = avrcp_tg_disconnect(&bdaddr);
271         if (status != OAL_STATUS_SUCCESS) {
272                 BT_ERR("DisConnection err: [%d]", status);
273                 result = BLUETOOTH_ERROR_INTERNAL;
274         }
275
276         BT_DBG("-");
277         return result;
278 }
279
280 int _bt_avrcp_set_track_info(media_metadata_attributes_t *meta_data)
281 {
282         oal_status_t result;
283         oal_media_metadata_attributes_t media_attr;
284
285         BT_DBG("+");
286
287         retv_if(meta_data == NULL, BLUETOOTH_ERROR_INTERNAL);
288
289         g_strlcpy(media_attr.title, meta_data->title, OAL_MAX_ATTR_STR_LEN);
290         g_strlcpy(media_attr.artist, meta_data->artist, OAL_MAX_ATTR_STR_LEN);
291         g_strlcpy(media_attr.album, meta_data->album, OAL_MAX_ATTR_STR_LEN);
292         g_strlcpy(media_attr.genre, meta_data->genre, OAL_MAX_ATTR_STR_LEN);
293         media_attr.total_tracks = meta_data->total_tracks;
294         media_attr.number = meta_data->number;
295         media_attr.duration = meta_data->duration;
296
297         result = avrcp_set_track_info(&media_attr);
298         if (result != OAL_STATUS_SUCCESS) {
299                 BT_ERR("hid_connect error: [%d]", result);
300                 return BLUETOOTH_ERROR_INTERNAL;
301         }
302
303         BT_DBG("-");
304         return BLUETOOTH_ERROR_NONE;
305 }
306
307 int _bt_avrcp_set_properties(media_player_settings_t *properties)
308 {
309         int ret;
310         BT_DBG("+");
311
312         ret = __bt_avrcp_set_equalizer(properties->equalizer);
313         if (ret != BLUETOOTH_ERROR_NONE) {
314                 BT_ERR("__bt_avrcp_set_equalizer failed");
315                 return ret;
316         }
317
318         ret = __bt_avrcp_set_repeat_status(properties->repeat);
319         if (ret != BLUETOOTH_ERROR_NONE) {
320                 BT_ERR("__bt_avrcp_set_repeat_status failed");
321                 return ret;
322         }
323
324         ret = __bt_avrcp_set_shuffel_mode(properties->shuffle);
325         if (ret != BLUETOOTH_ERROR_NONE) {
326                 BT_ERR("__bt_avrcp_set_shuffel_mode failed");
327                 return ret;
328         }
329
330         ret = __bt_avrcp_set_scan_mode(properties->scan);
331         if (ret != BLUETOOTH_ERROR_NONE) {
332                 BT_ERR("__bt_avrcp_set_scan_mode failed");
333                 return ret;
334         }
335
336         ret = __bt_avrcp_set_play_position(properties->position);
337         if (ret != BLUETOOTH_ERROR_NONE) {
338                 BT_ERR("__bt_avrcp_set_play_position failed");
339                 return ret;
340         }
341
342         ret = _bt_avrcp_set_track_info(&(properties->metadata));
343         if (ret != BLUETOOTH_ERROR_NONE) {
344                 BT_ERR("_bt_avrcp_set_track_info failed");
345                 return ret;
346         }
347
348         BT_DBG("-");
349         return ret;
350 }
351
352 int _bt_avrcp_set_property(int type, unsigned int value)
353 {
354         int ret;
355
356         BT_DBG("+");
357
358         switch (type) {
359         case EQUALIZER:
360                 ret = __bt_avrcp_set_equalizer(value);
361                 break;
362         case REPEAT:
363                 ret = __bt_avrcp_set_repeat_status(value);
364                 break;
365         case SHUFFLE:
366                 ret = __bt_avrcp_set_shuffel_mode(value);
367                 break;
368         case SCAN:
369                 ret = __bt_avrcp_set_scan_mode(value);
370                 break;
371         case STATUS:
372                 ret = __bt_avrcp_set_player_status(value);
373                 break;
374         case POSITION:
375                 ret = __bt_avrcp_set_play_position(value);
376                 break;
377         default:
378                 BT_DBG("Invalid Type");
379                 return BLUETOOTH_ERROR_INTERNAL;
380         }
381
382         if (ret != BLUETOOTH_ERROR_NONE) {
383                 BT_ERR("set property: %.2X failed", type);
384                 return ret;
385         }
386
387         BT_DBG("-");
388         return BLUETOOTH_ERROR_NONE;
389 }
390
391 static void __handle_player_property_equalizer(unsigned char *value)
392 {
393         media_player_equalizer_status equalizer;
394
395         switch (*value) {
396         case 0x01:
397                 equalizer = EQUALIZER_ON;
398                 break;
399         case 0x02:
400                 equalizer = EQUALIZER_OFF;
401                 break;
402         default:
403                 BT_ERR("Unknown equalizer setting");
404                 equalizer = EQUALIZER_INVALID;
405         }
406
407         _bt_send_event(BT_AVRCP_EVENT,
408                         BLUETOOTH_EVENT_AVRCP_SETTING_EQUALIZER_STATUS,
409                         g_variant_new("(u)", equalizer));
410 }
411
412 static void __handle_player_property_repeat(unsigned char *value)
413 {
414         media_player_repeat_status status;
415
416         switch (*value) {
417         case OAL_PLAYER_VAL_OFF_REPEAT:
418                 status = REPEAT_MODE_OFF;
419                 break;
420         case OAL_PLAYER_VAL_SINGLE_REPEAT:
421                 status = REPEAT_SINGLE_TRACK;
422                 break;
423         case OAL_PLAYER_VAL_GROUP_REPEAT:
424                 status = REPEAT_GROUP;
425                 break;
426         case OAL_PLAYER_VAL_ALL_REPEAT:
427                 status = REPEAT_ALL_TRACK;
428                 break;
429         default:
430                 BT_ERR("Invalid repeat setting");
431                 status = REPEAT_INVALID;
432         }
433
434         _bt_send_event(BT_AVRCP_EVENT,
435                         BLUETOOTH_EVENT_AVRCP_SETTING_REPEAT_STATUS,
436                         g_variant_new("(u)", status));
437 }
438
439 static void __handle_player_property_shuffle(unsigned char *value)
440 {
441         media_player_shuffle_status status;
442
443         switch (*value) {
444         case OAL_PLAYER_VAL_OFF_SHUFFLE:
445                 status = SHUFFLE_MODE_OFF;
446                 break;
447         case OAL_PLAYER_VAL_GROUP_SHUFFLE:
448                 status = SHUFFLE_GROUP;
449                 break;
450         case OAL_PLAYER_VAL_ALL_SHUFFLE:
451                 status = SHUFFLE_ALL_TRACK;
452                 break;
453         default:
454                 BT_ERR("Invalid shuffle setting");
455                 status = SHUFFLE_INVALID;
456         }
457
458         _bt_send_event(BT_AVRCP_EVENT,
459                         BLUETOOTH_EVENT_AVRCP_SETTING_SHUFFLE_STATUS,
460                         g_variant_new("(u)", status));
461 }
462
463 static void __handle_player_property_scan(unsigned char *value)
464 {
465         media_player_scan_status status;
466
467         switch (*value) {
468         case 0x01:
469                 status = SCAN_MODE_OFF;
470                 break;
471         case 0x02:
472                 status = SCAN_ALL_TRACK;
473                 break;
474         case 0x03:
475                 status = SCAN_GROUP;
476                 break;
477         default:
478                 BT_ERR("Unknown scan setting");
479                 status = SCAN_INVALID;
480         }
481
482         _bt_send_event(BT_AVRCP_EVENT,
483                         BLUETOOTH_EVENT_AVRCP_SETTING_SCAN_STATUS,
484                         g_variant_new("(u)", status));
485 }
486
487 static void __handle_transport_property_delay(unsigned int *value)
488 {
489         BT_DBG("+");
490         unsigned int delay;
491         delay = *value;
492
493         _bt_send_event(BT_AVRCP_EVENT,
494                         BLUETOOTH_EVENT_AVRCP_DELAY_CHANGED,
495                         g_variant_new("(u)", delay));
496
497         BT_DBG("-");
498 }
499
500 static void __handle_avrcp_connection_event(int event, bt_address_t *bdaddr)
501 {
502         int result = BLUETOOTH_ERROR_NONE;
503         char address[BT_ADDRESS_STRING_SIZE];
504         GVariant *param = NULL;
505         invocation_info_t *req_info;
506
507         _bt_convert_addr_type_to_string(address, bdaddr->addr);
508
509         if (event == BLUETOOTH_EVENT_AVRCP_CONNECTED) {
510                 /* Reply to async request for AVRCP Target connect, if any */
511                 req_info = __bt_get_request_info(BT_AVRCP_TARGET_CONNECT, address);
512                 if (!req_info) {
513                         /* Check if request for AVRCP Target disconnect failed */
514                         req_info = __bt_get_request_info(BT_AVRCP_TARGET_DISCONNECT, address);
515                         if (req_info)
516                                 result = BLUETOOTH_ERROR_INTERNAL;
517                 }
518         } else {
519                 /* Reply to async request for AVRCP Target disconnect, if any */
520                 req_info = __bt_get_request_info(BT_AVRCP_TARGET_DISCONNECT, address);
521                 if (!req_info) {
522                         /* Check if request for AVRCP Target connect failed */
523                         req_info = __bt_get_request_info(BT_AVRCP_TARGET_CONNECT, address);
524                         if (req_info)
525                                 result = BLUETOOTH_ERROR_INTERNAL;
526                 }
527         }
528
529         if (NULL != req_info) {
530                 GArray *out_param;
531
532                 /* Create out param */
533                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
534                 g_array_append_vals(out_param, address, sizeof(address));
535
536                 _bt_service_method_return(req_info->context, out_param, result);
537                 g_array_free(out_param, TRUE);
538                 g_free(req_info->user_data);
539                 _bt_free_info_from_invocation_list(req_info);
540         }
541
542         if (BLUETOOTH_ERROR_NONE == result) {
543                 param = g_variant_new("(is)", result, address);
544                 /* Send event to application */
545                 _bt_send_event(BT_AVRCP_EVENT, event, param);
546
547                 if (event == BLUETOOTH_EVENT_AVRCP_CONNECTED)
548                         /* Connected: Add AVRCP TARGET to headset list */
549                         _bt_add_headset_to_list(BT_AVRCP_TARGET, BT_STATE_CONNECTED, address);
550                 else
551                         /* Disconnected: Remove AVRCP TARGET from headset list */
552                         _bt_remove_headset_from_list(BT_AVRCP_TARGET, address);
553         }
554 }
555
556 static void __handle_avrcp_target_events(int event_type, gpointer event_data)
557 {
558         switch (event_type) {
559         case OAL_EVENT_AVRCP_CONNECTED:
560                 __handle_avrcp_connection_event(
561                                 BLUETOOTH_EVENT_AVRCP_CONNECTED,
562                                 (bt_address_t *)event_data);
563                 BT_PERMANENT_LOG("Connected AVRCP tg");
564                 break;
565         case OAL_EVENT_AVRCP_DISCONNECTED:
566                 __handle_avrcp_connection_event(
567                                 BLUETOOTH_EVENT_AVRCP_DISCONNECTED,
568                                 (bt_address_t *)event_data);
569                 BT_PERMANENT_LOG("Disconnected AVRCP tg");
570                 break;
571         case OAL_EVENT_AVRCP_SETTING_EQUALIZER_STATUS:
572                 __handle_player_property_equalizer((unsigned char *)event_data);
573                 break;
574         case OAL_EVENT_AVRCP_SETTING_REPEAT_STATUS:
575                 __handle_player_property_repeat((unsigned char *)event_data);
576                 break;
577         case OAL_EVENT_AVRCP_SETTING_SHUFFLE_STATUS:
578                 __handle_player_property_shuffle((unsigned char *)event_data);
579                 break;
580         case OAL_EVENT_AVRCP_SETTING_SCAN_STATUS:
581                 __handle_player_property_scan((unsigned char *)event_data);
582                 break;
583         case OAL_EVENT_AVRCP_REMOTE_FEATURES:
584                 break;
585         case OAL_EVENT_AVRCP_VOLUME_MUTE_CHANGED:
586                 break;
587         case OAL_EVENT_AVRCP_DELAY_CHANGED:
588                  __handle_transport_property_delay((unsigned int *)event_data);
589                 break;
590         default:
591                 BT_ERR("Unhandled AVRCP target event: %d", event_type);
592         }
593 }
594
595 int _bt_service_avrcp_enable(void)
596 {
597         oal_status_t status = OAL_STATUS_SUCCESS;
598
599         status = avrcp_enable();
600         if (OAL_STATUS_SUCCESS != status) {
601                 BT_ERR("Failed to initialize Bluetooth AVRCP Target Profile, status: %d", status);
602                 return BLUETOOTH_ERROR_INTERNAL;
603         }
604
605         /* Register AVRCP target event handler */
606         _bt_service_register_event_handler_callback(BT_AVRCP_MODULE, __handle_avrcp_target_events);
607
608         return BLUETOOTH_ERROR_NONE;
609 }
610
611 int _bt_service_avrcp_disable(void)
612 {
613         oal_status_t status = OAL_STATUS_SUCCESS;
614
615         status = avrcp_disable();
616         if (OAL_STATUS_SUCCESS != status) {
617                 BT_ERR("Failed to initialize Bluetooth A2DP Source Profile, status: %d", status);
618                 return BLUETOOTH_ERROR_INTERNAL;
619         }
620
621         /* Register AVRCP target event handler */
622         _bt_service_unregister_event_handler_callback(BT_AVRCP_MODULE);
623
624         return BLUETOOTH_ERROR_NONE;
625 }