2 * Open Adaptation Layer (OAL)
4 * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
24 #include <bluetooth.h>
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"
34 #define CHECK_OAL_HID_ENABLED() \
36 if (hid_api == NULL) { \
37 BT_ERR("HID Not Enabled"); \
38 return OAL_STATUS_NOT_READY; \
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);
50 static const bthh_interface_t * hid_api;
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,
63 oal_status_t hid_enable(void)
65 const bt_interface_t * blued_api;
69 blued_api = adapter_get_stack_interface();
71 if (blued_api == NULL) {
72 BT_ERR("Stack is not initialized");
73 return OAL_STATUS_NOT_READY;
75 if (hid_api != NULL) {
76 BT_WARN("HID Interface is already initialized...");
77 return OAL_STATUS_ALREADY_DONE;
80 hid_api = (const bthh_interface_t *)blued_api->get_profile_interface(BT_PROFILE_HIDHOST_ID);
82 if (hid_api == NULL) {
83 BT_ERR("HID interface failed");
84 return OAL_STATUS_INTERNAL_ERROR;
87 if ((ret = hid_api->init(&sBluetoothHidCallbacks)) != BT_STATUS_SUCCESS) {
88 BT_ERR("HID Init failed: %s", status2string(ret));
91 return convert_to_oal_status(ret);
93 return OAL_STATUS_SUCCESS;
96 oal_status_t hid_disable(void)
100 CHECK_OAL_HID_ENABLED();
105 return OAL_STATUS_SUCCESS;
108 void hid_cleanup(void)
114 oal_status_t hid_connect(bt_address_t * address)
120 CHECK_OAL_HID_ENABLED();
121 BT_INFO("[%s]", bdt_bd2str(address, &bdstr));
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);
128 return OAL_STATUS_SUCCESS;
131 oal_status_t hid_disconnect(bt_address_t * address)
137 CHECK_OAL_HID_ENABLED();
139 BT_INFO("[%s]", bdt_bd2str(address, &bdstr));
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);
146 return OAL_STATUS_SUCCESS;
149 oal_status_t hid_set_report(bt_address_t *address,
150 bthh_report_type_t reportType, char *report)
155 API_TRACE("len: %zd", 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);
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);
167 return OAL_STATUS_SUCCESS;
170 oal_status_t hid_send_data(bt_address_t *address, uint8_t *buf, uint16_t len)
175 API_TRACE("len: %d", len);
176 CHECK_OAL_HID_ENABLED();
177 OAL_CHECK_PARAMETER(address, return);
178 OAL_CHECK_PARAMETER(buf, return);
180 BT_INFO("[%s]", bdt_bd2str(address, &bdstr));
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);
187 return OAL_STATUS_SUCCESS;
190 static void connection_state_callback(bt_bdaddr_t *bd_addr, bthh_connection_state_t state)
192 event_hid_conn_t *event = g_new0(event_hid_conn_t, 1);
199 memcpy(event->address.addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
201 event->status = OAL_STATUS_SUCCESS;
204 case BTHH_CONN_STATE_CONNECTED:
205 event_type = OAL_EVENT_HID_CONNECTED;
207 case BTHH_CONN_STATE_DISCONNECTED:
208 event_type = OAL_EVENT_HID_DISCONNECTED;
210 case BTHH_CONN_STATE_CONNECTING:
211 case BTHH_CONN_STATE_DISCONNECTING:
214 case BTHH_CONN_STATE_FAILED_MOUSE_FROM_HOST:
215 event_type = OAL_EVENT_HID_DISCONNECTED;
216 event->status = OAL_STATUS_HID_FAILED_MOUSE;
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;
226 case BTHH_CONN_STATE_UNKNOWN:
228 BT_ERR("Unhandled Connection state %d", state);
233 send_event_bda_trace(event_type, event, sizeof(event_hid_conn_t), (bt_address_t*)bd_addr);
236 static void hid_info_callback(bt_bdaddr_t *bd_addr, bthh_hid_info_t *hid_info)
241 static void get_protocol_mode_callback(bt_bdaddr_t *bd_addr,
242 bthh_status_t hh_status, bthh_protocol_mode_t mode)
244 BT_INFO("status: %d, mode: %d", hh_status, mode);
247 static void idle_time_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, int idle_rate)
249 BT_INFO("status: %d", hh_status);
252 static void get_report_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status, uint8_t* rpt_data, int rpt_size)
254 BT_INFO("status: %d", hh_status);
257 static void virtual_unplug_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status)
259 BT_INFO("status: %d", hh_status);
262 static void handshake_callback(bt_bdaddr_t *bd_addr, bthh_status_t hh_status)
264 BT_INFO("status: %d", hh_status);