Modify bt-oal initialize code readably
[platform/core/connectivity/bluetooth-frwk.git] / bt-oal / oal-hid-host.c
1 /*
2  * Open Adaptation Layer (OAL)
3  *
4  * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *              http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include <stdio.h>
21 #include <dlog.h>
22 #include <string.h>
23
24 #include <bluetooth.h>
25 #include <bt_hh.h>
26
27 #include "oal-event.h"
28 #include "oal-internal.h"
29 #include "oal-common.h"
30 #include "oal-manager.h"
31 #include "oal-hid-host.h"
32 #include "oal-utils.h"
33
34 #define CHECK_OAL_HID_ENABLED() \
35         do { \
36                 if (hid_api == NULL) { \
37                         BT_ERR("HID Not Enabled"); \
38                         return OAL_STATUS_NOT_READY; \
39                 } \
40         } while (0)
41
42 static void connection_state_callback(bt_bdaddr_t *bd_addr, bthh_connection_state_t state);
43 static void hid_info_callback(bt_bdaddr_t *bd_addr, bthh_hid_info_t *hid_info);
44 static void get_protocol_mode_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, bthh_protocol_mode_t mode);
45 static void idle_time_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, int idle_rate);
46 static void get_report_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, uint8_t* rpt_data, int rpt_size);
47 static void virtual_unplug_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status);
48 static void handshake_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status);
49
50 static const bthh_interface_t * hid_api;
51
52 static bthh_callbacks_t sBluetoothHidCallbacks = {
53         .size = sizeof(sBluetoothHidCallbacks),
54         .connection_state_cb = connection_state_callback,
55         .hid_info_cb = hid_info_callback,
56         .protocol_mode_cb = get_protocol_mode_callback,
57         .idle_time_cb = idle_time_callback,
58         .get_report_cb = get_report_callback,
59         .virtual_unplug_cb = virtual_unplug_callback,
60         .handshake_cb = handshake_callback,
61 };
62
63 oal_status_t hid_enable(void)
64 {
65         const bt_interface_t * blued_api;
66         int ret;
67
68         API_TRACE();
69         blued_api = adapter_get_stack_interface();
70
71         if (blued_api == NULL) {
72                 BT_ERR("Stack is not initialized");
73                 return OAL_STATUS_NOT_READY;
74         }
75         if (hid_api != NULL) {
76                 BT_WARN("HID Interface is already initialized...");
77                 return OAL_STATUS_ALREADY_DONE;
78         }
79
80         hid_api = (const bthh_interface_t *)blued_api->get_profile_interface(BT_PROFILE_HIDHOST_ID);
81
82         if (hid_api == NULL) {
83                 BT_ERR("HID interface failed");
84                 return OAL_STATUS_INTERNAL_ERROR;
85         }
86
87         if ((ret = hid_api->init(&sBluetoothHidCallbacks)) != BT_STATUS_SUCCESS) {
88                 BT_ERR("HID Init failed: %s", status2string(ret));
89                 hid_api->cleanup();
90                 hid_api = NULL;
91                 return convert_to_oal_status(ret);
92         }
93         return OAL_STATUS_SUCCESS;
94 }
95
96 oal_status_t hid_disable(void)
97 {
98         API_TRACE();
99
100         CHECK_OAL_HID_ENABLED();
101
102         hid_api->cleanup();
103
104         hid_api = NULL;
105         return OAL_STATUS_SUCCESS;
106 }
107
108 void hid_cleanup(void)
109 {
110         BT_DBG();
111         hid_api = NULL;
112 }
113
114 oal_status_t hid_connect(bt_address_t * address)
115 {
116         int ret;
117         bdstr_t bdstr;
118
119         API_TRACE();
120         CHECK_OAL_HID_ENABLED();
121         BT_INFO("[%s]", bdt_bd2str(address, &bdstr));
122
123         ret = hid_api->connect((bt_bdaddr_t*)address);
124         if (ret != BT_STATUS_SUCCESS) {
125                 BT_ERR("ret: %s", status2string(ret));
126                 return convert_to_oal_status(ret);
127         }
128         return OAL_STATUS_SUCCESS;
129 }
130
131 oal_status_t hid_disconnect(bt_address_t * address)
132 {
133         int ret;
134         bdstr_t bdstr;
135
136         API_TRACE();
137         CHECK_OAL_HID_ENABLED();
138
139         BT_INFO("[%s]", bdt_bd2str(address, &bdstr));
140
141         ret = hid_api->disconnect((bt_bdaddr_t*)address);
142         if (ret != BT_STATUS_SUCCESS) {
143                 BT_ERR("ret: %s", status2string(ret));
144                 return convert_to_oal_status(ret);
145         }
146         return OAL_STATUS_SUCCESS;
147 }
148
149 oal_status_t hid_set_report(bt_address_t *address,
150                 bthh_report_type_t reportType, char *report)
151 {
152         int ret;
153         bdstr_t bdstr;
154
155         API_TRACE("len: %d", strlen(report));
156         CHECK_OAL_HID_ENABLED();
157         OAL_CHECK_PARAMETER(address, return);
158         OAL_CHECK_PARAMETER(report, return);
159         BT_INFO("[%s]", bdt_bd2str(address, &bdstr));
160         BT_INFO("[data:%s]", report);
161
162         ret = hid_api->set_report((bt_bdaddr_t*)address, reportType, report);
163         if (ret != BT_STATUS_SUCCESS) {
164                 BT_ERR("ret: %s", status2string(ret));
165                 return convert_to_oal_status(ret);
166         }
167         return OAL_STATUS_SUCCESS;
168 }
169
170 oal_status_t hid_send_data(bt_address_t *address, uint8_t *buf, uint16_t len)
171 {
172         int ret;
173         bdstr_t bdstr;
174
175         API_TRACE("len: %d", len);
176         CHECK_OAL_HID_ENABLED();
177         OAL_CHECK_PARAMETER(address, return);
178         OAL_CHECK_PARAMETER(buf, return);
179
180         BT_INFO("[%s]", bdt_bd2str(address, &bdstr));
181
182         ret = hid_api->send_data((bt_bdaddr_t*)address, (char *)buf);
183         if (ret != BT_STATUS_SUCCESS) {
184                 BT_ERR("ret: %s", status2string(ret));
185                 return convert_to_oal_status(ret);
186         }
187         return OAL_STATUS_SUCCESS;
188 }
189
190 static void connection_state_callback(bt_bdaddr_t *bd_addr, bthh_connection_state_t state)
191 {
192         event_hid_conn_t *event = g_new0(event_hid_conn_t, 1);
193         int event_type;
194
195         BT_DBG("%d", state);
196
197         if (!event)
198                 return;
199         memcpy(event->address.addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
200
201         event->status = OAL_STATUS_SUCCESS;
202
203         switch (state) {
204         case BTHH_CONN_STATE_CONNECTED:
205                 event_type = OAL_EVENT_HID_CONNECTED;
206                 break;
207         case BTHH_CONN_STATE_DISCONNECTED:
208                 event_type = OAL_EVENT_HID_DISCONNECTED;
209                 break;
210         case BTHH_CONN_STATE_CONNECTING:
211         case BTHH_CONN_STATE_DISCONNECTING:
212                 g_free(event);
213                 return;
214         case BTHH_CONN_STATE_FAILED_MOUSE_FROM_HOST:
215                 event_type = OAL_EVENT_HID_DISCONNECTED;
216                 event->status = OAL_STATUS_HID_FAILED_MOUSE;
217                 break;
218         case BTHH_CONN_STATE_FAILED_KBD_FROM_HOST:
219         case BTHH_CONN_STATE_FAILED_TOO_MANY_DEVICES:
220         case BTHH_CONN_STATE_FAILED_NO_BTHID_DRIVER:
221         case BTHH_CONN_STATE_FAILED_GENERIC:
222                 BT_ERR("HID Connection SPECIAL state(%d)", state);
223                 event_type = OAL_EVENT_HID_DISCONNECTED;
224                 event->status = OAL_STATUS_INTERNAL_ERROR;
225                 break;
226         case BTHH_CONN_STATE_UNKNOWN:
227         default:
228                 BT_ERR("Unhandled Connection state %d", state);
229                 g_free(event);
230                 return;
231         }
232
233         send_event_bda_trace(event_type, event, sizeof(event_hid_conn_t), (bt_address_t*)bd_addr);
234 }
235
236 static void hid_info_callback(bt_bdaddr_t *bd_addr, bthh_hid_info_t *hid_info)
237 {
238         BT_INFO("");
239 }
240
241 static void get_protocol_mode_callback(bt_bdaddr_t *bd_addr,
242                 bthh_status_t hh_status, bthh_protocol_mode_t mode)
243 {
244         BT_INFO("status: %d, mode: %d", hh_status, mode);
245 }
246
247 static void idle_time_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, int idle_rate)
248 {
249         BT_INFO("status: %d", hh_status);
250 }
251
252 static void get_report_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, uint8_t* rpt_data, int rpt_size)
253 {
254         BT_INFO("status: %d", hh_status);
255 }
256
257 static void virtual_unplug_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status)
258 {
259         BT_INFO("status: %d", hh_status);
260 }
261
262 static void handshake_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status)
263 {
264         BT_INFO("status: %d", hh_status);
265 }