-
Notifications
You must be signed in to change notification settings - Fork 15
/
blink1-lib-lowlevel-hiddata.h
221 lines (190 loc) · 5.86 KB
/
blink1-lib-lowlevel-hiddata.h
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
#include "hiddata.h"
static blink1_device* static_dev;
//
char *blink1_error_msg(int errCode)
{
static char buffer[80];
switch(errCode){
case USBOPEN_ERR_ACCESS: return "Access to device denied";
case USBOPEN_ERR_NOTFOUND: return "The specified device was not found";
case USBOPEN_ERR_IO: return "Communication error with device";
default:
snprintf(buffer, sizeof(buffer), "Unknown USB error %d", errCode);
return buffer;
}
return NULL; /* not reached */
}
//
int blink1_enumerate(void)
{
LOG("blink1_enumerate!\n");
return blink1_enumerateByVidPid( blink1_vid(), blink1_pid() );
}
// get all matching devices by VID/PID pair
int blink1_enumerateByVidPid(int vid, int pid)
{
int p = 0;
if( blink1_open() ) {
blink1_close(static_dev);
p = 1;
}
/*
struct hid_device_info *devs, *cur_dev;
devs = hid_enumerate(vid, pid);
cur_dev = devs;
while (cur_dev) {
if( (cur_dev->vendor_id != 0 && cur_dev->product_id != 0) &&
(cur_dev->vendor_id == vid && cur_dev->product_id == pid) ) {
if( cur_dev->serial_number != NULL ) { // can happen if not root
strncpy( blink1_infos[p].path, cur_dev->path,
sizeof(blink1_infos[p].path));
snprintf(blink1_infos[p].serial, sizeof(blink1_infos[p].serial),
"%ls", cur_dev->serial_number);
//wcscpy( blink1_infos[p].serial, cur_dev->serial_number );
//uint32_t sn = wcstol( cur_dev->serial_number, NULL, 16);
uint32_t serialnum = strtol( blink1_infos[p].serial, NULL, 16);
blink1_infos[p].type = BLINK1_MK1;
if( serialnum >= blink1mk2_serialstart ) {
blink1_infos[p].type = BLINK1_MK2;
}
p++;
}
}
cur_dev = cur_dev->next;
}
hid_free_enumeration(devs);
*/
blink1_cached_count = p;
blink1_sortCache();
return p;
}
//
blink1_device* blink1_openByPath(const char* path)
{
//if( path == NULL || strlen(path) == 0 ) {
// LOG("openByPath: empty path");
// return NULL;
//}
LOG("blink1_openByPath %s\n", path);
/*
blink1_device* handle = hid_open_path( path );
int i = blink1_getCacheIndexByPath( path );
if( i >= 0 ) { // good
blink1_infos[i].dev = handle;
}
else { // uh oh, not in cache, now what?
}
return handle;
*/
return blink1_open();
}
//
blink1_device* blink1_openBySerial(const char* serial)
{
if( serial == NULL || strlen(serial) == 0 ) {
LOG("openByPath: empty path");
return NULL;
}
int vid = blink1_vid();
int pid = blink1_pid();
LOG("blink1_openBySerial %s at vid/pid %x/%x\n", serial, vid,pid);
/*
wchar_t wserialstr[serialstrmax] = {L'\0'};
#ifdef _WIN32 // omg windows you suck
swprintf( wserialstr, serialstrmax, L"%S", serial); // convert to wchar_t*
#else
swprintf( wserialstr, serialstrmax, L"%s", serial); // convert to wchar_t*
#endif
LOG("serialstr: '%ls' \n", wserialstr );
blink1_device* handle = hid_open(vid,pid, wserialstr );
if( handle ) LOG("got a blink1_device handle\n");
int i = blink1_getCacheIndexBySerial( serial );
if( i >= 0 ) {
LOG("good, serial was in cache\n");
blink1_infos[i].dev = handle;
}
else { // uh oh, not in cache, now what?
LOG("uh oh, serial was not in cache\n");
}
return handle;
*/
return blink1_open();
}
//
blink1_device* blink1_openById( uint32_t i )
{
if( i > blink1_max_devices ) { // then i is a serial number not array index
char serialstr[serialstrmax];
snprintf(serialstr, sizeof(serialstr), "%X", i); // convert to wchar_t*
return blink1_openBySerial( serialstr );
}
else {
return blink1_openByPath( blink1_getCachedPath(i) );
}
}
//
blink1_device* blink1_open(void)
{
int rc = usbhidOpenDevice( &static_dev,
blink1_vid(), NULL,
blink1_pid(), NULL,
1); // NOTE: '0' means "not using report IDs"
LOG("blink1_open\n");
if( rc != USBOPEN_SUCCESS ) {
LOG("cannot open: \n");
static_dev = NULL;
}
return static_dev;
}
//
void blink1_close_internal( blink1_device* dev )
{
if( dev != NULL ) {
blink1_clearCacheDev(dev); // FIXME: hmmm
usbhidCloseDevice(dev);
}
//hid_exit();// FIXME: this cleans up libusb in a way that hid_close doesn't
}
//
int blink1_write( blink1_device* dev, void* buf, int len)
{
int rc;
if( dev==NULL ) {
return -1; // BLINK1_ERR_NOTOPEN;
}
if( (rc = usbhidSetReport(dev, buf, len) != 0) ){
LOG( "blink1_write error: %s\n", blink1_error_msg(rc));
}
return rc;
}
// len should contain length of buf
// after call, len will contain actual len of buf read
int blink1_read( blink1_device* dev, void* buf, int len)
{
if( dev==NULL ) {
return -1; // BLINK1_ERR_NOTOPEN;
}
uint8_t reportid = ((uint8_t*)buf)[0];
int rc = blink1_write( dev, buf, len); // FIXME: check rc
if((rc = usbhidGetReport(dev, reportid, (char*)buf, &len)) != 0) {
LOG("error reading data: %s\n", blink1_error_msg(rc));
}
return rc;
}
// FIXME: Does not work at all times
// for mk1 devices only
int blink1_readRGB_mk1(blink1_device *dev, uint16_t* fadeMillis,
uint8_t* r, uint8_t* g, uint8_t* b)
{
uint8_t buf[blink1_buf_size] = { blink1_report_id };
int rc;
int len = sizeof(buf);
blink1_sleep( 50 ); // FIXME:
if((rc = usbhidGetReport(dev, 1, (char*)buf, &len)) != 0) {
LOG("error reading data: %s\n", blink1_error_msg(rc));
}
*r = buf[2];
*g = buf[3];
*b = buf[4];
return rc;
}