1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 #ifndef ANDROID_INCLUDE_BT_HH_H
18 #define ANDROID_INCLUDE_BT_HH_H
19 
20 #include <base/strings/stringprintf.h>
21 #include <ble_address_with_type.h>
22 #include <raw_address.h>
23 #include <stdint.h>
24 
25 #include <string>
26 
27 #include "macros.h"
28 
29 __BEGIN_DECLS
30 
31 #define BTHH_MAX_DSC_LEN 884
32 
33 /* HH connection states */
34 typedef enum {
35   BTHH_CONN_STATE_CONNECTED = 0,
36   BTHH_CONN_STATE_CONNECTING = 1,
37   BTHH_CONN_STATE_DISCONNECTED = 2,
38   BTHH_CONN_STATE_DISCONNECTING = 3,
39   BTHH_CONN_STATE_ACCEPTING = 4,
40   BTHH_CONN_STATE_UNKNOWN = 0xff,
41 } bthh_connection_state_t;
42 
43 __END_DECLS
44 
bthh_connection_state_text(const bthh_connection_state_t & state)45 inline std::string bthh_connection_state_text(
46     const bthh_connection_state_t& state) {
47   switch (state) {
48     CASE_RETURN_TEXT(BTHH_CONN_STATE_CONNECTED);
49     CASE_RETURN_TEXT(BTHH_CONN_STATE_CONNECTING);
50     CASE_RETURN_TEXT(BTHH_CONN_STATE_DISCONNECTED);
51     CASE_RETURN_TEXT(BTHH_CONN_STATE_DISCONNECTING);
52     CASE_RETURN_TEXT(BTHH_CONN_STATE_ACCEPTING);
53     CASE_RETURN_TEXT(BTHH_CONN_STATE_UNKNOWN);
54     default:
55       return base::StringPrintf("UNKNOWN[%d]", state);
56   }
57 }
58 
59 __BEGIN_DECLS
60 
61 typedef enum {
62   BTHH_OK = 0,
63   BTHH_HS_HID_NOT_READY,  /* handshake error : device not ready */
64   BTHH_HS_INVALID_RPT_ID, /* handshake error : invalid report ID */
65   BTHH_HS_TRANS_NOT_SPT,  /* handshake error : transaction not spt */
66   BTHH_HS_INVALID_PARAM,  /* handshake error : invalid paremter */
67   BTHH_HS_ERROR,          /* handshake error : unspecified HS error */
68   BTHH_ERR,               /* general BTA HH error */
69   BTHH_ERR_SDP,           /* SDP error */
70   BTHH_ERR_PROTO,         /* SET_Protocol error,
71                                                         only used in BTA_HH_OPEN_EVT
72                              callback */
73   BTHH_ERR_DB_FULL,       /* device database full error, used  */
74   BTHH_ERR_TOD_UNSPT,     /* type of device not supported */
75   BTHH_ERR_NO_RES,        /* out of system resources */
76   BTHH_ERR_AUTH_FAILED,   /* authentication fail */
77   BTHH_ERR_HDL
78 } bthh_status_t;
79 
80 /* Protocol modes */
81 typedef enum {
82   BTHH_REPORT_MODE = 0x00,
83   BTHH_BOOT_MODE = 0x01,
84   BTHH_UNSUPPORTED_MODE = 0xff
85 } bthh_protocol_mode_t;
86 
87 /* Report types */
88 typedef enum {
89   BTHH_INPUT_REPORT = 1,
90   BTHH_OUTPUT_REPORT,
91   BTHH_FEATURE_REPORT
92 } bthh_report_type_t;
93 
94 /* Info for which profiles to enable */
95 typedef struct {
96   bool hidp_enabled;
97   bool hogp_enabled;
98 } bthh_profile_enable_t;
99 
100 typedef struct {
101   int attr_mask;
102   uint8_t sub_class;
103   uint8_t app_id;
104   int vendor_id;
105   int product_id;
106   int version;
107   uint8_t ctry_code;
108   int dl_len;
109   uint8_t dsc_list[BTHH_MAX_DSC_LEN];
110 } bthh_hid_info_t;
111 
112 /** Callback for connection state change.
113  *  state will have one of the values from bthh_connection_state_t
114  */
115 typedef void (*bthh_connection_state_callback)(RawAddress* bd_addr,
116                                                tBLE_ADDR_TYPE addr_type,
117                                                tBT_TRANSPORT transport,
118                                                bthh_connection_state_t state);
119 
120 /** Callback for vitual unplug api.
121  *  the status of the vitual unplug
122  */
123 typedef void (*bthh_virtual_unplug_callback)(RawAddress* bd_addr,
124                                              tBLE_ADDR_TYPE addr_type,
125                                              tBT_TRANSPORT transport,
126                                              bthh_status_t hh_status);
127 
128 /** Callback for get hid info
129  *  hid_info will contain attr_mask, sub_class, app_id, vendor_id, product_id,
130  * version, ctry_code, len
131  */
132 typedef void (*bthh_hid_info_callback)(RawAddress* bd_addr,
133                                        tBLE_ADDR_TYPE addr_type,
134                                        tBT_TRANSPORT transport,
135                                        bthh_hid_info_t hid_info);
136 
137 /** Callback for get protocol api.
138  *  the protocol mode is one of the value from bthh_protocol_mode_t
139  */
140 typedef void (*bthh_protocol_mode_callback)(RawAddress* bd_addr,
141                                             tBLE_ADDR_TYPE addr_type,
142                                             tBT_TRANSPORT transport,
143                                             bthh_status_t hh_status,
144                                             bthh_protocol_mode_t mode);
145 
146 /** Callback for get/set_idle_time api.
147  */
148 typedef void (*bthh_idle_time_callback)(RawAddress* bd_addr,
149                                         tBLE_ADDR_TYPE addr_type,
150                                         tBT_TRANSPORT transport,
151                                         bthh_status_t hh_status, int idle_rate);
152 
153 /** Callback for get report api.
154  *  if staus is ok rpt_data contains the report data
155  */
156 typedef void (*bthh_get_report_callback)(RawAddress* bd_addr,
157                                          tBLE_ADDR_TYPE addr_type,
158                                          tBT_TRANSPORT transport,
159                                          bthh_status_t hh_status,
160                                          uint8_t* rpt_data, int rpt_size);
161 
162 /** Callback for set_report/set_protocol api and if error
163  *  occurs for get_report/get_protocol api.
164  */
165 typedef void (*bthh_handshake_callback)(RawAddress* bd_addr,
166                                         tBLE_ADDR_TYPE addr_type,
167                                         tBT_TRANSPORT transport,
168                                         bthh_status_t hh_status);
169 
170 /** BT-HH callback structure. */
171 typedef struct {
172   /** set to sizeof(BtHfCallbacks) */
173   size_t size;
174   bthh_connection_state_callback connection_state_cb;
175   bthh_hid_info_callback hid_info_cb;
176   bthh_protocol_mode_callback protocol_mode_cb;
177   bthh_idle_time_callback idle_time_cb;
178   bthh_get_report_callback get_report_cb;
179   bthh_virtual_unplug_callback virtual_unplug_cb;
180   bthh_handshake_callback handshake_cb;
181 
182 } bthh_callbacks_t;
183 
184 /** Represents the standard BT-HH interface. */
185 typedef struct {
186   /** set to sizeof(BtHhInterface) */
187   size_t size;
188 
189   /**
190    * Register the BtHh callbacks
191    */
192   bt_status_t (*init)(bthh_callbacks_t* callbacks);
193 
194   /** connect to hid device */
195   bt_status_t (*connect)(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
196                          tBT_TRANSPORT transport);
197 
198   /** dis-connect from hid device */
199   bt_status_t (*disconnect)(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
200                             tBT_TRANSPORT transport, bool reconnect_allowed);
201 
202   /** Virtual UnPlug (VUP) the specified HID device */
203   bt_status_t (*virtual_unplug)(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
204                                 tBT_TRANSPORT transport);
205 
206   /** Set the HID device descriptor for the specified HID device. */
207   bt_status_t (*set_info)(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
208                           tBT_TRANSPORT transport, bthh_hid_info_t hid_info);
209 
210   /** Get the HID proto mode. */
211   bt_status_t (*get_protocol)(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
212                               tBT_TRANSPORT transport,
213                               bthh_protocol_mode_t protocolMode);
214 
215   /** Set the HID proto mode. */
216   bt_status_t (*set_protocol)(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
217                               tBT_TRANSPORT transport,
218                               bthh_protocol_mode_t protocolMode);
219 
220   /** Get the HID Idle Time */
221   bt_status_t (*get_idle_time)(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
222                                tBT_TRANSPORT transport);
223 
224   /** Set the HID Idle Time */
225   bt_status_t (*set_idle_time)(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
226                                tBT_TRANSPORT transport, uint8_t idleTime);
227 
228   /** Send a GET_REPORT to HID device. */
229   bt_status_t (*get_report)(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
230                             tBT_TRANSPORT transport,
231                             bthh_report_type_t reportType, uint8_t reportId,
232                             int bufferSize);
233 
234   /** Send a GET_REPORT_REPLY to HID driver. */
235   bt_status_t (*get_report_reply)(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
236                                   tBT_TRANSPORT transport, bthh_status_t status,
237                                   char* report, uint16_t size);
238 
239   /** Send a SET_REPORT to HID device. */
240   bt_status_t (*set_report)(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
241                             tBT_TRANSPORT transport,
242                             bthh_report_type_t reportType, char* report);
243 
244   /** Send data to HID device. */
245   bt_status_t (*send_data)(RawAddress* bd_addr, tBLE_ADDR_TYPE addr_type,
246                            tBT_TRANSPORT transport, char* data);
247 
248   /** Closes the interface. */
249   void (*cleanup)(void);
250 
251   /** Configure which profiles can be enabled. Affected after re-init */
252   void (*configure_enabled_profiles)(bool enable_hidp, bool enable_hogp);
253 
254 } bthh_interface_t;
255 __END_DECLS
256 
257 #if __has_include(<bluetooth/log.h>)
258 #include <bluetooth/log.h>
259 
260 namespace fmt {
261 template <>
262 struct formatter<bthh_connection_state_t>
263     : enum_formatter<bthh_connection_state_t> {};
264 template <>
265 struct formatter<bthh_protocol_mode_t> : enum_formatter<bthh_protocol_mode_t> {
266 };
267 template <>
268 struct formatter<bthh_report_type_t> : enum_formatter<bthh_report_type_t> {};
269 }  // namespace fmt
270 
271 #endif  // __has_include(<bluetooth/log.h>)
272 
273 #endif /* ANDROID_INCLUDE_BT_HH_H */
274