2 * This file is part of the libjaylink project.
4 * Copyright (C) 2014 Marc Schink <jaylink-dev@marcschink.de>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "libjaylink.h"
24 #include "libjaylink-internal.h"
26 #define CMD_GET_VERSION 0x01
27 #define CMD_SET_SPEED 0x05
28 #define CMD_GET_HW_STATUS 0x07
29 #define CMD_GET_FREE_MEMORY 0xd4
30 #define CMD_GET_CAPS 0xe8
31 #define CMD_GET_EXT_CAPS 0xed
32 #define CMD_GET_HW_VERSION 0xf0
34 struct jaylink_device
*device_allocate(struct jaylink_context
*ctx
)
36 struct jaylink_device
*dev
;
39 dev
= malloc(sizeof(struct jaylink_device
));
44 list
= list_prepend(ctx
->devs
, dev
);
60 static struct jaylink_device_handle
*allocate_device_handle(
61 struct jaylink_device
*dev
)
63 struct jaylink_device_handle
*devh
;
65 devh
= malloc(sizeof(struct jaylink_device_handle
));
70 devh
->dev
= jaylink_ref_device(dev
);
75 static void free_device_handle(struct jaylink_device_handle
*devh
)
77 jaylink_unref_device(devh
->dev
);
81 ssize_t
jaylink_get_device_list(struct jaylink_context
*ctx
,
82 struct jaylink_device
***list
)
85 return JAYLINK_ERR_ARG
;
87 return discovery_get_device_list(ctx
, list
);
90 void jaylink_free_device_list(struct jaylink_device
**list
, int unref_devices
)
101 jaylink_unref_device(list
[i
]);
109 int jaylink_device_get_serial_number(const struct jaylink_device
*dev
,
110 uint32_t *serial_number
)
112 if (!dev
|| !serial_number
)
113 return JAYLINK_ERR_ARG
;
115 *serial_number
= dev
->serial_number
;
120 int jaylink_device_get_usb_address(const struct jaylink_device
*dev
)
123 return JAYLINK_ERR_ARG
;
125 return dev
->usb_address
;
128 struct jaylink_device
*jaylink_ref_device(struct jaylink_device
*dev
)
138 void jaylink_unref_device(struct jaylink_device
*dev
)
145 if (dev
->refcnt
== 0) {
146 dev
->ctx
->devs
= list_remove(dev
->ctx
->devs
, dev
);
149 libusb_unref_device(dev
->usb_dev
);
155 int jaylink_open(struct jaylink_device
*dev
,
156 struct jaylink_device_handle
**devh
)
159 struct jaylink_device_handle
*handle
;
162 return JAYLINK_ERR_ARG
;
164 handle
= allocate_device_handle(dev
);
167 log_err(dev
->ctx
, "Device handle malloc failed.");
168 return JAYLINK_ERR_MALLOC
;
171 ret
= transport_open(handle
);
174 free_device_handle(handle
);
183 void jaylink_close(struct jaylink_device_handle
*devh
)
188 transport_close(devh
);
189 free_device_handle(devh
);
193 * Retrieve the firmware version of a device.
195 * @param[in,out] devh Device handle.
196 * @param[out] version Newly allocated string which contains the firmware
197 * version, and undefined if the device returns no
198 * firmware version or on failure. The string is
199 * null-terminated and must be free'd by the caller.
201 * @return The length of the newly allocated firmware version string including
202 * trailing null-terminator or 0 if the device returns no firmware
203 * version or any #jaylink_error error code on failure.
205 int jaylink_get_firmware_version(struct jaylink_device_handle
*devh
,
209 struct jaylink_context
*ctx
;
214 if (!devh
|| !version
)
215 return JAYLINK_ERR_ARG
;
217 ctx
= devh
->dev
->ctx
;
218 ret
= transport_start_write_read(devh
, 1, 2, 1);
220 if (ret
!= JAYLINK_OK
) {
221 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
225 buf
[0] = CMD_GET_VERSION
;
227 ret
= transport_write(devh
, buf
, 1);
229 if (ret
!= JAYLINK_OK
) {
230 log_err(ctx
, "transport_write() failed: %i.", ret
);
234 ret
= transport_read(devh
, buf
, 2);
236 if (ret
!= JAYLINK_OK
) {
237 log_err(ctx
, "transport_read() failed: %i.", ret
);
241 length
= buffer_get_u16(buf
, 0);
246 ret
= transport_start_read(devh
, length
);
248 if (ret
!= JAYLINK_OK
) {
249 log_err(ctx
, "transport_start_read() failed: %i.", ret
);
253 tmp
= malloc(length
);
256 log_err(ctx
, "Firmware version string malloc failed.");
257 return JAYLINK_ERR_MALLOC
;
260 ret
= transport_read(devh
, (uint8_t *)tmp
, length
);
262 if (ret
!= JAYLINK_OK
) {
263 log_err(ctx
, "transport_read() failed: %i.", ret
);
268 /* Last byte is reserved for null-terminator. */
276 * Retrieve the hardware version of a device.
278 * @note This function must only be used if the device has the
279 * #JAYLINK_DEV_CAP_GET_HW_VERSION capability.
281 * @param[in,out] devh Device handle.
282 * @param[out] version Hardware version on success, and undefined on failure.
284 * @retval JAYLINK_OK Success.
285 * @retval JAYLINK_ERR_ARG Invalid arguments.
286 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
287 * @retval JAYLINK_ERR Other error conditions.
289 * @see jaylink_get_caps() to retrieve device capabilities.
291 int jaylink_get_hardware_version(struct jaylink_device_handle
*devh
,
292 struct jaylink_hardware_version
*version
)
295 struct jaylink_context
*ctx
;
299 if (!devh
|| !version
)
300 return JAYLINK_ERR_ARG
;
302 ctx
= devh
->dev
->ctx
;
303 ret
= transport_start_write_read(devh
, 1, 4, 1);
305 if (ret
!= JAYLINK_OK
) {
306 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
310 buf
[0] = CMD_GET_HW_VERSION
;
312 ret
= transport_write(devh
, buf
, 1);
314 if (ret
!= JAYLINK_OK
) {
315 log_err(ctx
, "transport_write() failed: %i.", ret
);
319 ret
= transport_read(devh
, buf
, 4);
321 if (ret
!= JAYLINK_OK
) {
322 log_err(ctx
, "transport_read() failed: %i.", ret
);
326 tmp
= buffer_get_u32(buf
, 0);
328 version
->type
= (tmp
/ 1000000) % 100;
329 version
->major
= (tmp
/ 10000) % 100;
330 version
->minor
= (tmp
/ 100) % 100;
331 version
->revision
= tmp
% 100;
337 * Retrieve the hardware status of a device.
339 * @param[in,out] devh Device handle.
340 * @param[out] status Hardware status on success, and undefined on failure.
342 * @retval JAYLINK_OK Success.
343 * @retval JAYLINK_ERR_ARG Invalid arguments.
344 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
345 * @retval JAYLINK_ERR Other error conditions.
347 int jaylink_get_hardware_status(struct jaylink_device_handle
*devh
,
348 struct jaylink_hardware_status
*status
)
351 struct jaylink_context
*ctx
;
354 if (!devh
|| !status
)
355 return JAYLINK_ERR_ARG
;
357 ctx
= devh
->dev
->ctx
;
358 ret
= transport_start_write_read(devh
, 1, 8, 1);
360 if (ret
!= JAYLINK_OK
) {
361 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
365 buf
[0] = CMD_GET_HW_STATUS
;
367 ret
= transport_write(devh
, buf
, 1);
369 if (ret
!= JAYLINK_OK
) {
370 log_err(ctx
, "transport_write() failed: %i.", ret
);
374 ret
= transport_read(devh
, buf
, 8);
376 if (ret
!= JAYLINK_OK
) {
377 log_err(ctx
, "transport_read() failed: %i.", ret
);
381 status
->target_voltage
= buffer_get_u16(buf
, 0);
382 status
->tck
= buf
[2];
383 status
->tdi
= buf
[3];
384 status
->tdo
= buf
[4];
385 status
->tms
= buf
[5];
386 status
->tres
= buf
[6];
387 status
->trst
= buf
[7];
393 * Retrieve the capabilities of a device.
395 * The capabilities are stored in a 32-bit bit array consisting of
396 * #JAYLINK_DEV_CAPS_SIZE bytes where each individual bit represents a
397 * capability. The first bit of this array is the least significant bit of the
398 * first byte and the following bits are sequentially numbered in order of
399 * increasing bit significance and byte index. A set bit indicates a supported
400 * capability. See #jaylink_device_capability for a description of the
401 * capabilities and their bit positions.
403 * @param[in,out] devh Device handle.
404 * @param[out] caps Buffer to store capabilities on success. Its value is
405 * undefined on failure. The size of the buffer must be large
406 * enough to contain at least #JAYLINK_DEV_CAPS_SIZE bytes.
408 * @retval JAYLINK_OK Success.
409 * @retval JAYLINK_ERR_ARG Invalid arguments.
410 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
411 * @retval JAYLINK_ERR Other error conditions.
413 * @see jaylink_get_extended_caps() to retrieve extended device capabilities.
415 int jaylink_get_caps(struct jaylink_device_handle
*devh
, uint8_t *caps
)
418 struct jaylink_context
*ctx
;
422 return JAYLINK_ERR_ARG
;
424 ctx
= devh
->dev
->ctx
;
425 ret
= transport_start_write_read(devh
, 1, JAYLINK_DEV_CAPS_SIZE
, 1);
427 if (ret
!= JAYLINK_OK
) {
428 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
432 buf
[0] = CMD_GET_CAPS
;
434 ret
= transport_write(devh
, buf
, 1);
436 if (ret
!= JAYLINK_OK
) {
437 log_err(ctx
, "transport_write() failed: %i.", ret
);
441 ret
= transport_read(devh
, caps
, JAYLINK_DEV_CAPS_SIZE
);
443 if (ret
!= JAYLINK_OK
) {
444 log_err(ctx
, "transport_read() failed: %i.", ret
);
452 * Retrieve the extended capabilities of a device.
454 * The extended capabilities are stored in a 256-bit bit array consisting of
455 * #JAYLINK_DEV_EXT_CAPS_SIZE bytes. See jaylink_get_caps() for a further
456 * description of how the capabilities are represented in this bit array. For a
457 * description of the capabilities and their bit positions, see
458 * #jaylink_device_capability.
460 * @note This function must only be used if the device has the
461 * #JAYLINK_DEV_CAP_GET_EXT_CAPS capability.
463 * @param[in,out] devh Device handle.
464 * @param[out] caps Buffer to store capabilities on success. Its value is
465 * undefined on failure. The size of the buffer must be large
466 * enough to contain at least #JAYLINK_DEV_EXT_CAPS_SIZE bytes.
468 * @retval JAYLINK_OK Success.
469 * @retval JAYLINK_ERR_ARG Invalid arguments.
470 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
471 * @retval JAYLINK_ERR Other error conditions.
473 * @see jaylink_get_caps() to retrieve device capabilities.
475 int jaylink_get_extended_caps(struct jaylink_device_handle
*devh
, uint8_t *caps
)
478 struct jaylink_context
*ctx
;
482 return JAYLINK_ERR_ARG
;
484 ctx
= devh
->dev
->ctx
;
485 ret
= transport_start_write_read(devh
, 1, JAYLINK_DEV_EXT_CAPS_SIZE
, 1);
487 if (ret
!= JAYLINK_OK
) {
488 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
492 buf
[0] = CMD_GET_EXT_CAPS
;
494 ret
= transport_write(devh
, buf
, 1);
496 if (ret
!= JAYLINK_OK
) {
497 log_err(ctx
, "transport_write() failed: %i.", ret
);
501 ret
= transport_read(devh
, caps
, JAYLINK_DEV_EXT_CAPS_SIZE
);
503 if (ret
!= JAYLINK_OK
) {
504 log_err(ctx
, "transport_read() failed: %i.", ret
);
512 * Retrieve the size of free memory of a device.
514 * @note This function must only be used if the device has the
515 * #JAYLINK_DEV_CAP_GET_FREE_MEMORY capability.
517 * @param[in,out] devh Device handle.
518 * @param[out] size Size of free memory in bytes on success, and undefined on
521 * @retval JAYLINK_OK Success.
522 * @retval JAYLINK_ERR_ARG Invalid arguments.
523 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
524 * @retval JAYLINK_ERR Other error conditions.
526 * @see jaylink_get_caps() to retrieve device capabilities.
528 int jaylink_get_free_memory(struct jaylink_device_handle
*devh
, uint32_t *size
)
531 struct jaylink_context
*ctx
;
535 return JAYLINK_ERR_ARG
;
537 ctx
= devh
->dev
->ctx
;
538 ret
= transport_start_write_read(devh
, 1, 4, 1);
540 if (ret
!= JAYLINK_OK
) {
541 log_err(ctx
, "transport_start_write_read() failed: %i.", ret
);
545 buf
[0] = CMD_GET_FREE_MEMORY
;
547 ret
= transport_write(devh
, buf
, 1);
549 if (ret
!= JAYLINK_OK
) {
550 log_err(ctx
, "transport_write() failed: %i.", ret
);
554 ret
= transport_read(devh
, buf
, 4);
556 if (ret
!= JAYLINK_OK
) {
557 log_err(ctx
, "transport_read() failed: %i.", ret
);
561 *size
= buffer_get_u32(buf
, 0);
567 * Set the target interface speed of a device.
569 * @param[in,out] devh Device handle.
570 * @param[in] speed Speed in kHz or #JAYLINK_SPEED_ADAPTIVE_CLOCKING for
571 * adaptive clocking. Speed of 0 kHz is not allowed and
572 * adaptive clocking must only be used if the device has the
573 * #JAYLINK_DEV_CAP_ADAPTIVE_CLOCKING capability.
575 * @retval JAYLINK_OK Success.
576 * @retval JAYLINK_ERR_ARG Invalid arguments.
577 * @retval JAYLINK_ERR_TIMEOUT A timeout occurred.
578 * @retval JAYLINK_ERR Other error conditions.
580 int jaylink_set_speed(struct jaylink_device_handle
*devh
, uint16_t speed
)
583 struct jaylink_context
*ctx
;
587 return JAYLINK_ERR_ARG
;
589 ctx
= devh
->dev
->ctx
;
590 ret
= transport_start_write(devh
, 3, 1);
592 if (ret
!= JAYLINK_OK
) {
593 log_err(ctx
, "transport_start_write() failed: %i.", ret
);
597 buf
[0] = CMD_SET_SPEED
;
598 buffer_set_u16(buf
, speed
, 1);
600 ret
= transport_write(devh
, buf
, 3);
602 if (ret
!= JAYLINK_OK
) {
603 log_err(ctx
, "transport_write() failed: %i.", ret
);