File: hidparsertest.c

package info (click to toggle)
supercollider 1%3A3.13.0%2Brepack-3.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 80,304 kB
  • sloc: cpp: 476,363; lisp: 84,680; ansic: 77,685; sh: 25,509; python: 7,909; makefile: 3,440; perl: 1,964; javascript: 974; xml: 826; java: 677; yacc: 314; lex: 175; objc: 152; ruby: 136
file content (282 lines) | stat: -rw-r--r-- 8,711 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
/* hidapi_parser $ 
 *
 * Copyright (C) 2013, Marije Baalman <nescivi _at_ gmail.com>
 * This work was funded by a crowd-funding initiative for SuperCollider's [1] HID implementation
 * including a substantial donation from BEK, Bergen Center for Electronic Arts, Norway
 * 
 * [1] http://supercollider.sourceforge.net
 * [2] http://www.bek.no
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>
#include <string.h>
// #include <conio.h>

#include <hidapi.h>
#include "hidapi_parser.h"


// Headers needed for sleeping.
#ifdef _WIN32
	#include <windows.h>
#else
	#include <unistd.h>
#endif

void list_devices( void ){
	struct hid_device_info *devs, *cur_dev;
	devs = hid_enumerate(0x0, 0x0);
	cur_dev = devs;	
	while (cur_dev) {
		printf("Device Found\n  type: 0x%04hx 0x%04hx\n  path: %s\n  serial_number: %ls", cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number);
		printf("\n");
		printf("  Manufacturer: %ls\n", cur_dev->manufacturer_string);
		printf("  Product:      %ls\n", cur_dev->product_string);
		printf("  Release:      %hx\n", cur_dev->release_number);
		printf("  Interface:    %d\n",  cur_dev->interface_number);
		printf("\n");
		cur_dev = cur_dev->next;
	}
	hid_free_enumeration(devs);
}

// static hid_device * open_device( char vendor_id, char product_id ){
// 	handle = 
// 	return handle;
// }

#define MAX_STR 255

void print_element_info( struct hid_device_element *element ){
  
  printf( "index: %i, usage_page: %i, usage: %i, iotype: %i, type: %i, \n \
	  \tusage_min: %i, usage_max: %i, \n \
	  \tlogical_min: %i, logical_max: %i, \n \
	  \tphys_min: %i, phys_max: %i, unit_exponent: %i, unit: %i, \n \
	  \treport_size: %i, report_id: %i, report_index: %i \n",
	  element->index, element->usage_page, element->usage, element->io_type, element->type,
	  element->usage_min, element->usage_max,
	  element->logical_min, element->logical_max,
	  element->phys_min, element->phys_max, 
	  element->unit_exponent, element->unit,
	  element->report_size, element->report_id, element->report_index );
}

void print_collection_info( struct hid_device_collection *collection ){
  int i;
  printf( "COLLECTION index: %i, usage_page: %i, usage: %i, num_elements: %i, num_collections: %i \n",
	  collection->index, collection->usage_page, collection->usage_index, 
	  collection->num_elements, collection->num_collections );
 
  struct hid_device_collection * cur_collection = collection->first_collection;
  
  printf( "number of collections in collection: %i\n", collection->num_collections );
  for ( i=0; i<collection->num_collections; i++ ){
    if ( cur_collection != NULL ){
      printf("cur_collection %i\n", cur_collection );
      print_collection_info( cur_collection );
      cur_collection = cur_collection->next_collection;
    }
  }

  
  struct hid_device_element * cur_element = collection->first_element;
  
  printf( "number of elements in collection: %i\n", collection->num_elements );
  for ( i=0; i<collection->num_elements; i++ ){
    if ( cur_element != NULL ){
      printf("cur_element %i\n", cur_element );
      print_element_info( cur_element );
      cur_element = cur_element->next;
    }
  }
}

void print_device_info( hid_device *handle ){
  wchar_t wstr[MAX_STR];  
  int res;
  	// Read the Manufacturer String
	wstr[0] = 0x0000;
	res = hid_get_manufacturer_string(handle, wstr, MAX_STR);
	if (res < 0)
		printf("Unable to read manufacturer string\n");
	printf("Manufacturer String: %ls\n", wstr);

	// Read the Product String
	wstr[0] = 0x0000;
	res = hid_get_product_string(handle, wstr, MAX_STR);
	if (res < 0)
		printf("Unable to read product string\n");
	printf("Product String: %ls\n", wstr);

	// Read the Serial Number String
	wstr[0] = 0x0000;
	res = hid_get_serial_number_string(handle, wstr, MAX_STR);
	if (res < 0)
		printf("Unable to read serial number string\n");
	printf("Serial Number String: (%d) %ls", wstr[0], wstr);
	printf("\n");

	// Read Indexed String 1
	wstr[0] = 0x0000;
	res = hid_get_indexed_string(handle, 1, wstr, MAX_STR);
	if (res < 0)
		printf("Unable to read indexed string 1\n");
	printf("Indexed String 1: %ls\n", wstr);
}

static void my_element_cb(const struct hid_device_element *el, void *data)
{
    printf("in %s\t", __func__);
    printf("element: usage %i, value %i, index %i\t", el->usage, el->value, el->index );
    printf("user_data: %s\n", (const char *)data);
}

static void my_descriptor_cb(const struct hid_dev_desc *dd, void *data)
{
    printf("in %s\t", __func__);
//     printf("element: usage %i, value %i, index %i\n", el->usage, el->value, el->index );
    printf("user_data: %s\n", (const char *)data);
}

int main(int argc, char* argv[]){

  int res;
  unsigned char buf[256];
  unsigned char descr_buf[HIDAPI_MAX_DESCRIPTOR_SIZE];
    
  struct hid_dev_desc *devdesc;
//   struct hid_device_descriptor *descriptor;
//   hid_device *handle;
  
#ifdef WIN32
	UNREFERENCED_PARAMETER(argc);
	UNREFERENCED_PARAMETER(argv);
#endif

  if (hid_init())
    return -1;
  list_devices();
  
  int vendor_id;
  int product_id;
  
  if (argc == 3 ){          
    vendor_id = atoi( argv[1] );
    product_id = atoi( argv[2] );
  } else {
    printf( "please run again with vendor and product id to open specified device, e.g. hidparsertest 0x044f 0xd003\n" );
      return 0;
  }
  printf( "vendor %i, product %i", vendor_id, product_id );
  

  devdesc = hid_open_device( vendor_id, product_id, NULL );
  if (!devdesc){
    fprintf(stderr, "Unable to open device %d, %d\n", vendor_id, product_id );
    return 1;
  }
//   handle = hid_open( 0x044f, 0xd003, NULL);
//   if (!handle) {
// 	printf("unable to open device\n");
//  	return 1;
//   }
//   print_device_info( handle );
  
  print_device_info( devdesc->device );
    
//   descriptor = hid_read_descriptor( handle );
//   if ( descriptor == NULL ){
//     printf("unable to read descriptor\n");
//     return 1;
//   }

//   res = hid_get_report_descriptor( handle, descr_buf, HIDAPI_MAX_DESCRIPTOR_SIZE );
//   if (res < 0){
//     printf("Unable to read report descriptor\n");
//     return 1;
//   } else {
//     descriptor = (hid_device_descriptor *) malloc( sizeof( hid_device_descriptor) );
//     hid_descriptor_init( descriptor );
//     hid_parse_report_descriptor( descr_buf, res, descriptor );
// 
//   }

  // Set the hid_read() function to be non-blocking.
//   hid_set_nonblocking(handle, 1);

  print_collection_info( devdesc->device_collection );
  
//   printf("press key to continue\n" );
//   getchar();

  struct hid_device_element * cur_element = devdesc->device_collection->first_element;
  
  printf( "number of elements in device: %i\n", devdesc->device_collection->num_elements );
  while (cur_element != NULL ) {
    printf("cur_element %i\n", cur_element );
    print_element_info( cur_element );
//     printf("press key to continue\n" );
//     getchar();
    cur_element = cur_element->next;
  }
  
//   printf("press key to continue\n" );
//   getchar();

  char my_custom_data[40] = "Hello!";
  hid_set_descriptor_callback( devdesc, (hid_descriptor_callback) my_descriptor_cb, my_custom_data );
  hid_set_element_callback( devdesc, (hid_element_callback) my_element_cb, my_custom_data );  
  
//   Request state (cmd 0x81). The first byte is the report number (0x1).
//   buf[0] = 0x1;
//   buf[1] = 0x81;
//   hid_write(handle, buf, 17);
//   if (res < 0)
// 	  printf("Unable to write() (2)\n");

 	// Read requested state. hid_read() has been set to be
	// non-blocking by the call to hid_set_nonblocking() above.
	// This loop demonstrates the non-blocking nature of hid_read().
	res = 0;
	while (1) {
		res = hid_read(devdesc->device, buf, sizeof(buf));
		if ( res > 0 ) {
		  hid_parse_input_report( buf, res, devdesc );
		}
		#ifdef WIN32
		Sleep(500);
		#else
		usleep(500*100);
		#endif
	}

	hid_close_device( devdesc );
// 	hid_close(handle);

	/* Free static HIDAPI objects. */
	hid_exit();

#ifdef WIN32
	system("pause");
#endif

	return 0;
 
}