Mstdlib-1.24.0
m_io_hid.h
1/* The MIT License (MIT)
2 *
3 * Copyright (c) 2017 Monetra Technologies, LLC.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 */
23
24#ifndef __M_IO_HID_H__
25#define __M_IO_HID_H__
26
27#include <mstdlib/base/m_defs.h>
28#include <mstdlib/base/m_types.h>
29#include <mstdlib/io/m_io.h>
30#include <mstdlib/io/m_event.h>
31
32__BEGIN_DECLS
33
34/*! \addtogroup m_io_hid HID (Human Interface Device) IO functions
35 * \ingroup m_eventio_base
36 *
37 * ## HID (Human Interface Device) IO functions.
38 *
39 * Typically used with USB devices.
40 *
41 * Report IDs need to be the first byte of any data sent to a device and
42 * will be the first byte of any data received from a device. All buffer
43 * sizes report will include the extra byte for the report ID.
44 *
45 * If a device does not use report IDs 0 should be sent as the first byte
46 * of any data and will be the first byte of any read data.
47 *
48 * ## Supported OS
49 *
50 * - Windows
51 * - Linux
52 * - macOS
53 * - Android
54 *
55 * ## Android Requirements
56 *
57 * Android does not have blanket USB permissions. Access needs to be granted
58 * by the user on a per device basis. Permission granting is _not_ supported
59 * by mstdlib and must be handled by the app itself. Once permissions are
60 * granted mstdlib can access the device. Device enumeration does not need
61 * permission, it is only required to open a device.
62 *
63 * The manifest must include the uses-feature for USB host.
64 *
65 * <uses-feature android:name="android.hardware.usb.host" />
66 *
67*
68 * There are two methods for obtaining permissions.
69 * The Android [USB Host documentation](https://developer.android.com/guide/topics/connectivity/usb/host)
70 * provides a detailed overview of the permission process.
71 *
72 * UsbManager.hasPermission() should be used to determine if the app can
73 * access the device or if it needs permission from the user to do so.
74 * If the manifest method is used the request method may still be necessary
75 * to implement. However, the manifest method allows the user to associate
76 * the device with the app so permission only needs to be granted once.
77 *
78 * ### Manifest
79 *
80 * The device vendor and product ids can be registered by the App though the
81 * manifest file. When the device is connected the user will be prompted if
82 * they want to open the device with the application. There is an option to
83 * always open with the given application the user can select. If they do not
84 * select a default application they will be prompted every time the device
85 * is connected. Once allowed the application can use the device.
86 *
87 * The manifest will specify an intent filter for a given activity for
88 * USB device attached. A meta-data specifying supported devices is associated
89 * with the intent which Android uses to determine if the application supports
90 * the given device.
91 *
92 * <activity ...>
93 * <intent-filter>
94 * <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
95 * </intent-filter>
96 * <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
97 * android:resource="@xml/device_filter" />
98 * </activity>
99 *
100 * The device_filter xml file specifying one or more devices using vendor an product
101 * ids. The ids must be a decimal number and cannot be hex.
102 *
103 * <?xml version="1.0" encoding="utf-8"?>
104 * <resources>
105 * <usb-device vendor-id="1234" product-id="5678" />
106 * </resources>
107 *
108 * The disadvantage of this method is it work off of the device being attached.
109 * If the application is running and the device is already connected the user
110 * will not be prompted.
111 *
112 * ### Request Dialog
113 *
114 * This method uses the UsbManager.requestPermission() function to display a permission
115 * request to the user to allow USB access. The application will use an intent to
116 * make the request. A broadcast receiver will need to be registered with the intent
117 * in order for the app to receive the users response to the query. If approved by
118 * the user the application can use the device.
119 *
120 * This does not grant access to USB in general. The device in question is part of the
121 * permission request. The user is only given permission for that specific device.
122 *
123 * For this method the app should use mstdlib (or direct API calls) to enumerate the
124 * currently connected devices. Then use the path (mstdlib) to pull the device out
125 * of UsbManager.getDeviceList(). This device can then be used for the permission request.
126 *
127 * This method works if the device is already attached.
128 *
129 * @{
130 */
131
132struct M_io_hid_enum;
134
135/*! Create a HID enumeration object.
136 *
137 * \param[in] vendorid Optional. Filter by vendor id. Set to 0 if no filter should be applied.
138 * \param[in] productids Optional. Filter by product ids. Set to NULL if no filter should be applied.
139 * \param[in] num_productids Number of product ids in list of product ids. Should be 0 if productids is NULL.
140 * \param[in] serial Optional. Filter by serial number.
141 *
142 * \return HID enumeration object.
143 */
144M_API M_io_hid_enum_t *M_io_hid_enum(M_uint16 vendorid, const M_uint16 *productids, size_t num_productids, const char *serial);
145
146
147/*! Destroy a HID enumeration object.
148 *
149 * \param[in] hidenum HID enumeration object.
150 */
152
153
154/*! Number of HID objects in the enumeration.
155 *
156 * \param[in] hidenum HID enumeration object.
157 *
158 * \return Count of HID devices.
159 */
160M_API size_t M_io_hid_enum_count(const M_io_hid_enum_t *hidenum);
161
162
163/* Path to HID device.
164 *
165 * \param[in] hidenum HID enumeration object.
166 * \param[in] idx Index in HID enumeration.
167 *
168 * \return String.
169 */
170M_API const char *M_io_hid_enum_path(const M_io_hid_enum_t *hidenum, size_t idx);
171
172
173/* HID device manufacturer.
174 *
175 * \param[in] hidenum HID enumeration object.
176 * \param[in] idx Index in HID enumeration.
177 *
178 * \return String.
179 */
180M_API const char *M_io_hid_enum_manufacturer(const M_io_hid_enum_t *hidenum, size_t idx);
181
182
183/* HID device product.
184 *
185 * \param[in] hidenum HID enumeration object.
186 * \param[in] idx Index in HID enumeration.
187 *
188 * \return String.
189 */
190M_API const char *M_io_hid_enum_product(const M_io_hid_enum_t *hidenum, size_t idx);
191
192
193/* Hid device serial number.
194 *
195 * \param[in] hidenum HID enumeration object.
196 * \param[in] idx Index in HID enumeration.
197 *
198 * \return String.
199 */
200M_API const char *M_io_hid_enum_serial(const M_io_hid_enum_t *hidenum, size_t idx);
201
202
203/* Hid device vendor id.
204 *
205 * \param[in] hidenum HID enumeration object.
206 * \param[in] idx Index in HID enumeration.
207 *
208 * \return Vendor id.
209 */
210M_API M_uint16 M_io_hid_enum_vendorid(const M_io_hid_enum_t *hidenum, size_t idx);
211
212
213/* Hid device product id.
214 *
215 * \param[in] hidenum HID enumeration object.
216 * \param[in] idx Index in HID enumeration.
217 *
218 * \return Product id.
219 */
220M_API M_uint16 M_io_hid_enum_productid(const M_io_hid_enum_t *hidenum, size_t idx);
221
222
223/*! Create a HID connection.
224 *
225 * \param[out] io_out io object for communication.
226 * \param[in] vendorid Vendor id.
227 * \param[in] productid Product id.
228 * \param[in] serial Product serial number. Optional. If multiple devices with the same vendor an product id
229 * it is undefined which will be chosen.
230 *
231 * \return Result.
232 */
233M_API M_io_error_t M_io_hid_create(M_io_t **io_out, M_uint16 vendorid, M_uint16 productid, const char *serial /* May be NULL */);
234
235
236/*! Create a HID device connection.
237 *
238 * Creates a connection to the first device from from a given list of ids.
239 *
240 * \param[out] io_out io object for communication.
241 * \param[in] vendorid Vendor id.
242 * \param[in] productids A list of product ids to look for.
243 * \param[in] num_productids Number of product ids in the list of product ids. These should be in priority order.
244 * \param[in] serial Product serial number. Optional. If multiple devices with the same vendor an product id
245 * it is undefined which will be chosen.
246 *
247 * \return Result.
248 */
249M_API M_io_error_t M_io_hid_create_one(M_io_t **io_out, M_uint16 vendorid, const M_uint16 *productids, size_t num_productids, const char *serial /* May be NULL */);
250
251
252/*! Get the HID manufacturer from an io object.
253 *
254 * Queries the highest HID layer in the stack, if there are more than one.
255 *
256 * \param[in] io io object.
257 *
258 * \return new string containing manufacturer, or NULL if no HID layer was present/acquirable
259 */
261
262
263/*! Get the HID path from an io object.
264 *
265 * Queries the highest HID layer in the stack, if there are more than one.
266 *
267 * \param[in] io io object.
268 *
269 * \return new string containing path, or NULL if no HID layer was present/acquirable
270 */
271M_API char *M_io_hid_get_path(M_io_t *io);
272
273
274/*! Get the HID product from an io object.
275 *
276 * Queries the highest HID layer in the stack, if there are more than one.
277 *
278 * \param[in] io io object.
279 *
280 * \return new string containing product, or NULL if no HID layer was present/acquirable
281 */
283
284
285/*! Get the HID product ID from an io object.
286 *
287 * Queries the highest HID layer in the stack, if there are more than one.
288 *
289 * \param[in] io io object.
290 *
291 * \return product ID, or 0 if no HID layer was present/acquirable
292 */
293M_API M_uint16 M_io_hid_get_productid(M_io_t *io);
294
295
296/*! Get the HID vendor ID from an io object.
297 *
298 * Queries the highest HID layer in the stack, if there are more than one.
299 *
300 * \param[in] io io object.
301 *
302 * \return vendor ID, or 0 if no HID layer was present/acquirable
303 */
304M_API M_uint16 M_io_hid_get_vendorid(M_io_t *io);
305
306
307/*! Get the HID serial number from an io object.
308 *
309 * Queries the highest HID layer in the stack, if there are more than one.
310 *
311 * \param[in] io io object.
312 *
313 * \return new string containing serial number, or NULL if no HID layer was present/acquirable
314 */
316
317
318/*! Get the HID maximum input and output report sizes from an io object.
319 *
320 * The report sizes returned may be 1 byte larger than the actual report size
321 * to account for the report ID that is prepended to the data block.
322 *
323 * Queries the highest HID layer in the stack, if there are more than one.
324 *
325 * \param[in] io io object.
326 * \param[out] max_input_size Maximum input report size, or 0 if no HID layer was present/acquirable
327 * \param[out] max_output_size Maximum output report size, or 0 if no HID layer was present/acquirable
328 */
329M_API void M_io_hid_get_max_report_sizes(M_io_t *io, size_t *max_input_size, size_t *max_output_size);
330
331/*! @} */
332
333__END_DECLS
334
335#endif /* __M_IO_HID_H__ */
void M_io_hid_get_max_report_sizes(M_io_t *io, size_t *max_input_size, size_t *max_output_size)
void M_io_hid_enum_destroy(M_io_hid_enum_t *hidenum)
M_uint16 M_io_hid_get_productid(M_io_t *io)
M_io_error_t M_io_hid_create(M_io_t **io_out, M_uint16 vendorid, M_uint16 productid, const char *serial)
const char * M_io_hid_enum_path(const M_io_hid_enum_t *hidenum, size_t idx)
const char * M_io_hid_enum_manufacturer(const M_io_hid_enum_t *hidenum, size_t idx)
char * M_io_hid_get_product(M_io_t *io)
M_io_hid_enum_t * M_io_hid_enum(M_uint16 vendorid, const M_uint16 *productids, size_t num_productids, const char *serial)
char * M_io_hid_get_path(M_io_t *io)
size_t M_io_hid_enum_count(const M_io_hid_enum_t *hidenum)
char * M_io_hid_get_serial(M_io_t *io)
const char * M_io_hid_enum_serial(const M_io_hid_enum_t *hidenum, size_t idx)
M_uint16 M_io_hid_enum_productid(const M_io_hid_enum_t *hidenum, size_t idx)
M_io_error_t M_io_hid_create_one(M_io_t **io_out, M_uint16 vendorid, const M_uint16 *productids, size_t num_productids, const char *serial)
M_uint16 M_io_hid_get_vendorid(M_io_t *io)
struct M_io_hid_enum M_io_hid_enum_t
Definition: m_io_hid.h:133
M_uint16 M_io_hid_enum_vendorid(const M_io_hid_enum_t *hidenum, size_t idx)
char * M_io_hid_get_manufacturer(M_io_t *io)
const char * M_io_hid_enum_product(const M_io_hid_enum_t *hidenum, size_t idx)
enum M_io_error M_io_error_t
Definition: m_io.h:93
struct M_io M_io_t
Definition: m_io.h:59