1 /* hidapi_parser $
2  *
3  * Copyright (C) 2013, Marije Baalman <nescivi _at_ gmail.com>
4  * This work was funded by a crowd-funding initiative for SuperCollider's [1] HID implementation
5  * including a substantial donation from BEK, Bergen Center for Electronic Arts, Norway
6  *
7  * [1] http://supercollider.sourceforge.net
8  * [2] http://www.bek.no
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  */
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <math.h>
29 
30 #ifdef _WIN32
31 #include <windows.h>
32 // for MinGW < 5.3 include locally provided "../windows hidsdi.h" rather
33 // than #include <hidsdi.h>:
34 // #include "../windows/hidsdi.h"
35 #include <hidsdi.h>
36 #endif
37 
38 #include "hidapi_parser.h"
39 
40 
41 
42 // SET IN CMAKE
43 // #define DEBUG_PARSER
44 
45 //// ---------- HID descriptor parser
46 
47 // main items
48 #define HID_INPUT 0x80
49 #define HID_OUTPUT 0x90
50 #define HID_COLLECTION 0xA0
51 #define HID_FEATURE 0xB0
52 #define HID_END_COLLECTION 0xC0
53 
54 // HID Report Items from HID 1.11 Section 6.2.2
55 #define HID_USAGE_PAGE 0x04
56 #define HID_USAGE 0x08
57 #define HID_USAGE_MIN 0x18
58 #define HID_USAGE_MAX 0x28
59 
60 #define HID_DESIGNATOR_INDEX 0x38
61 #define HID_DESIGNATOR_MIN 0x48
62 #define HID_DESIGNATOR_MAX 0x58
63 
64 #define HID_STRING_INDEX 0x78
65 #define HID_STRING_MIN 0x88
66 #define HID_STRING_MAX 0x98
67 
68 #define HID_DELIMITER 0xA8
69 
70 #define HID_LOGICAL_MIN 0x14
71 #define HID_LOGICAL_MAX 0x24
72 
73 #define HID_PHYSICAL_MIN 0x34
74 #define HID_PHYSICAL_MAX 0x44
75 
76 #define HID_UNIT_EXPONENT 0x54
77 #define HID_UNIT 0x64
78 
79 #define HID_REPORT_SIZE 0x74
80 #define HID_REPORT_ID 0x84
81 
82 #define HID_REPORT_COUNT 0x94
83 
84 #define HID_PUSH 0xA4
85 #define HID_POP 0xB4
86 
87 #define HID_RESERVED 0xC4 // above this it is all reserved
88 
89 
90 // HID Report Usage Pages from HID Usage Tables 1.12 Section 3, Table 1
91 // #define HID_USAGE_PAGE_GENERICDESKTOP  0x01
92 // #define HID_USAGE_PAGE_KEY_CODES       0x07
93 // #define HID_USAGE_PAGE_LEDS            0x08
94 // #define HID_USAGE_PAGE_BUTTONS         0x09
95 
96 // HID Report Usages from HID Usage Tables 1.12 Section 4, Table 6
97 // #define HID_USAGE_POINTER  0x01
98 // #define HID_USAGE_MOUSE    0x02
99 // #define HID_USAGE_JOYSTICK 0x04
100 // #define HID_USAGE_KEYBOARD 0x06
101 // #define HID_USAGE_X        0x30
102 // #define HID_USAGE_Y        0x31
103 // #define HID_USAGE_Z        0x32
104 // #define HID_USAGE_RX       0x33
105 // #define HID_USAGE_RY       0x34
106 // #define HID_USAGE_RZ       0x35
107 // #define HID_USAGE_SLIDER   0x36
108 // #define HID_USAGE_DIAL     0x37
109 // #define HID_USAGE_WHEEL    0x38
110 
111 
112 // HID Report Collection Types from HID 1.12 6.2.2.6
113 #define HID_COLLECTION_PHYSICAL    0x00
114 #define HID_COLLECTION_APPLICATION 0x01
115 #define HID_COLLECTION_LOGICAL 0x02
116 #define HID_COLLECTION_REPORT 0x03
117 #define HID_COLLECTION_NAMED_ARRAY 0x04
118 #define HID_COLLECTION_USAGE_SWITCH 0x05
119 #define HID_COLLECTION_USAGE_MODIFIER 0x06
120 #define HID_COLLECTION_RESERVED 0x07
121 #define HID_COLLECTION_VENDOR 0x80
122 
123 // HID Input/Output/Feature Item Data (attributes) from HID 1.11 6.2.2.5
124 /// more like flags - for input, output, and feature
125 #define HID_ITEM_CONSTANT 0x1 // data(0), constant(1)
126 #define HID_ITEM_VARIABLE 0x2 // array(0), variable(1)
127 #define HID_ITEM_RELATIVE 0x4 // absolute(0), relative(1)
128 #define HID_ITEM_WRAP 0x8 // no wrap(0), wrap(1)
129 #define HID_ITEM_LINEAR 0x10 // linear(0), non linear(1)
130 #define HID_ITEM_PREFERRED 0x20 // no preferred(0), preferred(1)
131 #define HID_ITEM_NULL 0x40 // no null(0), null(1)
132 #define HID_ITEM_VOLATILE 0x60 // non volatile(0), volatile(1)
133 #define HID_ITEM_BITFIELD 0x80 // bit field(0), buffered bytes(1)
134 
135 // Report Types from HID 1.11 Section 7.2.1
136 #define HID_REPORT_TYPE_INPUT   1
137 #define HID_REPORT_TYPE_OUTPUT  2
138 #define HID_REPORT_TYPE_FEATURE 3
139 
140 
141 #define BITMASK1(n) ((1ULL << (n)) - 1ULL)
142 #define INVERTBITMASK1(n) ( 255 -(n))
143 #define BITTESTMASK1(n) (1ULL << (n))
144 
145 // struct hid_device_descriptor * hid_new_descriptor(){
146 //   struct hid_device_descriptor * descriptor;
147 //   descriptor = (struct hid_device_descriptor *) malloc( sizeof( struct hid_device_descriptor) );
148 // //     hid_descriptor_init( descriptor );
149 //
150 //   descriptor->first = NULL;
151 //   hid_set_descriptor_callback(descriptor, NULL, NULL);
152 //   hid_set_element_callback(descriptor, NULL, NULL);
153 //   return descriptor;
154 // }
155 
hid_new_element()156 struct hid_device_element * hid_new_element(){
157   struct hid_device_element * element = (struct hid_device_element *) malloc( sizeof( struct hid_device_element ) );
158   element->next = NULL;
159   element->parent_collection = NULL;
160   element->index = -1;
161   element->repeat = 0;
162 
163   element->usage_min = 0;
164   element->usage_max = 0;
165   element->logical_min = 0;
166   element->logical_max = 0;
167   element->phys_min = 0;
168   element->phys_max = 0;
169   element->report_id = 0;
170   element->unit = 0;
171   element->unit_exponent = 0;
172 
173   element->rawvalue = 0;
174 
175   return element;
176 }
177 
hid_free_element(struct hid_device_element * ele)178 void hid_free_element( struct hid_device_element * ele ){
179   free( ele );
180 }
181 
hid_new_collection()182 struct hid_device_collection * hid_new_collection(){
183   struct hid_device_collection * collection = (struct hid_device_collection *) malloc( sizeof( struct hid_device_collection ) );
184   collection->first_collection = NULL;
185   collection->next_collection = NULL;
186   collection->parent_collection = NULL;
187   collection->first_element = NULL;
188   collection->num_collections = 0;
189   collection->num_elements = 0;
190   collection->index = -1;
191   collection->usage_page = 0;
192   collection->usage_index = 0;
193   return collection;
194 }
195 
hid_free_collection(struct hid_device_collection * coll)196 void hid_free_collection( struct hid_device_collection * coll ){
197   struct hid_device_element * cur_element = coll->first_element;
198   struct hid_device_element * next_element;
199   while (cur_element != NULL ) {
200     next_element = cur_element->next;
201     free( cur_element );
202     cur_element = next_element;
203   }
204   struct hid_device_collection * cur_collection = coll->first_collection;
205   struct hid_device_collection * next_collection;
206   while (cur_collection != NULL ) {
207     next_collection = cur_collection->next_collection;
208     free( cur_collection );
209     cur_collection = next_collection;
210   }
211   free( coll );
212 }
213 
hid_set_descriptor_callback(struct hid_dev_desc * devd,hid_descriptor_callback cb,void * user_data)214 void hid_set_descriptor_callback( struct hid_dev_desc * devd, hid_descriptor_callback cb, void *user_data ){
215     devd->_descriptor_callback = cb;
216     devd->_descriptor_data = user_data;
217 }
218 
hid_set_readerror_callback(struct hid_dev_desc * devd,hid_descriptor_callback cb,void * user_data)219 void hid_set_readerror_callback( struct hid_dev_desc * devd, hid_descriptor_callback cb, void *user_data ){
220     devd->_readerror_callback = cb;
221     devd->_readerror_data = user_data;
222 }
223 
hid_set_element_callback(struct hid_dev_desc * devd,hid_element_callback cb,void * user_data)224 void hid_set_element_callback( struct hid_dev_desc * devd, hid_element_callback cb, void *user_data ){
225     devd->_element_callback = cb;
226     devd->_element_data = user_data;
227 }
228 
hid_set_from_making_element(struct hid_device_element * making,struct hid_device_element * new_element)229 void hid_set_from_making_element( struct hid_device_element * making, struct hid_device_element * new_element ){
230 
231 	new_element->type = making->type;
232 	new_element->isrelative = (making->type & HID_ITEM_RELATIVE ) > 0;
233 	new_element->isarray = ( (making->type & HID_ITEM_VARIABLE ) == 0 );
234 	new_element->isvariable = (making->type & HID_ITEM_CONSTANT ) == 0;
235 
236 	new_element->usage_page = making->usage_page;
237 	new_element->logical_min = making->logical_min;
238 	new_element->logical_max = making->logical_max;
239 	new_element->usage_min = making->usage_min;
240 	new_element->usage_max = making->usage_max;
241 	if ( (making->phys_min == 0) && (making->phys_max == 0) ){
242 	  new_element->phys_min = making->logical_min;
243 	  new_element->phys_max = making->logical_max;
244 
245 	} else {
246 	  new_element->phys_min = making->phys_min;
247 	  new_element->phys_max = making->phys_max;
248 	}
249 	new_element->unit = making->unit;
250 	new_element->unit_exponent = making->unit_exponent;
251 
252 	new_element->report_size = making->report_size;
253 	new_element->report_id = making->report_id;
254 }
255 
hid_element_get_signed_value(int inputvalue,int bytesize)256 int hid_element_get_signed_value( int inputvalue, int bytesize ){
257   int outputvalue;
258   int bitSignIndex = bytesize*8 - 1;
259   int signBit = 0x1 << bitSignIndex;
260   if ( signBit & inputvalue ){
261     unsigned int bitMask = BITMASK1( bytesize*8 );
262     unsigned int uvalue = (unsigned int) inputvalue;
263     unsigned int negvalue = ~(uvalue);
264     negvalue = ~(uvalue) & bitMask;
265     negvalue = negvalue + 1;
266     outputvalue = -1 * negvalue;
267   } else {
268     outputvalue = inputvalue;
269   }
270   return outputvalue;
271 }
272 
273 // int hid_parse_report_descriptor( char* descr_buf, int size, struct hid_device_descriptor * descriptor ){
hid_parse_report_descriptor(unsigned char * descr_buf,int size,struct hid_dev_desc * device_desc)274 int hid_parse_report_descriptor( unsigned char* descr_buf, int size, struct hid_dev_desc * device_desc ){
275   struct hid_device_collection * device_collection = hid_new_collection();
276   device_desc->device_collection = device_collection;
277 
278   struct hid_device_collection * parent_collection = device_desc->device_collection;
279   struct hid_device_collection * prev_collection = 0;
280   struct hid_device_element * prev_element = 0;
281 
282   struct hid_device_element * making_element = hid_new_element();
283 
284   int current_usages[256];
285   int current_usage_index = 0;
286   int current_report_size;
287 
288   int current_usage_min = -1;
289   int current_usage_max = -1;
290 
291   int current_report_count = 0;
292 
293 //   unsigned char current_input;
294 //   unsigned char current_output;
295   int collection_nesting = 0;
296 
297   int next_byte_tag = -1;
298   int next_byte_size = 0;
299   int next_byte_type = 0;
300   int next_val = 0;
301 
302   unsigned char toadd = 0;
303   int byte_count = 0;
304 
305   int i,j;
306 
307   int numreports = 1;
308   int report_lengths[256];
309   int report_ids[256];
310   report_ids[0] = 0;
311   report_lengths[0] = 0;
312 
313   int k;
314   int index;
315 
316   device_collection->num_collections = 0;
317   device_collection->num_elements = 0;
318 #ifdef DEBUG_PARSER
319   printf("----------- parsing report descriptor --------------\n " );
320 #endif
321   for ( i = 0; i < size; i++){
322 #ifdef DEBUG_PARSER
323 	  printf("\nbuffer value: %02hhx ", descr_buf[i]);
324 	  printf("\tbyte_type %i, %i, %i \t", next_byte_tag, next_byte_size, next_val);
325 #endif
326 	  if ( next_byte_tag != -1 ){
327 // 	      unsigned char ubyte = (unsigned char) descr_buf[i];
328 // 	      char sbyte = descr_buf[i]; // descr_buf is signed already
329 	      int shift = byte_count*8;
330 	      int bufval = (int) descr_buf[i];
331 	      next_val |= (bufval << shift);
332 #ifdef DEBUG_PARSER
333 	      printf("\t nextval shift: %i", next_val);
334 #endif
335 	      byte_count++;
336 	      if ( byte_count == next_byte_size ){
337 		switch( next_byte_tag ){
338 		  case HID_USAGE_PAGE:
339 		    making_element->usage_page = next_val;
340 #ifdef DEBUG_PARSER
341 		    printf("\n\tusage page: 0x%02hhx", making_element->usage_page);
342 #endif
343 		    break;
344 		  case HID_USAGE:
345 		    making_element->usage = next_val;
346 		    current_usage_min = -1;
347 		    current_usage_max = -1;
348 		    current_usages[ current_usage_index ] = next_val;
349 #ifdef DEBUG_PARSER
350 		    printf("\n\tusage: 0x%02hhx, %i", current_usages[ current_usage_index ], current_usage_index );
351 #endif
352 		    current_usage_index++;
353 		    break;
354 		  case HID_COLLECTION:
355 		  {
356 		    //TODO: COULD ALSO READ WHICH KIND OF COLLECTION
357 		    struct hid_device_collection * new_collection = hid_new_collection();
358 		    if ( parent_collection->num_collections == 0 ){
359 		      parent_collection->first_collection = new_collection;
360 		    }
361 		    if ( device_collection->num_collections == 0 ){
362 		      device_collection->first_collection = new_collection;
363 		    } else {
364 		      prev_collection->next_collection = new_collection;
365 		    }
366 		    new_collection->parent_collection = parent_collection;
367 		    new_collection->type = next_val;
368 		    new_collection->usage_page = making_element->usage_page;
369 		    new_collection->usage_index = making_element->usage;
370 		    new_collection->usage_min = making_element->usage_min;
371 		    new_collection->usage_max = making_element->usage_max;
372 		    new_collection->index = device_collection->num_collections;
373 		    device_collection->num_collections++;
374 		    if ( device_collection != parent_collection ){
375 		      parent_collection->num_collections++;
376 		    }
377 		    parent_collection = new_collection;
378 		    prev_collection = new_collection;
379 		    collection_nesting++;
380 #ifdef DEBUG_PARSER
381 		    printf("\n\tcollection: %i, %i", collection_nesting, next_val );
382 #endif
383 		    break;
384 		  }
385 		  case HID_USAGE_MIN:
386 		    current_usage_min = next_val;
387 		    making_element->usage_min = next_val;
388 #ifdef DEBUG_PARSER
389 		    printf("\n\tusage min: %i", current_usage_min);
390 #endif
391 		    break;
392 		  case HID_USAGE_MAX:
393 		    current_usage_max = next_val;
394 		    making_element->usage_max = next_val;
395 #ifdef DEBUG_PARSER
396 		    printf("\n\tusage max: %i", current_usage_max);
397 #endif
398 		    break;
399 		  case HID_LOGICAL_MIN:
400 		    making_element->logical_min = hid_element_get_signed_value( next_val, byte_count );
401 #ifdef DEBUG_PARSER
402 		    printf("\n\tlogical min: %i", making_element->logical_min);
403 #endif
404 		    break;
405 		  case HID_LOGICAL_MAX:
406  		    if ( making_element->logical_min >= 0 ){
407  		      making_element->logical_max = next_val;
408  		    } else {
409 		      making_element->logical_max = hid_element_get_signed_value( next_val, byte_count );
410 		    }
411 #ifdef DEBUG_PARSER
412 		    printf("\n\tlogical max: %i", making_element->logical_max);
413 #endif
414 		    break;
415 		  case HID_PHYSICAL_MIN:
416 		    making_element->phys_min = hid_element_get_signed_value( next_val, byte_count );
417 #ifdef DEBUG_PARSER
418 		    printf("\n\tphysical min: %i", making_element->phys_min);
419 #endif
420 		    break;
421 		  case HID_PHYSICAL_MAX:
422  		    if ( making_element->phys_min >= 0 ){
423  		      making_element->phys_max = next_val;
424  		    } else {
425 		      making_element->phys_max = hid_element_get_signed_value( next_val, byte_count );
426 		    }
427 #ifdef DEBUG_PARSER
428 		    printf("\n\tphysical max: %i", making_element->phys_min);
429 #endif
430 		    break;
431 		  case HID_REPORT_COUNT:
432 		    current_report_count = next_val;
433 #ifdef DEBUG_PARSER
434 		    printf("\n\treport count: %i", current_report_count);
435 #endif
436 		    break;
437 		  case HID_REPORT_SIZE:
438 		    making_element->report_size = next_val;
439 #ifdef DEBUG_PARSER
440 		    printf("\n\treport size: %i", making_element->report_size);
441 #endif
442 		    break;
443 		  case HID_REPORT_ID:
444 		    making_element->report_id = next_val;
445 		    // check if report id already exists
446 		    int reportexists = 0;
447 		    for ( j = 0; j < numreports; j++ ){
448 		      reportexists = (report_ids[j] == making_element->report_id);
449 		    }
450 		    if ( !reportexists ){
451 		      report_ids[ numreports ] = making_element->report_id;
452 		      report_lengths[ numreports ] = 0;
453 		      numreports++;
454 		    }
455 #ifdef DEBUG_PARSER
456 		    printf("\n\treport id: %i", making_element->report_id);
457 #endif
458 		    break;
459 		  case HID_POP:
460 		    // TODO: something useful with pop
461 #ifdef DEBUG_PARSER
462 		    printf("\n\tpop: %i", next_val );
463 #endif
464 		    break;
465 		  case HID_PUSH:
466 		    // TODO: something useful with push
467 #ifdef DEBUG_PARSER
468 		    printf("\n\tpop: %i", next_val );
469 #endif
470 		    break;
471 		  case HID_UNIT:
472 		    making_element->unit = next_val;
473 #ifdef DEBUG_PARSER
474 		    printf("\n\tunit: %i", next_val );
475 #endif
476 		    break;
477 		  case HID_UNIT_EXPONENT:
478 		    making_element->unit_exponent = hid_element_get_signed_value( next_val, byte_count );
479 #ifdef DEBUG_PARSER
480 		    printf("\n\tunit exponent: %i", next_val );
481 #endif
482 		    break;
483 		  case HID_INPUT:
484 #ifdef DEBUG_PARSER
485 		    printf("\n\tinput: %i", next_val);
486 		    printf("\tmaking_element->usage: %i", making_element->usage);
487 #endif
488 		    making_element->type = next_val;
489 		    // add the elements for this report
490 		    for ( j=0; j<current_report_count; j++ ){
491 			struct hid_device_element * new_element = hid_new_element();
492 // 			= (struct hid_device_element *) malloc( sizeof( struct hid_device_element ) );
493 			new_element->io_type = 1;
494 			new_element->index = device_collection->num_elements;
495 			new_element->parent_collection = parent_collection;
496 			hid_set_from_making_element( making_element, new_element );
497 			if ( current_usage_min == -1 ){
498 			  new_element->usage = current_usages[j]; /// FIXME
499 			} else {
500 			  new_element->usage = current_usage_min + j;
501 			}
502 			new_element->report_index = j;
503 
504 			new_element->value = 0;
505 			new_element->array_value = 0;
506 			if ( parent_collection->num_elements == 0 ){
507 			    parent_collection->first_element = new_element;
508 			}
509 			if ( device_collection->num_elements == 0 ){
510 			    device_collection->first_element = new_element;
511 			}
512 			device_collection->num_elements++;
513 			if ( parent_collection != device_collection ) {
514 			  parent_collection->num_elements++;
515 			}
516 			if ( prev_element != NULL ){
517 			    prev_element->next = new_element;
518 			}
519 			prev_element = new_element;
520 		    }
521 		    for ( j=0; j < current_usage_index; j++ ){
522 			current_usages[j] = 0;
523 		    }
524 		    current_usage_index = 0;
525 		    current_usage_min = -1;
526 		    current_usage_max = -1;
527 		    making_element->usage_min = -1;
528 		    making_element->usage_max = -1;
529 		    making_element->usage = 0;
530 		    break;
531 		  case HID_OUTPUT:
532 #ifdef DEBUG_PARSER
533 		    printf("\n\toutput: %i", next_val);
534 		    printf("\tmaking_element->usage: %i", making_element->usage);
535 #endif
536 		    making_element->type = next_val;
537 		    // add the elements for this report
538 		    for ( j=0; j<current_report_count; j++ ){
539 			struct hid_device_element * new_element = hid_new_element();
540 // 			struct hid_device_element * new_element = (struct hid_device_element *) malloc( sizeof( struct hid_device_element ) );
541 			new_element->io_type = 2;
542 			new_element->index = device_collection->num_elements;
543 			new_element->parent_collection = parent_collection;
544 			hid_set_from_making_element( making_element, new_element );
545 			if ( current_usage_min == -1 ){
546 			  new_element->usage = current_usages[j]; /// FIXME
547 			} else {
548 			  new_element->usage = current_usage_min + j;
549 			}
550 			new_element->report_index = j;
551 
552 			index = 0;
553 			for ( k=0; k<numreports; k++ ){
554 			  if ( making_element->report_id == report_ids[k] ){
555 			    index = k;
556 			    break;
557 			  }
558 			}
559 			report_lengths[index] += making_element->report_size;
560 
561 			new_element->value = 0;
562 			new_element->array_value = 0;
563 			if ( parent_collection->num_elements == 0 ){
564 			    parent_collection->first_element = new_element;
565 			}
566 			if ( device_collection->num_elements == 0 ){
567 			    device_collection->first_element = new_element;
568 			}
569 			device_collection->num_elements++;
570 			if ( parent_collection != device_collection ) {
571 			  parent_collection->num_elements++;
572 			}
573 			if ( prev_element != NULL ){
574 			    prev_element->next = new_element;
575 			}
576 			prev_element = new_element;
577 		    }
578 		    for ( j=0; j < current_usage_index; j++ ){
579 			current_usages[j] = 0;
580 		    }
581 		    current_usage_index = 0;
582 		    current_usage_min = -1;
583 		    current_usage_max = -1;
584 		    making_element->usage_min = -1;
585 		    making_element->usage_max = -1;
586 		    making_element->usage = 0;
587 		    break;
588 		  case HID_FEATURE:
589 #ifdef DEBUG_PARSER
590 		    printf("\n\tfeature: %i", next_val);
591 		    printf("\tcurrent_usage: %i", making_element->usage);
592 #endif
593 		    making_element->type = next_val;
594 		    // add the elements for this report
595 		    for ( j=0; j<current_report_count; j++ ){
596 			struct hid_device_element * new_element = hid_new_element();
597 			new_element->io_type = 3;
598 			new_element->index = device_collection->num_elements;
599 			new_element->parent_collection = parent_collection;
600 			hid_set_from_making_element( making_element, new_element );
601 			if ( current_usage_min == -1 ){
602 			  new_element->usage = current_usages[j]; /// FIXME
603 			} else {
604 			  new_element->usage = current_usage_min + j;
605 			}
606 			new_element->report_index = j;
607 
608 			new_element->value = 0;
609 			new_element->array_value = 0;
610 			if ( parent_collection->num_elements == 0 ){
611 			    parent_collection->first_element = new_element;
612 			}
613 			if ( device_collection->num_elements == 0 ){
614 			    device_collection->first_element = new_element;
615 			}
616 			device_collection->num_elements++;
617 			if ( parent_collection != device_collection ) {
618 			  parent_collection->num_elements++;
619 			}
620 			if ( prev_element != NULL ){
621 			    prev_element->next = new_element;
622 			}
623 			prev_element = new_element;
624 		    }
625 		    for ( j=0; j < current_usage_index; j++ ){
626 			current_usages[j] = 0;
627 		    }
628 		    current_usage_index = 0;
629 		    current_usage_min = -1;
630 		    current_usage_max = -1;
631 		    making_element->usage_min = -1;
632 		    making_element->usage_max = -1;
633 		    making_element->usage = 0;
634 		    break;
635 #ifdef DEBUG_PARSER
636 		  default:
637 		    if ( next_byte_tag >= HID_RESERVED ){
638 		      printf("\n\treserved bytes 0x%02hhx, %i", next_byte_tag, next_val );
639 		    } else {
640 		      printf("\n\tundefined byte type 0x%02hhx, %i", next_byte_tag, next_val );
641 		    }
642 #endif
643 		}
644 	      next_byte_tag = -1;
645 	      }
646 	  } else {
647 #ifdef DEBUG_PARSER
648 	    printf("\tsetting next byte type: %i, 0x%02hhx ", descr_buf[i], descr_buf[i] );
649 #endif
650 	    if ( descr_buf[i] == HID_END_COLLECTION ){ // JUST one byte
651 // 	      prev_collection = parent_collection;
652 	      making_element->usage_page = parent_collection->usage_page;
653 	      making_element->usage = parent_collection->usage_index;
654 	      parent_collection = parent_collection->parent_collection;
655 	      for ( j=0; j < current_usage_index; j++ ){
656 		current_usages[j] = 0;
657 	      }
658 	      making_element->usage_min = -1;
659 	      making_element->usage_max = -1;
660 	      current_usage_index = 0;
661 	      current_usage_min = -1;
662 	      current_usage_max = -1;
663 	      collection_nesting--;
664 #ifdef DEBUG_PARSER
665 	      printf("\n\tend collection: %i, %i\n", collection_nesting, descr_buf[i] );
666 #endif
667 	    } else {
668 	      byte_count = 0;
669 	      next_val = 0;
670 // 	      u_next_val = 0;
671 	      next_byte_tag = descr_buf[i] & 0xFC;
672 	      next_byte_type = descr_buf[i] & 0x0C;
673 	      next_byte_size = descr_buf[i] & 0x03;
674 	      if ( next_byte_size == 3 ){
675 		  next_byte_size = 4;
676 	      }
677 #ifdef DEBUG_PARSER
678 	      printf("\t next byte type:  0x%02hhx, %i, %i ", next_byte_tag, next_byte_type, next_byte_size );
679 #endif
680 	    }
681 	  }
682   }
683 #ifdef DEBUG_PARSER
684   printf("----------- end parsing report descriptor --------------\n " );
685 #endif
686 
687   device_desc->number_of_reports = numreports;
688   device_desc->report_lengths = (int*) malloc( sizeof( int ) * numreports );
689   device_desc->report_ids = (int*) malloc( sizeof( int ) * numreports );
690   for ( j = 0; j<numreports; j++ ){
691       device_desc->report_lengths[j] = report_lengths[j];
692       device_desc->report_ids[j] = report_ids[j];
693   }
694 
695 #ifdef DEBUG_PARSER
696   printf("----------- end setting report ids --------------\n " );
697 #endif
698 
699   return 0;
700 }
701 
hid_element_set_value_from_input(struct hid_device_element * element,int value)702 void hid_element_set_value_from_input( struct hid_device_element * element, int value ){
703     element->rawvalue = value;
704     if (element->logical_min < 0){
705         // value should be interpreted as signed value
706         // so: check report size, test the highest bit, if one, invert and add one, otherwise keep value
707         int bitSignIndex = element->report_size - 1;
708         int signBit = 0x1 << bitSignIndex;
709         if (signBit & value){
710             unsigned int bitMask = BITMASK1(element->report_size);
711             unsigned int uvalue = (unsigned int)value;
712             unsigned int negvalue = ~(uvalue);
713             negvalue = ~(uvalue)& bitMask;
714             negvalue = negvalue + 1;
715             element->value = -1 * negvalue;
716         }
717         else {
718             element->value = value;
719         }
720     }
721     else {
722         // value should be interpreted as unsigned value
723         // so: keep value as is
724         if (element->isarray){ // array elements should be parsed differently
725             if (value == 0){ // previous key was pressed, so keep previous usage
726                 element->value = 0;
727                 element->array_value = 0;
728             }
729             else { // new key, so value + usage min is the current usage
730                 element->usage = element->usage_min + value;
731                 element->value = 1;
732                 element->array_value = value;
733             }
734         }
735         else {
736             element->value = value;
737         }
738     }
739 }
740 
hid_element_map_logical(struct hid_device_element * element)741 float hid_element_map_logical( struct hid_device_element * element ){
742   float result;
743   if ( element->isarray ){
744     result = (float) element->value;
745   } else {
746     result = ( (float) element->value - (float) element->logical_min)/( (float) element->logical_max - (float) element->logical_min );
747   }
748   return result;
749 }
750 
751 /** TODO: this needs a linking with the math library */
hid_element_resolution(struct hid_device_element * element)752 float hid_element_resolution( struct hid_device_element * element ){
753     float result = 0;
754 //     result = ( element->logical_max - element->logical_min) / ( ( element->phys_max - element->phys_min) * pow(10, element->unit_exponent) );
755     return result;
756 }
757 
hid_element_map_physical(struct hid_device_element * element)758 float hid_element_map_physical( struct hid_device_element * element ){
759   float result;
760   float logicalvalue = hid_element_map_logical(element);
761   result = logicalvalue * ( element->phys_max - element->phys_min ) + element->phys_min;
762   return result;
763 }
764 
765 /** is this used anywhere? */
hid_element_set_rawvalue(struct hid_device_element * element,int value)766 void hid_element_set_rawvalue( struct hid_device_element * element, int value ){
767   element->value = value;
768 }
769 
770 /** is this used anywhere? */
hid_element_set_logicalvalue(struct hid_device_element * element,float value)771 void hid_element_set_logicalvalue( struct hid_device_element * element, float value ){
772   int mapvalue;
773   mapvalue = (int) ( value * ( (float) element->logical_max - (float) element->logical_min ) ) - element->logical_min;
774   element->value = mapvalue;
775 }
776 
hid_get_next_input_element(struct hid_device_element * curel)777 struct hid_device_element * hid_get_next_input_element( struct hid_device_element * curel ){
778 
779   struct hid_device_element * nextel = curel->next;
780   while ( nextel != NULL ){
781       if ( nextel->io_type == 1 ){
782 	  return nextel;
783       } else {
784 	  nextel = nextel->next;
785       }
786   }
787   return nextel; // is NULL
788 //  return curel; // return the previous element
789   // is NULL
790 }
791 
hid_get_next_input_element_with_reportid(struct hid_device_element * curel,int reportid)792 struct hid_device_element * hid_get_next_input_element_with_reportid( struct hid_device_element * curel, int reportid ){
793 
794   struct hid_device_element * nextel = curel->next;
795   while ( nextel != NULL ){
796       if ( nextel->io_type == 1 && ( nextel->report_id == reportid ) ){
797 	  return nextel;
798       } else {
799 	  nextel = nextel->next;
800       }
801   }
802   return nextel;
803  // return curel; // return the previous element
804   // is NULL
805 }
806 
hid_get_next_output_element(struct hid_device_element * curel)807 struct hid_device_element * hid_get_next_output_element( struct hid_device_element * curel ){
808 
809   struct hid_device_element * nextel = curel->next;
810   while ( nextel != NULL ){
811       if ( nextel->io_type == 2 ){
812 	  return nextel;
813       } else {
814 	  nextel = nextel->next;
815       }
816   }
817   return nextel;
818 //  return curel; // return the previous element
819   // is NULL
820 }
821 
hid_get_next_output_element_with_reportid(struct hid_device_element * curel,int reportid)822 struct hid_device_element * hid_get_next_output_element_with_reportid( struct hid_device_element * curel, int reportid ){
823 
824   struct hid_device_element * nextel = curel->next;
825   while ( nextel != NULL ){
826       if ( nextel->io_type == 2 && ( nextel->report_id == reportid ) ){
827 	  return nextel;
828       } else {
829 	  nextel = nextel->next;
830       }
831   }
832   return NULL;
833 //   return curel; // return the previous element
834   // is NULL
835 }
836 
hid_get_next_feature_element(struct hid_device_element * curel)837 struct hid_device_element * hid_get_next_feature_element( struct hid_device_element * curel ){
838 
839   struct hid_device_element * nextel = curel->next;
840   while ( nextel != NULL ){
841       if ( nextel->io_type == 3 ){
842 	  return nextel;
843       } else {
844 	  nextel = nextel->next;
845       }
846   }
847   return nextel;
848   //return curel; // return the previous element
849   // is NULL
850 }
851 
852 struct hid_parsing_byte {
853     int nextVal;
854     int currentSize;
855     int bitIndex;
856     int remainingBits;
857     int shiftedByte;
858 };
859 
hid_parse_single_byte(unsigned char current_byte,struct hid_parsing_byte * pbyte)860 int hid_parse_single_byte( unsigned char current_byte, struct hid_parsing_byte * pbyte ){
861   int nextVal;
862   unsigned char bitMask;
863   unsigned char invBitMask;
864   unsigned char maskedByte;
865   int currentBitsize = pbyte->currentSize - pbyte->bitIndex;
866   if ( currentBitsize >= pbyte->remainingBits ){
867       // using the full byte
868       nextVal = ( current_byte << pbyte->bitIndex );
869       pbyte->bitIndex += pbyte->remainingBits;
870       pbyte->remainingBits = 0;
871   } else {
872       // use a partial byte:
873       bitMask = BITMASK1( currentBitsize );
874       nextVal = bitMask & current_byte;
875       nextVal = nextVal << pbyte->bitIndex;
876       pbyte->remainingBits -= currentBitsize;
877       // shift the remaining value
878       invBitMask = INVERTBITMASK1( bitMask );
879       maskedByte = current_byte & invBitMask;
880       pbyte->shiftedByte = maskedByte >> currentBitsize;
881       pbyte->bitIndex = pbyte->currentSize; // is this always true?
882   };
883   pbyte->nextVal += nextVal;
884   if ( (pbyte->currentSize - pbyte->bitIndex) == 0 ){
885     pbyte->bitIndex = 0;
886     nextVal = pbyte->nextVal;
887     pbyte->nextVal = 0;
888     return nextVal;
889   }
890   return -1;
891 }
892 
hid_parse_input_report(unsigned char * buf,int size,struct hid_dev_desc * devdesc)893 int hid_parse_input_report( unsigned char* buf, int size, struct hid_dev_desc * devdesc ){
894 
895 #ifdef APPLE
896   return hid_parse_input_elements_values( buf, devdesc );
897 #endif
898 #ifdef WIN32
899   return hid_parse_input_elements_values( buf, size, devdesc );
900 #endif
901 #ifdef LINUX_FREEBSD
902   struct hid_parsing_byte pbyte;
903   pbyte.nextVal = 0;
904   pbyte.currentSize = 10;
905   pbyte.bitIndex = 0;
906   pbyte.remainingBits = 0;
907   pbyte.shiftedByte = 0;
908 
909   struct hid_device_collection * device_collection = devdesc->device_collection;
910   struct hid_device_element * cur_element = device_collection->first_element;
911   int newvalue;
912   int i = 0;
913   int starti = 0;
914   int reportid = 0;
915 
916   if ( devdesc->number_of_reports > 1 ){
917       reportid = (int) buf[i];
918       starti = 1;
919   }
920 
921   if ( cur_element->io_type != 1 || ( cur_element->report_id != reportid ) ){
922       cur_element = hid_get_next_input_element_with_reportid(cur_element, reportid );
923   }
924 
925   for ( i = starti; i < size; i++){
926     unsigned char curbyte = buf[i];
927     pbyte.remainingBits = 8;
928     pbyte.shiftedByte = curbyte;
929     while( pbyte.remainingBits > 0 ) {
930       // get next element
931       pbyte.currentSize = cur_element->report_size;
932       newvalue = hid_parse_single_byte( pbyte.shiftedByte, &pbyte );
933       if ( newvalue != -1 ){
934 	if ( devdesc->_element_callback != NULL ){
935 	  if ( newvalue != cur_element->rawvalue || cur_element->repeat ){
936 	    hid_element_set_value_from_input( cur_element, newvalue );
937 	    devdesc->_element_callback( cur_element, devdesc->_element_data );
938 	  }
939 	}
940 	cur_element = hid_get_next_input_element_with_reportid( cur_element, reportid );
941       }
942     }
943   }
944   return 0;
945 #endif
946 }
947 
hid_throw_readerror(struct hid_dev_desc * devd)948 void hid_throw_readerror( struct hid_dev_desc * devd ){
949   devd->_readerror_callback( devd, devd->_readerror_data );
950 }
951 
hid_send_output_report(struct hid_dev_desc * devd,int reportid)952 int hid_send_output_report( struct hid_dev_desc * devd, int reportid ){
953   char * buf;
954   // find the right report id
955   int index = 0;
956   int i;
957   for ( i=0; i<devd->number_of_reports; i++ ){
958     if ( reportid == devd->report_ids[i] ){
959       index = i;
960       break;
961     }
962   }
963 
964   size_t buflength = devd->report_lengths[ index ] / 8;
965   #ifdef DEBUG_PARSER
966     printf("report id %i, buflength %i\t", reportid, buflength );
967 #endif
968 
969 //   if ( reportid != 0 ){
970   buflength++; // one more byte if report id is not 0
971 //   }
972   buf = (char *) malloc( sizeof( char ) * buflength );
973   memset(buf, 0x0, sizeof(char) * buflength);
974 
975 
976   // iterate over elements, find which ones are output elements with the right report id,
977   // and set their output values to the buffer
978 
979 
980   struct hid_device_collection * device_collection = devd->device_collection;
981   struct hid_device_element * cur_element = device_collection->first_element;
982   if ( cur_element->io_type != 2 || ( cur_element->report_id != reportid ) ){
983       cur_element = hid_get_next_output_element_with_reportid(cur_element, reportid);
984   }
985 
986 #ifdef DEBUG_PARSER
987   printf("-----------------------\n");
988 #endif
989 
990   buf[0] = reportid;
991   int byte_index = 1;
992   int bit_offset = 0;
993   int next_val = 0;
994 
995 
996   while ( cur_element != NULL && (byte_index < buflength) ){
997     int current_output = 0;
998     unsigned char current_byte = 0;
999     int current_bit_size = cur_element->report_size;
1000     int current_byte_size = (int) ceil( (float) current_bit_size / 8);
1001 #ifdef DEBUG_PARSER
1002     printf("report_size %i, bytesize %i, bitsize %i, bitoffset %i, byte_index %i \n", cur_element->report_size, current_byte_size, current_bit_size, bit_offset, byte_index );
1003     printf("current_output %i \t", current_output );
1004 #endif
1005     current_output = cur_element->value << bit_offset;
1006 #ifdef DEBUG_PARSER
1007     printf("current_output shift %i \t", current_output );
1008 #endif
1009     int i;
1010     for ( i=0; i<current_byte_size; i++ ){
1011 	current_byte = current_output % 256;
1012 	current_output = current_output >> 8;
1013 	buf[ byte_index + i ] += current_byte;
1014 #ifdef DEBUG_PARSER
1015     printf("current_output %i, current_byte %i, buf %i\t", current_output, current_byte, buf[ byte_index + i ] );
1016 #endif
1017     }
1018     bit_offset += current_bit_size;
1019     byte_index += (int) floor( (float) current_bit_size / 8 );
1020     bit_offset = bit_offset%8;
1021 #ifdef DEBUG_PARSER
1022     printf("bit_offset %i, byte_index %i\n", bit_offset, byte_index );
1023 #endif
1024     cur_element = hid_get_next_output_element_with_reportid(cur_element, reportid);
1025   }
1026 #ifdef DEBUG_PARSER
1027   printf("-----------------------\n");
1028 #endif
1029 
1030 
1031   int res = hid_write(devd->device, (const unsigned char*)buf, buflength);
1032 
1033   free( buf );
1034   return res;
1035 }
1036 
hid_send_output_report_old(struct hid_dev_desc * devd,int reportid)1037 int hid_send_output_report_old( struct hid_dev_desc * devd, int reportid ){
1038   char * buf;
1039   // find the right report id
1040   int index = 0;
1041   int i;
1042   for ( i=0; i<devd->number_of_reports; i++ ){
1043     if ( reportid == devd->report_ids[i] ){
1044       index = i;
1045       break;
1046     }
1047   }
1048 
1049   size_t buflength = devd->report_lengths[ index ] / 8;
1050   #ifdef DEBUG_PARSER
1051     printf("report id %i, buflength %i\t", reportid, buflength );
1052 #endif
1053 
1054   if ( reportid != 0 ){
1055       buflength++; // one more byte if report id is not 0
1056   }
1057   buf = (char *) malloc( sizeof( char ) * buflength );
1058   memset(buf, 0x0, sizeof(char) * buflength);
1059 
1060   // iterate over elements, find which ones are output elements with the right report id,
1061   // and set their output values to the buffer
1062 
1063   int next_byte_size;
1064   int next_mod_bit_size;
1065   int byte_count = 0;
1066   int next_val = 0;
1067 
1068   struct hid_device_collection * device_collection = devd->device_collection;
1069   struct hid_device_element * cur_element = device_collection->first_element;
1070   if ( cur_element->io_type != 2 || ( cur_element->report_id != reportid ) ){
1071       cur_element = hid_get_next_output_element_with_reportid(cur_element, reportid);
1072   }
1073   next_byte_size = cur_element->report_size/8;
1074 
1075 #ifdef DEBUG_PARSER
1076     printf("report_size %i, bytesize %i, bitsize %i \t", cur_element->report_size, next_byte_size, next_mod_bit_size );
1077 #endif
1078 
1079 #ifdef DEBUG_PARSER
1080   printf("-----------------------\n");
1081 #endif
1082 
1083   for ( i = 0; i < buflength; i++){
1084     unsigned char curbyte = 0;
1085     if ( cur_element->report_size == 8 ){
1086       curbyte = (unsigned char) cur_element->value;
1087 #ifdef DEBUG_PARSER
1088 	printf("element page %i, usage %i, index %i, value %i, report_size %i, curbyte %i\n", cur_element->usage_page, cur_element->usage, cur_element->index, cur_element->value, cur_element->report_size, curbyte );
1089 #endif
1090       cur_element = hid_get_next_output_element_with_reportid( cur_element, reportid );
1091       next_byte_size = cur_element->report_size/8;
1092     } else if ( cur_element->report_size == 16 ){
1093       int shift = byte_count*8;
1094       curbyte = (unsigned char) (cur_element->value >> shift);
1095       byte_count++;
1096 #ifdef DEBUG_PARSER
1097 	printf("element page %i, usage %i, index %i, value %i, report_size %i, curbyte %i\n", cur_element->usage_page, cur_element->usage, cur_element->index, cur_element->value, cur_element->report_size, curbyte );
1098 #endif
1099       if ( byte_count == next_byte_size ){
1100 	cur_element = hid_get_next_output_element_with_reportid( cur_element, reportid );
1101 	next_byte_size = cur_element->report_size/8;
1102       }
1103     } else if ( cur_element->report_size < 8 ){
1104       int bitindex = 0;
1105       char curbits = 0;
1106       // fill up the byte
1107       while( bitindex < 8 ){
1108 	curbits = cur_element->value & BITMASK1( cur_element->report_size );
1109 	curbits = curbits << bitindex;
1110 	curbyte += curbits;
1111 	bitindex += cur_element->report_size;
1112 #ifdef DEBUG_PARSER
1113 	printf("element page %i, usage %i, index %i, value %i, report_size %i, curbyte %i\n", cur_element->usage_page, cur_element->usage, cur_element->index, cur_element->value, cur_element->report_size, curbyte );
1114 #endif
1115 	cur_element = hid_get_next_output_element_with_reportid( cur_element, reportid );
1116 	next_byte_size = cur_element->report_size/8;
1117       }
1118     }
1119     buf[ i ] = curbyte;
1120   }
1121 #ifdef DEBUG_PARSER
1122   printf("-----------------------\n");
1123 #endif
1124 
1125 
1126   int res = hid_write(devd->device, (const unsigned char*)buf, buflength);
1127 
1128   free( buf );
1129   return res;
1130 }
1131 
1132 
hid_read_descriptor(hid_device * devd)1133 struct hid_dev_desc * hid_read_descriptor( hid_device * devd ){
1134   struct hid_dev_desc * desc;
1135 
1136 #ifdef APPLE
1137   desc = (struct hid_dev_desc *) malloc( sizeof( struct hid_dev_desc ) );
1138   desc->device = devd;
1139   hid_parse_element_info( desc );
1140   return desc;
1141 #endif
1142 #ifdef WIN32
1143   desc = (struct hid_dev_desc *) malloc( sizeof( struct hid_dev_desc ) );
1144   desc->device = devd;
1145   hid_parse_element_info( desc );
1146   return desc;
1147 #endif
1148 #ifdef LINUX_FREEBSD
1149   unsigned char descr_buf[HIDAPI_MAX_DESCRIPTOR_SIZE];
1150   int res;
1151   res = hid_get_report_descriptor( devd, descr_buf, HIDAPI_MAX_DESCRIPTOR_SIZE );
1152   if (res < 0){
1153     printf("Unable to read report descriptor\n");
1154     return NULL;
1155   } else {
1156     desc = (struct hid_dev_desc *) malloc( sizeof( struct hid_dev_desc ) );
1157     desc->device = devd;
1158     hid_parse_report_descriptor( descr_buf, res, desc );
1159     return desc;
1160   }
1161 #endif
1162 }
1163 
hid_open_device_path(const char * path,unsigned short vendor,unsigned short product)1164 struct hid_dev_desc * hid_open_device_path( const char *path, unsigned short vendor, unsigned short product ){
1165   hid_device * handle = hid_open_path( path );
1166   if (!handle){
1167       return NULL;
1168   }
1169   struct hid_dev_desc * newdesc = hid_read_descriptor( handle );
1170   if ( newdesc == NULL ){
1171     hid_close( handle );
1172     return NULL;
1173   }
1174   struct hid_device_info * newinfo = hid_enumerate(vendor,product);
1175   //newdesc->device = handle;
1176   int havenotfound = strcmp(path, newinfo->path) != 0;
1177   while (havenotfound && (newinfo != NULL) ){
1178     newinfo = newinfo->next;
1179     havenotfound = strcmp(path, newinfo->path) != 0;
1180   }
1181   if ( newinfo == NULL ){
1182     hid_close( handle );
1183     return NULL;
1184   }
1185 
1186   newdesc->info = newinfo;
1187 
1188   // Set the hid_read() function to be non-blocking.
1189   hid_set_nonblocking( handle, 1);
1190 
1191   return newdesc;
1192 }
1193 
1194 // this one is actually not secure when vendor and product have double entries, so you do not actually know which one you are opening
hid_open_device(unsigned short vendor,unsigned short product,const wchar_t * serial_number)1195 struct hid_dev_desc * hid_open_device(  unsigned short vendor, unsigned short product, const wchar_t *serial_number ){
1196   hid_device * handle = hid_open( vendor, product, serial_number );
1197   if (!handle){
1198       return NULL;
1199   }
1200   struct hid_dev_desc * newdesc = hid_read_descriptor( handle );
1201   if ( newdesc == NULL ){
1202     hid_close( handle );
1203     return NULL;
1204   }
1205   struct hid_device_info * newinfo = hid_enumerate(vendor,product);
1206   //newdesc->device = handle;
1207   //TODO: if serial_number is given, the info descriptor should also point to that one!
1208 //   int havenotfound = wcscmp(serial_number, newinfo->serial_number) == 0;
1209 //   while (havenotfound && (newinfo != NULL) ){
1210 //     newinfo = newinfo->next;
1211 //     havenotfound = wcscmp(serial_number, newinfo->serial_number) == 0;
1212 //   }
1213   if ( newinfo == NULL ){
1214     hid_close( handle );
1215     return NULL;
1216   }
1217 
1218   newdesc->info = newinfo;
1219 
1220   // Set the hid_read() function to be non-blocking.
1221   hid_set_nonblocking( handle, 1);
1222 
1223   return newdesc;
1224 }
1225 
hid_close_device(struct hid_dev_desc * devdesc)1226 void hid_close_device( struct hid_dev_desc * devdesc ){
1227   hid_close( devdesc->device );
1228   hid_free_enumeration( devdesc->info );
1229   hid_free_collection( devdesc->device_collection );
1230   free( devdesc->report_ids );
1231   free( devdesc->report_lengths );
1232 //   hid_free_descriptor( devdesc->descriptor );
1233   //TODO: more memory freeing?
1234 }
1235 
hid_element_set_output_value(struct hid_dev_desc * devdesc,struct hid_device_element * element,int value)1236 void hid_element_set_output_value( struct hid_dev_desc * devdesc, struct hid_device_element * element, int value ){
1237     element->value = value;
1238 #ifdef APPLE
1239     hid_send_element_output( devdesc, element );
1240 #endif
1241 #ifdef WIN32
1242     hid_send_element_output( devdesc, element );
1243 #endif
1244 #ifdef LINUX_FREEBSD
1245     hid_send_output_report( devdesc, element->report_id );
1246 #endif
1247 }
1248 
1249 
1250 #ifdef WIN32
1251 
debug_element(struct hid_device_element * element)1252 void debug_element(struct hid_device_element *element)
1253 {
1254     printf("index: %d\n", element->index);
1255     printf("parent_collection: %p\n", element->parent_collection);
1256     printf("io_type: %d\n", element->io_type);
1257     printf("usage_page: %d\n", element->usage_page);
1258     printf("usage_min: %d\n", element->usage_min);
1259     printf("usage_max: %d\n", element->usage_max);
1260     printf("usage: %d\n", element->usage);
1261     printf("type: %d\n", element->type);
1262     printf("isarray: %d\n", element->isarray);
1263     printf("isrelative: %d\n", element->isrelative);
1264     printf("isvariable: %d\n", element->isvariable);
1265     printf("logical_min: %d\n", element->logical_min);
1266     printf("logical_max: %d\n", element->logical_max);
1267     printf("phys_min: %d\n", element->phys_min);
1268     printf("phys_max: %d\n", element->phys_max);
1269     printf("unit: %d\n", element->unit);
1270     printf("unit_exponent: %d\n", element->unit_exponent);
1271     printf("report_id: %d\n", element->report_id);
1272     printf("report_size: %d\n", element->report_size);
1273     printf("report_index: %d\n", element->report_index);
1274     printf("\n\n");
1275     fflush(stdout);
1276 }
1277 
debug_collection(struct hid_device_collection * collection,int col_index)1278 void debug_collection(struct hid_device_collection *collection, int col_index)
1279 {
1280     printf("COLLECTION[%d] @%p:\n", col_index, collection);
1281     printf("index: %d\n", collection->index);
1282     printf("type: %d\n", collection->type);
1283     printf("usage_page: %d\n", collection->usage_page);
1284     printf("usage_index: %d\n", collection->usage_index);
1285     printf("parent: %p\n", collection->parent_collection);
1286     printf("children collections: %d\n", collection->num_collections);
1287     if (collection->first_collection)
1288         printf("first_collection: %p\n", collection->first_collection);
1289     if (collection->next_collection)
1290         printf("next_collection: %p\n", collection->next_collection);
1291     printf("children elements: %d\n", collection->num_elements);
1292     if (collection->first_element)
1293         printf("first_element: %p\n", collection->first_element);
1294     printf("\n\n");
1295     fflush(stdout);
1296 }
1297 
add_element_to_collection(struct hid_device_collection * collection,struct hid_device_element * element)1298 static void add_element_to_collection(struct hid_device_collection *collection, struct hid_device_element *element)
1299 {
1300     if (!collection->first_element){
1301         collection->first_element = element;
1302     }
1303     collection->num_elements++;
1304     element->parent_collection = collection;
1305 }
1306 
1307 
duplicate_element_with_new_usage(struct hid_device_element * source_element,int new_usage,struct hid_device_collection * device_collection,int * index)1308 static struct hid_device_element *duplicate_element_with_new_usage(struct hid_device_element *source_element, int new_usage, struct hid_device_collection *device_collection, int *index)
1309 {
1310     struct hid_device_element *new_element = hid_new_element();
1311     memcpy(new_element, source_element, sizeof(struct hid_device_element));
1312     new_element->index = (*index)++;
1313     device_collection->num_elements++;
1314     // Update the collection
1315     add_element_to_collection(source_element->parent_collection, new_element);
1316     new_element->usage = new_usage;
1317     return new_element;
1318 }
1319 
1320 
fill_element_from_button_caps(PHIDP_BUTTON_CAPS pCaps,struct hid_device_element * element)1321 static void fill_element_from_button_caps(PHIDP_BUTTON_CAPS pCaps, struct hid_device_element *element)
1322 {
1323     USHORT bitField = pCaps->BitField;
1324     element->usage_page = pCaps->UsagePage;
1325     element->type = bitField & 0xf;
1326     element->logical_min = 0;
1327     element->logical_max = 1;
1328     element->isarray = ((bitField & HID_ITEM_VARIABLE) == 0);
1329     element->isrelative = pCaps->IsAbsolute ? 0 : 1;
1330     element->isvariable = ((bitField & HID_ITEM_CONSTANT) == 0);
1331     element->report_id = pCaps->ReportID;
1332     element->report_size = pCaps->Range.UsageMax - pCaps->Range.UsageMin + 1;
1333     element->report_index = 1; // TODO: not sure about this one. The API does not seem to provide this. Perhaps set to 1?
1334 
1335 }
1336 
1337 
fill_element_from_value_caps(PHIDP_VALUE_CAPS pCaps,struct hid_device_element * element)1338 static void fill_element_from_value_caps(PHIDP_VALUE_CAPS pCaps, struct hid_device_element *element)
1339 {
1340     USHORT bitField = pCaps->BitField;
1341     element->usage_page = pCaps->UsagePage;
1342     element->type = bitField & 0xf;
1343     element->isarray = ((bitField & HID_ITEM_VARIABLE) == 0);
1344     element->isrelative = pCaps->IsAbsolute ? 0 : 1;
1345     element->isvariable = ((bitField & HID_ITEM_CONSTANT) == 0);
1346     element->logical_min = pCaps->LogicalMin;
1347     element->logical_max = pCaps->LogicalMax;
1348     element->phys_min = pCaps->PhysicalMin;
1349     element->phys_max = pCaps->PhysicalMax;
1350     element->unit = pCaps->Units;
1351     element->unit_exponent = pCaps->UnitsExp;
1352     element->report_id = pCaps->ReportID;
1353     element->report_size = pCaps->BitSize;
1354     element->report_index = pCaps->ReportCount;
1355 }
1356 
hid_parse_caps(struct hid_device_element ** pplast_element,struct hid_device_collection ** ppcollections,struct hid_device_collection * pdevice_collection,const PHIDP_PREPARSED_DATA pp_data,const PHIDP_CAPS caps,int report_type,BOOL is_button,int * index)1357 static int hid_parse_caps(struct hid_device_element **pplast_element, struct hid_device_collection **ppcollections, struct hid_device_collection *pdevice_collection,
1358     const PHIDP_PREPARSED_DATA pp_data, const PHIDP_CAPS caps, int report_type, BOOL is_button, int *index)
1359 {
1360     int i, j;
1361     USHORT numCaps;
1362     enum _HIDP_REPORT_TYPE api_report_type;
1363     struct hid_device_element *plast_element = *pplast_element;
1364 
1365     if (is_button){
1366         switch (report_type){
1367             case HID_REPORT_TYPE_INPUT: numCaps = caps->NumberInputButtonCaps; api_report_type = HidP_Input; break;
1368             case HID_REPORT_TYPE_OUTPUT: numCaps = caps->NumberOutputButtonCaps; api_report_type = HidP_Output; break;
1369             case HID_REPORT_TYPE_FEATURE: numCaps = caps->NumberFeatureButtonCaps; api_report_type = HidP_Feature; break;
1370         }
1371         PHIDP_BUTTON_CAPS pButtonCaps;
1372         pButtonCaps = malloc(numCaps * sizeof(HIDP_BUTTON_CAPS));
1373         if (HidP_GetButtonCaps(api_report_type, pButtonCaps, &numCaps, pp_data) != HIDP_STATUS_SUCCESS){
1374             free(pButtonCaps);
1375             return -1;
1376         }
1377         for (i = 0; i < numCaps; i++){
1378         	// Create a new element
1379             struct hid_device_element *new_element = hid_new_element();
1380             if (plast_element){
1381                 plast_element->next = new_element;
1382             }
1383             // Connect to previous element
1384             plast_element = new_element;
1385             // Add element to collections, and fill element values
1386             PHIDP_BUTTON_CAPS pCaps = &pButtonCaps[i];
1387             add_element_to_collection(pdevice_collection, new_element);
1388             add_element_to_collection(ppcollections[pCaps->LinkCollection], new_element);
1389             new_element->io_type = report_type;
1390             new_element->index = (*index)++;
1391             fill_element_from_button_caps(pCaps, new_element);
1392             if (pCaps->IsRange){
1393                 // If it is a range, we copy the element, and update the usage. We want to have an element per usage.
1394                 new_element->usage = pCaps->Range.UsageMin;
1395 #ifdef DEBUG_PARSER
1396                 debug_element(new_element);
1397 #endif
1398                 for (j = pCaps->Range.UsageMin + 1; j <= pCaps->Range.UsageMax; j++){
1399                     new_element = duplicate_element_with_new_usage(plast_element, j, pdevice_collection, index);
1400                     plast_element->next = new_element;
1401                     plast_element = new_element;
1402 #ifdef DEBUG_PARSER
1403                     debug_element(new_element);
1404 #endif
1405                 }
1406             }
1407             else{
1408                 new_element->usage = pCaps->NotRange.Usage;
1409 #ifdef DEBUG_PARSER
1410                 debug_element(new_element);
1411 #endif
1412             }
1413         }
1414         free(pButtonCaps);
1415     }
1416     else {
1417         switch (report_type){
1418             case HID_REPORT_TYPE_INPUT: numCaps = caps->NumberInputValueCaps; api_report_type = HidP_Input; break;
1419             case HID_REPORT_TYPE_OUTPUT: numCaps = caps->NumberOutputValueCaps; api_report_type = HidP_Output; break;
1420             case HID_REPORT_TYPE_FEATURE: numCaps = caps->NumberFeatureValueCaps; api_report_type = HidP_Feature; break;
1421         }
1422         PHIDP_VALUE_CAPS pValueCaps;
1423         pValueCaps = malloc(numCaps * sizeof(HIDP_VALUE_CAPS));
1424         if (HidP_GetValueCaps(api_report_type, pValueCaps, &numCaps, pp_data) != HIDP_STATUS_SUCCESS){
1425             free(pValueCaps);
1426             return -1;
1427         }
1428         for (i = 0; i < numCaps; i++){
1429         	// Create a new element
1430             struct hid_device_element *new_element = hid_new_element();
1431             if (plast_element){
1432                 plast_element->next = new_element;
1433             }
1434             // Connect to previous element
1435             plast_element = new_element;
1436             // Add element to collections, and fill element values
1437             PHIDP_VALUE_CAPS pCaps = &pValueCaps[i];
1438             add_element_to_collection(pdevice_collection, new_element);
1439             add_element_to_collection(ppcollections[pCaps->LinkCollection], new_element);
1440             new_element->io_type = report_type;
1441             new_element->index = (*index)++;
1442             fill_element_from_value_caps(pCaps, new_element);
1443 
1444             if (pCaps->IsRange){
1445                 // If it is a range, we copy the element, and update the usage. We want to have an element per usage.
1446                 new_element->usage = pCaps->Range.UsageMin;
1447                 debug_element(new_element);
1448                 for (j = pCaps->Range.UsageMin + 1; j <= pCaps->Range.UsageMax; j++){
1449                     new_element = duplicate_element_with_new_usage(plast_element, j, pdevice_collection, index);
1450                     plast_element->next = new_element;
1451                     plast_element = new_element;
1452 #ifdef DEBUG_PARSER
1453                     debug_element(new_element);
1454 #endif
1455                 }
1456             }
1457             else{
1458                 new_element->usage = pCaps->NotRange.Usage;
1459 #ifdef DEBUG_PARSER
1460                 debug_element(new_element);
1461 #endif
1462             }
1463         }
1464         free(pValueCaps);
1465     }
1466 
1467     // make sure the last element index is visible outside
1468     *pplast_element = plast_element;
1469     return 0;
1470 }
1471 
1472 
1473 
hid_send_element_output(struct hid_dev_desc * devdesc,struct hid_device_element * element)1474 int hid_send_element_output( struct hid_dev_desc * devdesc, struct hid_device_element * element ){
1475     return 0;
1476 }
hid_parse_input_elements_values(unsigned char * buf,int size,struct hid_dev_desc * devdesc)1477 int hid_parse_input_elements_values( unsigned char* buf, int size, struct hid_dev_desc * devdesc ){
1478     // If there is only one report, there will be no report ID in the report. Otherwise, it is the first byte
1479     int i;
1480     int report_id = 0;
1481     int report_length = 0;
1482     struct hid_device_collection * device_collection = devdesc->device_collection;
1483     struct hid_device_element * cur_element = device_collection->first_element;
1484     NTSTATUS res;
1485 
1486     if (devdesc->number_of_reports != 1){
1487         report_id = buf[0];
1488     }
1489 
1490     // I thtink on Windows we do not need to calculate the report size here, and we can just get it from the size parameter that we got from above
1491     for (i = 0; i < devdesc->number_of_reports; i++){
1492         if (devdesc->report_ids[i] == report_id){
1493             report_length = size;
1494         }
1495     }
1496     if (report_length == 0){
1497         // This should not happen, the report was not found
1498         return -1;
1499     }
1500 
1501     if (cur_element->io_type != HID_REPORT_TYPE_INPUT){
1502         cur_element = hid_get_next_input_element(cur_element);
1503     }
1504 
1505     // The Windows API has a function to get the data of all the buttons that are on, and another to get the value data by component page and usage
1506     // We get all the buttons that are on
1507     HANDLE dev_handle = get_device_handle(devdesc->device);
1508     PHIDP_PREPARSED_DATA pp_data;
1509     if (!HidD_GetPreparsedData(dev_handle, &pp_data)){
1510         return -1;
1511     }
1512     long usage_and_page_length = HidP_MaxUsageListLength(HidP_Input, 0, pp_data);
1513     PUSAGE_AND_PAGE usage_and_page_list = malloc(usage_and_page_length * sizeof(USAGE_AND_PAGE));
1514     memset(usage_and_page_list, 0, usage_and_page_length * sizeof(USAGE_AND_PAGE));
1515 
1516     NTSTATUS ntres = HidP_GetButtonsEx(HidP_Input, 0, usage_and_page_list, &usage_and_page_length, pp_data, buf, report_length);
1517     if ( ntres != HIDP_STATUS_SUCCESS){
1518         free(usage_and_page_list);
1519         return -1;
1520     }
1521 
1522     while (cur_element != NULL){
1523         // Check that the element is part of this report
1524         if (cur_element->report_id != report_id){
1525             cur_element = hid_get_next_input_element(cur_element);
1526             continue;
1527         }
1528 
1529         if (devdesc->_element_callback != NULL){
1530             // TODO may need to use HidP_GetUsageValueArray, if element->report_index > 1
1531             unsigned long new_value;
1532             res = HidP_GetUsageValue(HidP_Input, cur_element->usage_page, 0, cur_element->usage, &new_value, pp_data, buf, report_length);
1533             if (res == HIDP_STATUS_SUCCESS){
1534                 if (new_value != cur_element->rawvalue || cur_element->repeat){
1535 #ifdef DEBUG_PARSER
1536                     printf("element page %i, usage %i, index %i, value %i, rawvalue %i, newvalue %i\n", cur_element->usage_page, cur_element->usage, cur_element->index, cur_element->value, cur_element->rawvalue, new_value);
1537 #endif
1538                     hid_element_set_value_from_input(cur_element, new_value);
1539                     devdesc->_element_callback(cur_element, devdesc->_element_data);
1540                 }
1541             }
1542             else if (res == HIDP_STATUS_USAGE_NOT_FOUND){
1543                 // Then see if we can find the element's page and usage in the buttons that are set to on, if not, it is implicitly 0
1544                 new_value = 0;
1545                 for (i = 0; i < usage_and_page_length; i++){
1546                     USAGE usage = usage_and_page_list[i].Usage;
1547                     if (usage_and_page_list[i].UsagePage = cur_element->usage_page && usage == cur_element->usage){
1548                         new_value = 1;
1549                         break;
1550                     }
1551                 }
1552                 if (new_value != cur_element->rawvalue || cur_element->repeat){
1553                     hid_element_set_value_from_input(cur_element, new_value);
1554 #ifdef DEBUG_PARSER
1555                     printf("element page %i, usage %i, index %i, value %i, rawvalue %i, newvalue %i\n", cur_element->usage_page, cur_element->usage, cur_element->index, cur_element->value, cur_element->rawvalue, new_value);
1556 #endif
1557                     devdesc->_element_callback(cur_element, devdesc->_element_data);
1558                 }
1559             }
1560         }
1561         cur_element = hid_get_next_input_element(cur_element);
1562     }
1563     free(usage_and_page_list);
1564 
1565     return 0;
1566 }
hid_parse_element_info(struct hid_dev_desc * devdesc)1567 void hid_parse_element_info( struct hid_dev_desc * devdesc ){
1568 
1569     int i, j;
1570     hid_device * dev = devdesc->device;
1571 
1572     struct hid_device_collection * device_collection = hid_new_collection();
1573     devdesc->device_collection = device_collection;
1574 
1575     struct hid_device_collection * parent_collection = devdesc->device_collection;
1576 
1577     device_collection->num_collections = 0;
1578     device_collection->num_elements = 0;
1579 
1580     int numreports = 1;
1581     int report_lengths[256];
1582     int report_ids[256];
1583     report_ids[0] = 0;
1584     report_lengths[0] = 0;
1585 
1586     // To keep track of indices
1587     int new_index = 0;
1588 
1589     int numColls = 0;
1590 
1591     NTSTATUS nt_res;
1592     PHIDP_PREPARSED_DATA pp_data = NULL;
1593     HIDP_CAPS caps;
1594 
1595     /* Open a handle to the device */
1596     HANDLE dev_handle = get_device_handle(dev);
1597 
1598     /* Check validity of write_handle. */
1599     if (dev_handle == INVALID_HANDLE_VALUE) {
1600         /* Unable to open the device. */
1601         //register_error(dev, "CreateFile");
1602         // TODO: not sure what to do here
1603         return;
1604     }
1605 
1606     /* Get the Usage Page and Usage for this device. */
1607     BOOLEAN res = HidD_GetPreparsedData(dev_handle, &pp_data);
1608     if (!res){
1609         // TODO: what should we do here?
1610         return;
1611     }
1612 
1613     nt_res = HidP_GetCaps(pp_data, &caps);
1614     if (nt_res != HIDP_STATUS_SUCCESS) {
1615         // TODO: what should we do here
1616         return;
1617     }
1618     numColls = caps.NumberLinkCollectionNodes;
1619 
1620     device_collection->num_collections = numColls;
1621     device_collection->usage_page = caps.UsagePage;
1622     device_collection->usage_index = caps.Usage;
1623 
1624     device_collection->index = new_index++;
1625     device_collection->num_elements = 0;
1626 
1627     PHIDP_LINK_COLLECTION_NODE linkCollectionNodes;
1628     linkCollectionNodes = malloc(numColls * sizeof(HIDP_LINK_COLLECTION_NODE));
1629     struct hid_device_collection **collections = malloc(numColls * sizeof(struct hid_device_collection *));
1630     nt_res = HidP_GetLinkCollectionNodes( linkCollectionNodes, &numColls, pp_data );
1631     if (nt_res != HIDP_STATUS_SUCCESS){
1632         // TODO: what to do here?
1633         return;
1634     }
1635 
1636     // Create the N collections, and put them in an array, so that we can efficiently construct the pointers to each other using the Windows API
1637     for (i = 0; i < numColls; i++){
1638         collections[i] = hid_new_collection();
1639     }
1640 
1641     // And now fill the data and create the collection links
1642     for (i = 0; i < numColls; i++){
1643         PHIDP_LINK_COLLECTION_NODE p_collection = &linkCollectionNodes[i];
1644         // Documentation says that if parent is 0, then there is no parent, but then how do you indicate that the parent is at index 0???
1645         // I think that is wrong, and 0 indicates that the parent is the collection at index
1646         // I will assume that the collection at index 0 is always the outermost one
1647         if (i == 0){
1648             device_collection->first_collection = collections[i];
1649             collections[i]->parent_collection = device_collection;
1650         }
1651         else{
1652             collections[i]->parent_collection = collections[p_collection->Parent];
1653         }
1654         if (p_collection->NextSibling)
1655             collections[i]->next_collection = collections[p_collection->NextSibling];
1656 
1657         if (p_collection->FirstChild)
1658             collections[i]->first_collection = collections[p_collection->FirstChild];
1659 
1660         collections[i]->num_collections = p_collection->NumberOfChildren;
1661         collections[i]->type = p_collection->CollectionType;
1662         collections[i]->usage_page = p_collection->LinkUsagePage;
1663         collections[i]->usage_index = p_collection->LinkUsage;
1664         collections[i]->index = new_index++; // TODO not sure about this one
1665 #ifdef DEBUG_PARSER
1666         debug_collection(collections[i], i);
1667 #endif
1668     }
1669 #ifdef DEBUG_PARSER
1670     debug_collection(device_collection, 100);
1671 #endif
1672 
1673     /* Now, create the elements, parsing the (input, output, feature) x (button, values) capabilities */
1674     int index_element = 0;
1675     new_index = 0;
1676     struct hid_device_element *last_element = NULL;
1677     hid_parse_caps(&last_element, collections, device_collection, pp_data, &caps, HID_REPORT_TYPE_INPUT, FALSE, &new_index);
1678     hid_parse_caps(&last_element, collections, device_collection, pp_data, &caps, HID_REPORT_TYPE_INPUT, TRUE, &new_index);
1679     hid_parse_caps(&last_element, collections, device_collection, pp_data, &caps, HID_REPORT_TYPE_OUTPUT, FALSE, &new_index);
1680     hid_parse_caps(&last_element, collections, device_collection, pp_data, &caps, HID_REPORT_TYPE_OUTPUT, TRUE, &new_index);
1681     hid_parse_caps(&last_element, collections, device_collection, pp_data, &caps, HID_REPORT_TYPE_FEATURE, FALSE, &new_index);
1682     hid_parse_caps(&last_element, collections, device_collection, pp_data, &caps, HID_REPORT_TYPE_FEATURE, TRUE, &new_index);
1683 
1684     /* Reports */
1685     // Perhaps look at this (from MSDN):  The XxxReportByteLength members of a HID collection's HIDP_CAPS structure specify the required size of input, output, and feature reports
1686     // On Windows it is not clear that knowing the report size is important at this point, since we get it implicitly on the read size. It's quite likely that the calculation done here
1687     // is not right, but it does not affect (should revisit later)
1688     struct hid_device_element *element = device_collection->first_element;
1689     while (element != NULL){
1690         int report_id = element->report_id;
1691         int report_size = element->report_size;
1692         int report_count = element->report_index; // TODO: report_count is not used????
1693 
1694         int reportexists = 0;
1695         for (j = 0; j < numreports; j++){
1696             reportexists = (report_ids[j] == report_id);
1697         }
1698         if (!reportexists){
1699             report_ids[numreports] = report_id;
1700             report_lengths[numreports] = 0;
1701             numreports++;
1702         }
1703         int k = 0;
1704         int index = 0;
1705         for (k = 0; k<numreports; k++){
1706             if (report_id == report_ids[k]){
1707                 index = k;
1708                 break;
1709             }
1710         }
1711         report_lengths[index] += report_size;
1712         element = element->next;
1713     }
1714 
1715     devdesc->number_of_reports = numreports;
1716     devdesc->report_lengths = (int*)malloc(sizeof(int) * numreports);
1717     devdesc->report_ids = (int*)malloc(sizeof(int) * numreports);
1718     for (j = 0; j<numreports; j++){
1719         devdesc->report_lengths[j] = report_lengths[j];
1720         devdesc->report_ids[j] = report_ids[j];
1721     }
1722 
1723     /* And clean up the temp structures */
1724     free(collections);
1725     free(linkCollectionNodes);
1726     HidD_FreePreparsedData(pp_data);
1727 }
1728 #endif
1729 
1730 
1731 #ifdef APPLE
1732 
1733 #include <IOKit/hid/IOHIDManager.h>
1734 #include <IOKit/hid/IOHIDKeys.h>
1735 #include <CoreFoundation/CoreFoundation.h>
1736 
1737 // from: https://developer.apple.com/library/mac/documentation/devicedrivers/conceptual/HID/new_api_10_5/tn2187.html#//apple_ref/doc/uid/TP40000970-CH214-SW2
1738 
hid_send_element_output(struct hid_dev_desc * devdesc,struct hid_device_element * element)1739 int hid_send_element_output( struct hid_dev_desc * devdesc, struct hid_device_element * element ){
1740   IOReturn  tIOReturn;
1741   IOHIDDeviceRef device_handle = get_device_handle( devdesc->device );
1742   IOHIDElementRef tIOHIDElementRef = element->appleIOHIDElementRef;
1743 
1744   // get the logical mix/max for this LED element
1745   CFIndex minCFIndex = IOHIDElementGetLogicalMin( tIOHIDElementRef );
1746   CFIndex maxCFIndex = IOHIDElementGetLogicalMax( tIOHIDElementRef );
1747   // calculate the range
1748   CFIndex modCFIndex = maxCFIndex - minCFIndex + 1;
1749   // compute the value for this LED element
1750   CFIndex tCFIndex = minCFIndex + ( element->value % modCFIndex );
1751 
1752   uint64_t timestamp = 0; // create the IO HID Value to be sent
1753 
1754   IOHIDValueRef tIOHIDValueRef = IOHIDValueCreateWithIntegerValue( kCFAllocatorDefault, tIOHIDElementRef, timestamp, tCFIndex );
1755 
1756   if ( tIOHIDValueRef ) {
1757     tIOReturn = IOHIDDeviceSetValue( device_handle, tIOHIDElementRef, tIOHIDValueRef );
1758     CFRelease( tIOHIDValueRef );
1759     if ( tIOReturn == kIOReturnSuccess ){
1760       return 0;
1761     }
1762   }
1763   return -1;
1764 }
1765 
1766 // int hid_parse_input_report( unsigned char* buf, int size, struct hid_dev_desc * devdesc ){
hid_parse_input_elements_values(unsigned char * buf,struct hid_dev_desc * devdesc)1767 int hid_parse_input_elements_values( unsigned char* buf, struct hid_dev_desc * devdesc ){
1768   struct hid_device_collection * device_collection = devdesc->device_collection;
1769   struct hid_device_element * cur_element = device_collection->first_element;
1770   int i=0;
1771   int newvalue;
1772   int reportid = 0;
1773 
1774   IOHIDDeviceRef device_handle = get_device_handle( devdesc->device );
1775   IOHIDValueRef newValueRef;
1776   IOReturn  tIOReturn;
1777 
1778   /*
1779   if ( devdesc->number_of_reports > 1 ){
1780       reportid = (int) buf[i];
1781   }
1782 
1783   if ( cur_element->io_type != 1 || ( cur_element->report_id != reportid ) ){
1784       cur_element = hid_get_next_input_element_with_reportid(cur_element, reportid );
1785   }
1786   */
1787 //  printf( "======== start of report: cur_element %i\n", cur_element );
1788   if ( cur_element->io_type != 1 ){
1789         cur_element = hid_get_next_input_element(cur_element);
1790   }
1791   //printf( "cur_element %i", cur_element );
1792 
1793   while( cur_element != NULL ){
1794 	if ( devdesc->_element_callback != NULL ){
1795 	  tIOReturn = IOHIDDeviceGetValue( device_handle, cur_element->appleIOHIDElementRef, &newValueRef );
1796 	 // printf("element page %i, usage %i, index %i, value %i, rawvalue %i, newvalueref %i\n", cur_element->usage_page, cur_element->usage, cur_element->index, cur_element->value, cur_element->rawvalue, newValueRef );
1797 	  if ( tIOReturn == kIOReturnSuccess ){
1798 	    newvalue = IOHIDValueGetIntegerValue( newValueRef );
1799 	    if ( newvalue != cur_element->rawvalue || cur_element->repeat ){
1800 #ifdef DEBUG_PARSER
1801 	printf("element page %i, usage %i, index %i, value %i, rawvalue %i, newvalue %i\n", cur_element->usage_page, cur_element->usage, cur_element->index, cur_element->value, cur_element->rawvalue, newvalue );
1802 #endif
1803 	      hid_element_set_value_from_input( cur_element, newvalue );
1804 	      devdesc->_element_callback( cur_element, devdesc->_element_data );
1805 	    }
1806 	  }
1807 	}
1808 //	cur_element = hid_get_next_input_element_with_reportid( cur_element, reportid );
1809 	cur_element = hid_get_next_input_element( cur_element );
1810 //	printf( "cur_element %i\n", cur_element );
1811   }
1812 //  printf( "======== end of report\n");
1813   return 0;
1814 }
1815 
1816 /*
1817 IOReturn  tIOReturn = IOHIDDeviceGetValue(
1818                             deviceRef,  // IOHIDDeviceRef for the HID device
1819                             elementRef, // IOHIDElementRef for the HID element
1820                             valueRef);  // IOHIDValueRef for the HID element's new value
1821 */
1822 
hid_parse_element_info(struct hid_dev_desc * devdesc)1823 void hid_parse_element_info( struct hid_dev_desc * devdesc )
1824 {
1825   hid_device * dev = devdesc->device;
1826 
1827   struct hid_device_collection * device_collection = hid_new_collection();
1828   devdesc->device_collection = device_collection;
1829 
1830   struct hid_device_collection * parent_collection = devdesc->device_collection;
1831   struct hid_device_collection * prev_collection;
1832   struct hid_device_element * prev_element;
1833 
1834   device_collection->num_collections = 0;
1835   device_collection->num_elements = 0;
1836 
1837   int numreports = 1;
1838   int report_lengths[256];
1839   int report_ids[256];
1840   report_ids[0] = 0;
1841   report_lengths[0] = 0;
1842 
1843   IOHIDDeviceRef device_handle = get_device_handle( dev );
1844   CFArrayRef elementCFArrayRef = IOHIDDeviceCopyMatchingElements(device_handle,
1845       NULL /* matchingCFDictRef */
1846       ,  kIOHIDOptionsTypeNone);
1847   if (elementCFArrayRef) {
1848     // iterate over all the elements
1849     CFIndex elementIndex, elementCount = CFArrayGetCount(elementCFArrayRef);
1850     for (elementIndex = 0; elementIndex < elementCount; elementIndex++) {
1851       IOHIDElementRef tIOHIDElementRef = (IOHIDElementRef)CFArrayGetValueAtIndex(elementCFArrayRef,elementIndex);
1852       if (tIOHIDElementRef) {
1853 	  IOHIDElementType tIOHIDElementType = IOHIDElementGetType(tIOHIDElementRef);
1854 	  uint32_t usagePage = IOHIDElementGetUsagePage(tIOHIDElementRef);
1855 	  uint32_t usage     = IOHIDElementGetUsage(tIOHIDElementRef);
1856 
1857 	  if ( tIOHIDElementType == kIOHIDElementTypeCollection ){
1858 	      //TODO: COULD ALSO READ WHICH KIND OF COLLECTION
1859 	      struct hid_device_collection * new_collection = hid_new_collection();
1860 	      if ( parent_collection->num_collections == 0 ){
1861 	    	  parent_collection->first_collection = new_collection;
1862 	      }
1863 	      if ( device_collection->num_collections == 0 ){
1864 	    	  device_collection->first_collection = new_collection;
1865 	      } else {
1866 	    	  prev_collection->next_collection = new_collection;
1867 	      }
1868 	      new_collection->parent_collection = parent_collection;
1869 	      IOHIDElementCollectionType tIOHIDElementCollectionType = IOHIDElementGetCollectionType(tIOHIDElementRef);
1870 	      new_collection->type = (int) tIOHIDElementCollectionType;
1871 	      new_collection->usage_page = usagePage;
1872 	      new_collection->usage_index = usage;
1873 	      new_collection->index = device_collection->num_collections;
1874 	      device_collection->num_collections++;
1875 	      if ( device_collection != parent_collection ){
1876 	    	  parent_collection->num_collections++;
1877 	      }
1878 	      parent_collection = new_collection;
1879 	      prev_collection = new_collection;
1880 //  	      collection_nesting++;
1881 	  } else {
1882 	      struct hid_device_element * new_element = hid_new_element();
1883 	      new_element->appleIOHIDElementRef = tIOHIDElementRef; // set the element ref
1884 	      new_element->index = device_collection->num_elements;
1885 	      // check input (1), output (2), or feature (3)
1886 	      // type - this we parse later on again, so perhaps would be good to bittest this rightaway in general
1887 // 		["Data","Constant"],
1888           Boolean isVirtual = IOHIDElementIsVirtual(tIOHIDElementRef);
1889 //                 ["Array","Variable"]
1890           Boolean isArray = IOHIDElementIsArray(tIOHIDElementRef);
1891 //                 ["Absolute","Relative"]
1892           Boolean isRelative = IOHIDElementIsRelative(tIOHIDElementRef);
1893 //                 ["NoWrap","Wrap"],
1894           Boolean isWrapping = IOHIDElementIsWrapping(tIOHIDElementRef);
1895 //                 ["Linear","NonLinear"],
1896           Boolean isNonLinear = IOHIDElementIsNonLinear(tIOHIDElementRef);
1897 //                 ["PreferredState","NoPreferred"],
1898           Boolean hasPreferredState = IOHIDElementHasPreferredState(tIOHIDElementRef);
1899 //                 ["NoNullPosition", "NullState"],
1900           Boolean hasNullState = IOHIDElementHasNullState(tIOHIDElementRef);
1901 	      int type = 0;
1902 	      new_element->type = 0;
1903 	      type = (int) isVirtual;
1904 	      new_element->isvariable = (int) !isVirtual;
1905 	      new_element->type += type;
1906 	      new_element->isarray = (int) isArray;
1907 	      type = ((int) !isArray) << 1;
1908 	      new_element->type += type;
1909 	      new_element->isrelative = (int) isRelative;
1910 	      type = ((int) isRelative) << 2;
1911 	      new_element->type += type;
1912 	      type = ((int) isWrapping) << 3;
1913 	      new_element->type += type;
1914 	      type = ((int) isNonLinear) << 4;
1915 	      new_element->type += type;
1916 	      type = ((int) !hasPreferredState) << 5;
1917 	      new_element->type += type;
1918 	      type = ((int) hasNullState) << 6;
1919 	      new_element->type += type;
1920 	      switch (tIOHIDElementType) {
1921 		case kIOHIDElementTypeInput_Misc:
1922 		{
1923 		  new_element->io_type = 1;
1924 // 		  printf("type: Misc, ");
1925 		  break;
1926 		}
1927 		case kIOHIDElementTypeInput_Button:
1928 		{
1929 		  new_element->io_type = 1;
1930 // 		  printf("type: Button, ");
1931 		  break;
1932 		}
1933 		case kIOHIDElementTypeInput_Axis:
1934 		{
1935 		  new_element->io_type = 1;
1936 // 		  printf("type: Axis, ");
1937 		  break;
1938 		}
1939 		case kIOHIDElementTypeInput_ScanCodes:
1940 		{
1941 		  new_element->io_type = 1;
1942 // 		  printf("type: ScanCodes, ");
1943 		  break;
1944 		}
1945 		case kIOHIDElementTypeOutput:
1946 		{
1947 		  new_element->io_type = 2;
1948 // 		  printf("type: Output, ");
1949 		  break;
1950 		}
1951 		case kIOHIDElementTypeFeature:
1952 		{
1953 		  new_element->io_type = 3;
1954 // 		  printf("type: Feature, ");
1955 		  break;
1956 		}
1957 	      }
1958 	      new_element->parent_collection = parent_collection;
1959 	      new_element->usage_page = usagePage;
1960 	      new_element->usage = usage;
1961 	      CFIndex logicalMin = IOHIDElementGetLogicalMin(tIOHIDElementRef);
1962 	      CFIndex logicalMax = IOHIDElementGetLogicalMax(tIOHIDElementRef);
1963 	      new_element->logical_min = logicalMin;
1964 	      new_element->logical_max = logicalMax;
1965 	      CFIndex physicalMin = IOHIDElementGetPhysicalMin(tIOHIDElementRef);
1966 	      CFIndex physicalMax = IOHIDElementGetPhysicalMax(tIOHIDElementRef);
1967 	      new_element->phys_min = physicalMin;
1968 	      new_element->phys_max = physicalMax;
1969 	      uint32_t unit    = IOHIDElementGetUnit(tIOHIDElementRef);
1970 	      uint32_t unitExp = IOHIDElementGetUnitExponent(tIOHIDElementRef);
1971 	      new_element->unit = unit;
1972 	      new_element->unit_exponent = unitExp;
1973 	      uint32_t reportID    = IOHIDElementGetReportID(tIOHIDElementRef);
1974 	      uint32_t reportSize  = IOHIDElementGetReportSize(tIOHIDElementRef);
1975 	      uint32_t reportCount = IOHIDElementGetReportCount(tIOHIDElementRef);
1976 	      new_element->report_size = reportSize;
1977 	      new_element->report_id = reportID;
1978 	      new_element->report_index = reportCount; // ?? - was j... index
1979 	      new_element->value = 0;
1980 	      new_element->array_value = 0;
1981 
1982 	      int reportexists = 0;
1983 	      for ( int j = 0; j < numreports; j++ ){
1984 	    	  reportexists = (report_ids[j] == reportID);
1985 	      }
1986 	      if ( !reportexists ){
1987 	      	report_ids[ numreports ] = reportID;
1988 	      	report_lengths[ numreports ] = 0;
1989 	      	numreports++;
1990 	      }
1991 	      int k = 0;
1992 	      int index = 0;
1993 	      for ( k=0; k<numreports; k++ ){
1994 	      	if ( reportID == report_ids[k] ){
1995 	      		index = k;
1996 	      		break;
1997 	      	}
1998 	      }
1999 	      report_lengths[index] += reportSize;
2000 
2001 	      if ( parent_collection->num_elements == 0 ){
2002 	    	  parent_collection->first_element = new_element;
2003 	      }
2004 	      if ( device_collection->num_elements == 0 ){
2005 	    	  device_collection->first_element = new_element;
2006 	      } else {
2007 	    	  prev_element->next = new_element;
2008 	      }
2009 	      device_collection->num_elements++;
2010 	      if ( parent_collection != device_collection ) {
2011 	    	  parent_collection->num_elements++;
2012 	      }
2013 	      prev_element = new_element;
2014 	  }
2015 	}
2016     }
2017     CFRelease(elementCFArrayRef);
2018   }
2019   devdesc->number_of_reports = numreports;
2020   devdesc->report_lengths = (int*) malloc( sizeof( int ) * numreports );
2021   devdesc->report_ids = (int*) malloc( sizeof( int ) * numreports );
2022   for ( int j = 0; j<numreports; j++ ){
2023 	  devdesc->report_lengths[j] = report_lengths[j];
2024 	  devdesc->report_ids[j] = report_ids[j];
2025   }
2026   //return 0;
2027 }
2028 
2029 #endif
2030