diff options
Diffstat (limited to 'src/hid_osx.c')
-rw-r--r-- | src/hid_osx.c | 323 |
1 files changed, 230 insertions, 93 deletions
diff --git a/src/hid_osx.c b/src/hid_osx.c index 5c40747..6be5cd7 100644 --- a/src/hid_osx.c +++ b/src/hid_osx.c | |||
@@ -19,11 +19,13 @@ | |||
19 | 19 | ||
20 | #include "fido.h" | 20 | #include "fido.h" |
21 | 21 | ||
22 | #define REPORT_LEN 65 | 22 | struct hid_osx { |
23 | |||
24 | struct dev { | ||
25 | IOHIDDeviceRef ref; | 23 | IOHIDDeviceRef ref; |
26 | CFStringRef loop_id; | 24 | CFStringRef loop_id; |
25 | int report_pipe[2]; | ||
26 | size_t report_in_len; | ||
27 | size_t report_out_len; | ||
28 | unsigned char report[CTAP_MAX_REPORT_LEN]; | ||
27 | }; | 29 | }; |
28 | 30 | ||
29 | static int | 31 | static int |
@@ -64,7 +66,8 @@ get_utf8(IOHIDDeviceRef dev, CFStringRef key, void *buf, size_t len) | |||
64 | return (-1); | 66 | return (-1); |
65 | } | 67 | } |
66 | 68 | ||
67 | if (CFStringGetCString(ref, buf, len, kCFStringEncodingUTF8) == false) { | 69 | if (CFStringGetCString(ref, buf, (long)len, |
70 | kCFStringEncodingUTF8) == false) { | ||
68 | fido_log_debug("%s: CFStringGetCString", __func__); | 71 | fido_log_debug("%s: CFStringGetCString", __func__); |
69 | return (-1); | 72 | return (-1); |
70 | } | 73 | } |
@@ -72,30 +75,35 @@ get_utf8(IOHIDDeviceRef dev, CFStringRef key, void *buf, size_t len) | |||
72 | return (0); | 75 | return (0); |
73 | } | 76 | } |
74 | 77 | ||
75 | static bool | 78 | static int |
76 | is_fido(IOHIDDeviceRef dev) | 79 | get_report_len(IOHIDDeviceRef dev, int dir, size_t *report_len) |
77 | { | 80 | { |
78 | uint32_t usage_page; | 81 | CFStringRef key; |
79 | int32_t report_len; | 82 | int32_t v; |
80 | 83 | ||
81 | if (get_int32(dev, CFSTR(kIOHIDPrimaryUsagePageKey), | 84 | if (dir == 0) |
82 | (int32_t *)&usage_page) != 0 || usage_page != 0xf1d0) | 85 | key = CFSTR(kIOHIDMaxInputReportSizeKey); |
83 | return (false); | 86 | else |
87 | key = CFSTR(kIOHIDMaxOutputReportSizeKey); | ||
84 | 88 | ||
85 | if (get_int32(dev, CFSTR(kIOHIDMaxInputReportSizeKey), | 89 | if (get_int32(dev, key, &v) < 0) { |
86 | &report_len) < 0 || report_len != REPORT_LEN - 1) { | 90 | fido_log_debug("%s: get_int32/%d", __func__, dir); |
87 | fido_log_debug("%s: unsupported report len", __func__); | 91 | return (-1); |
88 | return (false); | ||
89 | } | 92 | } |
90 | 93 | ||
91 | return (true); | 94 | if ((*report_len = (size_t)v) > CTAP_MAX_REPORT_LEN) { |
95 | fido_log_debug("%s: report_len=%zu", __func__, *report_len); | ||
96 | return (-1); | ||
97 | } | ||
98 | |||
99 | return (0); | ||
92 | } | 100 | } |
93 | 101 | ||
94 | static int | 102 | static int |
95 | get_id(IOHIDDeviceRef dev, int16_t *vendor_id, int16_t *product_id) | 103 | get_id(IOHIDDeviceRef dev, int16_t *vendor_id, int16_t *product_id) |
96 | { | 104 | { |
97 | int32_t vendor; | 105 | int32_t vendor; |
98 | int32_t product; | 106 | int32_t product; |
99 | 107 | ||
100 | if (get_int32(dev, CFSTR(kIOHIDVendorIDKey), &vendor) < 0 || | 108 | if (get_int32(dev, CFSTR(kIOHIDVendorIDKey), &vendor) < 0 || |
101 | vendor > UINT16_MAX) { | 109 | vendor > UINT16_MAX) { |
@@ -175,6 +183,31 @@ get_path(IOHIDDeviceRef dev) | |||
175 | return (strdup(path)); | 183 | return (strdup(path)); |
176 | } | 184 | } |
177 | 185 | ||
186 | static bool | ||
187 | is_fido(IOHIDDeviceRef dev) | ||
188 | { | ||
189 | char buf[32]; | ||
190 | uint32_t usage_page; | ||
191 | |||
192 | if (get_int32(dev, CFSTR(kIOHIDPrimaryUsagePageKey), | ||
193 | (int32_t *)&usage_page) < 0 || usage_page != 0xf1d0) | ||
194 | return (false); | ||
195 | |||
196 | if (get_utf8(dev, CFSTR(kIOHIDTransportKey), buf, sizeof(buf)) < 0) { | ||
197 | fido_log_debug("%s: get_utf8 transport", __func__); | ||
198 | return (false); | ||
199 | } | ||
200 | |||
201 | #ifndef FIDO_HID_ANY | ||
202 | if (strcasecmp(buf, "usb") != 0) { | ||
203 | fido_log_debug("%s: transport", __func__); | ||
204 | return (false); | ||
205 | } | ||
206 | #endif | ||
207 | |||
208 | return (true); | ||
209 | } | ||
210 | |||
178 | static int | 211 | static int |
179 | copy_info(fido_dev_info_t *di, IOHIDDeviceRef dev) | 212 | copy_info(fido_dev_info_t *di, IOHIDDeviceRef dev) |
180 | { | 213 | { |
@@ -199,11 +232,12 @@ copy_info(fido_dev_info_t *di, IOHIDDeviceRef dev) | |||
199 | int | 232 | int |
200 | fido_hid_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen) | 233 | fido_hid_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen) |
201 | { | 234 | { |
202 | IOHIDManagerRef manager = NULL; | 235 | IOHIDManagerRef manager = NULL; |
203 | CFSetRef devset = NULL; | 236 | CFSetRef devset = NULL; |
204 | CFIndex devcnt; | 237 | size_t devcnt; |
205 | IOHIDDeviceRef *devs = NULL; | 238 | CFIndex n; |
206 | int r = FIDO_ERR_INTERNAL; | 239 | IOHIDDeviceRef *devs = NULL; |
240 | int r = FIDO_ERR_INTERNAL; | ||
207 | 241 | ||
208 | *olen = 0; | 242 | *olen = 0; |
209 | 243 | ||
@@ -226,11 +260,13 @@ fido_hid_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen) | |||
226 | goto fail; | 260 | goto fail; |
227 | } | 261 | } |
228 | 262 | ||
229 | if ((devcnt = CFSetGetCount(devset)) < 0) { | 263 | if ((n = CFSetGetCount(devset)) < 0) { |
230 | fido_log_debug("%s: CFSetGetCount", __func__); | 264 | fido_log_debug("%s: CFSetGetCount", __func__); |
231 | goto fail; | 265 | goto fail; |
232 | } | 266 | } |
233 | 267 | ||
268 | devcnt = (size_t)n; | ||
269 | |||
234 | if ((devs = calloc(devcnt, sizeof(*devs))) == NULL) { | 270 | if ((devs = calloc(devcnt, sizeof(*devs))) == NULL) { |
235 | fido_log_debug("%s: calloc", __func__); | 271 | fido_log_debug("%s: calloc", __func__); |
236 | goto fail; | 272 | goto fail; |
@@ -238,7 +274,7 @@ fido_hid_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen) | |||
238 | 274 | ||
239 | CFSetGetValues(devset, (void *)devs); | 275 | CFSetGetValues(devset, (void *)devs); |
240 | 276 | ||
241 | for (CFIndex i = 0; i < devcnt; i++) { | 277 | for (size_t i = 0; i < devcnt; i++) { |
242 | if (copy_info(&devlist[*olen], devs[i]) == 0) { | 278 | if (copy_info(&devlist[*olen], devs[i]) == 0) { |
243 | devlist[*olen].io = (fido_dev_io_t) { | 279 | devlist[*olen].io = (fido_dev_io_t) { |
244 | fido_hid_open, | 280 | fido_hid_open, |
@@ -263,157 +299,258 @@ fail: | |||
263 | return (r); | 299 | return (r); |
264 | } | 300 | } |
265 | 301 | ||
302 | static void | ||
303 | report_callback(void *context, IOReturn result, void *dev, IOHIDReportType type, | ||
304 | uint32_t id, uint8_t *ptr, CFIndex len) | ||
305 | { | ||
306 | struct hid_osx *ctx = context; | ||
307 | ssize_t r; | ||
308 | |||
309 | (void)dev; | ||
310 | |||
311 | if (result != kIOReturnSuccess || type != kIOHIDReportTypeInput || | ||
312 | id != 0 || len < 0 || (size_t)len != ctx->report_in_len) { | ||
313 | fido_log_debug("%s: io error", __func__); | ||
314 | return; | ||
315 | } | ||
316 | |||
317 | if ((r = write(ctx->report_pipe[1], ptr, (size_t)len)) < 0 || | ||
318 | (size_t)r != (size_t)len) { | ||
319 | fido_log_debug("%s: write", __func__); | ||
320 | return; | ||
321 | } | ||
322 | } | ||
323 | |||
324 | static void | ||
325 | removal_callback(void *context, IOReturn result, void *sender) | ||
326 | { | ||
327 | (void)context; | ||
328 | (void)result; | ||
329 | (void)sender; | ||
330 | |||
331 | CFRunLoopStop(CFRunLoopGetMain()); | ||
332 | } | ||
333 | |||
334 | static int | ||
335 | set_nonblock(int fd) | ||
336 | { | ||
337 | int flags; | ||
338 | |||
339 | if ((flags = fcntl(fd, F_GETFL)) == -1) { | ||
340 | fido_log_debug("%s: fcntl F_GETFL", __func__); | ||
341 | return (-1); | ||
342 | } | ||
343 | |||
344 | if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) { | ||
345 | fido_log_debug("%s: fcntl, F_SETFL", __func__); | ||
346 | return (-1); | ||
347 | } | ||
348 | |||
349 | return (0); | ||
350 | } | ||
351 | |||
352 | static int | ||
353 | disable_sigpipe(int fd) | ||
354 | { | ||
355 | int disabled = 1; | ||
356 | |||
357 | if (fcntl(fd, F_SETNOSIGPIPE, &disabled) == -1) { | ||
358 | fido_log_debug("%s: fcntl F_SETNOSIGPIPE", __func__); | ||
359 | return (-1); | ||
360 | } | ||
361 | |||
362 | return (0); | ||
363 | } | ||
364 | |||
266 | void * | 365 | void * |
267 | fido_hid_open(const char *path) | 366 | fido_hid_open(const char *path) |
268 | { | 367 | { |
368 | struct hid_osx *ctx; | ||
269 | io_registry_entry_t entry = MACH_PORT_NULL; | 369 | io_registry_entry_t entry = MACH_PORT_NULL; |
270 | struct dev *dev = NULL; | 370 | char loop_id[32]; |
271 | int ok = -1; | 371 | int ok = -1; |
272 | int r; | 372 | int r; |
273 | char loop_id[32]; | ||
274 | 373 | ||
275 | if ((dev = calloc(1, sizeof(*dev))) == NULL) { | 374 | if ((ctx = calloc(1, sizeof(*ctx))) == NULL) { |
276 | fido_log_debug("%s: calloc", __func__); | 375 | fido_log_debug("%s: calloc", __func__); |
277 | goto fail; | 376 | goto fail; |
278 | } | 377 | } |
279 | 378 | ||
379 | ctx->report_pipe[0] = -1; | ||
380 | ctx->report_pipe[1] = -1; | ||
381 | |||
382 | if (pipe(ctx->report_pipe) == -1) { | ||
383 | fido_log_debug("%s: pipe", __func__); | ||
384 | goto fail; | ||
385 | } | ||
386 | |||
387 | if (set_nonblock(ctx->report_pipe[0]) < 0 || | ||
388 | set_nonblock(ctx->report_pipe[1]) < 0) { | ||
389 | fido_log_debug("%s: set_nonblock", __func__); | ||
390 | goto fail; | ||
391 | } | ||
392 | |||
393 | if (disable_sigpipe(ctx->report_pipe[1]) < 0) { | ||
394 | fido_log_debug("%s: disable_sigpipe", __func__); | ||
395 | goto fail; | ||
396 | } | ||
397 | |||
280 | if ((entry = IORegistryEntryFromPath(kIOMasterPortDefault, | 398 | if ((entry = IORegistryEntryFromPath(kIOMasterPortDefault, |
281 | path)) == MACH_PORT_NULL) { | 399 | path)) == MACH_PORT_NULL) { |
282 | fido_log_debug("%s: IORegistryEntryFromPath", __func__); | 400 | fido_log_debug("%s: IORegistryEntryFromPath", __func__); |
283 | goto fail; | 401 | goto fail; |
284 | } | 402 | } |
285 | 403 | ||
286 | if ((dev->ref = IOHIDDeviceCreate(kCFAllocatorDefault, | 404 | if ((ctx->ref = IOHIDDeviceCreate(kCFAllocatorDefault, |
287 | entry)) == NULL) { | 405 | entry)) == NULL) { |
288 | fido_log_debug("%s: IOHIDDeviceCreate", __func__); | 406 | fido_log_debug("%s: IOHIDDeviceCreate", __func__); |
289 | goto fail; | 407 | goto fail; |
290 | } | 408 | } |
291 | 409 | ||
292 | if (IOHIDDeviceOpen(dev->ref, | 410 | if (get_report_len(ctx->ref, 0, &ctx->report_in_len) < 0 || |
411 | get_report_len(ctx->ref, 1, &ctx->report_out_len) < 0) { | ||
412 | fido_log_debug("%s: get_report_len", __func__); | ||
413 | goto fail; | ||
414 | } | ||
415 | |||
416 | if (ctx->report_in_len > sizeof(ctx->report)) { | ||
417 | fido_log_debug("%s: report_in_len=%zu", __func__, | ||
418 | ctx->report_in_len); | ||
419 | goto fail; | ||
420 | } | ||
421 | |||
422 | if (IOHIDDeviceOpen(ctx->ref, | ||
293 | kIOHIDOptionsTypeSeizeDevice) != kIOReturnSuccess) { | 423 | kIOHIDOptionsTypeSeizeDevice) != kIOReturnSuccess) { |
294 | fido_log_debug("%s: IOHIDDeviceOpen", __func__); | 424 | fido_log_debug("%s: IOHIDDeviceOpen", __func__); |
295 | goto fail; | 425 | goto fail; |
296 | } | 426 | } |
297 | 427 | ||
298 | if ((r = snprintf(loop_id, sizeof(loop_id), "fido2-%p", | 428 | if ((r = snprintf(loop_id, sizeof(loop_id), "fido2-%p", |
299 | (void *)dev->ref)) < 0 || (size_t)r >= sizeof(loop_id)) { | 429 | (void *)ctx->ref)) < 0 || (size_t)r >= sizeof(loop_id)) { |
300 | fido_log_debug("%s: snprintf", __func__); | 430 | fido_log_debug("%s: snprintf", __func__); |
301 | goto fail; | 431 | goto fail; |
302 | } | 432 | } |
303 | 433 | ||
304 | if ((dev->loop_id = CFStringCreateWithCString(NULL, loop_id, | 434 | if ((ctx->loop_id = CFStringCreateWithCString(NULL, loop_id, |
305 | kCFStringEncodingASCII)) == NULL) { | 435 | kCFStringEncodingASCII)) == NULL) { |
306 | fido_log_debug("%s: CFStringCreateWithCString", __func__); | 436 | fido_log_debug("%s: CFStringCreateWithCString", __func__); |
307 | goto fail; | 437 | goto fail; |
308 | } | 438 | } |
309 | 439 | ||
440 | IOHIDDeviceRegisterInputReportCallback(ctx->ref, ctx->report, | ||
441 | (long)ctx->report_in_len, &report_callback, ctx); | ||
442 | IOHIDDeviceRegisterRemovalCallback(ctx->ref, &removal_callback, ctx); | ||
443 | IOHIDDeviceScheduleWithRunLoop(ctx->ref, CFRunLoopGetMain(), | ||
444 | ctx->loop_id); | ||
445 | |||
310 | ok = 0; | 446 | ok = 0; |
311 | fail: | 447 | fail: |
312 | if (entry != MACH_PORT_NULL) | 448 | if (entry != MACH_PORT_NULL) |
313 | IOObjectRelease(entry); | 449 | IOObjectRelease(entry); |
314 | 450 | ||
315 | if (ok < 0 && dev != NULL) { | 451 | if (ok < 0 && ctx != NULL) { |
316 | if (dev->ref != NULL) | 452 | if (ctx->ref != NULL) |
317 | CFRelease(dev->ref); | 453 | CFRelease(ctx->ref); |
318 | if (dev->loop_id != NULL) | 454 | if (ctx->loop_id != NULL) |
319 | CFRelease(dev->loop_id); | 455 | CFRelease(ctx->loop_id); |
320 | free(dev); | 456 | if (ctx->report_pipe[0] != -1) |
321 | dev = NULL; | 457 | close(ctx->report_pipe[0]); |
458 | if (ctx->report_pipe[1] != -1) | ||
459 | close(ctx->report_pipe[1]); | ||
460 | free(ctx); | ||
461 | ctx = NULL; | ||
322 | } | 462 | } |
323 | 463 | ||
324 | return (dev); | 464 | return (ctx); |
325 | } | 465 | } |
326 | 466 | ||
327 | void | 467 | void |
328 | fido_hid_close(void *handle) | 468 | fido_hid_close(void *handle) |
329 | { | 469 | { |
330 | struct dev *dev = handle; | 470 | struct hid_osx *ctx = handle; |
471 | |||
472 | IOHIDDeviceRegisterInputReportCallback(ctx->ref, ctx->report, | ||
473 | (long)ctx->report_in_len, NULL, ctx); | ||
474 | IOHIDDeviceRegisterRemovalCallback(ctx->ref, NULL, NULL); | ||
475 | IOHIDDeviceUnscheduleFromRunLoop(ctx->ref, CFRunLoopGetMain(), | ||
476 | ctx->loop_id); | ||
331 | 477 | ||
332 | if (IOHIDDeviceClose(dev->ref, | 478 | if (IOHIDDeviceClose(ctx->ref, |
333 | kIOHIDOptionsTypeSeizeDevice) != kIOReturnSuccess) | 479 | kIOHIDOptionsTypeSeizeDevice) != kIOReturnSuccess) |
334 | fido_log_debug("%s: IOHIDDeviceClose", __func__); | 480 | fido_log_debug("%s: IOHIDDeviceClose", __func__); |
335 | 481 | ||
336 | CFRelease(dev->ref); | 482 | CFRelease(ctx->ref); |
337 | CFRelease(dev->loop_id); | 483 | CFRelease(ctx->loop_id); |
338 | |||
339 | free(dev); | ||
340 | } | ||
341 | 484 | ||
342 | static void | 485 | explicit_bzero(ctx->report, sizeof(ctx->report)); |
343 | read_callback(void *context, IOReturn result, void *dev, IOHIDReportType type, | 486 | close(ctx->report_pipe[0]); |
344 | uint32_t report_id, uint8_t *report, CFIndex report_len) | 487 | close(ctx->report_pipe[1]); |
345 | { | ||
346 | (void)context; | ||
347 | (void)dev; | ||
348 | (void)report; | ||
349 | 488 | ||
350 | if (result != kIOReturnSuccess || type != kIOHIDReportTypeInput || | 489 | free(ctx); |
351 | report_id != 0 || report_len != REPORT_LEN - 1) { | ||
352 | fido_log_debug("%s: io error", __func__); | ||
353 | } | ||
354 | } | ||
355 | |||
356 | static void | ||
357 | removal_callback(void *context, IOReturn result, void *sender) | ||
358 | { | ||
359 | (void)context; | ||
360 | (void)result; | ||
361 | (void)sender; | ||
362 | |||
363 | CFRunLoopStop(CFRunLoopGetCurrent()); | ||
364 | } | 490 | } |
365 | 491 | ||
366 | int | 492 | int |
367 | fido_hid_read(void *handle, unsigned char *buf, size_t len, int ms) | 493 | fido_hid_read(void *handle, unsigned char *buf, size_t len, int ms) |
368 | { | 494 | { |
369 | struct dev *dev = handle; | 495 | struct hid_osx *ctx = handle; |
370 | CFRunLoopRunResult r; | 496 | ssize_t r; |
371 | 497 | ||
372 | (void)ms; /* XXX */ | 498 | explicit_bzero(buf, len); |
499 | explicit_bzero(ctx->report, sizeof(ctx->report)); | ||
373 | 500 | ||
374 | if (len != REPORT_LEN - 1) { | 501 | if (len != ctx->report_in_len || len > sizeof(ctx->report)) { |
375 | fido_log_debug("%s: invalid len", __func__); | 502 | fido_log_debug("%s: len %zu", __func__, len); |
376 | return (-1); | 503 | return (-1); |
377 | } | 504 | } |
378 | 505 | ||
379 | explicit_bzero(buf, len); | 506 | if (ms == -1) |
380 | 507 | ms = 5000; /* wait 5 seconds by default */ | |
381 | IOHIDDeviceRegisterInputReportCallback(dev->ref, buf, len, | ||
382 | &read_callback, NULL); | ||
383 | IOHIDDeviceRegisterRemovalCallback(dev->ref, &removal_callback, dev); | ||
384 | IOHIDDeviceScheduleWithRunLoop(dev->ref, CFRunLoopGetCurrent(), | ||
385 | dev->loop_id); | ||
386 | 508 | ||
387 | r = CFRunLoopRunInMode(dev->loop_id, 0.3, true); | 509 | if (CFRunLoopGetCurrent() != CFRunLoopGetMain()) |
510 | fido_log_debug("%s: CFRunLoopGetCurrent != CFRunLoopGetMain", | ||
511 | __func__); | ||
388 | 512 | ||
389 | IOHIDDeviceRegisterInputReportCallback(dev->ref, buf, len, NULL, NULL); | 513 | CFRunLoopRunInMode(ctx->loop_id, (double)ms/1000.0, true); |
390 | IOHIDDeviceRegisterRemovalCallback(dev->ref, NULL, NULL); | ||
391 | IOHIDDeviceUnscheduleFromRunLoop(dev->ref, CFRunLoopGetCurrent(), | ||
392 | dev->loop_id); | ||
393 | 514 | ||
394 | if (r != kCFRunLoopRunHandledSource) { | 515 | if ((r = read(ctx->report_pipe[0], buf, len)) < 0 || (size_t)r != len) { |
395 | fido_log_debug("%s: CFRunLoopRunInMode=%d", __func__, (int)r); | 516 | fido_log_debug("%s: read", __func__); |
396 | return (-1); | 517 | return (-1); |
397 | } | 518 | } |
398 | 519 | ||
399 | return (REPORT_LEN - 1); | 520 | return ((int)len); |
400 | } | 521 | } |
401 | 522 | ||
402 | int | 523 | int |
403 | fido_hid_write(void *handle, const unsigned char *buf, size_t len) | 524 | fido_hid_write(void *handle, const unsigned char *buf, size_t len) |
404 | { | 525 | { |
405 | struct dev *dev = handle; | 526 | struct hid_osx *ctx = handle; |
406 | 527 | ||
407 | if (len != REPORT_LEN) { | 528 | if (len != ctx->report_out_len + 1 || len > LONG_MAX) { |
408 | fido_log_debug("%s: invalid len", __func__); | 529 | fido_log_debug("%s: len %zu", __func__, len); |
409 | return (-1); | 530 | return (-1); |
410 | } | 531 | } |
411 | 532 | ||
412 | if (IOHIDDeviceSetReport(dev->ref, kIOHIDReportTypeOutput, 0, buf + 1, | 533 | if (IOHIDDeviceSetReport(ctx->ref, kIOHIDReportTypeOutput, 0, buf + 1, |
413 | len - 1) != kIOReturnSuccess) { | 534 | (long)(len - 1)) != kIOReturnSuccess) { |
414 | fido_log_debug("%s: IOHIDDeviceSetReport", __func__); | 535 | fido_log_debug("%s: IOHIDDeviceSetReport", __func__); |
415 | return (-1); | 536 | return (-1); |
416 | } | 537 | } |
417 | 538 | ||
418 | return (REPORT_LEN); | 539 | return ((int)len); |
540 | } | ||
541 | |||
542 | size_t | ||
543 | fido_hid_report_in_len(void *handle) | ||
544 | { | ||
545 | struct hid_osx *ctx = handle; | ||
546 | |||
547 | return (ctx->report_in_len); | ||
548 | } | ||
549 | |||
550 | size_t | ||
551 | fido_hid_report_out_len(void *handle) | ||
552 | { | ||
553 | struct hid_osx *ctx = handle; | ||
554 | |||
555 | return (ctx->report_out_len); | ||
419 | } | 556 | } |