Merge "Invoke HAL_DISCOVERY_STATE_STOPPED event once" into tizen
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / bluez_hal / src / bt-hal-avrcp-ctrl.c
1 /*
2  * Bluetooth-frwk
3  *
4  * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
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 <stdbool.h>
24 #include <stddef.h>
25 #include <string.h>
26 #include <stdlib.h>
27 #include <dlog.h>
28
29 #include "bt-hal.h"
30 #include "bt-hal-log.h"
31 #include "bt-hal-msg.h"
32 #include "bt-hal-utils.h"
33 #include "bt-hal-avrcp-ctrl-dbus-handler.h"
34 #include "bt-hal-avrcp-transport-dbus-handler.h"
35
36 #define AVRC_MAX_NUM_MEDIA_ATTR_ID               7
37
38 static const btrc_ctrl_callbacks_t *bt_hal_avrcp_ctrl_cbacks;
39
40 static bool interface_ready(void)
41 {
42         return bt_hal_avrcp_ctrl_cbacks != NULL;
43 }
44
45 static bt_status_t avrcp_ctrl_connect(bt_bdaddr_t *bd_addr)
46 {
47         DBG("");
48         return _bt_hal_dbus_handler_avrcp_ctrl_connect(bd_addr);
49 }
50
51 static bt_status_t avrcp_ctrl_disconnect(bt_bdaddr_t *bd_addr)
52 {
53         DBG("");
54         return _bt_hal_dbus_handler_avrcp_ctrl_disconnect(bd_addr);
55 }
56
57 static bt_status_t avrcp_ctrl_send_pass_through_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code, uint8_t key_state)
58 {
59         DBG("");
60         return _bt_hal_dbus_handler_avrcp_ctrl_cmd(bd_addr, key_code, key_state);
61 }
62
63 static bt_status_t avrcp_ctrl_set_player_app_setting_cmd(bt_bdaddr_t *bd_addr,
64                                 uint8_t num_attrib, uint8_t* type, uint8_t* value)
65 {
66         int i = 0;
67         int ret = BT_STATUS_SUCCESS;
68
69         DBG("");
70         for (i = 0; i < num_attrib; i++)
71                 ret = _bt_hal_dbus_handler_avrcp_ctrl_set_property(bd_addr, type[i], value[i]);
72
73         return ret;
74 }
75
76 static bt_status_t avrcp_transport_setting_cmd(bt_bdaddr_t *bd_addr,
77                                 uint8_t num_attrib, int *type, unsigned int *value)
78 {
79         int i = 0;
80         int ret = BT_STATUS_SUCCESS;
81
82         DBG("");
83         for (i = 0; i < num_attrib; i++)
84                 ret = _bt_hal_dbus_handler_avrcp_transport_set_property(bd_addr, type[i], value[i]);
85
86         return ret;
87 }
88
89 static void __bt_hal_handle_avrcp_ctrl_conn_state(void *buf, uint16_t len)
90 {
91         struct hal_ev_avrcp_ctrl_conn_state *ev = buf;
92
93         if (bt_hal_avrcp_ctrl_cbacks->connection_state_cb) {
94                 if (ev->state == HAL_AVRCP_CTRL_STATE_CONNECTED)
95                         bt_hal_avrcp_ctrl_cbacks->connection_state_cb(
96                                         TRUE, TRUE, (bt_bdaddr_t *) ev->bdaddr);
97                 else
98                         bt_hal_avrcp_ctrl_cbacks->connection_state_cb(
99                                         FALSE, FALSE, (bt_bdaddr_t *) ev->bdaddr);
100         }
101 }
102
103 btrc_play_status_t __get_play_status(int status)
104 {
105         btrc_play_status_t play_status;
106         play_status = BTRC_PLAYSTATE_ERROR;
107
108         switch (status) {
109         case BTRC_PLAYSTATE_STOPPED:
110                 play_status = BTRC_PLAYSTATE_STOPPED;
111                 break;
112         case BTRC_PLAYSTATE_PLAYING:
113                 play_status = BTRC_PLAYSTATE_PLAYING;
114                 break;
115         case BTRC_PLAYSTATE_PAUSED:
116                 play_status = BTRC_PLAYSTATE_PAUSED;
117                 break;
118         case BTRC_PLAYSTATE_FWD_SEEK:
119                 play_status = BTRC_PLAYSTATE_FWD_SEEK;
120                 break;
121         case BTRC_PLAYSTATE_REV_SEEK:
122                 play_status = BTRC_PLAYSTATE_REV_SEEK;
123                 break;
124         default:
125                 DBG("Wrong play status received:");
126                 break;
127         }
128         return play_status;
129 }
130
131 static void __bt_hal_handle_avrcp_ctrl_playstatus_changed_event(void *buf, uint16_t len)
132 {
133         struct hal_ev_play_status_changed *ev = buf;
134
135         if (bt_hal_avrcp_ctrl_cbacks->play_position_changed_cb)
136                 bt_hal_avrcp_ctrl_cbacks->play_status_changed_cb((bt_bdaddr_t *)ev->bdaddr, ev->status);
137 }
138
139 static void __bt_hal_handle_avrcp_ctrl_playposition_changed_event(void *buf, uint16_t len)
140 {
141         struct hal_ev_play_position *ev = buf;
142
143         if (bt_hal_avrcp_ctrl_cbacks->play_position_changed_cb)
144                 bt_hal_avrcp_ctrl_cbacks->play_position_changed_cb((bt_bdaddr_t *)ev->bdaddr, ev->len, ev->pos);
145
146 }
147
148 static void __bt_hal_handle_avrcp_ctrl_player_setting_changed(void *buf, uint16_t len)
149 {
150         struct hal_ev_player_setting *ev = buf;
151         btrc_player_settings_t player_setting;
152
153         memset(&player_setting, 0, sizeof(player_setting));
154         player_setting.num_attr = ev->num_attr;
155         memcpy(player_setting.attr_ids, ev->attr_ids, sizeof(player_setting.attr_ids));
156         memcpy(player_setting.attr_values, ev->attr_values, sizeof(player_setting.attr_values));
157
158         if (bt_hal_avrcp_ctrl_cbacks->playerapplicationsetting_changed_cb)
159                 bt_hal_avrcp_ctrl_cbacks->playerapplicationsetting_changed_cb(
160                                 (bt_bdaddr_t *)ev->bdaddr, &player_setting);
161 }
162
163 static void __bt_hal_handle_avrcp_ctrl_pass_cmd_res_event(void *buf, uint16_t len)
164 {
165         struct hal_ev_pass_cmd_rsp *ev = (struct hal_ev_pass_cmd_rsp *)buf;
166
167         if (bt_hal_avrcp_ctrl_cbacks->passthrough_rsp_cb)
168                 bt_hal_avrcp_ctrl_cbacks->passthrough_rsp_cb(NULL,
169                         ev->key_code, ev->key_state);
170 }
171
172 static void __bt_hal_handle_avrcp_ctrl_set_app_setting_res_event(void *buf, uint16_t len)
173 {
174         struct hal_ev_set_player_app_setting_rsp *ev = buf;
175
176         if (bt_hal_avrcp_ctrl_cbacks->setplayerappsetting_rsp_cb)
177                 bt_hal_avrcp_ctrl_cbacks->setplayerappsetting_rsp_cb((bt_bdaddr_t *)ev->bdaddr, ev->resp);
178 }
179
180 static void __bt_hal_handle_avrcp_ctrl_track_changed_event(void *buf, uint16_t len)
181 {
182         struct hal_ev_track_changed *ev = buf;
183         btrc_element_attr_val_t attr[HAL_MAX_ATTR_NUM];
184         int i;
185
186         for (i = 0; i < ev->num_attr; i++) {
187                 attr[i].attr_id = ev->attr[i].attr_id;
188                 memcpy(attr[i].text, ev->attr[i].text, sizeof(ev->attr[i].text));
189         }
190
191         DBG("call track_changed_cb");
192         if (bt_hal_avrcp_ctrl_cbacks->track_changed_cb)
193                 bt_hal_avrcp_ctrl_cbacks->track_changed_cb(
194                                 (bt_bdaddr_t *)ev->bdaddr, ev->num_attr, attr);
195 }
196
197 static void __bt_hal_handle_avrcp_ctrl_event(int message, void *buf, uint16_t len)
198 {
199         DBG("+");
200         if (!interface_ready())
201                 return;
202         switch (message) {
203         case HAL_EV_AVRCP_CTRL_CONN_STATE:
204                 DBG("Event: HAL_EV_AVRCP_CTRL_CONN_STATE");
205                 __bt_hal_handle_avrcp_ctrl_conn_state(buf, len);
206                 break;
207         case HAL_EV_AVRCP_CTRL_PASS_THROUGH_RSP:
208                 DBG("Event: HAL_EV_AVRCP_CTRL_PASS_THROUGH_RSP");
209                 __bt_hal_handle_avrcp_ctrl_pass_cmd_res_event(buf, len);
210                 break;
211         case HAL_EV_AVRCP_CTRL_SET_PLAYER_APP_SETTING_RSP:
212                 DBG("Event: HAL_EV_AVRCP_CTRL_SET_PLAYER_APP_SETTING_RSP");
213                 __bt_hal_handle_avrcp_ctrl_set_app_setting_res_event(buf, len);
214                 break;
215         case HAL_EV_AVRCP_CTRL_PLAYER_APP_SETTING_CHANGED:
216                 DBG("Event: HAL_EV_AVRCP_CTRL_PLAYER_APP_SETTING_CHANGED");
217                 __bt_hal_handle_avrcp_ctrl_player_setting_changed(buf, len);
218                 break;
219         case HAL_EV_AVRCP_CTRL_TRACK_CHANGED:
220                 DBG("Event: HAL_EV_AVRCP_CTRL_TRACK_CHANGED");
221                 __bt_hal_handle_avrcp_ctrl_track_changed_event(buf, len);
222                 break;
223         case HAL_EV_AVRCP_CTRL_PLAY_POSITION_CHANGED:
224                 DBG("Event: HAL_EV_AVRCP_CTRL_PLAY_POSITION_CHANGED");
225                 __bt_hal_handle_avrcp_ctrl_playposition_changed_event(buf, len);
226                 break;
227         case HAL_EV_AVRCP_CTRL_PLAY_STATUS_CHANGED:
228                 DBG("Event: HAL_EV_AVRCP_CTRL_PLAY_STATUS_CHANGED");
229                 __bt_hal_handle_avrcp_ctrl_playstatus_changed_event(buf, len);
230                 break;
231         default:
232                 DBG("Event Currently not handled!!");
233                 break;
234         }
235
236         DBG("-");
237 }
238
239 static bt_status_t init(btrc_ctrl_callbacks_t* callbacks)
240 {
241         DBG("");
242
243         if (interface_ready())
244                 return BT_STATUS_DONE;
245
246         bt_hal_avrcp_ctrl_cbacks = callbacks;
247         DBG("Register AVRCP Ctroller events callback function");
248         _bt_hal_register_avrcp_ctrl_dbus_handler_cb(__bt_hal_handle_avrcp_ctrl_event);
249         _bt_hal_register_event_handler_cb(HAL_AVRCP_CTRL, __bt_hal_handle_avrcp_ctrl_event);
250         return BT_STATUS_SUCCESS;
251 }
252
253 static void cleanup(void)
254 {
255         DBG("");
256
257         if (!interface_ready())
258                 return;
259
260         _bt_hal_unregister_event_handler_cb(HAL_AVRCP_CTRL);
261         bt_hal_avrcp_ctrl_cbacks = NULL;
262 }
263
264 static btrc_ctrl_interface_t avrcp_ctrl_if = {
265         .size = sizeof(avrcp_ctrl_if),
266         .init = init,
267         .connect = avrcp_ctrl_connect,
268         .disconnect = avrcp_ctrl_disconnect,
269         .send_pass_through_cmd = avrcp_ctrl_send_pass_through_cmd,
270         .set_player_app_setting_cmd = avrcp_ctrl_set_player_app_setting_cmd,
271         .set_transport_setting_cmd = avrcp_transport_setting_cmd,
272         .cleanup = cleanup
273 };
274
275 btrc_ctrl_interface_t *bt_get_avrcp_ctrl_interface(void)
276 {
277         DBG("Get AVRCP Controller Profile Interface");
278         return &avrcp_ctrl_if;
279 }