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