Reduce the predefined logic (PredefinedPreprocessor)
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / 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 _bt_convert_oal_status_to_bt_error(result);
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 _bt_convert_oal_status_to_bt_error(result);
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 _bt_convert_oal_status_to_bt_error(result);
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 _bt_convert_oal_status_to_bt_error(result);
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 _bt_convert_oal_status_to_bt_error(result);
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 _bt_convert_oal_status_to_bt_error(result);
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 = _bt_convert_oal_status_to_bt_error(status);
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 = _bt_convert_oal_status_to_bt_error(status);
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 _bt_convert_oal_status_to_bt_error(result);
301         }
302
303         BT_DBG("-");
304         return BLUETOOTH_ERROR_NONE;
305 }
306
307 int _bt_avrcp_target_notify_volume(bluetooth_device_address_t *address, unsigned int volume)
308 {
309         int result = BLUETOOTH_ERROR_NONE;
310         bt_address_t bdaddr;
311
312         memcpy(bdaddr.addr, address->addr, BT_ADDRESS_BYTES_NUM);
313
314         result = avrcp_tg_set_volume(&bdaddr, volume);
315         if (result != OAL_STATUS_SUCCESS) {
316                 BT_ERR("hid_connect error: [%d]", result);
317                 return _bt_convert_oal_status_to_bt_error(result);
318         }
319
320         return BLUETOOTH_ERROR_NONE;
321 }
322
323 int _bt_avrcp_target_get_volume(bluetooth_device_address_t *address, unsigned int *volume)
324 {
325         int result = BLUETOOTH_ERROR_NONE;
326         bt_address_t bdaddr;
327
328         memcpy(bdaddr.addr, address->addr, BT_ADDRESS_BYTES_NUM);
329
330         result = avrcp_tg_get_volume(&bdaddr, volume);
331         if (result != OAL_STATUS_SUCCESS) {
332                 BT_ERR("hid_connect error: [%d]", result);
333                 return _bt_convert_oal_status_to_bt_error(result);
334         }
335
336         return BLUETOOTH_ERROR_NONE;
337 }
338
339 int _bt_avrcp_set_properties(media_player_settings_t *properties)
340 {
341         int ret;
342         BT_DBG("+");
343
344         ret = __bt_avrcp_set_equalizer(properties->equalizer);
345         if (ret != BLUETOOTH_ERROR_NONE) {
346                 BT_ERR("__bt_avrcp_set_equalizer failed");
347                 return ret;
348         }
349
350         ret = __bt_avrcp_set_repeat_status(properties->repeat);
351         if (ret != BLUETOOTH_ERROR_NONE) {
352                 BT_ERR("__bt_avrcp_set_repeat_status failed");
353                 return ret;
354         }
355
356         ret = __bt_avrcp_set_shuffel_mode(properties->shuffle);
357         if (ret != BLUETOOTH_ERROR_NONE) {
358                 BT_ERR("__bt_avrcp_set_shuffel_mode failed");
359                 return ret;
360         }
361
362         ret = __bt_avrcp_set_scan_mode(properties->scan);
363         if (ret != BLUETOOTH_ERROR_NONE) {
364                 BT_ERR("__bt_avrcp_set_scan_mode failed");
365                 return ret;
366         }
367
368         ret = __bt_avrcp_set_play_position(properties->position);
369         if (ret != BLUETOOTH_ERROR_NONE) {
370                 BT_ERR("__bt_avrcp_set_play_position failed");
371                 return ret;
372         }
373
374         ret = _bt_avrcp_set_track_info(&(properties->metadata));
375         if (ret != BLUETOOTH_ERROR_NONE) {
376                 BT_ERR("_bt_avrcp_set_track_info failed");
377                 return ret;
378         }
379
380         BT_DBG("-");
381         return ret;
382 }
383
384 int _bt_avrcp_set_property(int type, unsigned int value)
385 {
386         int ret;
387
388         BT_DBG("+");
389
390         switch (type) {
391         case EQUALIZER:
392                 ret = __bt_avrcp_set_equalizer(value);
393                 break;
394         case REPEAT:
395                 ret = __bt_avrcp_set_repeat_status(value);
396                 break;
397         case SHUFFLE:
398                 ret = __bt_avrcp_set_shuffel_mode(value);
399                 break;
400         case SCAN:
401                 ret = __bt_avrcp_set_scan_mode(value);
402                 break;
403         case STATUS:
404                 ret = __bt_avrcp_set_player_status(value);
405                 break;
406         case POSITION:
407                 ret = __bt_avrcp_set_play_position(value);
408                 break;
409         default:
410                 BT_DBG("Invalid Type");
411                 return BLUETOOTH_ERROR_INTERNAL;
412         }
413
414         if (ret != BLUETOOTH_ERROR_NONE) {
415                 BT_ERR("set property: %.2X failed", type);
416                 return ret;
417         }
418
419         BT_DBG("-");
420         return BLUETOOTH_ERROR_NONE;
421 }
422
423 static void __handle_player_property_equalizer(unsigned char *value)
424 {
425         media_player_equalizer_status equalizer;
426
427         switch (*value) {
428         case 0x01:
429                 equalizer = EQUALIZER_ON;
430                 break;
431         case 0x02:
432                 equalizer = EQUALIZER_OFF;
433                 break;
434         default:
435                 BT_ERR("Unknown equalizer setting");
436                 equalizer = EQUALIZER_INVALID;
437         }
438
439         _bt_send_event(BT_AVRCP_EVENT,
440                         BLUETOOTH_EVENT_AVRCP_SETTING_EQUALIZER_STATUS,
441                         g_variant_new("(u)", equalizer));
442 }
443
444 static void __handle_player_property_repeat(unsigned char *value)
445 {
446         media_player_repeat_status status;
447
448         switch (*value) {
449         case OAL_PLAYER_VAL_OFF_REPEAT:
450                 status = REPEAT_MODE_OFF;
451                 break;
452         case OAL_PLAYER_VAL_SINGLE_REPEAT:
453                 status = REPEAT_SINGLE_TRACK;
454                 break;
455         case OAL_PLAYER_VAL_GROUP_REPEAT:
456                 status = REPEAT_GROUP;
457                 break;
458         case OAL_PLAYER_VAL_ALL_REPEAT:
459                 status = REPEAT_ALL_TRACK;
460                 break;
461         default:
462                 BT_ERR("Invalid repeat setting");
463                 status = REPEAT_INVALID;
464         }
465
466         _bt_send_event(BT_AVRCP_EVENT,
467                         BLUETOOTH_EVENT_AVRCP_SETTING_REPEAT_STATUS,
468                         g_variant_new("(u)", status));
469 }
470
471 static void __handle_player_property_shuffle(unsigned char *value)
472 {
473         media_player_shuffle_status status;
474
475         switch (*value) {
476         case OAL_PLAYER_VAL_OFF_SHUFFLE:
477                 status = SHUFFLE_MODE_OFF;
478                 break;
479         case OAL_PLAYER_VAL_GROUP_SHUFFLE:
480                 status = SHUFFLE_GROUP;
481                 break;
482         case OAL_PLAYER_VAL_ALL_SHUFFLE:
483                 status = SHUFFLE_ALL_TRACK;
484                 break;
485         default:
486                 BT_ERR("Invalid shuffle setting");
487                 status = SHUFFLE_INVALID;
488         }
489
490         _bt_send_event(BT_AVRCP_EVENT,
491                         BLUETOOTH_EVENT_AVRCP_SETTING_SHUFFLE_STATUS,
492                         g_variant_new("(u)", status));
493 }
494
495 static void __handle_player_property_scan(unsigned char *value)
496 {
497         media_player_scan_status status;
498
499         switch (*value) {
500         case 0x01:
501                 status = SCAN_MODE_OFF;
502                 break;
503         case 0x02:
504                 status = SCAN_ALL_TRACK;
505                 break;
506         case 0x03:
507                 status = SCAN_GROUP;
508                 break;
509         default:
510                 BT_ERR("Unknown scan setting");
511                 status = SCAN_INVALID;
512         }
513
514         _bt_send_event(BT_AVRCP_EVENT,
515                         BLUETOOTH_EVENT_AVRCP_SETTING_SCAN_STATUS,
516                         g_variant_new("(u)", status));
517 }
518
519 static void __handle_transport_property_delay(unsigned int *value)
520 {
521         BT_DBG("+");
522         unsigned int delay;
523         delay = *value;
524
525         _bt_send_event(BT_AVRCP_EVENT,
526                         BLUETOOTH_EVENT_AVRCP_DELAY_CHANGED,
527                         g_variant_new("(u)", delay));
528
529         BT_DBG("-");
530 }
531
532 static void __handle_transport_property_volume(unsigned int avrcp_volume)
533 {
534         _bt_audio_handle_transport_volume_changed(avrcp_volume);
535 }
536
537 static void __handle_avrcp_connection_event(int event, bt_address_t *bdaddr)
538 {
539         int result = BLUETOOTH_ERROR_NONE;
540         char address[BT_ADDRESS_STRING_SIZE];
541         GVariant *param = NULL;
542         invocation_info_t *req_info;
543
544         _bt_convert_addr_type_to_string(address, bdaddr->addr);
545
546         if (event == BLUETOOTH_EVENT_AVRCP_CONNECTED) {
547                 /* Reply to async request for AVRCP Target connect, if any */
548                 req_info = __bt_get_request_info(BT_AVRCP_TARGET_CONNECT, address);
549                 if (!req_info) {
550                         /* Check if request for AVRCP Target disconnect failed */
551                         req_info = __bt_get_request_info(BT_AVRCP_TARGET_DISCONNECT, address);
552                         if (req_info)
553                                 result = BLUETOOTH_ERROR_INTERNAL;
554                 }
555         } else {
556                 /* Reply to async request for AVRCP Target disconnect, if any */
557                 req_info = __bt_get_request_info(BT_AVRCP_TARGET_DISCONNECT, address);
558                 if (!req_info) {
559                         /* Check if request for AVRCP Target connect failed */
560                         req_info = __bt_get_request_info(BT_AVRCP_TARGET_CONNECT, address);
561                         if (req_info)
562                                 result = BLUETOOTH_ERROR_INTERNAL;
563                 }
564         }
565
566         if (NULL != req_info) {
567                 GArray *out_param;
568
569                 /* Create out param */
570                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
571                 g_array_append_vals(out_param, address, sizeof(address));
572
573                 _bt_service_method_return(req_info->context, out_param, result);
574                 g_array_free(out_param, TRUE);
575                 _bt_free_info_from_invocation_list(req_info);
576         }
577
578         if (BLUETOOTH_ERROR_NONE == result) {
579                 param = g_variant_new("(is)", result, address);
580                 /* Send event to application */
581                 _bt_send_event(BT_AVRCP_EVENT, event, param);
582
583                 if (event == BLUETOOTH_EVENT_AVRCP_CONNECTED)
584                         /* Connected: Add AVRCP TARGET to headset list */
585                         _bt_add_headset_to_list(BT_AVRCP_TARGET, BT_STATE_CONNECTED, address);
586                 else
587                         /* Disconnected: Remove AVRCP TARGET from headset list */
588                         _bt_remove_headset_from_list(BT_AVRCP_TARGET, address);
589         }
590 }
591
592 static void __handle_avrcp_target_events(int event_type, gpointer event_data)
593 {
594         switch (event_type) {
595         case OAL_EVENT_AVRCP_CONNECTED:
596                 __handle_avrcp_connection_event(
597                                 BLUETOOTH_EVENT_AVRCP_CONNECTED,
598                                 (bt_address_t *)event_data);
599                 BT_PERMANENT_LOG("Connected AVRCP tg");
600                 break;
601         case OAL_EVENT_AVRCP_DISCONNECTED:
602                 __handle_avrcp_connection_event(
603                                 BLUETOOTH_EVENT_AVRCP_DISCONNECTED,
604                                 (bt_address_t *)event_data);
605                 BT_PERMANENT_LOG("Disconnected AVRCP tg");
606                 break;
607         case OAL_EVENT_AVRCP_SETTING_EQUALIZER_STATUS:
608                 __handle_player_property_equalizer((unsigned char *)event_data);
609                 break;
610         case OAL_EVENT_AVRCP_SETTING_REPEAT_STATUS:
611                 __handle_player_property_repeat((unsigned char *)event_data);
612                 break;
613         case OAL_EVENT_AVRCP_SETTING_SHUFFLE_STATUS:
614                 __handle_player_property_shuffle((unsigned char *)event_data);
615                 break;
616         case OAL_EVENT_AVRCP_SETTING_SCAN_STATUS:
617                 __handle_player_property_scan((unsigned char *)event_data);
618                 break;
619         case OAL_EVENT_AVRCP_REMOTE_FEATURES:
620                 break;
621         case OAL_EVENT_AVRCP_VOLUME_MUTE_CHANGED: {
622                 oal_avrcp_volume_mute_t *volume_mute = (oal_avrcp_volume_mute_t *)event_data;
623
624                 if (volume_mute)
625                         __handle_transport_property_volume(volume_mute->volume);
626                 break;
627         }
628         case OAL_EVENT_AVRCP_DELAY_CHANGED:
629                  __handle_transport_property_delay((unsigned int *)event_data);
630                 break;
631         default:
632                 BT_ERR("Unhandled AVRCP target event: %d", event_type);
633         }
634 }
635
636 int _bt_service_avrcp_enable(void)
637 {
638         oal_status_t status = OAL_STATUS_SUCCESS;
639
640         status = avrcp_enable();
641         if (OAL_STATUS_SUCCESS != status) {
642                 BT_ERR("Failed to initialize Bluetooth AVRCP Target Profile, status: %d", status);
643                 return _bt_convert_oal_status_to_bt_error(status);
644         }
645
646         /* Register AVRCP target event handler */
647         _bt_service_register_event_handler_callback(BT_AVRCP_MODULE, __handle_avrcp_target_events);
648
649         return BLUETOOTH_ERROR_NONE;
650 }
651
652 int _bt_service_avrcp_disable(void)
653 {
654         oal_status_t status = OAL_STATUS_SUCCESS;
655
656         status = avrcp_disable();
657         if (OAL_STATUS_SUCCESS != status) {
658                 BT_ERR("Failed to initialize Bluetooth A2DP Source Profile, status: %d", status);
659                 return _bt_convert_oal_status_to_bt_error(status);
660         }
661
662         /* Register AVRCP target event handler */
663         _bt_service_unregister_event_handler_callback(BT_AVRCP_MODULE);
664
665         return BLUETOOTH_ERROR_NONE;
666 }