tizen 2.3.1 release
[framework/connectivity/bluez.git] / android / hal-avrcp.c
1 /*
2  * Copyright (C) 2014 Intel Corporation
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 <stdbool.h>
19 #include <stddef.h>
20 #include <string.h>
21 #include <stdlib.h>
22
23 #include "hal-utils.h"
24 #include "hal-log.h"
25 #include "hal.h"
26 #include "hal-msg.h"
27 #include "ipc-common.h"
28 #include "hal-ipc.h"
29
30 static const btrc_callbacks_t *cbs = NULL;
31
32 static bool interface_ready(void)
33 {
34         return cbs != NULL;
35 }
36
37 static void handle_remote_features(void *buf, uint16_t len, int fd)
38 {
39         struct hal_ev_avrcp_remote_features *ev = buf;
40
41         if (cbs->remote_features_cb)
42                 cbs->remote_features_cb((bt_bdaddr_t *) (ev->bdaddr),
43                                                                 ev->features);
44 }
45
46 static void handle_get_play_status(void *buf, uint16_t len, int fd)
47 {
48         if (cbs->get_play_status_cb)
49                 cbs->get_play_status_cb();
50 }
51
52 static void handle_list_player_attrs(void *buf, uint16_t len, int fd)
53 {
54         if (cbs->list_player_app_attr_cb)
55                 cbs->list_player_app_attr_cb();
56 }
57
58 static void handle_list_player_values(void *buf, uint16_t len, int fd)
59 {
60         struct hal_ev_avrcp_list_player_values *ev = buf;
61
62         if (cbs->list_player_app_values_cb)
63                 cbs->list_player_app_values_cb(ev->attr);
64 }
65
66 static void handle_get_player_values(void *buf, uint16_t len, int fd)
67 {
68         struct hal_ev_avrcp_get_player_values *ev = buf;
69         btrc_player_attr_t attrs[4];
70         int i;
71
72         if (!cbs->get_player_app_value_cb)
73                 return;
74
75         /* Convert uint8_t array to btrc_player_attr_t array */
76         for (i = 0; i < ev->number; i++)
77                 attrs[i] = ev->attrs[i];
78
79         cbs->get_player_app_value_cb(ev->number, attrs);
80 }
81
82 static void handle_get_player_attrs_text(void *buf, uint16_t len, int fd)
83 {
84         struct hal_ev_avrcp_get_player_attrs_text *ev = buf;
85         btrc_player_attr_t attrs[4];
86         int i;
87
88         if (!cbs->get_player_app_attrs_text_cb)
89                 return;
90
91         /* Convert uint8_t array to btrc_player_attr_t array */
92         for (i = 0; i < ev->number; i++)
93                 attrs[i] = ev->attrs[i];
94
95         cbs->get_player_app_attrs_text_cb(ev->number, attrs);
96 }
97
98 static void handle_get_player_values_text(void *buf, uint16_t len, int fd)
99 {
100         struct hal_ev_avrcp_get_player_values_text *ev = buf;
101
102         if (cbs->get_player_app_values_text_cb)
103                 cbs->get_player_app_values_text_cb(ev->attr, ev->number,
104                                                                 ev->values);
105 }
106
107 static void handle_set_player_value(void *buf, uint16_t len, int fd)
108 {
109         struct hal_ev_avrcp_set_player_values *ev = buf;
110         struct hal_avrcp_player_attr_value *attrs;
111         btrc_player_settings_t values;
112         int i;
113
114         if (!cbs->set_player_app_value_cb)
115                 return;
116
117         attrs = (struct hal_avrcp_player_attr_value *) ev->attrs;
118
119         /* Convert to btrc_player_settings_t */
120         values.num_attr = ev->number;
121         for (i = 0; i < ev->number; i++) {
122                 values.attr_ids[i] = attrs[i].attr;
123                 values.attr_values[i] = attrs[i].value;
124         }
125
126         cbs->set_player_app_value_cb(&values);
127 }
128
129 static void handle_get_element_attrs(void *buf, uint16_t len, int fd)
130 {
131         struct hal_ev_avrcp_get_element_attrs *ev = buf;
132         btrc_media_attr_t attrs[BTRC_MAX_APP_SETTINGS];
133         int i;
134
135         if (!cbs->get_element_attr_cb)
136                 return;
137
138         /* Convert uint8_t array to btrc_media_attr_t array */
139         for (i = 0; i < ev->number; i++)
140                 attrs[i] = ev->attrs[i];
141
142         cbs->get_element_attr_cb(ev->number, attrs);
143 }
144
145 static void handle_register_notification(void *buf, uint16_t len, int fd)
146 {
147         struct hal_ev_avrcp_register_notification *ev = buf;
148
149         if (cbs->register_notification_cb)
150                 cbs->register_notification_cb(ev->event, ev->param);
151 }
152
153 static void handle_volume_changed(void *buf, uint16_t len, int fd)
154 {
155         struct hal_ev_avrcp_volume_changed *ev = buf;
156
157         if (cbs->volume_change_cb)
158                 cbs->volume_change_cb(ev->volume, ev->type);
159 }
160
161 static void handle_passthrough_cmd(void *buf, uint16_t len, int fd)
162 {
163         struct hal_ev_avrcp_passthrough_cmd *ev = buf;
164
165         if (cbs->passthrough_cmd_cb)
166                 cbs->passthrough_cmd_cb(ev->id, ev->state);
167 }
168
169 /*
170  * handlers will be called from notification thread context,
171  * index in table equals to 'opcode - HAL_MINIMUM_EVENT'
172  */
173 static const struct hal_ipc_handler ev_handlers[] = {
174         /* HAL_EV_AVRCP_REMOTE_FEATURES */
175         { handle_remote_features, false,
176                         sizeof(struct hal_ev_avrcp_remote_features) },
177         /* HAL_EV_AVRCP_GET_PLAY_STATUS */
178         { handle_get_play_status, false, 0 },
179         /* HAL_EV_AVRCP_LIST_PLAYER_ATTRS */
180         { handle_list_player_attrs, false, 0 },
181         /* HAL_EV_AVRCP_LIST_PLAYER_VALUES */
182         { handle_list_player_values, false,
183                         sizeof(struct hal_ev_avrcp_list_player_values) },
184         /* HAL_EV_AVRCP_GET_PLAYER_VALUES */
185         { handle_get_player_values, true,
186                         sizeof(struct hal_ev_avrcp_get_player_values) },
187         /* HAL_EV_AVRCP_GET_PLAYER_ATTRS_TEXT */
188         { handle_get_player_attrs_text, true,
189                         sizeof(struct hal_ev_avrcp_get_player_attrs_text) },
190         /* HAL_EV_AVRCP_GET_PLAYER_VALUES_TEXT */
191         { handle_get_player_values_text, true,
192                         sizeof(struct hal_ev_avrcp_get_player_values_text) },
193         /* HAL_EV_AVRCP_SET_PLAYER_VALUES */
194         { handle_set_player_value, true,
195                         sizeof(struct hal_ev_avrcp_set_player_values) },
196         /* HAL_EV_AVRCP_GET_ELEMENT_ATTRS */
197         { handle_get_element_attrs, true,
198                         sizeof(struct hal_ev_avrcp_get_element_attrs) },
199         /* HAL_EV_AVRCP_REGISTER_NOTIFICATION */
200         { handle_register_notification, false,
201                         sizeof(struct hal_ev_avrcp_register_notification) },
202         /* HAL_EV_AVRCP_VOLUME_CHANGED */
203         { handle_volume_changed, false,
204                         sizeof(struct hal_ev_avrcp_volume_changed) },
205         /* HAL_EV_AVRCP_PASSTHROUGH_CMD */
206         { handle_passthrough_cmd, false,
207                         sizeof(struct hal_ev_avrcp_passthrough_cmd) },
208 };
209
210 static bt_status_t init(btrc_callbacks_t *callbacks)
211 {
212         struct hal_cmd_register_module cmd;
213         int ret;
214
215         DBG("");
216
217         if (interface_ready())
218                 return BT_STATUS_DONE;
219
220         cbs = callbacks;
221
222         hal_ipc_register(HAL_SERVICE_ID_AVRCP, ev_handlers,
223                                 sizeof(ev_handlers) / sizeof(ev_handlers[0]));
224
225         cmd.service_id = HAL_SERVICE_ID_AVRCP;
226         cmd.mode = HAL_MODE_DEFAULT;
227         cmd.max_clients = 1;
228
229         ret = hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_REGISTER_MODULE,
230                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
231
232         if (ret != BT_STATUS_SUCCESS) {
233                 cbs = NULL;
234                 hal_ipc_unregister(HAL_SERVICE_ID_AVRCP);
235         }
236
237         return ret;
238 }
239
240 static bt_status_t get_play_status_rsp(btrc_play_status_t status,
241                                         uint32_t song_len, uint32_t song_pos)
242 {
243         struct hal_cmd_avrcp_get_play_status cmd;
244
245         DBG("");
246
247         if (!interface_ready())
248                 return BT_STATUS_NOT_READY;
249
250         cmd.status = status;
251         cmd.duration = song_len;
252         cmd.position = song_pos;
253
254         return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAY_STATUS,
255                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
256 }
257
258 static bt_status_t list_player_app_attr_rsp(int num_attr,
259                                                 btrc_player_attr_t *p_attrs)
260 {
261         char buf[IPC_MTU];
262         struct hal_cmd_avrcp_list_player_attrs *cmd = (void *) buf;
263         size_t len;
264
265         DBG("");
266
267         if (!interface_ready())
268                 return BT_STATUS_NOT_READY;
269
270         if (num_attr < 0)
271                 return BT_STATUS_PARM_INVALID;
272
273         len = sizeof(*cmd) + num_attr;
274         if (len > IPC_MTU)
275                 return BT_STATUS_PARM_INVALID;
276
277         cmd->number = num_attr;
278         memcpy(cmd->attrs, p_attrs, num_attr);
279
280         return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
281                                         HAL_OP_AVRCP_LIST_PLAYER_ATTRS,
282                                         len, cmd, NULL, NULL, NULL);
283 }
284
285 static bt_status_t list_player_app_value_rsp(int num_val, uint8_t *p_vals)
286 {
287         char buf[IPC_MTU];
288         struct hal_cmd_avrcp_list_player_values *cmd = (void *) buf;
289         size_t len;
290
291         DBG("");
292
293         if (!interface_ready())
294                 return BT_STATUS_NOT_READY;
295
296         if (num_val < 0)
297                 return BT_STATUS_PARM_INVALID;
298
299         len = sizeof(*cmd) + num_val;
300
301         if (len > IPC_MTU)
302                 return BT_STATUS_PARM_INVALID;
303
304         cmd->number = num_val;
305         memcpy(cmd->values, p_vals, num_val);
306
307         return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
308                                         HAL_OP_AVRCP_LIST_PLAYER_VALUES,
309                                         len, cmd, NULL, NULL, NULL);
310 }
311
312 static bt_status_t get_player_app_value_rsp(btrc_player_settings_t *p_vals)
313 {
314         char buf[IPC_MTU];
315         struct hal_cmd_avrcp_get_player_attrs *cmd = (void *) buf;
316         size_t len, attrs_len;
317         int i;
318
319         DBG("");
320
321         if (!interface_ready())
322                 return BT_STATUS_NOT_READY;
323
324         if (!p_vals)
325                 return BT_STATUS_PARM_INVALID;
326
327         attrs_len = p_vals->num_attr *
328                                 sizeof(struct hal_avrcp_player_attr_value);
329         len = sizeof(*cmd) + attrs_len;
330
331         if (len > IPC_MTU)
332                 return BT_STATUS_PARM_INVALID;
333
334         cmd->number = p_vals->num_attr;
335
336         for (i = 0; i < p_vals->num_attr; i++) {
337                 cmd->attrs[i].attr = p_vals->attr_ids[i];
338                 cmd->attrs[i].value = p_vals->attr_values[i];
339         }
340
341         return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
342                                         HAL_OP_AVRCP_GET_PLAYER_ATTRS,
343                                         len, cmd, NULL, NULL, NULL);
344 }
345
346 static int write_text(uint8_t *ptr, uint8_t id, uint8_t *text, size_t *len)
347 {
348         struct hal_avrcp_player_setting_text *value = (void *) ptr;
349         size_t attr_len = sizeof(*value);
350
351         if (attr_len + *len > IPC_MTU)
352                 return 0;
353
354         value->id = id;
355         value->len = strnlen((const char *) text, BTRC_MAX_ATTR_STR_LEN);
356
357         *len += attr_len;
358
359         if (value->len + *len > IPC_MTU)
360                 value->len = IPC_MTU - *len;
361
362         memcpy(value->text, text, value->len);
363
364         *len += value->len;
365
366         return attr_len + value->len;
367 }
368
369 static uint8_t write_player_setting_text(uint8_t *ptr, uint8_t num_attr,
370                                         btrc_player_setting_text_t *p_attrs,
371                                         size_t *len)
372 {
373         int i;
374
375         for (i = 0; i < num_attr && *len < IPC_MTU; i++) {
376                 int ret;
377
378                 ret = write_text(ptr, p_attrs[i].id, p_attrs[i].text, len);
379                 if (ret == 0)
380                         break;
381
382                 ptr += ret;
383         }
384
385         return i;
386 }
387
388 static bt_status_t get_player_app_attr_text_rsp(int num_attr,
389                                         btrc_player_setting_text_t *p_attrs)
390 {
391         char buf[IPC_MTU];
392         struct hal_cmd_avrcp_get_player_attrs_text *cmd = (void *) buf;
393         uint8_t *ptr;
394         size_t len;
395
396         DBG("");
397
398         if (!interface_ready())
399                 return BT_STATUS_NOT_READY;
400
401         if (num_attr < 0 || num_attr > BTRC_MAX_APP_SETTINGS)
402                 return BT_STATUS_PARM_INVALID;
403
404         len = sizeof(*cmd);
405         ptr = (uint8_t *) &cmd->attrs[0];
406         cmd->number = write_player_setting_text(ptr, num_attr, p_attrs, &len);
407
408         return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
409                                         HAL_OP_AVRCP_GET_PLAYER_ATTRS_TEXT,
410                                         len, cmd, NULL, NULL, NULL);
411 }
412
413 static bt_status_t get_player_app_value_text_rsp(int num_val,
414                                         btrc_player_setting_text_t *p_vals)
415 {
416         char buf[IPC_MTU];
417         struct hal_cmd_avrcp_get_player_values_text *cmd = (void *) buf;
418         uint8_t *ptr;
419         size_t len;
420
421         DBG("");
422
423         if (!interface_ready())
424                 return BT_STATUS_NOT_READY;
425
426         if (num_val < 0)
427                 return BT_STATUS_PARM_INVALID;
428
429         len = sizeof(*cmd);
430         ptr = (uint8_t *) &cmd->values[0];
431         cmd->number = write_player_setting_text(ptr, num_val, p_vals, &len);
432
433         return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
434                                         HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT,
435                                         len, cmd, NULL, NULL, NULL);
436 }
437
438 static uint8_t write_element_attr_text(uint8_t *ptr, uint8_t num_attr,
439                                         btrc_element_attr_val_t *p_attrs,
440                                         size_t *len)
441 {
442         int i;
443
444         for (i = 0; i < num_attr && *len < IPC_MTU; i++) {
445                 int ret;
446
447                 ret = write_text(ptr, p_attrs[i].attr_id, p_attrs[i].text, len);
448                 if (ret == 0)
449                         break;
450
451                 ptr += ret;
452         }
453
454         return i;
455 }
456
457 static bt_status_t get_element_attr_rsp(uint8_t num_attr,
458                                         btrc_element_attr_val_t *p_attrs)
459 {
460         char buf[IPC_MTU];
461         struct hal_cmd_avrcp_get_element_attrs_text *cmd = (void *) buf;
462         size_t len;
463         uint8_t *ptr;
464
465         DBG("");
466
467         if (!interface_ready())
468                 return BT_STATUS_NOT_READY;
469
470         len = sizeof(*cmd);
471         ptr = (uint8_t *) &cmd->values[0];
472         cmd->number = write_element_attr_text(ptr, num_attr, p_attrs, &len);
473
474         return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
475                                         HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT,
476                                         len, cmd, NULL, NULL, NULL);
477 }
478
479 static bt_status_t set_player_app_value_rsp(btrc_status_t rsp_status)
480 {
481         struct hal_cmd_avrcp_set_player_attrs_value cmd;
482
483         DBG("");
484
485         if (!interface_ready())
486                 return BT_STATUS_NOT_READY;
487
488         cmd.status = rsp_status;
489
490         return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
491                                         HAL_OP_AVRCP_SET_PLAYER_ATTRS_VALUE,
492                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
493 }
494
495 static bt_status_t play_status_changed_rsp(btrc_notification_type_t type,
496                                                 btrc_play_status_t *play_status)
497 {
498         char buf[IPC_MTU];
499         struct hal_cmd_avrcp_register_notification *cmd = (void *) buf;
500         size_t len;
501
502         cmd->event = BTRC_EVT_PLAY_STATUS_CHANGED;
503         cmd->type = type;
504         cmd->len = 1;
505         memcpy(cmd->data, play_status, cmd->len);
506
507         len = sizeof(*cmd) + cmd->len;
508
509         return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
510                                         HAL_OP_AVRCP_REGISTER_NOTIFICATION,
511                                         len, cmd, NULL, NULL, NULL);
512 }
513
514 static bt_status_t track_change_rsp(btrc_notification_type_t type,
515                                                         btrc_uid_t *track)
516 {
517         char buf[IPC_MTU];
518         struct hal_cmd_avrcp_register_notification *cmd = (void *) buf;
519         size_t len;
520
521         cmd->event = BTRC_EVT_TRACK_CHANGE;
522         cmd->type = type;
523         cmd->len = sizeof(*track);
524         memcpy(cmd->data, track, cmd->len);
525
526         len = sizeof(*cmd) + cmd->len;
527
528         return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
529                                         HAL_OP_AVRCP_REGISTER_NOTIFICATION,
530                                         len, cmd, NULL, NULL, NULL);
531 }
532
533 static bt_status_t track_reached_end_rsp(btrc_notification_type_t type)
534 {
535         struct hal_cmd_avrcp_register_notification cmd;
536
537         cmd.event = BTRC_EVT_TRACK_REACHED_END;
538         cmd.type = type;
539         cmd.len = 0;
540
541         return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
542                                         HAL_OP_AVRCP_REGISTER_NOTIFICATION,
543                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
544 }
545
546 static bt_status_t track_reached_start_rsp(btrc_notification_type_t type)
547 {
548         struct hal_cmd_avrcp_register_notification cmd;
549
550         cmd.event = BTRC_EVT_TRACK_REACHED_START;
551         cmd.type = type;
552         cmd.len = 0;
553
554         return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
555                                         HAL_OP_AVRCP_REGISTER_NOTIFICATION,
556                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
557 }
558
559 static bt_status_t play_pos_changed_rsp(btrc_notification_type_t type,
560                                                         uint32_t *song_pos)
561 {
562         char buf[IPC_MTU];
563         struct hal_cmd_avrcp_register_notification *cmd = (void *) buf;
564         size_t len;
565
566         cmd->event = BTRC_EVT_PLAY_POS_CHANGED;
567         cmd->type = type;
568         cmd->len = sizeof(*song_pos);
569         memcpy(cmd->data, song_pos, cmd->len);
570
571         len = sizeof(*cmd) + cmd->len;
572
573         return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
574                                         HAL_OP_AVRCP_REGISTER_NOTIFICATION,
575                                         len, cmd, NULL, NULL, NULL);
576 }
577
578 static bt_status_t settings_changed_rsp(btrc_notification_type_t type,
579                                         btrc_player_settings_t *player_setting)
580 {
581         char buf[IPC_MTU];
582         struct hal_cmd_avrcp_register_notification *cmd = (void *) buf;
583         struct hal_avrcp_player_attr_value *attrs;
584         size_t len, param_len;
585         int i;
586
587         param_len = player_setting->num_attr * sizeof(*attrs);
588         len = sizeof(*cmd) + param_len;
589
590         if (len > IPC_MTU)
591                 return BT_STATUS_PARM_INVALID;
592
593         cmd->event = BTRC_EVT_APP_SETTINGS_CHANGED;
594         cmd->type = type;
595         cmd->len = param_len;
596
597         attrs = (struct hal_avrcp_player_attr_value *) &cmd->data[0];
598         for (i = 0; i < player_setting->num_attr; i++) {
599                 attrs[i].attr = player_setting->attr_ids[i];
600                 attrs[i].value = player_setting->attr_values[i];
601         }
602
603         return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP,
604                                         HAL_OP_AVRCP_REGISTER_NOTIFICATION,
605                                         len, cmd, NULL, NULL, NULL);
606 }
607
608 static bt_status_t register_notification_rsp(btrc_event_id_t event_id,
609                                         btrc_notification_type_t type,
610                                         btrc_register_notification_t *p_param)
611 {
612         DBG("");
613
614         if (!interface_ready())
615                 return BT_STATUS_NOT_READY;
616
617         switch (event_id) {
618         case BTRC_EVT_PLAY_STATUS_CHANGED:
619                 return play_status_changed_rsp(type, &p_param->play_status);
620         case BTRC_EVT_TRACK_CHANGE:
621                 return track_change_rsp(type, &p_param->track);
622         case BTRC_EVT_TRACK_REACHED_END:
623                 return track_reached_end_rsp(type);
624         case BTRC_EVT_TRACK_REACHED_START:
625                 return track_reached_start_rsp(type);
626         case BTRC_EVT_PLAY_POS_CHANGED:
627                 return play_pos_changed_rsp(type, &p_param->song_pos);
628         case BTRC_EVT_APP_SETTINGS_CHANGED:
629                 return settings_changed_rsp(type, &p_param->player_setting);
630         default:
631                 return BT_STATUS_PARM_INVALID;
632         }
633 }
634
635 static bt_status_t set_volume(uint8_t volume)
636 {
637         struct hal_cmd_avrcp_set_volume cmd;
638
639         DBG("");
640
641         if (!interface_ready())
642                 return BT_STATUS_NOT_READY;
643
644         cmd.value = volume;
645
646         return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_VOLUME,
647                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
648 }
649
650 static void cleanup(void)
651 {
652         struct hal_cmd_unregister_module cmd;
653
654         DBG("");
655
656         if (!interface_ready())
657                 return;
658
659         cmd.service_id = HAL_SERVICE_ID_AVRCP;
660
661         hal_ipc_cmd(HAL_SERVICE_ID_CORE, HAL_OP_UNREGISTER_MODULE,
662                                         sizeof(cmd), &cmd, NULL, NULL, NULL);
663
664         hal_ipc_unregister(HAL_SERVICE_ID_AVRCP);
665
666         cbs = NULL;
667 }
668
669 static btrc_interface_t iface = {
670         .size = sizeof(iface),
671         .init = init,
672         .get_play_status_rsp = get_play_status_rsp,
673         .list_player_app_attr_rsp = list_player_app_attr_rsp,
674         .list_player_app_value_rsp = list_player_app_value_rsp,
675         .get_player_app_value_rsp = get_player_app_value_rsp,
676         .get_player_app_attr_text_rsp = get_player_app_attr_text_rsp,
677         .get_player_app_value_text_rsp = get_player_app_value_text_rsp,
678         .get_element_attr_rsp = get_element_attr_rsp,
679         .set_player_app_value_rsp = set_player_app_value_rsp,
680         .register_notification_rsp = register_notification_rsp,
681         .set_volume = set_volume,
682         .cleanup = cleanup
683 };
684
685 btrc_interface_t *bt_get_avrcp_interface(void)
686 {
687         return &iface;
688 }