Deleted Added
full compact
parser.y (146357) parser.y (162128)
1%{
2/*
3 * parser.y
1%{
2/*
3 * parser.y
4 *
5 * Copyright (c) 2004 Maksim Yevmenkin <m_evmenkin@yahoo.com>
4 */
5
6/*-
7 * Copyright (c) 2006 Maksim Yevmenkin <m_evmenkin@yahoo.com>
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright

--- 7 unchanged lines hidden (view full) ---

21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright

--- 7 unchanged lines hidden (view full) ---

23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
29 * $Id: parser.y,v 1.4 2004/11/17 21:59:42 max Exp $
30 * $FreeBSD: head/usr.sbin/bluetooth/bthidd/parser.y 146357 2005-05-18 23:03:44Z emax $
31 * $Id: parser.y,v 1.7 2006/09/07 21:06:53 max Exp $
32 * $FreeBSD: head/usr.sbin/bluetooth/bthidd/parser.y 162128 2006-09-07 21:47:49Z emax $
31 */
32
33#include <sys/queue.h>
34#include <bluetooth.h>
33 */
34
35#include <sys/queue.h>
36#include <bluetooth.h>
37#include <dev/usb/usb.h>
38#include <dev/usb/usbhid.h>
35#include <errno.h>
36#include <limits.h>
37#include <stdio.h>
38#include <string.h>
39#include <unistd.h>
40#include <usbhid.h>
41
42#ifndef BTHIDCONTROL

--- 11 unchanged lines hidden (view full) ---

54#define LOGWARNING stderr
55#define EOL "\n"
56#endif /* ndef BTHIDCONTROL */
57
58#include "bthid_config.h"
59
60 int yyparse (void);
61 int yylex (void);
39#include <errno.h>
40#include <limits.h>
41#include <stdio.h>
42#include <string.h>
43#include <unistd.h>
44#include <usbhid.h>
45
46#ifndef BTHIDCONTROL

--- 11 unchanged lines hidden (view full) ---

58#define LOGWARNING stderr
59#define EOL "\n"
60#endif /* ndef BTHIDCONTROL */
61
62#include "bthid_config.h"
63
64 int yyparse (void);
65 int yylex (void);
62static int check_hid_device(hid_device_p hid_device);
66 void yyerror (char const *);
67static int32_t check_hid_device(hid_device_p hid_device);
63static void free_hid_device (hid_device_p hid_device);
64
68static void free_hid_device (hid_device_p hid_device);
69
70extern FILE *yyin;
65extern int yylineno;
71extern int yylineno;
66 char *config_file = BTHIDD_CONFFILE;
67 char *hids_file = BTHIDD_HIDSFILE;
72 char const *config_file = BTHIDD_CONFFILE;
73 char const *hids_file = BTHIDD_HIDSFILE;
68
69static char buffer[1024];
74
75static char buffer[1024];
70static int hid_descriptor_size;
76static int32_t hid_descriptor_size;
71static hid_device_t *hid_device = NULL;
72static LIST_HEAD(, hid_device) hid_devices;
73
74%}
75
76%union {
77 bdaddr_t bdaddr;
77static hid_device_t *hid_device = NULL;
78static LIST_HEAD(, hid_device) hid_devices;
79
80%}
81
82%union {
83 bdaddr_t bdaddr;
78 int num;
84 int32_t num;
79}
80
81%token <bdaddr> T_BDADDRSTRING
82%token <num> T_HEXBYTE
83%token T_DEVICE T_BDADDR T_CONTROL_PSM T_INTERRUPT_PSM T_RECONNECT_INITIATE
84%token T_BATTERY_POWER T_NORMALLY_CONNECTABLE T_HID_DESCRIPTOR
85%token T_TRUE T_FALSE T_ERROR
86

--- 105 unchanged lines hidden (view full) ---

192 ;
193
194hid_descriptor_bytes: hid_descriptor_byte
195 | hid_descriptor_bytes hid_descriptor_byte
196 ;
197
198hid_descriptor_byte: T_HEXBYTE
199 {
85}
86
87%token <bdaddr> T_BDADDRSTRING
88%token <num> T_HEXBYTE
89%token T_DEVICE T_BDADDR T_CONTROL_PSM T_INTERRUPT_PSM T_RECONNECT_INITIATE
90%token T_BATTERY_POWER T_NORMALLY_CONNECTABLE T_HID_DESCRIPTOR
91%token T_TRUE T_FALSE T_ERROR
92

--- 105 unchanged lines hidden (view full) ---

198 ;
199
200hid_descriptor_bytes: hid_descriptor_byte
201 | hid_descriptor_bytes hid_descriptor_byte
202 ;
203
204hid_descriptor_byte: T_HEXBYTE
205 {
200 if (hid_descriptor_size >= sizeof(buffer)) {
206 if (hid_descriptor_size >= (int32_t) sizeof(buffer)) {
201 SYSLOG(LOGCRIT, "HID descriptor is too big" EOL);
202 YYABORT;
203 }
204
205 buffer[hid_descriptor_size ++] = $1;
206 }
207 ;
208

--- 7 unchanged lines hidden (view full) ---

216/* Display parser error message */
217void
218yyerror(char const *message)
219{
220 SYSLOG(LOGERR, "%s in line %d" EOL, message, yylineno);
221}
222
223/* Re-read config file */
207 SYSLOG(LOGCRIT, "HID descriptor is too big" EOL);
208 YYABORT;
209 }
210
211 buffer[hid_descriptor_size ++] = $1;
212 }
213 ;
214

--- 7 unchanged lines hidden (view full) ---

222/* Display parser error message */
223void
224yyerror(char const *message)
225{
226 SYSLOG(LOGERR, "%s in line %d" EOL, message, yylineno);
227}
228
229/* Re-read config file */
224int
230int32_t
225read_config_file(void)
226{
231read_config_file(void)
232{
227 extern FILE *yyin;
228 int e;
233 int32_t e;
229
230 if (config_file == NULL) {
231 SYSLOG(LOGERR, "Unknown config file name!" EOL);
232 return (-1);
233 }
234
235 if ((yyin = fopen(config_file, "r")) == NULL) {
236 SYSLOG(LOGERR, "Could not open config file '%s'. %s (%d)" EOL,

--- 15 unchanged lines hidden (view full) ---

252 return (e);
253}
254
255/* Clean config */
256void
257clean_config(void)
258{
259 while (!LIST_EMPTY(&hid_devices)) {
234
235 if (config_file == NULL) {
236 SYSLOG(LOGERR, "Unknown config file name!" EOL);
237 return (-1);
238 }
239
240 if ((yyin = fopen(config_file, "r")) == NULL) {
241 SYSLOG(LOGERR, "Could not open config file '%s'. %s (%d)" EOL,

--- 15 unchanged lines hidden (view full) ---

257 return (e);
258}
259
260/* Clean config */
261void
262clean_config(void)
263{
264 while (!LIST_EMPTY(&hid_devices)) {
260 hid_device_p hid_device = LIST_FIRST(&hid_devices);
265 hid_device_p d = LIST_FIRST(&hid_devices);
261
266
262 LIST_REMOVE(hid_device, next);
263 free_hid_device(hid_device);
267 LIST_REMOVE(d, next);
268 free_hid_device(d);
264 }
265}
266
267/* Lookup config entry */
268hid_device_p
269get_hid_device(bdaddr_p bdaddr)
270{
269 }
270}
271
272/* Lookup config entry */
273hid_device_p
274get_hid_device(bdaddr_p bdaddr)
275{
271 hid_device_p hid_device;
276 hid_device_p d;
272
277
273 LIST_FOREACH(hid_device, &hid_devices, next)
274 if (memcmp(&hid_device->bdaddr, bdaddr, sizeof(bdaddr_t)) == 0)
278 LIST_FOREACH(d, &hid_devices, next)
279 if (memcmp(&d->bdaddr, bdaddr, sizeof(bdaddr_t)) == 0)
275 break;
276
280 break;
281
277 return (hid_device);
282 return (d);
278}
279
280/* Get next config entry */
281hid_device_p
282get_next_hid_device(hid_device_p d)
283{
284 return ((d == NULL)? LIST_FIRST(&hid_devices) : LIST_NEXT(d, next));
285}
286
287/* Print config entry */
288void
283}
284
285/* Get next config entry */
286hid_device_p
287get_next_hid_device(hid_device_p d)
288{
289 return ((d == NULL)? LIST_FIRST(&hid_devices) : LIST_NEXT(d, next));
290}
291
292/* Print config entry */
293void
289print_hid_device(hid_device_p hid_device, FILE *f)
294print_hid_device(hid_device_p d, FILE *f)
290{
291 /* XXX FIXME hack! */
292 struct report_desc {
293 unsigned int size;
294 unsigned char data[1];
295 };
296 /* XXX FIXME hack! */
297
295{
296 /* XXX FIXME hack! */
297 struct report_desc {
298 unsigned int size;
299 unsigned char data[1];
300 };
301 /* XXX FIXME hack! */
302
298 struct report_desc *desc = (struct report_desc *) hid_device->desc;
299 int i;
303 struct report_desc *desc = (struct report_desc *) d->desc;
304 uint32_t i;
300
301 fprintf(f,
302"device {\n" \
303" bdaddr %s;\n" \
304" control_psm 0x%x;\n" \
305" interrupt_psm 0x%x;\n" \
306" reconnect_initiate %s;\n" \
307" battery_power %s;\n" \
308" normally_connectable %s;\n" \
309" hid_descriptor {",
305
306 fprintf(f,
307"device {\n" \
308" bdaddr %s;\n" \
309" control_psm 0x%x;\n" \
310" interrupt_psm 0x%x;\n" \
311" reconnect_initiate %s;\n" \
312" battery_power %s;\n" \
313" normally_connectable %s;\n" \
314" hid_descriptor {",
310 bt_ntoa(&hid_device->bdaddr, NULL),
311 hid_device->control_psm, hid_device->interrupt_psm,
312 hid_device->reconnect_initiate? "true" : "false",
313 hid_device->battery_power? "true" : "false",
314 hid_device->normally_connectable? "true" : "false");
315 bt_ntoa(&d->bdaddr, NULL),
316 d->control_psm, d->interrupt_psm,
317 d->reconnect_initiate? "true" : "false",
318 d->battery_power? "true" : "false",
319 d->normally_connectable? "true" : "false");
315
316 for (i = 0; i < desc->size; i ++) {
317 if ((i % 8) == 0)
318 fprintf(f, "\n ");
319
320 fprintf(f, "0x%2.2x ", desc->data[i]);
321 }
322
323 fprintf(f,
324"\n" \
325" };\n" \
326"}\n");
327}
328
329/* Check config entry */
320
321 for (i = 0; i < desc->size; i ++) {
322 if ((i % 8) == 0)
323 fprintf(f, "\n ");
324
325 fprintf(f, "0x%2.2x ", desc->data[i]);
326 }
327
328 fprintf(f,
329"\n" \
330" };\n" \
331"}\n");
332}
333
334/* Check config entry */
330static int
331check_hid_device(hid_device_p hid_device)
335static int32_t
336check_hid_device(hid_device_p d)
332{
337{
333 if (get_hid_device(&hid_device->bdaddr) != NULL) {
338 hid_data_t hd;
339 hid_item_t hi;
340 int32_t page;
341
342 if (get_hid_device(&d->bdaddr) != NULL) {
334 SYSLOG(LOGERR, "Ignoring duplicated entry for bdaddr %s" EOL,
343 SYSLOG(LOGERR, "Ignoring duplicated entry for bdaddr %s" EOL,
335 bt_ntoa(&hid_device->bdaddr, NULL));
344 bt_ntoa(&d->bdaddr, NULL));
336 return (0);
337 }
338
345 return (0);
346 }
347
339 if (hid_device->control_psm == 0) {
348 if (d->control_psm == 0) {
340 SYSLOG(LOGERR, "Ignoring entry with invalid control PSM" EOL);
341 return (0);
342 }
343
349 SYSLOG(LOGERR, "Ignoring entry with invalid control PSM" EOL);
350 return (0);
351 }
352
344 if (hid_device->interrupt_psm == 0) {
353 if (d->interrupt_psm == 0) {
345 SYSLOG(LOGERR, "Ignoring entry with invalid interrupt PSM" EOL);
346 return (0);
347 }
348
354 SYSLOG(LOGERR, "Ignoring entry with invalid interrupt PSM" EOL);
355 return (0);
356 }
357
349 if (hid_device->desc == NULL) {
358 if (d->desc == NULL) {
350 SYSLOG(LOGERR, "Ignoring entry without HID descriptor" EOL);
351 return (0);
352 }
353
359 SYSLOG(LOGERR, "Ignoring entry without HID descriptor" EOL);
360 return (0);
361 }
362
363 /* XXX somehow need to make sure descriptor is valid */
364 for (hd = hid_start_parse(d->desc, ~0, -1); hid_get_item(hd, &hi) > 0; ) {
365 switch (hi.kind) {
366 case hid_collection:
367 case hid_endcollection:
368 case hid_output:
369 case hid_feature:
370 break;
371
372 case hid_input:
373 /* Check if the device may send keystrokes */
374 page = HID_PAGE(hi.usage);
375 if (page == HUP_KEYBOARD || page == HUP_CONSUMER)
376 d->keyboard = 1;
377 break;
378 }
379 }
380 hid_end_parse(hd);
381
354 return (1);
355}
356
357/* Free config entry */
358static void
382 return (1);
383}
384
385/* Free config entry */
386static void
359free_hid_device(hid_device_p hid_device)
387free_hid_device(hid_device_p d)
360{
388{
361 if (hid_device->desc != NULL)
362 hid_dispose_report_desc(hid_device->desc);
389 if (d->desc != NULL)
390 hid_dispose_report_desc(d->desc);
363
391
364 memset(hid_device, 0, sizeof(*hid_device));
365 free(hid_device);
392 memset(d, 0, sizeof(*d));
393 free(d);
366}
367
368/* Re-read hids file */
394}
395
396/* Re-read hids file */
369int
397int32_t
370read_hids_file(void)
371{
398read_hids_file(void)
399{
372 FILE *f = NULL;
373 hid_device_t *hid_device = NULL;
374 char *line = NULL;
400 FILE *f;
401 hid_device_t *d;
402 char *line;
375 bdaddr_t bdaddr;
403 bdaddr_t bdaddr;
376 int lineno;
404 int32_t lineno;
377
378 if (hids_file == NULL) {
379 SYSLOG(LOGERR, "Unknown HIDs file name!" EOL);
380 return (-1);
381 }
382
383 if ((f = fopen(hids_file, "r")) == NULL) {
384 if (errno == ENOENT)

--- 9 unchanged lines hidden (view full) ---

394 continue; /* ignore empty lines */
395
396 if (!bt_aton(line, &bdaddr)) {
397 SYSLOG(LOGWARNING, "Ignoring unparseable BD_ADDR in " \
398 "%s:%d" EOL, hids_file, lineno);
399 continue;
400 }
401
405
406 if (hids_file == NULL) {
407 SYSLOG(LOGERR, "Unknown HIDs file name!" EOL);
408 return (-1);
409 }
410
411 if ((f = fopen(hids_file, "r")) == NULL) {
412 if (errno == ENOENT)

--- 9 unchanged lines hidden (view full) ---

422 continue; /* ignore empty lines */
423
424 if (!bt_aton(line, &bdaddr)) {
425 SYSLOG(LOGWARNING, "Ignoring unparseable BD_ADDR in " \
426 "%s:%d" EOL, hids_file, lineno);
427 continue;
428 }
429
402 if ((hid_device = get_hid_device(&bdaddr)) != NULL)
403 hid_device->new_device = 0;
430 if ((d = get_hid_device(&bdaddr)) != NULL)
431 d->new_device = 0;
404 }
405
406 fclose(f);
407
408 return (0);
409}
410
411/* Write hids file */
432 }
433
434 fclose(f);
435
436 return (0);
437}
438
439/* Write hids file */
412int
440int32_t
413write_hids_file(void)
414{
415 char path[PATH_MAX];
441write_hids_file(void)
442{
443 char path[PATH_MAX];
416 FILE *f = NULL;
417 hid_device_t *hid_device = NULL;
444 FILE *f;
445 hid_device_t *d;
418
419 if (hids_file == NULL) {
420 SYSLOG(LOGERR, "Unknown HIDs file name!" EOL);
421 return (-1);
422 }
423
424 snprintf(path, sizeof(path), "%s.new", hids_file);
425
426 if ((f = fopen(path, "w")) == NULL) {
427 SYSLOG(LOGERR, "Could not open HIDs file '%s'. %s (%d)" EOL,
428 path, strerror(errno), errno);
429 return (-1);
430 }
431
446
447 if (hids_file == NULL) {
448 SYSLOG(LOGERR, "Unknown HIDs file name!" EOL);
449 return (-1);
450 }
451
452 snprintf(path, sizeof(path), "%s.new", hids_file);
453
454 if ((f = fopen(path, "w")) == NULL) {
455 SYSLOG(LOGERR, "Could not open HIDs file '%s'. %s (%d)" EOL,
456 path, strerror(errno), errno);
457 return (-1);
458 }
459
432 LIST_FOREACH(hid_device, &hid_devices, next)
433 if (!hid_device->new_device)
434 fprintf(f, "%s\n", bt_ntoa(&hid_device->bdaddr, NULL));
460 LIST_FOREACH(d, &hid_devices, next)
461 if (!d->new_device)
462 fprintf(f, "%s\n", bt_ntoa(&d->bdaddr, NULL));
435
436 fclose(f);
437
438 if (rename(path, hids_file) < 0) {
439 SYSLOG(LOGERR, "Could not rename new HIDs file '%s' to '%s'. " \
440 "%s (%d)" EOL, path, hids_file, strerror(errno), errno);
441 unlink(path);
442 return (-1);
443 }
444
445 return (0);
446}
447
463
464 fclose(f);
465
466 if (rename(path, hids_file) < 0) {
467 SYSLOG(LOGERR, "Could not rename new HIDs file '%s' to '%s'. " \
468 "%s (%d)" EOL, path, hids_file, strerror(errno), errno);
469 unlink(path);
470 return (-1);
471 }
472
473 return (0);
474}
475