descr.c revision 187994
1/* $NetBSD: descr.c,v 1.9 2000/09/24 02:13:24 augustss Exp $ */ 2 3/* 4 * Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD: head/lib/libusbhid/descr.c 187994 2009-02-02 00:49:39Z alfred $"); 31 32#include <sys/types.h> 33 34#include <assert.h> 35#include <errno.h> 36#include <stdlib.h> 37#include <string.h> 38#include <unistd.h> 39#include <sys/time.h> 40#include <sys/ioctl.h> 41 42#include <dev/usb2/include/usb2_ioctl.h> 43 44#include "usbhid.h" 45#include "usbvar.h" 46 47int 48hid_set_immed(int fd, int enable) 49{ 50 int ret; 51 ret = ioctl(fd, USB_SET_IMMED, &enable); 52 if (ret < 0) 53 ret = hid_set_immed_compat7(fd, enable); 54 return (ret); 55} 56 57int 58hid_get_report_id(int fd) 59{ 60 int temp = -1; 61 int ret; 62 63 ret = ioctl(fd, USB_GET_REPORT_ID, &temp); 64 if (ret < 0) 65 ret = hid_get_report_id_compat7(fd); 66 else 67 ret = temp; 68 69 return (ret); 70} 71 72report_desc_t 73hid_get_report_desc(int fd) 74{ 75 struct usb2_gen_descriptor ugd; 76 report_desc_t rep; 77 void *data; 78 79 memset(&ugd, 0, sizeof(ugd)); 80 81 /* get actual length first */ 82 ugd.ugd_data = NULL; 83 ugd.ugd_maxlen = 65535; 84 if (ioctl(fd, USB_GET_REPORT_DESC, &ugd) < 0) { 85 /* could not read descriptor */ 86 /* try FreeBSD 7 compat code */ 87 return (hid_get_report_desc_compat7(fd)); 88 } 89 90 /* 91 * NOTE: The kernel will return a failure if 92 * "ugd_actlen" is zero. 93 */ 94 data = malloc(ugd.ugd_actlen); 95 if (data == NULL) 96 return (NULL); 97 98 /* fetch actual descriptor */ 99 ugd.ugd_data = data; 100 ugd.ugd_maxlen = ugd.ugd_actlen; 101 if (ioctl(fd, USB_GET_REPORT_DESC, &ugd) < 0) { 102 /* could not read descriptor */ 103 free(data); 104 return (NULL); 105 } 106 107 /* check END_COLLECTION */ 108 if (((unsigned char *)ugd.ugd_data)[ugd.ugd_actlen -1] != 0xC0) { 109 /* invalid end byte */ 110 free(data); 111 return (NULL); 112 } 113 114 rep = hid_use_report_desc(data, ugd.ugd_actlen); 115 116 free(data); 117 118 return (rep); 119} 120 121report_desc_t 122hid_use_report_desc(unsigned char *data, unsigned int size) 123{ 124 report_desc_t r; 125 126 r = malloc(sizeof(*r) + size); 127 if (r == 0) { 128 errno = ENOMEM; 129 return (NULL); 130 } 131 r->size = size; 132 memcpy(r->data, data, size); 133 return (r); 134} 135 136void 137hid_dispose_report_desc(report_desc_t r) 138{ 139 140 free(r); 141} 142