summaryrefslogtreecommitdiffstats
path: root/usr.sbin/bluetooth/bthidd/parser.y
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bluetooth/bthidd/parser.y')
-rw-r--r--usr.sbin/bluetooth/bthidd/parser.y132
1 files changed, 80 insertions, 52 deletions
diff --git a/usr.sbin/bluetooth/bthidd/parser.y b/usr.sbin/bluetooth/bthidd/parser.y
index eda82f6..8d95f4e 100644
--- a/usr.sbin/bluetooth/bthidd/parser.y
+++ b/usr.sbin/bluetooth/bthidd/parser.y
@@ -1,8 +1,10 @@
%{
/*
* parser.y
- *
- * Copyright (c) 2004 Maksim Yevmenkin <m_evmenkin@yahoo.com>
+ */
+
+/*-
+ * Copyright (c) 2006 Maksim Yevmenkin <m_evmenkin@yahoo.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -26,12 +28,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: parser.y,v 1.4 2004/11/17 21:59:42 max Exp $
+ * $Id: parser.y,v 1.7 2006/09/07 21:06:53 max Exp $
* $FreeBSD$
*/
#include <sys/queue.h>
#include <bluetooth.h>
+#include <dev/usb/usb.h>
+#include <dev/usb/usbhid.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
@@ -59,15 +63,17 @@
int yyparse (void);
int yylex (void);
-static int check_hid_device(hid_device_p hid_device);
+ void yyerror (char const *);
+static int32_t check_hid_device(hid_device_p hid_device);
static void free_hid_device (hid_device_p hid_device);
+extern FILE *yyin;
extern int yylineno;
- char *config_file = BTHIDD_CONFFILE;
- char *hids_file = BTHIDD_HIDSFILE;
+ char const *config_file = BTHIDD_CONFFILE;
+ char const *hids_file = BTHIDD_HIDSFILE;
static char buffer[1024];
-static int hid_descriptor_size;
+static int32_t hid_descriptor_size;
static hid_device_t *hid_device = NULL;
static LIST_HEAD(, hid_device) hid_devices;
@@ -75,7 +81,7 @@ static LIST_HEAD(, hid_device) hid_devices;
%union {
bdaddr_t bdaddr;
- int num;
+ int32_t num;
}
%token <bdaddr> T_BDADDRSTRING
@@ -197,7 +203,7 @@ hid_descriptor_bytes: hid_descriptor_byte
hid_descriptor_byte: T_HEXBYTE
{
- if (hid_descriptor_size >= sizeof(buffer)) {
+ if (hid_descriptor_size >= (int32_t) sizeof(buffer)) {
SYSLOG(LOGCRIT, "HID descriptor is too big" EOL);
YYABORT;
}
@@ -221,11 +227,10 @@ yyerror(char const *message)
}
/* Re-read config file */
-int
+int32_t
read_config_file(void)
{
- extern FILE *yyin;
- int e;
+ int32_t e;
if (config_file == NULL) {
SYSLOG(LOGERR, "Unknown config file name!" EOL);
@@ -257,10 +262,10 @@ void
clean_config(void)
{
while (!LIST_EMPTY(&hid_devices)) {
- hid_device_p hid_device = LIST_FIRST(&hid_devices);
+ hid_device_p d = LIST_FIRST(&hid_devices);
- LIST_REMOVE(hid_device, next);
- free_hid_device(hid_device);
+ LIST_REMOVE(d, next);
+ free_hid_device(d);
}
}
@@ -268,13 +273,13 @@ clean_config(void)
hid_device_p
get_hid_device(bdaddr_p bdaddr)
{
- hid_device_p hid_device;
+ hid_device_p d;
- LIST_FOREACH(hid_device, &hid_devices, next)
- if (memcmp(&hid_device->bdaddr, bdaddr, sizeof(bdaddr_t)) == 0)
+ LIST_FOREACH(d, &hid_devices, next)
+ if (memcmp(&d->bdaddr, bdaddr, sizeof(bdaddr_t)) == 0)
break;
- return (hid_device);
+ return (d);
}
/* Get next config entry */
@@ -286,7 +291,7 @@ get_next_hid_device(hid_device_p d)
/* Print config entry */
void
-print_hid_device(hid_device_p hid_device, FILE *f)
+print_hid_device(hid_device_p d, FILE *f)
{
/* XXX FIXME hack! */
struct report_desc {
@@ -295,8 +300,8 @@ print_hid_device(hid_device_p hid_device, FILE *f)
};
/* XXX FIXME hack! */
- struct report_desc *desc = (struct report_desc *) hid_device->desc;
- int i;
+ struct report_desc *desc = (struct report_desc *) d->desc;
+ uint32_t i;
fprintf(f,
"device {\n" \
@@ -307,11 +312,11 @@ print_hid_device(hid_device_p hid_device, FILE *f)
" battery_power %s;\n" \
" normally_connectable %s;\n" \
" hid_descriptor {",
- bt_ntoa(&hid_device->bdaddr, NULL),
- hid_device->control_psm, hid_device->interrupt_psm,
- hid_device->reconnect_initiate? "true" : "false",
- hid_device->battery_power? "true" : "false",
- hid_device->normally_connectable? "true" : "false");
+ bt_ntoa(&d->bdaddr, NULL),
+ d->control_psm, d->interrupt_psm,
+ d->reconnect_initiate? "true" : "false",
+ d->battery_power? "true" : "false",
+ d->normally_connectable? "true" : "false");
for (i = 0; i < desc->size; i ++) {
if ((i % 8) == 0)
@@ -327,53 +332,76 @@ print_hid_device(hid_device_p hid_device, FILE *f)
}
/* Check config entry */
-static int
-check_hid_device(hid_device_p hid_device)
+static int32_t
+check_hid_device(hid_device_p d)
{
- if (get_hid_device(&hid_device->bdaddr) != NULL) {
+ hid_data_t hd;
+ hid_item_t hi;
+ int32_t page;
+
+ if (get_hid_device(&d->bdaddr) != NULL) {
SYSLOG(LOGERR, "Ignoring duplicated entry for bdaddr %s" EOL,
- bt_ntoa(&hid_device->bdaddr, NULL));
+ bt_ntoa(&d->bdaddr, NULL));
return (0);
}
- if (hid_device->control_psm == 0) {
+ if (d->control_psm == 0) {
SYSLOG(LOGERR, "Ignoring entry with invalid control PSM" EOL);
return (0);
}
- if (hid_device->interrupt_psm == 0) {
+ if (d->interrupt_psm == 0) {
SYSLOG(LOGERR, "Ignoring entry with invalid interrupt PSM" EOL);
return (0);
}
- if (hid_device->desc == NULL) {
+ if (d->desc == NULL) {
SYSLOG(LOGERR, "Ignoring entry without HID descriptor" EOL);
return (0);
}
+ /* XXX somehow need to make sure descriptor is valid */
+ for (hd = hid_start_parse(d->desc, ~0, -1); hid_get_item(hd, &hi) > 0; ) {
+ switch (hi.kind) {
+ case hid_collection:
+ case hid_endcollection:
+ case hid_output:
+ case hid_feature:
+ break;
+
+ case hid_input:
+ /* Check if the device may send keystrokes */
+ page = HID_PAGE(hi.usage);
+ if (page == HUP_KEYBOARD || page == HUP_CONSUMER)
+ d->keyboard = 1;
+ break;
+ }
+ }
+ hid_end_parse(hd);
+
return (1);
}
/* Free config entry */
static void
-free_hid_device(hid_device_p hid_device)
+free_hid_device(hid_device_p d)
{
- if (hid_device->desc != NULL)
- hid_dispose_report_desc(hid_device->desc);
+ if (d->desc != NULL)
+ hid_dispose_report_desc(d->desc);
- memset(hid_device, 0, sizeof(*hid_device));
- free(hid_device);
+ memset(d, 0, sizeof(*d));
+ free(d);
}
/* Re-read hids file */
-int
+int32_t
read_hids_file(void)
{
- FILE *f = NULL;
- hid_device_t *hid_device = NULL;
- char *line = NULL;
+ FILE *f;
+ hid_device_t *d;
+ char *line;
bdaddr_t bdaddr;
- int lineno;
+ int32_t lineno;
if (hids_file == NULL) {
SYSLOG(LOGERR, "Unknown HIDs file name!" EOL);
@@ -399,8 +427,8 @@ read_hids_file(void)
continue;
}
- if ((hid_device = get_hid_device(&bdaddr)) != NULL)
- hid_device->new_device = 0;
+ if ((d = get_hid_device(&bdaddr)) != NULL)
+ d->new_device = 0;
}
fclose(f);
@@ -409,12 +437,12 @@ read_hids_file(void)
}
/* Write hids file */
-int
+int32_t
write_hids_file(void)
{
char path[PATH_MAX];
- FILE *f = NULL;
- hid_device_t *hid_device = NULL;
+ FILE *f;
+ hid_device_t *d;
if (hids_file == NULL) {
SYSLOG(LOGERR, "Unknown HIDs file name!" EOL);
@@ -429,9 +457,9 @@ write_hids_file(void)
return (-1);
}
- LIST_FOREACH(hid_device, &hid_devices, next)
- if (!hid_device->new_device)
- fprintf(f, "%s\n", bt_ntoa(&hid_device->bdaddr, NULL));
+ LIST_FOREACH(d, &hid_devices, next)
+ if (!d->new_device)
+ fprintf(f, "%s\n", bt_ntoa(&d->bdaddr, NULL));
fclose(f);
OpenPOWER on IntegriCloud