2 * Copyright (C) 2013 Intel Corporation
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <hardware/bluetooth.h>
23 #include <hardware/bt_hh.h>
26 #include "pollhandler.h"
27 #include "../hal-utils.h"
29 const bthh_interface_t *if_hh = NULL;
31 SINTMAP(bthh_protocol_mode_t, -1, "(unknown)")
32 DELEMENT(BTHH_REPORT_MODE),
33 DELEMENT(BTHH_BOOT_MODE),
34 DELEMENT(BTHH_UNSUPPORTED_MODE),
37 SINTMAP(bthh_report_type_t, -1, "(unknown)")
38 DELEMENT(BTHH_INPUT_REPORT),
39 DELEMENT(BTHH_OUTPUT_REPORT),
40 DELEMENT(BTHH_FEATURE_REPORT),
43 SINTMAP(bthh_connection_state_t, -1, "(unknown)")
44 DELEMENT(BTHH_CONN_STATE_CONNECTED),
45 DELEMENT(BTHH_CONN_STATE_CONNECTING),
46 DELEMENT(BTHH_CONN_STATE_DISCONNECTED),
47 DELEMENT(BTHH_CONN_STATE_DISCONNECTING),
48 DELEMENT(BTHH_CONN_STATE_FAILED_MOUSE_FROM_HOST),
49 DELEMENT(BTHH_CONN_STATE_FAILED_KBD_FROM_HOST),
50 DELEMENT(BTHH_CONN_STATE_FAILED_TOO_MANY_DEVICES),
51 DELEMENT(BTHH_CONN_STATE_FAILED_NO_BTHID_DRIVER),
52 DELEMENT(BTHH_CONN_STATE_FAILED_GENERIC),
53 DELEMENT(BTHH_CONN_STATE_UNKNOWN),
56 SINTMAP(bthh_status_t, -1, "(unknown)")
58 DELEMENT(BTHH_HS_HID_NOT_READY),
59 DELEMENT(BTHH_HS_INVALID_RPT_ID),
60 DELEMENT(BTHH_HS_TRANS_NOT_SPT),
61 DELEMENT(BTHH_HS_INVALID_PARAM),
62 DELEMENT(BTHH_HS_ERROR),
64 DELEMENT(BTHH_ERR_SDP),
65 DELEMENT(BTHH_ERR_PROTO),
66 DELEMENT(BTHH_ERR_DB_FULL),
67 DELEMENT(BTHH_ERR_TOD_UNSPT),
68 DELEMENT(BTHH_ERR_NO_RES),
69 DELEMENT(BTHH_ERR_AUTH_FAILED),
70 DELEMENT(BTHH_ERR_HDL),
73 static char connected_device_addr[MAX_ADDR_STR_LEN];
75 * Callback for connection state change.
76 * state will have one of the values from bthh_connection_state_t
78 static void connection_state_cb(bt_bdaddr_t *bd_addr,
79 bthh_connection_state_t state)
81 char addr[MAX_ADDR_STR_LEN];
83 haltest_info("%s: bd_addr=%s connection_state=%s\n", __func__,
84 bt_bdaddr_t2str(bd_addr, addr),
85 bthh_connection_state_t2str(state));
86 if (state == BTHH_CONN_STATE_CONNECTED)
87 strcpy(connected_device_addr, addr);
91 * Callback for virtual unplug api.
92 * the status of the virtual unplug
94 static void virtual_unplug_cb(bt_bdaddr_t *bd_addr, bthh_status_t hh_status)
96 char addr[MAX_ADDR_STR_LEN];
98 haltest_info("%s: bd_addr=%s hh_status=%s\n", __func__,
99 bt_bdaddr_t2str(bd_addr, addr),
100 bthh_status_t2str(hh_status));
103 /* Callback for Android 5.0 handshake api. */
104 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
105 static void handshake_cb(bt_bdaddr_t *bd_addr, bthh_status_t hh_status)
107 char addr[MAX_ADDR_STR_LEN];
109 haltest_info("%s: bd_addr=%s hh_status=%s\n", __func__,
110 bt_bdaddr_t2str(bd_addr, addr),
111 bthh_status_t2str(hh_status));
116 * Callback for get hid info
117 * hid_info will contain attr_mask, sub_class, app_id, vendor_id, product_id,
118 * version, ctry_code, len
120 static void hid_info_cb(bt_bdaddr_t *bd_addr, bthh_hid_info_t hid_info)
122 char addr[MAX_ADDR_STR_LEN];
124 /* TODO: bluedroid does not seem to ever call this callback */
125 haltest_info("%s: bd_addr=%s\n", __func__,
126 bt_bdaddr_t2str(bd_addr, addr));
130 * Callback for get/set protocol api.
131 * the protocol mode is one of the value from bthh_protocol_mode_t
133 static void protocol_mode_cb(bt_bdaddr_t *bd_addr, bthh_status_t hh_status,
134 bthh_protocol_mode_t mode)
136 char addr[MAX_ADDR_STR_LEN];
138 haltest_info("%s: bd_addr=%s hh_status=%s mode=%s\n", __func__,
139 bt_bdaddr_t2str(bd_addr, addr),
140 bthh_status_t2str(hh_status),
141 bthh_protocol_mode_t2str(mode));
144 /* Callback for get/set_idle_time api. */
145 static void idle_time_cb(bt_bdaddr_t *bd_addr, bthh_status_t hh_status,
148 char addr[MAX_ADDR_STR_LEN];
150 haltest_info("%s: bd_addr=%s hh_status=%s idle_rate=%d\n", __func__,
151 bt_bdaddr_t2str(bd_addr, addr),
152 bthh_status_t2str(hh_status), idle_rate);
157 * Callback for get report api.
158 * if status is ok rpt_data contains the report data
160 static void get_report_cb(bt_bdaddr_t *bd_addr, bthh_status_t hh_status,
161 uint8_t *rpt_data, int rpt_size)
163 char addr[MAX_ADDR_STR_LEN];
165 /* TODO: print actual report */
166 haltest_info("%s: bd_addr=%s hh_status=%s rpt_size=%d\n", __func__,
167 bt_bdaddr_t2str(bd_addr, addr),
168 bthh_status_t2str(hh_status), rpt_size);
171 static bthh_callbacks_t bthh_callbacks = {
172 .size = sizeof(bthh_callbacks),
173 .connection_state_cb = connection_state_cb,
174 .hid_info_cb = hid_info_cb,
175 .protocol_mode_cb = protocol_mode_cb,
176 .idle_time_cb = idle_time_cb,
177 .get_report_cb = get_report_cb,
178 .virtual_unplug_cb = virtual_unplug_cb,
179 #if ANDROID_VERSION >= PLATFORM_VER(5, 0, 0)
180 .handshake_cb = handshake_cb
186 static void init_p(int argc, const char **argv)
188 RETURN_IF_NULL(if_hh);
190 EXEC(if_hh->init, &bthh_callbacks);
195 static void connect_c(int argc, const char **argv, enum_func *enum_func,
199 *user = (void *) connected_device_addr;
200 *enum_func = enum_one_string;
204 static void connect_p(int argc, const char **argv)
208 RETURN_IF_NULL(if_hh);
209 VERIFY_ADDR_ARG(2, &addr);
211 EXEC(if_hh->connect, &addr);
216 /* Same completion as connect_c */
217 #define disconnect_c connect_c
219 static void disconnect_p(int argc, const char **argv)
223 RETURN_IF_NULL(if_hh);
224 VERIFY_ADDR_ARG(2, &addr);
226 EXEC(if_hh->disconnect, &addr);
231 /* Same completion as connect_c */
232 #define virtual_unplug_c connect_c
234 static void virtual_unplug_p(int argc, const char **argv)
238 RETURN_IF_NULL(if_hh);
239 VERIFY_ADDR_ARG(2, &addr);
241 EXEC(if_hh->virtual_unplug, &addr);
246 /* Same completion as connect_c */
247 #define set_info_c connect_c
249 static void set_info_p(int argc, const char **argv)
252 bthh_hid_info_t hid_info;
254 RETURN_IF_NULL(if_hh);
255 VERIFY_ADDR_ARG(2, &addr);
257 memset(&hid_info, 0, sizeof(hid_info));
260 * This command is intentionally not supported. See comment from
261 * bt_hid_info() in android/hidhost.c
263 EXEC(if_hh->set_info, &addr, hid_info);
268 static void get_protocol_c(int argc, const char **argv, enum_func *enum_func,
272 *user = connected_device_addr;
273 *enum_func = enum_one_string;
274 } else if (argc == 4) {
275 *user = TYPE_ENUM(bthh_protocol_mode_t);
276 *enum_func = enum_defines;
280 static void get_protocol_p(int argc, const char **argv)
283 bthh_protocol_mode_t protocolMode;
285 RETURN_IF_NULL(if_hh);
286 VERIFY_ADDR_ARG(2, &addr);
289 haltest_error("No protocol mode specified\n");
292 protocolMode = str2bthh_protocol_mode_t(argv[3]);
294 EXEC(if_hh->get_protocol, &addr, protocolMode);
299 /* Same completion as get_protocol_c */
300 #define set_protocol_c get_protocol_c
302 static void set_protocol_p(int argc, const char **argv)
305 bthh_protocol_mode_t protocolMode;
307 RETURN_IF_NULL(if_hh);
308 VERIFY_ADDR_ARG(2, &addr);
311 haltest_error("No protocol mode specified\n");
314 protocolMode = str2bthh_protocol_mode_t(argv[3]);
316 EXEC(if_hh->set_protocol, &addr, protocolMode);
321 static void get_report_c(int argc, const char **argv, enum_func *enum_func,
325 *user = connected_device_addr;
326 *enum_func = enum_one_string;
327 } else if (argc == 4) {
328 *user = TYPE_ENUM(bthh_report_type_t);
329 *enum_func = enum_defines;
333 static void get_report_p(int argc, const char **argv)
336 bthh_report_type_t reportType;
340 RETURN_IF_NULL(if_hh);
341 VERIFY_ADDR_ARG(2, &addr);
344 haltest_error("No report type specified\n");
347 reportType = str2bthh_report_type_t(argv[3]);
350 haltest_error("No reportId specified\n");
353 reportId = (uint8_t) atoi(argv[4]);
356 haltest_error("No bufferSize specified\n");
359 bufferSize = atoi(argv[5]);
361 EXEC(if_hh->get_report, &addr, reportType, reportId, bufferSize);
366 static void set_report_c(int argc, const char **argv, enum_func *enum_func,
370 *user = connected_device_addr;
371 *enum_func = enum_one_string;
372 } else if (argc == 4) {
373 *user = TYPE_ENUM(bthh_report_type_t);
374 *enum_func = enum_defines;
378 static void set_report_p(int argc, const char **argv)
381 bthh_report_type_t reportType;
383 RETURN_IF_NULL(if_hh);
384 VERIFY_ADDR_ARG(2, &addr);
387 haltest_error("No report type specified\n");
390 reportType = str2bthh_report_type_t(argv[3]);
393 haltest_error("No report specified\n");
397 EXEC(if_hh->set_report, &addr, reportType, (char *) argv[4]);
402 static void send_data_c(int argc, const char **argv, enum_func *enum_func,
406 *user = connected_device_addr;
407 *enum_func = enum_one_string;
411 static void send_data_p(int argc, const char **argv)
415 RETURN_IF_NULL(if_hh);
416 VERIFY_ADDR_ARG(2, &addr);
419 haltest_error("No data to send specified\n");
423 EXEC(if_hh->send_data, &addr, (char *) argv[3]);
428 static void cleanup_p(int argc, const char **argv)
430 RETURN_IF_NULL(if_hh);
432 EXECV(if_hh->cleanup);
435 /* Methods available in bthh_interface_t */
436 static struct method methods[] = {
438 STD_METHODCH(connect, "<addr>"),
439 STD_METHODCH(disconnect, "<addr>"),
440 STD_METHODCH(virtual_unplug, "<addr>"),
441 STD_METHODCH(set_info, "<addr>"),
442 STD_METHODCH(get_protocol, "<addr> <mode>"),
443 STD_METHODCH(set_protocol, "<addr> <mode>"),
444 STD_METHODCH(get_report, "<addr> <type> <report_id> <size>"),
445 STD_METHODCH(set_report, "<addr> <type> <hex_encoded_report>"),
446 STD_METHODCH(send_data, "<addr> <hex_encoded_data>"),
451 const struct interface hh_if = {