39
39
#define M210_DEV_MAX_TIMEOUT_RETRIES 5
42
int fds[M210_DEV_USB_INTERFACE_COUNT];
42
int fds[M210_DEV_USB_INTERFACE_COUNT];
45
45
struct m210_dev_packet {
47
uint8_t data[M210_DEV_PACKET_SIZE];
47
uint8_t data[M210_DEV_PACKET_SIZE];
48
48
} __attribute__((packed));
50
50
static struct hidraw_devinfo const DEVINFO_M210 = {
57
m210_dev_write(struct m210_dev const *const dev_ptr,
58
uint8_t const *const bytes,
59
size_t const bytes_size)
61
enum m210_err err = M210_ERR_OK;
62
size_t const request_size = bytes_size + 3;
63
uint8_t *request = malloc(request_size);
65
if (request == NULL) {
70
request[0] = 0x00; /* Without this, response is not sent. Why?? */
71
request[1] = 0x02; /* report id */
72
request[2] = bytes_size;
74
/* Copy report paylod to the end of the request. */
75
memcpy(request + 3, bytes, bytes_size);
77
/* Send request to the interface 0. */
78
if (write(dev_ptr->fds[0], request, request_size) == -1) {
89
m210_dev_read(struct m210_dev const *const dev_ptr,
92
size_t const response_size)
94
enum m210_err err = M210_ERR_OK;
96
int const fd = dev_ptr->fds[interface];
97
static struct timeval select_interval;
99
memset(&select_interval, 0, sizeof(struct timeval));
101
FD_SET(fd, &readfds);
103
select_interval.tv_usec = M210_DEV_READ_INTERVAL;
105
switch (select(fd + 1, &readfds, NULL, NULL, &select_interval)) {
107
err = M210_ERR_DEV_TIMEOUT;
116
if (read(fd, response, response_size) == -1) {
126
m210_dev_find_hidraw_devnode(int const iface,
127
char *const path_ptr,
128
size_t const path_size)
130
enum m210_err err = M210_ERR_OK;
131
struct udev_list_entry *list_entry = NULL;
132
struct udev_enumerate *enumerate = NULL;
133
struct udev *udev = NULL;
141
enumerate = udev_enumerate_new(udev);
142
if (enumerate == NULL) {
147
if (udev_enumerate_add_match_subsystem(enumerate, "hidraw")) {
152
if (udev_enumerate_scan_devices(enumerate)) {
157
list_entry = udev_enumerate_get_list_entry(enumerate);
159
while (list_entry != NULL) {
164
struct udev_device *device;
166
struct udev_device *parent;
168
syspath = udev_list_entry_get_name(list_entry);
169
device = udev_device_new_from_syspath(udev, syspath);
170
devnode = udev_device_get_devnode(device);
172
/* Second parent: usb */
173
parent = udev_device_get_parent(device);
174
parent = udev_device_get_parent(parent);
176
ifn = atoi(udev_device_get_sysattr_value(parent,
177
"bInterfaceNumber"));
178
parent = udev_device_get_parent(parent);
179
vendor = strtol(udev_device_get_sysattr_value(parent,
182
product = strtol(udev_device_get_sysattr_value(parent,
185
if (vendor == DEVINFO_M210.vendor
186
&& product == DEVINFO_M210.product
188
strncpy(path_ptr, devnode, path_size);
189
udev_device_unref(device);
192
list_entry = udev_list_entry_get_next(list_entry);
193
udev_device_unref(device);
195
err = M210_ERR_NO_DEV;
198
udev_enumerate_unref(enumerate);
209
m210_dev_accept_download(struct m210_dev const *const dev_ptr)
211
uint8_t const bytes[] = {0xb6};
212
return m210_dev_write(dev_ptr, bytes, sizeof(bytes));
216
m210_dev_reject_download(struct m210_dev const *const dev_ptr)
218
uint8_t const bytes[] = {0xb7};
219
return m210_dev_write(dev_ptr, bytes, sizeof(bytes));
223
m210_dev_connect_hidraw(struct m210_dev *const dev_ptr,
224
char *const *const hidraw_path_ptrs)
226
enum m210_err err = M210_ERR_OK;
227
int fds[M210_DEV_USB_INTERFACE_COUNT];
229
for (size_t i = 0; i < M210_DEV_USB_INTERFACE_COUNT; ++i) {
230
struct hidraw_devinfo devinfo;
231
int fd = open(hidraw_path_ptrs[i], O_RDWR);
237
if (ioctl(fd, HIDIOCGRAWINFO, &devinfo)) {
242
if (memcmp(&devinfo, &DEVINFO_M210,
243
sizeof(struct hidraw_devinfo)) != 0) {
244
err = M210_ERR_BAD_DEV;
253
memcpy(dev_ptr->fds, fds, sizeof(fds));
56
static enum m210_err m210_dev_write(struct m210_dev const *const dev_ptr,
57
uint8_t const *const bytes,
58
size_t const bytes_size)
60
enum m210_err err = M210_ERR_OK;
61
size_t const request_size = bytes_size + 3;
62
uint8_t *request = malloc(request_size);
64
if (request == NULL) {
69
request[0] = 0x00; /* Without this, response is not sent. Why?? */
70
request[1] = 0x02; /* report id */
71
request[2] = bytes_size;
73
/* Copy report paylod to the end of the request. */
74
memcpy(request + 3, bytes, bytes_size);
76
/* Send request to the interface 0. */
77
if (write(dev_ptr->fds[0], request, request_size) == -1) {
87
static enum m210_err m210_dev_read(struct m210_dev const *const dev_ptr,
90
size_t const response_size)
92
enum m210_err err = M210_ERR_OK;
94
int const fd = dev_ptr->fds[interface];
95
static struct timeval select_interval;
97
memset(&select_interval, 0, sizeof(struct timeval));
101
select_interval.tv_usec = M210_DEV_READ_INTERVAL;
103
switch (select(fd + 1, &readfds, NULL, NULL, &select_interval)) {
105
err = M210_ERR_DEV_TIMEOUT;
114
if (read(fd, response, response_size) == -1) {
123
static enum m210_err m210_dev_find_hidraw_devnode(int const iface,
124
char *const path_ptr,
125
size_t const path_size)
127
enum m210_err err = M210_ERR_OK;
128
struct udev_list_entry *list_entry = NULL;
129
struct udev_enumerate *enumerate = NULL;
130
struct udev *udev = NULL;
138
enumerate = udev_enumerate_new(udev);
139
if (enumerate == NULL) {
144
if (udev_enumerate_add_match_subsystem(enumerate, "hidraw")) {
149
if (udev_enumerate_scan_devices(enumerate)) {
154
list_entry = udev_enumerate_get_list_entry(enumerate);
156
while (list_entry != NULL) {
161
struct udev_device *device;
163
struct udev_device *parent;
165
syspath = udev_list_entry_get_name(list_entry);
166
device = udev_device_new_from_syspath(udev, syspath);
167
devnode = udev_device_get_devnode(device);
169
/* Second parent: usb */
170
parent = udev_device_get_parent(device);
171
parent = udev_device_get_parent(parent);
173
ifn = atoi(udev_device_get_sysattr_value(parent,
174
"bInterfaceNumber"));
175
parent = udev_device_get_parent(parent);
176
vendor = strtol(udev_device_get_sysattr_value(parent,
179
product = strtol(udev_device_get_sysattr_value(parent,
182
if (vendor == DEVINFO_M210.vendor
183
&& product == DEVINFO_M210.product
185
strncpy(path_ptr, devnode, path_size);
186
udev_device_unref(device);
189
list_entry = udev_list_entry_get_next(list_entry);
190
udev_device_unref(device);
192
err = M210_ERR_NO_DEV;
195
udev_enumerate_unref(enumerate);
205
static enum m210_err m210_dev_accept_download(struct m210_dev const *const dev_ptr)
207
uint8_t const bytes[] = {0xb6};
208
return m210_dev_write(dev_ptr, bytes, sizeof(bytes));
211
static enum m210_err m210_dev_reject_download(struct m210_dev const *const dev_ptr)
213
uint8_t const bytes[] = {0xb7};
214
return m210_dev_write(dev_ptr, bytes, sizeof(bytes));
217
static enum m210_err m210_dev_connect_hidraw(struct m210_dev *const dev_ptr,
218
char *const *const hidraw_path_ptrs)
220
enum m210_err err = M210_ERR_OK;
221
int fds[M210_DEV_USB_INTERFACE_COUNT];
223
for (size_t i = 0; i < M210_DEV_USB_INTERFACE_COUNT; ++i) {
224
struct hidraw_devinfo devinfo;
225
int fd = open(hidraw_path_ptrs[i], O_RDWR);
231
if (ioctl(fd, HIDIOCGRAWINFO, &devinfo)) {
236
if (memcmp(&devinfo, &DEVINFO_M210,
237
sizeof(struct hidraw_devinfo)) != 0) {
238
err = M210_ERR_BAD_DEV;
247
memcpy(dev_ptr->fds, fds, sizeof(fds));
261
255
1: Request just packet count.
264
258
=============================
265
259
GET_PACKET_COUNT >
269
263
2: Download packets.
272
266
==============================
273
267
GET_PACKET_COUNT >
290
m210_dev_begin_download(struct m210_dev const *const dev_ptr,
291
uint16_t *const packet_count_ptr)
293
static uint8_t const bytes[] = {0xb5};
294
uint8_t response[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
295
enum m210_err err = M210_ERR_OK;
296
int timeout_retries = 0;
298
while (timeout_retries < M210_DEV_MAX_TIMEOUT_RETRIES) {
299
err = m210_dev_write(dev_ptr, bytes, sizeof(bytes));
305
err = m210_dev_read(dev_ptr, 0, response, sizeof(response));
307
if (err == M210_ERR_DEV_TIMEOUT) {
308
/* In addition to typical reasons for
309
* timeout, M210 device timeouts if
310
* queried the packet count but if it
311
* does not have any notes. By
312
* querying the packet count multiple
313
* times, we ensure that the
314
* timeouting is really due to lack of
322
/* Check that the response is correct. */
323
if (response[0] == 0xaa
324
&& response[1] == 0xaa
325
&& response[2] == 0xaa
326
&& response[3] == 0xaa
327
&& response[4] == 0xaa
328
&& response[7] == 0x55
329
&& response[8] == 0x55) {
335
memcpy(packet_count_ptr, response + 5, 2);
336
*packet_count_ptr = be16toh(*packet_count_ptr);
340
if (err == M210_ERR_DEV_TIMEOUT) {
341
/* M210 has timeouted because it does not have
342
* any notes: its ok, the packet count is set
346
/* Try to leave the device as it was before
348
m210_dev_reject_download(dev_ptr);
355
m210_dev_read_packet(struct m210_dev const *const dev_ptr,
356
struct m210_dev_packet *const packet_ptr)
358
enum m210_err err = m210_dev_read(dev_ptr, 0, packet_ptr,
359
sizeof(struct m210_dev_packet));
361
packet_ptr->num = be16toh(packet_ptr->num);
367
m210_dev_connect(struct m210_dev **const dev_ptr_ptr)
369
struct m210_dev *dev_ptr = NULL;
370
enum m210_err err = M210_ERR_OK;
371
char iface0_path[PATH_MAX];
372
char iface1_path[PATH_MAX];
373
char *paths[M210_DEV_USB_INTERFACE_COUNT] = {iface0_path, iface1_path};
375
dev_ptr = malloc(sizeof(struct m210_dev));
381
for (size_t i = 0; i < M210_DEV_USB_INTERFACE_COUNT; ++i) {
382
memset(paths[i], 0, PATH_MAX);
384
err = m210_dev_find_hidraw_devnode(i, paths[i], PATH_MAX);
389
err = m210_dev_connect_hidraw(dev_ptr, paths);
395
*dev_ptr_ptr = dev_ptr;
400
m210_dev_disconnect(struct m210_dev **const dev_ptr_ptr)
402
struct m210_dev *const dev_ptr = *dev_ptr_ptr;
403
enum m210_err err = M210_ERR_OK;
409
for (int i = 0; i < M210_DEV_USB_INTERFACE_COUNT; ++i) {
410
if (close(dev_ptr->fds[i]) == -1) {
283
static enum m210_err m210_dev_begin_download(struct m210_dev const *const dev_ptr,
284
uint16_t *const packet_count_ptr)
286
static uint8_t const bytes[] = {0xb5};
287
uint8_t response[] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
288
enum m210_err err = M210_ERR_OK;
289
int timeout_retries = 0;
291
while (timeout_retries < M210_DEV_MAX_TIMEOUT_RETRIES) {
292
err = m210_dev_write(dev_ptr, bytes, sizeof(bytes));
298
err = m210_dev_read(dev_ptr, 0, response, sizeof(response));
300
if (err == M210_ERR_DEV_TIMEOUT) {
301
/* In addition to typical reasons for
302
* timeout, M210 device timeouts if
303
* queried the packet count but if it
304
* does not have any notes. By
305
* querying the packet count multiple
306
* times, we ensure that the
307
* timeouting is really due to lack of
315
/* Check that the response is correct. */
316
if (response[0] == 0xaa
317
&& response[1] == 0xaa
318
&& response[2] == 0xaa
319
&& response[3] == 0xaa
320
&& response[4] == 0xaa
321
&& response[7] == 0x55
322
&& response[8] == 0x55) {
328
memcpy(packet_count_ptr, response + 5, 2);
329
*packet_count_ptr = be16toh(*packet_count_ptr);
333
if (err == M210_ERR_DEV_TIMEOUT) {
334
/* M210 has timeouted because it does not have
335
* any notes: its ok, the packet count is set
339
/* Try to leave the device as it was before
341
m210_dev_reject_download(dev_ptr);
347
static enum m210_err m210_dev_read_packet(struct m210_dev const *const dev_ptr,
348
struct m210_dev_packet *const packet_ptr)
350
enum m210_err err = m210_dev_read(dev_ptr, 0, packet_ptr,
351
sizeof(struct m210_dev_packet));
353
packet_ptr->num = be16toh(packet_ptr->num);
358
enum m210_err m210_dev_connect(struct m210_dev **const dev_ptr_ptr)
360
struct m210_dev *dev_ptr = NULL;
361
enum m210_err err = M210_ERR_OK;
362
char iface0_path[PATH_MAX];
363
char iface1_path[PATH_MAX];
364
char *paths[M210_DEV_USB_INTERFACE_COUNT] = {iface0_path, iface1_path};
366
dev_ptr = malloc(sizeof(struct m210_dev));
372
for (size_t i = 0; i < M210_DEV_USB_INTERFACE_COUNT; ++i) {
373
memset(paths[i], 0, PATH_MAX);
375
err = m210_dev_find_hidraw_devnode(i, paths[i], PATH_MAX);
380
err = m210_dev_connect_hidraw(dev_ptr, paths);
386
*dev_ptr_ptr = dev_ptr;
390
enum m210_err m210_dev_disconnect(struct m210_dev **const dev_ptr_ptr)
392
struct m210_dev *const dev_ptr = *dev_ptr_ptr;
393
enum m210_err err = M210_ERR_OK;
399
for (int i = 0; i < M210_DEV_USB_INTERFACE_COUNT; ++i) {
400
if (close(dev_ptr->fds[i]) == -1) {
432
422
more than the maximum number of bytes in devices memory.
436
m210_dev_get_notes_size(struct m210_dev const *const dev_ptr,
437
uint32_t *const size_ptr)
439
uint16_t packet_count = 0;
440
enum m210_err err = M210_ERR_OK;
442
err = m210_dev_begin_download(dev_ptr, &packet_count);
447
err = m210_dev_reject_download(dev_ptr);
450
*size_ptr = packet_count * M210_DEV_PACKET_SIZE;
456
m210_dev_get_info(struct m210_dev *const dev_ptr,
457
struct m210_dev_info *const info_ptr)
459
enum m210_err err = M210_ERR_OK;
460
static uint8_t const bytes[] = {0x95};
461
uint8_t response[M210_DEV_RESPONSE_SIZE];
462
uint32_t used_memory = 0;
464
err = m210_dev_write(dev_ptr, bytes, sizeof(bytes));
470
memset(response, 0, sizeof(response));
471
err = m210_dev_read(dev_ptr, 0, response, sizeof(response));
476
/* Check that the response is correct. */
477
if (response[0] == 0x80
478
&& response[1] == 0xa9
479
&& response[2] == 0x28
480
&& response[9] == 0x0e) {
485
err = m210_dev_get_notes_size(dev_ptr, &used_memory);
490
memcpy(&(info_ptr->firmware_version), response + 3, 2);
491
memcpy(&(info_ptr->analog_version), response + 5, 2);
492
memcpy(&(info_ptr->pad_version), response + 7, 2);
494
info_ptr->firmware_version = be16toh(info_ptr->firmware_version);
495
info_ptr->analog_version = be16toh(info_ptr->analog_version);
496
info_ptr->pad_version = be16toh(info_ptr->pad_version);
497
info_ptr->mode = response[10];
498
info_ptr->used_memory = used_memory;
505
m210_dev_delete_notes(struct m210_dev *const dev_ptr)
507
uint8_t const bytes[] = {0xb0};
508
return m210_dev_write(dev_ptr, bytes, sizeof(bytes));
512
m210_dev_download(struct m210_dev const *const dev_ptr,
513
uint16_t packet_count,
514
uint16_t *const lost_nums,
517
enum m210_err err = M210_ERR_OK;
518
uint16_t lost_count = 0;
520
for (int i = 0; i < packet_count; ++i) {
521
struct m210_dev_packet packet;
522
uint16_t const expected_packet_number = i + 1;
524
err = m210_dev_read_packet(dev_ptr, &packet);
529
if (packet.num != expected_packet_number) {
530
lost_nums[lost_count++] = expected_packet_number;
534
if (fwrite(packet.data, sizeof(packet.data), 1,
542
while (lost_count > 0) {
543
struct m210_dev_packet packet;
545
uint8_t resend_request[] = {0xb7, 0x00};
546
resend_request[1] = htobe16(lost_nums[0]);
548
err = m210_dev_write(dev_ptr, resend_request,
549
sizeof(resend_request));
554
err = m210_dev_read_packet(dev_ptr, &packet);
559
if (packet.num == lost_nums[0]) {
560
lost_nums[0] = lost_nums[--lost_count];
561
if (fwrite(packet.data, sizeof(packet.data), 1,
573
m210_dev_download_notes(struct m210_dev *const dev_ptr, FILE *file)
575
enum m210_err err = M210_ERR_OK;
576
uint16_t *lost_nums = NULL;
577
uint16_t packet_count = 0;
579
err = m210_dev_begin_download(dev_ptr, &packet_count);
584
if (packet_count == 0) {
585
err = m210_dev_reject_download(dev_ptr);
589
lost_nums = calloc(packet_count, sizeof(uint16_t));
590
if (lost_nums == NULL) {
591
int const original_errno = errno;
592
m210_dev_reject_download(dev_ptr);
593
errno = original_errno;
598
err = m210_dev_accept_download(dev_ptr);
603
err = m210_dev_download(dev_ptr, packet_count, lost_nums, file);
609
All packets have been received, time to thank the device for
612
err = m210_dev_accept_download(dev_ptr);
425
static enum m210_err m210_dev_get_notes_size(struct m210_dev const *const dev_ptr,
426
uint32_t *const size_ptr)
428
uint16_t packet_count = 0;
429
enum m210_err err = M210_ERR_OK;
431
err = m210_dev_begin_download(dev_ptr, &packet_count);
436
err = m210_dev_reject_download(dev_ptr);
439
*size_ptr = packet_count * M210_DEV_PACKET_SIZE;
444
enum m210_err m210_dev_get_info(struct m210_dev *const dev_ptr,
445
struct m210_dev_info *const info_ptr)
447
enum m210_err err = M210_ERR_OK;
448
static uint8_t const bytes[] = {0x95};
449
uint8_t response[M210_DEV_RESPONSE_SIZE];
450
uint32_t used_memory = 0;
452
err = m210_dev_write(dev_ptr, bytes, sizeof(bytes));
458
memset(response, 0, sizeof(response));
459
err = m210_dev_read(dev_ptr, 0, response, sizeof(response));
464
/* Check that the response is correct. */
465
if (response[0] == 0x80
466
&& response[1] == 0xa9
467
&& response[2] == 0x28
468
&& response[9] == 0x0e) {
473
err = m210_dev_get_notes_size(dev_ptr, &used_memory);
478
memcpy(&(info_ptr->firmware_version), response + 3, 2);
479
memcpy(&(info_ptr->analog_version), response + 5, 2);
480
memcpy(&(info_ptr->pad_version), response + 7, 2);
482
info_ptr->firmware_version = be16toh(info_ptr->firmware_version);
483
info_ptr->analog_version = be16toh(info_ptr->analog_version);
484
info_ptr->pad_version = be16toh(info_ptr->pad_version);
485
info_ptr->mode = response[10];
486
info_ptr->used_memory = used_memory;
492
enum m210_err m210_dev_delete_notes(struct m210_dev *const dev_ptr)
494
uint8_t const bytes[] = {0xb0};
495
return m210_dev_write(dev_ptr, bytes, sizeof(bytes));
498
static enum m210_err m210_dev_download(struct m210_dev const *const dev_ptr,
499
uint16_t packet_count,
500
uint16_t *const lost_nums,
503
enum m210_err err = M210_ERR_OK;
504
uint16_t lost_count = 0;
506
for (int i = 0; i < packet_count; ++i) {
507
struct m210_dev_packet packet;
508
uint16_t const expected_packet_number = i + 1;
510
err = m210_dev_read_packet(dev_ptr, &packet);
515
if (packet.num != expected_packet_number) {
516
lost_nums[lost_count++] = expected_packet_number;
520
if (fwrite(packet.data, sizeof(packet.data), 1,
528
while (lost_count > 0) {
529
struct m210_dev_packet packet;
531
uint8_t resend_request[] = {0xb7, 0x00};
532
resend_request[1] = htobe16(lost_nums[0]);
534
err = m210_dev_write(dev_ptr, resend_request,
535
sizeof(resend_request));
540
err = m210_dev_read_packet(dev_ptr, &packet);
545
if (packet.num == lost_nums[0]) {
546
lost_nums[0] = lost_nums[--lost_count];
547
if (fwrite(packet.data, sizeof(packet.data), 1,
558
enum m210_err m210_dev_download_notes(struct m210_dev *const dev_ptr, FILE *file)
560
enum m210_err err = M210_ERR_OK;
561
uint16_t *lost_nums = NULL;
562
uint16_t packet_count = 0;
564
err = m210_dev_begin_download(dev_ptr, &packet_count);
569
if (packet_count == 0) {
570
err = m210_dev_reject_download(dev_ptr);
574
lost_nums = calloc(packet_count, sizeof(uint16_t));
575
if (lost_nums == NULL) {
576
int const original_errno = errno;
577
m210_dev_reject_download(dev_ptr);
578
errno = original_errno;
583
err = m210_dev_accept_download(dev_ptr);
588
err = m210_dev_download(dev_ptr, packet_count, lost_nums, file);
594
All packets have been received, time to thank the device for
597
err = m210_dev_accept_download(dev_ptr);