diff -Nru libjaylink-0.2.0/autogen.sh libjaylink-0.3.1/autogen.sh --- libjaylink-0.2.0/autogen.sh 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/autogen.sh 2022-08-27 08:10:29.000000000 +0000 @@ -28,7 +28,7 @@ echo "Generating build system..." $LIBTOOLIZE --install --copy || exit 1 -aclocal -I m4 || exit 1 -autoheader || exit 1 -autoconf || exit 1 -automake --add-missing --copy || exit 1 +aclocal --warnings=all -I m4 || exit 1 +autoheader --warnings=all || exit 1 +autoconf --warnings=all || exit 1 +automake --warnings=all --add-missing --copy || exit 1 diff -Nru libjaylink-0.2.0/configure.ac libjaylink-0.3.1/configure.ac --- libjaylink-0.2.0/configure.ac 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/configure.ac 2022-08-27 08:10:29.000000000 +0000 @@ -19,7 +19,7 @@ AC_PREREQ([2.64]) -AC_INIT([libjaylink], [0.2.0], [dev@zapb.de], [libjaylink], +AC_INIT([libjaylink], [0.3.1], [dev@zapb.de], [libjaylink], [https://gitlab.zapb.de/libjaylink/libjaylink.git]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) @@ -35,7 +35,8 @@ # Checks for programs. AC_PROG_CC -AC_PROG_CC_C99 +# AC_PROG_CC_C99 is dropped in Autoconf >= 2.70 and done in AC_PROG_CC. +m4_version_prereq([2.70],[],[AC_PROG_CC_C99]) # Automake >= 1.12 requires AM_PROG_AR when using options -Wall and -Werror. # To be compatible with older versions of Automake use AM_PROG_AR if it's @@ -50,7 +51,7 @@ # Checks for libraries. -# Check for libusb-1.0 which is always needed. +# Check for libusb-1.0. PKG_CHECK_MODULES([libusb], [libusb-1.0 >= 1.0.16], [HAVE_LIBUSB=yes], [HAVE_LIBUSB=no]) @@ -72,7 +73,7 @@ # Libtool interface version of libjaylink. This is not the same as the package # version. For information about the versioning system of libtool, see: # http://www.gnu.org/software/libtool/manual/libtool.html#Libtool-versioning -JAYLINK_SET_LIBRARY_VERSION([JAYLINK_VERSION_LIBRARY], [1:0:1]) +JAYLINK_SET_LIBRARY_VERSION([JAYLINK_VERSION_LIBRARY], [2:0:2]) AC_ARG_ENABLE([subproject-build], AS_HELP_STRING([--enable-subproject-build], [enable sub-project build [default=no]])) diff -Nru libjaylink-0.2.0/debian/changelog libjaylink-0.3.1/debian/changelog --- libjaylink-0.2.0/debian/changelog 2020-07-11 13:57:19.000000000 +0000 +++ libjaylink-0.3.1/debian/changelog 2022-08-27 08:16:56.000000000 +0000 @@ -1,3 +1,11 @@ +libjaylink (0.3.1-1) unstable; urgency=medium + + * New upstream release + * Fix homepage + * Add watch file + + -- Jonathan McDowell Sat, 27 Aug 2022 09:16:56 +0100 + libjaylink (0.2.0-1) unstable; urgency=medium * New upstream release diff -Nru libjaylink-0.2.0/debian/control libjaylink-0.3.1/debian/control --- libjaylink-0.2.0/debian/control 2020-07-11 13:56:20.000000000 +0000 +++ libjaylink-0.3.1/debian/control 2022-08-27 08:16:40.000000000 +0000 @@ -5,7 +5,7 @@ Build-Depends: debhelper-compat (= 12), pkg-config, libusb-1.0-0-dev Standards-Version: 4.5.0 Section: libs -Homepage: http://git.zapb.de/libjaylink.git +Homepage: http://git.zapb.de/libjaylink/libjaylink Vcs-Git: https://salsa.debian.org/electronics-team/libjaylink.git -b debian Vcs-Browser: https://salsa.debian.org/electronics-team/libjaylink Rules-Requires-Root: no diff -Nru libjaylink-0.2.0/debian/copyright libjaylink-0.3.1/debian/copyright --- libjaylink-0.2.0/debian/copyright 2020-07-11 13:56:20.000000000 +0000 +++ libjaylink-0.3.1/debian/copyright 2022-08-27 08:16:40.000000000 +0000 @@ -3,7 +3,7 @@ Source: http://git.zapb.de/libjaylink.git Files: * -Copyright: 2014-2017 Marc Schink +Copyright: 2014-2022 Marc Schink License: GPL-2+ License: GPL-2+ diff -Nru libjaylink-0.2.0/debian/watch libjaylink-0.3.1/debian/watch --- libjaylink-0.2.0/debian/watch 1970-01-01 00:00:00.000000000 +0000 +++ libjaylink-0.3.1/debian/watch 2022-08-27 08:16:40.000000000 +0000 @@ -0,0 +1,2 @@ +version=4 +https://gitlab.zapb.de/libjaylink/libjaylink/-/tags .*/[\d\.]+/libjaylink-([\d\.]+)\.tar\.bz2 diff -Nru libjaylink-0.2.0/libjaylink/c2.c libjaylink-0.3.1/libjaylink/c2.c --- libjaylink-0.2.0/libjaylink/c2.c 1970-01-01 00:00:00.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/c2.c 2022-08-27 08:10:29.000000000 +0000 @@ -0,0 +1,349 @@ +/* + * This file is part of the libjaylink project. + * + * Copyright (C) 2021-2022 Marc Schink + * + * 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 2 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, see . + */ + +#include + +#include "libjaylink.h" +#include "libjaylink-internal.h" + +/** + * @file + * + * Silicon Labs 2-wire (C2) interface functions. + */ + +/** @cond PRIVATE */ +#define CMD_C2_IO 0x17 + +#define C2_CMD_DATA_READ 0x00 +#define C2_CMD_DATA_WRITE 0x01 +#define C2_CMD_ADDR_READ 0x02 +#define C2_CMD_ADDR_WRITE 0x03 +/** @endcond */ + +/** + * Read the C2 address register. + * + * @note This function must only be used if the #JAYLINK_TIF_C2 interface is + * available and selected. + * + * @param[in,out] devh Device handle. + * @param[out] address Value read from the address register on success, and + * undefined on failure. + * + * @retval JAYLINK_OK Success. + * @retval JAYLINK_ERR_ARG Invalid arguments. + * @retval JAYLINK_ERR_TIMEOUT A timeout occurred. + * @retval JAYLINK_ERR_IO Input/output error. + * @retval JAYLINK_ERR_DEV Unspecified device error. + * @retval JAYLINK_ERR Other error conditions. + * + * @since 0.3.0 + */ +JAYLINK_API int jaylink_c2_read_address(struct jaylink_device_handle *devh, + uint8_t *address) +{ + int ret; + uint8_t buf[6]; + struct jaylink_context *ctx; + + if (!devh || !address) + return JAYLINK_ERR_ARG; + + ctx = devh->dev->ctx; + + ret = transport_start_write_read(devh, 5, 1 + 4, true); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_start_write_read() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + buf[0] = CMD_C2_IO; + buf[1] = C2_CMD_ADDR_READ; + buf[2] = 0x00; + /* Length is always 1 for this command. */ + buffer_set_u16(buf, 1, 3); + + ret = transport_write(devh, buf, 5); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_write() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + ret = transport_read(devh, address, 1); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_read() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + ret = transport_read(devh, buf, 4); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_read() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + uint32_t err = buffer_get_u32(buf, 0); + + if (err != 0) { + return JAYLINK_ERR_DEV; + } + + return JAYLINK_OK; +} + +/** + * Write to the C2 address register. + * + * @note This function must only be used if the #JAYLINK_TIF_C2 interface is + * available and selected. + * + * @param[in,out] devh Device handle. + * @param[in] address Value to write into the address register. + * + * @retval JAYLINK_OK Success. + * @retval JAYLINK_ERR_ARG Invalid arguments. + * @retval JAYLINK_ERR_TIMEOUT A timeout occurred. + * @retval JAYLINK_ERR_IO Input/output error. + * @retval JAYLINK_ERR_DEV Unspecified device error. + * @retval JAYLINK_ERR Other error conditions. + * + * @since 0.3.0 + */ +JAYLINK_API int jaylink_c2_write_address(struct jaylink_device_handle *devh, + uint8_t address) +{ + int ret; + uint8_t buf[6]; + struct jaylink_context *ctx; + + if (!devh) + return JAYLINK_ERR_ARG; + + ctx = devh->dev->ctx; + + ret = transport_start_write_read(devh, 5 + 1, 4, true); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_start_write_read() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + buf[0] = CMD_C2_IO; + buf[1] = C2_CMD_ADDR_WRITE; + /* Length is always 1 for this command. */ + buffer_set_u16(buf, 1, 2); + buf[4] = 0x00; + buf[5] = address; + + ret = transport_write(devh, buf, 6); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_write() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + ret = transport_read(devh, buf, 4); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_read() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + uint32_t err = buffer_get_u32(buf, 0); + + if (err != 0) { + return JAYLINK_ERR_DEV; + } + + return JAYLINK_OK; +} + +/** + * Read the C2 data register. + * + * @note This function must only be used if the #JAYLINK_TIF_C2 interface is + * available and selected. + * + * @param[in,out] devh Device handle. + * @param[out] data Buffer to store the read data on success. Its content is + * undefined on failure. + * @param[in] length Number of bytes to read, but not more than + * #JAYLINK_C2_MAX_LENGTH. + * + * @retval JAYLINK_OK Success. + * @retval JAYLINK_ERR_ARG Invalid arguments. + * @retval JAYLINK_ERR_TIMEOUT A timeout occurred. + * @retval JAYLINK_ERR_IO Input/output error. + * @retval JAYLINK_ERR_DEV Unspecified device error. + * @retval JAYLINK_ERR Other error conditions. + * + * @since 0.3.0 + */ +JAYLINK_API int jaylink_c2_read_data(struct jaylink_device_handle *devh, + uint8_t *data, uint8_t length) +{ + int ret; + struct jaylink_context *ctx; + uint8_t buf[5]; + + if (!devh || !data) + return JAYLINK_ERR_ARG; + + if (length > JAYLINK_C2_MAX_LENGTH) + return JAYLINK_ERR_ARG; + + ctx = devh->dev->ctx; + + ret = transport_start_write_read(devh, 5, 4 + length, true); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_start_write_read() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + buf[0] = CMD_C2_IO; + buf[1] = C2_CMD_DATA_READ; + buf[2] = 0x00; + buffer_set_u16(buf, length, 3); + + ret = transport_write(devh, buf, 5); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_write() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + ret = transport_read(devh, data, length); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_read() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + ret = transport_read(devh, buf, 4); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_read() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + uint32_t err = buffer_get_u32(buf, 0); + + if (err != 0) { + return JAYLINK_ERR_DEV; + } + + return JAYLINK_OK; +} + +/** + * Write to the C2 data register. + * + * @note This function must only be used if the #JAYLINK_TIF_C2 interface is + * available and selected. + * + * @param[in,out] devh Device handle. + * @param[in] data Buffer to be written into the data register. + * @param[in] length Number of bytes to write, but not more than + * #JAYLINK_C2_MAX_LENGTH. + * + * @retval JAYLINK_OK Success. + * @retval JAYLINK_ERR_ARG Invalid arguments. + * @retval JAYLINK_ERR_TIMEOUT A timeout occurred. + * @retval JAYLINK_ERR_IO Input/output error. + * @retval JAYLINK_ERR_DEV Unspecified device error. + * @retval JAYLINK_ERR Other error conditions. + * + * @since 0.3.0 + */ +JAYLINK_API int jaylink_c2_write_data(struct jaylink_device_handle *devh, + const uint8_t *data, uint8_t length) +{ + int ret; + uint8_t buf[5]; + struct jaylink_context *ctx; + + if (!devh || !data) + return JAYLINK_ERR_ARG; + + if (length > JAYLINK_C2_MAX_LENGTH) + return JAYLINK_ERR_ARG; + + ctx = devh->dev->ctx; + + ret = transport_start_write_read(devh, 5 + length, 4, true); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_start_write_read() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + buf[0] = CMD_C2_IO; + buf[1] = C2_CMD_DATA_WRITE; + buffer_set_u16(buf, length, 2); + buf[4] = 0x00; + + ret = transport_write(devh, buf, 5); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_write() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + ret = transport_write(devh, data, length); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_write() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + ret = transport_read(devh, buf, 4); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_read() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + uint32_t err = buffer_get_u32(buf, 0); + + if (err != 0) { + return JAYLINK_ERR_DEV; + } + + return JAYLINK_OK; +} diff -Nru libjaylink-0.2.0/libjaylink/core.c libjaylink-0.3.1/libjaylink/core.c --- libjaylink-0.2.0/libjaylink/core.c 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/core.c 2022-08-27 08:10:29.000000000 +0000 @@ -64,7 +64,7 @@ * * @section sec_website Website * - * git.zapb.de/libjaylink.git + * gitlab.zapb.de/libjaylink/libjaylink.git */ /** diff -Nru libjaylink-0.2.0/libjaylink/device.c libjaylink-0.3.1/libjaylink/device.c --- libjaylink-0.2.0/libjaylink/device.c 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/device.c 2022-08-27 08:10:29.000000000 +0000 @@ -149,7 +149,7 @@ tmp = allocate_device_list(num); if (!tmp) { - log_err(ctx, "Failed to allocate device list."); + log_err(ctx, "Failed to allocate device list"); return JAYLINK_ERR_MALLOC; } @@ -329,7 +329,7 @@ MAX_USB_PATH_DEPTH); if (ret == LIBUSB_ERROR_OVERFLOW) { - log_err(ctx, "Failed to get port numbers: %s.", + log_err(ctx, "Failed to get port numbers: %s", libusb_error_name(ret)); return JAYLINK_ERR_ARG; } @@ -549,17 +549,17 @@ if (dev->iface == JAYLINK_HIF_USB) { #ifdef HAVE_LIBUSB log_dbg(ctx, "Device destroyed (bus:address = " - "%03u:%03u).", + "%03u:%03u)", libusb_get_bus_number(dev->usb_dev), libusb_get_device_address(dev->usb_dev)); libusb_unref_device(dev->usb_dev); #endif } else if (dev->iface == JAYLINK_HIF_TCP) { - log_dbg(ctx, "Device destroyed (IPv4 address = %s).", + log_dbg(ctx, "Device destroyed (IPv4 address = %s)", dev->ipv4_address); } else { - log_err(ctx, "BUG: Invalid host interface: %u.", + log_err(ctx, "BUG: Invalid host interface: %u", dev->iface); } @@ -616,7 +616,7 @@ handle = allocate_device_handle(dev); if (!handle) { - log_err(dev->ctx, "Device handle malloc failed."); + log_err(dev->ctx, "Device handle malloc failed"); return JAYLINK_ERR_MALLOC; } @@ -714,7 +714,7 @@ ret = transport_start_write_read(devh, 1, 2, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -724,7 +724,7 @@ ret = transport_write(devh, buf, 1); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -732,7 +732,7 @@ ret = transport_read(devh, buf, 2); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -746,7 +746,7 @@ ret = transport_start_read(devh, dummy); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_read() failed: %s.", + log_err(ctx, "transport_start_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -754,14 +754,14 @@ tmp = malloc(dummy); if (!tmp) { - log_err(ctx, "Firmware version string malloc failed."); + log_err(ctx, "Firmware version string malloc failed"); return JAYLINK_ERR_MALLOC; } ret = transport_read(devh, (uint8_t *)tmp, dummy); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); free(tmp); return ret; @@ -823,7 +823,7 @@ ret = transport_start_write_read(devh, 5, length, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -834,7 +834,7 @@ ret = transport_write(devh, buf, 5); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -842,7 +842,7 @@ ret = transport_read(devh, (uint8_t *)info, length); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -901,7 +901,7 @@ ret = transport_start_write_read(devh, 5, length, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -912,7 +912,7 @@ ret = transport_write(devh, buf, 5); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -920,7 +920,7 @@ ret = transport_read(devh, (uint8_t *)values, length); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -969,7 +969,7 @@ ret = transport_start_write_read(devh, 1, 4, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -979,7 +979,7 @@ ret = transport_write(devh, buf, 1); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -987,7 +987,7 @@ ret = transport_read(devh, buf, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1030,7 +1030,7 @@ ret = transport_start_write_read(devh, 1, 8, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1040,7 +1040,7 @@ ret = transport_write(devh, buf, 1); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1048,7 +1048,7 @@ ret = transport_read(devh, buf, 8); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1105,7 +1105,7 @@ ret = transport_start_write_read(devh, 1, JAYLINK_DEV_CAPS_SIZE, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1115,7 +1115,7 @@ ret = transport_write(devh, buf, 1); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1123,7 +1123,7 @@ ret = transport_read(devh, caps, JAYLINK_DEV_CAPS_SIZE); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1173,7 +1173,7 @@ true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1183,7 +1183,7 @@ ret = transport_write(devh, buf, 1); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1191,7 +1191,7 @@ ret = transport_read(devh, caps, JAYLINK_DEV_EXT_CAPS_SIZE); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1231,7 +1231,7 @@ ret = transport_start_write_read(devh, 1, 4, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1241,7 +1241,7 @@ ret = transport_write(devh, buf, 1); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1249,7 +1249,7 @@ ret = transport_read(devh, buf, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1294,7 +1294,7 @@ true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1304,7 +1304,7 @@ ret = transport_write(devh, buf, 1); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1312,7 +1312,7 @@ ret = transport_read(devh, config, JAYLINK_DEV_CONFIG_SIZE); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1353,7 +1353,7 @@ ret = transport_start_write(devh, 1 + JAYLINK_DEV_CONFIG_SIZE, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write() failed: %s.", + log_err(ctx, "transport_start_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1363,7 +1363,7 @@ ret = transport_write(devh, buf, 1); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1371,7 +1371,7 @@ ret = transport_write(devh, config, JAYLINK_DEV_CONFIG_SIZE); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1548,7 +1548,7 @@ ret = transport_start_write_read(devh, 14, REG_MIN_SIZE, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1556,7 +1556,7 @@ ret = transport_write(devh, buf, 14); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1564,7 +1564,7 @@ ret = transport_read(devh, buf, REG_MIN_SIZE); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1576,12 +1576,12 @@ if (num > JAYLINK_MAX_CONNECTIONS) { log_err(ctx, "Maximum number of device connections exceeded: " - "%u.", num); + "%u", num); return JAYLINK_ERR_PROTO; } if (entry_size != REG_CONN_INFO_SIZE) { - log_err(ctx, "Invalid connection entry size: %u bytes.", + log_err(ctx, "Invalid connection entry size: %u bytes", entry_size); return JAYLINK_ERR_PROTO; } @@ -1591,7 +1591,7 @@ if (size > REG_MAX_SIZE) { log_err(ctx, "Maximum registration information size exceeded: " - "%u bytes.", size); + "%u bytes", size); return JAYLINK_ERR_PROTO; } @@ -1599,7 +1599,7 @@ ret = transport_start_read(devh, size - REG_MIN_SIZE); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_read() failed: %s.", + log_err(ctx, "transport_start_read() failed: %s", jaylink_strerror(ret)); return JAYLINK_ERR; } @@ -1608,14 +1608,14 @@ size - REG_MIN_SIZE); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return JAYLINK_ERR; } } if (!handle) { - log_err(ctx, "Obtained invalid connection handle."); + log_err(ctx, "Obtained invalid connection handle"); return JAYLINK_ERR_PROTO; } @@ -1688,7 +1688,7 @@ ret = transport_start_write_read(devh, 14, REG_MIN_SIZE, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1696,7 +1696,7 @@ ret = transport_write(devh, buf, 14); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1704,7 +1704,7 @@ ret = transport_read(devh, buf, REG_MIN_SIZE); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -1715,12 +1715,12 @@ if (num > JAYLINK_MAX_CONNECTIONS) { log_err(ctx, "Maximum number of device connections exceeded: " - "%u.", num); + "%u", num); return JAYLINK_ERR_PROTO; } if (entry_size != REG_CONN_INFO_SIZE) { - log_err(ctx, "Invalid connection entry size: %u bytes.", + log_err(ctx, "Invalid connection entry size: %u bytes", entry_size); return JAYLINK_ERR_PROTO; } @@ -1730,7 +1730,7 @@ if (size > REG_MAX_SIZE) { log_err(ctx, "Maximum registration information size exceeded: " - "%u bytes.", size); + "%u bytes", size); return JAYLINK_ERR_PROTO; } @@ -1738,7 +1738,7 @@ ret = transport_start_read(devh, size - REG_MIN_SIZE); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_read() failed: %s.", + log_err(ctx, "transport_start_read() failed: %s", jaylink_strerror(ret)); return JAYLINK_ERR; } @@ -1747,7 +1747,7 @@ size - REG_MIN_SIZE); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return JAYLINK_ERR; } diff -Nru libjaylink-0.2.0/libjaylink/discovery.c libjaylink-0.3.1/libjaylink/discovery.c --- libjaylink-0.2.0/libjaylink/discovery.c 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/discovery.c 2022-08-27 08:10:29.000000000 +0000 @@ -87,7 +87,7 @@ ret = discovery_usb_scan(ctx); if (ret != JAYLINK_OK) { - log_err(ctx, "USB device discovery failed."); + log_err(ctx, "USB device discovery failed"); return ret; } } @@ -97,7 +97,7 @@ ret = discovery_tcp_scan(ctx); if (ret != JAYLINK_OK) { - log_err(ctx, "TCP/IP device discovery failed."); + log_err(ctx, "TCP/IP device discovery failed"); return ret; } } diff -Nru libjaylink-0.2.0/libjaylink/discovery_tcp.c libjaylink-0.3.1/libjaylink/discovery_tcp.c --- libjaylink-0.2.0/libjaylink/discovery_tcp.c 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/discovery_tcp.c 2022-08-27 08:10:29.000000000 +0000 @@ -160,46 +160,46 @@ * Use inet_ntoa() instead of inet_ntop() because the latter requires * at least Windows Vista. */ - log_dbg(ctx, "Received advertisement message (IPv4 address = %s).", + log_dbg(ctx, "Received advertisement message (IPv4 address = %s)", inet_ntoa(addr->sin_addr)); if (!parse_adv_message(&tmp, buffer)) { - log_dbg(ctx, "Received invalid advertisement message."); + log_dbg(ctx, "Received invalid advertisement message"); return NULL; } - log_dbg(ctx, "Found device (IPv4 address = %s).", tmp.ipv4_address); - log_dbg(ctx, "Device: MAC address = %02x:%02x:%02x:%02x:%02x:%02x.", + log_dbg(ctx, "Found device (IPv4 address = %s)", tmp.ipv4_address); + log_dbg(ctx, "Device: MAC address = %02x:%02x:%02x:%02x:%02x:%02x", tmp.mac_address[0], tmp.mac_address[1], tmp.mac_address[2], tmp.mac_address[3], tmp.mac_address[4], tmp.mac_address[5]); - log_dbg(ctx, "Device: Serial number = %u.", tmp.serial_number); + log_dbg(ctx, "Device: Serial number = %u", tmp.serial_number); if (tmp.has_product_name) - log_dbg(ctx, "Device: Product = %s.", tmp.product_name); + log_dbg(ctx, "Device: Product = %s", tmp.product_name); if (tmp.has_nickname) - log_dbg(ctx, "Device: Nickname = %s.", tmp.nickname); + log_dbg(ctx, "Device: Nickname = %s", tmp.nickname); dev = find_device(ctx->discovered_devs, &tmp); if (dev) { - log_dbg(ctx, "Ignoring already discovered device."); + log_dbg(ctx, "Ignoring already discovered device"); return NULL; } dev = find_device(ctx->devs, &tmp); if (dev) { - log_dbg(ctx, "Using existing device instance."); + log_dbg(ctx, "Using existing device instance"); return jaylink_ref_device(dev); } - log_dbg(ctx, "Allocating new device instance."); + log_dbg(ctx, "Allocating new device instance"); dev = device_allocate(ctx); if (!dev) { - log_warn(ctx, "Device instance malloc failed."); + log_warn(ctx, "Device instance malloc failed"); return NULL; } @@ -243,7 +243,7 @@ sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock < 0) { - log_err(ctx, "Failed to create discovery socket."); + log_err(ctx, "Failed to create discovery socket"); return JAYLINK_ERR; } @@ -252,7 +252,7 @@ if (!socket_set_option(sock, SOL_SOCKET, SO_BROADCAST, &opt_value, sizeof(opt_value))) { log_err(ctx, "Failed to enable broadcast option for discovery " - "socket."); + "socket"); socket_close(sock); return JAYLINK_ERR; } @@ -264,7 +264,7 @@ if (!socket_bind(sock, (struct sockaddr *)&addr, sizeof(struct sockaddr_in))) { - log_err(ctx, "Failed to bind discovery socket."); + log_err(ctx, "Failed to bind discovery socket"); socket_close(sock); return JAYLINK_ERR; } @@ -276,19 +276,19 @@ memset(buf, 0, DISC_MESSAGE_SIZE); memcpy(buf, "Discover", 8); - log_dbg(ctx, "Sending discovery message."); + log_dbg(ctx, "Sending discovery message"); length = DISC_MESSAGE_SIZE; if (!socket_sendto(sock, (char *)buf, &length, 0, (const struct sockaddr *)&addr, sizeof(addr))) { - log_err(ctx, "Failed to send discovery message."); + log_err(ctx, "Failed to send discovery message"); socket_close(sock); return JAYLINK_ERR_IO; } if (length < DISC_MESSAGE_SIZE) { - log_err(ctx, "Only sent %zu bytes of discovery message.", + log_err(ctx, "Only sent %zu bytes of discovery message", length); socket_close(sock); return JAYLINK_ERR_IO; @@ -317,7 +317,7 @@ if (!socket_recvfrom(sock, buf, &length, 0, (struct sockaddr *)&addr, &addr_length)) { log_warn(ctx, "Failed to receive advertisement " - "message."); + "message"); continue; } @@ -340,11 +340,11 @@ socket_close(sock); if (ret < 0) { - log_err(ctx, "select() failed."); + log_err(ctx, "select() failed"); return JAYLINK_ERR; } - log_dbg(ctx, "Found %zu TCP/IP device(s).", num_devs); + log_dbg(ctx, "Found %zu TCP/IP device(s)", num_devs); return JAYLINK_OK; } diff -Nru libjaylink-0.2.0/libjaylink/discovery_usb.c libjaylink-0.3.1/libjaylink/discovery_usb.c --- libjaylink-0.2.0/libjaylink/discovery_usb.c 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/discovery_usb.c 2022-08-27 08:10:29.000000000 +0000 @@ -147,7 +147,7 @@ ret = libusb_get_device_descriptor(usb_dev, &desc); if (ret != LIBUSB_SUCCESS) { - log_warn(ctx, "Failed to get device descriptor: %s.", + log_warn(ctx, "Failed to get device descriptor: %s", libusb_error_name(ret)); return NULL; } @@ -169,7 +169,7 @@ return NULL; log_dbg(ctx, "Found device (VID:PID = %04x:%04x, bus:address = " - "%03u:%03u).", desc.idVendor, desc.idProduct, + "%03u:%03u)", desc.idVendor, desc.idProduct, libusb_get_bus_number(usb_dev), libusb_get_device_address(usb_dev)); @@ -180,15 +180,15 @@ dev = find_device(ctx, usb_dev); if (dev) { - log_dbg(ctx, "Device: USB address = %u.", dev->usb_address); + log_dbg(ctx, "Device: USB address = %u", dev->usb_address); if (dev->has_serial_number) - log_dbg(ctx, "Device: Serial number = %u.", + log_dbg(ctx, "Device: Serial number = %u", dev->serial_number); else - log_dbg(ctx, "Device: Serial number = N/A."); + log_dbg(ctx, "Device: Serial number = N/A"); - log_dbg(ctx, "Using existing device instance."); + log_dbg(ctx, "Using existing device instance"); return jaylink_ref_device(dev); } @@ -196,7 +196,7 @@ ret = libusb_open(usb_dev, &usb_devh); if (ret != LIBUSB_SUCCESS) { - log_warn(ctx, "Failed to open device: %s.", + log_warn(ctx, "Failed to open device: %s", libusb_error_name(ret)); return NULL; } @@ -210,31 +210,31 @@ libusb_close(usb_devh); if (ret < 0) { - log_warn(ctx, "Failed to retrieve serial number: %s.", + log_warn(ctx, "Failed to retrieve serial number: %s", libusb_error_name(ret)); has_serial_number = false; } if (has_serial_number) { if (!parse_serial_number(buf, &serial_number)) { - log_warn(ctx, "Failed to parse serial number."); + log_warn(ctx, "Failed to parse serial number"); return NULL; } } - log_dbg(ctx, "Device: USB address = %u.", usb_address); + log_dbg(ctx, "Device: USB address = %u", usb_address); if (has_serial_number) - log_dbg(ctx, "Device: Serial number = %u.", serial_number); + log_dbg(ctx, "Device: Serial number = %u", serial_number); else - log_dbg(ctx, "Device: Serial number = N/A."); + log_dbg(ctx, "Device: Serial number = N/A"); - log_dbg(ctx, "Allocating new device instance."); + log_dbg(ctx, "Allocating new device instance"); dev = device_allocate(ctx); if (!dev) { - log_warn(ctx, "Device instance malloc failed."); + log_warn(ctx, "Device instance malloc failed"); return NULL; } @@ -258,10 +258,10 @@ if (ret == LIBUSB_ERROR_IO) { log_err(ctx, "Failed to retrieve device list: input/output " - "error."); + "error"); return JAYLINK_ERR_IO; } else if (ret < 0) { - log_err(ctx, "Failed to retrieve device list: %s.", + log_err(ctx, "Failed to retrieve device list: %s", libusb_error_name(ret)); return JAYLINK_ERR; } @@ -279,7 +279,7 @@ } libusb_free_device_list(devs, true); - log_dbg(ctx, "Found %zu USB device(s).", num); + log_dbg(ctx, "Found %zu USB device(s)", num); return JAYLINK_OK; } diff -Nru libjaylink-0.2.0/libjaylink/emucom.c libjaylink-0.3.1/libjaylink/emucom.c --- libjaylink-0.2.0/libjaylink/emucom.c 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/emucom.c 2022-08-27 08:10:29.000000000 +0000 @@ -105,7 +105,7 @@ ret = transport_start_write_read(devh, 10, 4, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -119,7 +119,7 @@ ret = transport_write(devh, buf, 10); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -127,7 +127,7 @@ ret = transport_read(devh, buf, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -143,14 +143,14 @@ } if (tmp & EMUCOM_ERR) { - log_err(ctx, "Failed to read from channel 0x%x: 0x%x.", + log_err(ctx, "Failed to read from channel 0x%x: 0x%x", channel, tmp); return JAYLINK_ERR_DEV; } if (tmp > *length) { log_err(ctx, "Requested at most %u bytes but device " - "returned %u bytes.", *length, tmp); + "returned %u bytes", *length, tmp); return JAYLINK_ERR_PROTO; } @@ -162,7 +162,7 @@ ret = transport_start_read(devh, tmp); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_read() failed: %s.", + log_err(ctx, "transport_start_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -170,7 +170,7 @@ ret = transport_read(devh, buffer, tmp); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -221,7 +221,7 @@ ret = transport_start_write(devh, 10, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write() failed: %s.", + log_err(ctx, "transport_start_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -235,7 +235,7 @@ ret = transport_write(devh, buf, 10); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -243,7 +243,7 @@ ret = transport_start_write_read(devh, *length, 4, false); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -251,7 +251,7 @@ ret = transport_write(devh, buffer, *length); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -259,7 +259,7 @@ ret = transport_read(devh, buf, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -270,14 +270,14 @@ return JAYLINK_ERR_DEV_NOT_SUPPORTED; if (tmp & EMUCOM_ERR) { - log_err(ctx, "Failed to write to channel 0x%x: 0x%x.", + log_err(ctx, "Failed to write to channel 0x%x: 0x%x", channel, tmp); return JAYLINK_ERR_DEV; } if (tmp > *length) { log_err(ctx, "Only %u bytes were supposed to be written, but " - "the device reported %u written bytes.", *length, tmp); + "the device reported %u written bytes", *length, tmp); return JAYLINK_ERR_PROTO; } diff -Nru libjaylink-0.2.0/libjaylink/fileio.c libjaylink-0.3.1/libjaylink/fileio.c --- libjaylink-0.2.0/libjaylink/fileio.c 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/fileio.c 2022-08-27 08:10:29.000000000 +0000 @@ -105,7 +105,7 @@ ret = transport_start_write(devh, 18 + filename_length, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write() failed: %s.", + log_err(ctx, "transport_start_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -131,7 +131,7 @@ ret = transport_write(devh, buf, 18 + filename_length); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -139,7 +139,7 @@ ret = transport_start_read(devh, *length); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_read() failed: %s.", + log_err(ctx, "transport_start_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -147,7 +147,7 @@ ret = transport_read(devh, buffer, *length); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -155,7 +155,7 @@ ret = transport_start_read(devh, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_read() failed: %s.", + log_err(ctx, "transport_start_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -163,7 +163,7 @@ ret = transport_read(devh, buf, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -240,7 +240,7 @@ ret = transport_start_write(devh, 18 + filename_length, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write() failed: %s.", + log_err(ctx, "transport_start_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -266,7 +266,7 @@ ret = transport_write(devh, buf, 18 + filename_length); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -274,7 +274,7 @@ ret = transport_start_write(devh, *length, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write() failed: %s.", + log_err(ctx, "transport_start_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -282,7 +282,7 @@ ret = transport_write(devh, buffer, *length); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -290,7 +290,7 @@ ret = transport_start_read(devh, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_read() failed: %s.", + log_err(ctx, "transport_start_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -298,7 +298,7 @@ ret = transport_read(devh, buf, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -359,7 +359,7 @@ ret = transport_start_write(devh, 6 + length, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write() failed: %s.", + log_err(ctx, "transport_start_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -377,7 +377,7 @@ ret = transport_write(devh, buf, 6 + length); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -385,7 +385,7 @@ ret = transport_start_read(devh, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_read() failed: %s.", + log_err(ctx, "transport_start_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -393,7 +393,7 @@ ret = transport_read(devh, buf, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -451,7 +451,7 @@ ret = transport_start_write(devh, 6 + length, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write() failed: %s.", + log_err(ctx, "transport_start_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -469,7 +469,7 @@ ret = transport_write(devh, buf, 6 + length); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -477,7 +477,7 @@ ret = transport_start_read(devh, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_read() failed: %s.", + log_err(ctx, "transport_start_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -485,7 +485,7 @@ ret = transport_read(devh, buf, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } diff -Nru libjaylink-0.2.0/libjaylink/jtag.c libjaylink-0.3.1/libjaylink/jtag.c --- libjaylink-0.2.0/libjaylink/jtag.c 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/jtag.c 2022-08-27 08:10:29.000000000 +0000 @@ -34,6 +34,10 @@ #define CMD_JTAG_IO_V3 0xcf #define CMD_JTAG_CLEAR_TRST 0xde #define CMD_JTAG_SET_TRST 0xdf +#define CMD_JTAG_CLEAR_TMS 0xc9 +#define CMD_JTAG_SET_TMS 0xca +#define CMD_JTAG_CLEAR_TCK 0xda +#define CMD_JTAG_SET_TCK 0xdb /** * Error code indicating that there is not enough free memory on the device to @@ -108,7 +112,7 @@ read_length, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -120,7 +124,7 @@ ret = transport_write(devh, buf, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -128,7 +132,7 @@ ret = transport_write(devh, tms, num_bytes); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -136,7 +140,7 @@ ret = transport_write(devh, tdi, num_bytes); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -144,7 +148,7 @@ ret = transport_read(devh, tdo, num_bytes); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -155,7 +159,7 @@ ret = transport_read(devh, &status, 1); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -163,7 +167,7 @@ if (status == JTAG_IO_ERR_NO_MEMORY) { return JAYLINK_ERR_DEV_NO_MEMORY; } else if (status > 0) { - log_err(ctx, "JTAG I/O operation failed: 0x%x.", status); + log_err(ctx, "JTAG I/O operation failed: 0x%x", status); return JAYLINK_ERR_DEV; } @@ -196,7 +200,7 @@ ret = transport_start_write(devh, 1, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write() failed: %s.", + log_err(ctx, "transport_start_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -206,7 +210,7 @@ ret = transport_write(devh, buf, 1); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -240,7 +244,7 @@ ret = transport_start_write(devh, 1, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write() failed: %s.", + log_err(ctx, "transport_start_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -250,7 +254,183 @@ ret = transport_write(devh, buf, 1); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + return JAYLINK_OK; +} + +/** + * Clear the JTAG test mode select (TMS) signal. + * + * @param[in,out] devh Device handle. + * + * @retval JAYLINK_OK Success. + * @retval JAYLINK_ERR_ARG Invalid arguments. + * @retval JAYLINK_ERR_TIMEOUT A timeout occurred. + * @retval JAYLINK_ERR_IO Input/output error. + * @retval JAYLINK_ERR Other error conditions. + * + * @since 0.3.0 + */ +JAYLINK_API int jaylink_jtag_clear_tms(struct jaylink_device_handle *devh) +{ + int ret; + struct jaylink_context *ctx; + uint8_t buf[1]; + + if (!devh) + return JAYLINK_ERR_ARG; + + ctx = devh->dev->ctx; + ret = transport_start_write(devh, 1, true); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_start_write() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + buf[0] = CMD_JTAG_CLEAR_TMS; + + ret = transport_write(devh, buf, 1); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_write() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + return JAYLINK_OK; +} + +/** + * Set the JTAG test mode select (TMS) signal. + * + * @param[in,out] devh Device handle. + * + * @retval JAYLINK_OK Success. + * @retval JAYLINK_ERR_ARG Invalid arguments. + * @retval JAYLINK_ERR_TIMEOUT A timeout occurred. + * @retval JAYLINK_ERR_IO Input/output error. + * @retval JAYLINK_ERR Other error conditions. + * + * @since 0.3.0 + */ +JAYLINK_API int jaylink_jtag_set_tms(struct jaylink_device_handle *devh) +{ + int ret; + struct jaylink_context *ctx; + uint8_t buf[1]; + + if (!devh) + return JAYLINK_ERR_ARG; + + ctx = devh->dev->ctx; + ret = transport_start_write(devh, 1, true); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_start_write() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + buf[0] = CMD_JTAG_SET_TMS; + + ret = transport_write(devh, buf, 1); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_write() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + return JAYLINK_OK; +} + +/** + * Clear the JTAG test clock (TCK) signal. + * + * @param[in,out] devh Device handle. + * + * @retval JAYLINK_OK Success. + * @retval JAYLINK_ERR_ARG Invalid arguments. + * @retval JAYLINK_ERR_TIMEOUT A timeout occurred. + * @retval JAYLINK_ERR_IO Input/output error. + * @retval JAYLINK_ERR Other error conditions. + * + * @since 0.3.0 + */ +JAYLINK_API int jaylink_jtag_clear_tck(struct jaylink_device_handle *devh) +{ + int ret; + struct jaylink_context *ctx; + uint8_t buf[1]; + + if (!devh) + return JAYLINK_ERR_ARG; + + ctx = devh->dev->ctx; + ret = transport_start_write(devh, 1, true); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_start_write() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + buf[0] = CMD_JTAG_CLEAR_TCK; + + ret = transport_write(devh, buf, 1); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_write() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + return JAYLINK_OK; +} + +/** + * Set the JTAG test clock (TCK) signal. + * + * @param[in,out] devh Device handle. + * + * @retval JAYLINK_OK Success. + * @retval JAYLINK_ERR_ARG Invalid arguments. + * @retval JAYLINK_ERR_TIMEOUT A timeout occurred. + * @retval JAYLINK_ERR_IO Input/output error. + * @retval JAYLINK_ERR Other error conditions. + * + * @since 0.3.0 + */ +JAYLINK_API int jaylink_jtag_set_tck(struct jaylink_device_handle *devh) +{ + int ret; + struct jaylink_context *ctx; + uint8_t buf[1]; + + if (!devh) + return JAYLINK_ERR_ARG; + + ctx = devh->dev->ctx; + ret = transport_start_write(devh, 1, true); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_start_write() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + buf[0] = CMD_JTAG_SET_TCK; + + ret = transport_write(devh, buf, 1); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } diff -Nru libjaylink-0.2.0/libjaylink/libjaylink.h libjaylink-0.3.1/libjaylink/libjaylink.h --- libjaylink-0.2.0/libjaylink/libjaylink.h 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/libjaylink.h 2022-08-27 08:10:29.000000000 +0000 @@ -156,7 +156,9 @@ /** Device supports EMUCOM. */ JAYLINK_DEV_CAP_EMUCOM = 33, /** Device supports ethernet connectivity. */ - JAYLINK_DEV_CAP_ETHERNET = 38 + JAYLINK_DEV_CAP_ETHERNET = 38, + /** Device supports SPI. */ + JAYLINK_DEV_CAP_SPI = 56, }; /** Hardware information. */ @@ -204,7 +206,9 @@ * @note The value is valid only if the device is configured in DHCP * mode. */ - JAYLINK_HW_INFO_IPV4_DNS = (1 << 19) + JAYLINK_HW_INFO_IPV4_DNS = (1 << 19), + /** USB voltage in mV. */ + JAYLINK_HW_INFO_VUSB = (1 << 23), }; /** Device counters. */ @@ -240,6 +244,12 @@ JAYLINK_TIF_FINE = 3, /** 2-wire JTAG for PIC32 compliant devices. */ JAYLINK_TIF_2W_JTAG_PIC32 = 4, + /** Serial Peripheral Interface (SPI). */ + JAYLINK_TIF_SPI = 5, + /** Silicon Labs 2-wire interface (C2). */ + JAYLINK_TIF_C2 = 6, + /** Compact JTAG (cJTAG). **/ + JAYLINK_TIF_CJTAG = 7, }; /** @@ -266,6 +276,22 @@ JAYLINK_SWO_MODE_UART = 0 }; +/** Serial Peripheral Interface (SPI) flags. */ +enum jaylink_spi_flag { + /** Do not drive chip select (CS) before the transfer begins. */ + JAYLINK_SPI_FLAG_CS_START_U = 0x00, + /** Drive chip select (CS) low before the transfer begins. */ + JAYLINK_SPI_FLAG_CS_START_0 = 0x02, + /** Drive chip select (CS) high before the transfer begins. */ + JAYLINK_SPI_FLAG_CS_START_1 = 0x03, + /** Do not drive chip select (CS) after the transfer is complete. */ + JAYLINK_SPI_FLAG_CS_END_U = 0x00, + /** Drive chip select (CS) low after the transfer is complete. */ + JAYLINK_SPI_FLAG_CS_END_0 = 0x08, + /** Drive chip select (CS) high after the transfer is complete. */ + JAYLINK_SPI_FLAG_CS_END_1 = 0x0c, +}; + /** Target interface speed information. */ struct jaylink_speed { /** Base frequency in Hz. */ @@ -401,6 +427,9 @@ */ #define JAYLINK_EMUCOM_CHANNEL_USER 0x10000 +/** Maximum length of a 2-wire (C2) interface data transfer. */ +#define JAYLINK_C2_MAX_LENGTH 64 + /** * @struct jaylink_context * @@ -451,6 +480,17 @@ JAYLINK_API int jaylink_exit(struct jaylink_context *ctx); JAYLINK_API bool jaylink_library_has_cap(enum jaylink_capability cap); +/*--- c2.c ------------------------------------------------------------------*/ + +JAYLINK_API int jaylink_c2_read_address(struct jaylink_device_handle *devh, + uint8_t *address); +JAYLINK_API int jaylink_c2_write_address(struct jaylink_device_handle *devh, + uint8_t address); +JAYLINK_API int jaylink_c2_read_data(struct jaylink_device_handle *devh, + uint8_t *data, uint8_t length); +JAYLINK_API int jaylink_c2_write_data(struct jaylink_device_handle *devh, + const uint8_t *data, uint8_t length); + /*--- device.c --------------------------------------------------------------*/ JAYLINK_API int jaylink_get_devices(struct jaylink_context *ctx, @@ -553,6 +593,10 @@ uint16_t length, enum jaylink_jtag_version version); JAYLINK_API int jaylink_jtag_clear_trst(struct jaylink_device_handle *devh); JAYLINK_API int jaylink_jtag_set_trst(struct jaylink_device_handle *devh); +JAYLINK_API int jaylink_jtag_clear_tms(struct jaylink_device_handle *devh); +JAYLINK_API int jaylink_jtag_set_tms(struct jaylink_device_handle *devh); +JAYLINK_API int jaylink_jtag_clear_tck(struct jaylink_device_handle *devh); +JAYLINK_API int jaylink_jtag_set_tck(struct jaylink_device_handle *devh); /*--- log.c -----------------------------------------------------------------*/ @@ -567,10 +611,20 @@ JAYLINK_API const char *jaylink_log_get_domain( const struct jaylink_context *ctx); +/*--- spi.c -----------------------------------------------------------------*/ + +JAYLINK_API int jaylink_spi_io(struct jaylink_device_handle *devh, + const uint8_t *mosi, uint8_t *miso, uint32_t length, + uint32_t flags); + /*--- strutil.c -------------------------------------------------------------*/ JAYLINK_API int jaylink_parse_serial_number(const char *str, uint32_t *serial_number); +JAYLINK_API const char *jaylink_hardware_type_string( + enum jaylink_hardware_type type); +JAYLINK_API const char *jaylink_target_interface_string( + enum jaylink_target_interface iface); /*--- swd.c -----------------------------------------------------------------*/ diff -Nru libjaylink-0.2.0/libjaylink/libjaylink-internal.h libjaylink-0.3.1/libjaylink/libjaylink-internal.h --- libjaylink-0.2.0/libjaylink/libjaylink-internal.h 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/libjaylink-internal.h 2022-08-27 08:10:29.000000000 +0000 @@ -255,6 +255,8 @@ /*--- socket.c --------------------------------------------------------------*/ +JAYLINK_PRIV int socket_connect(int sock, const struct sockaddr *address, + size_t address_length, size_t timeout); JAYLINK_PRIV bool socket_close(int sock); JAYLINK_PRIV bool socket_bind(int sock, const struct sockaddr *address, size_t length); @@ -267,8 +269,11 @@ size_t address_length); JAYLINK_PRIV bool socket_recvfrom(int sock, void *buffer, size_t *length, int flags, struct sockaddr *address, size_t *address_length); +JAYLINK_PRIV bool socket_get_option(int sock, int level, int option, + void *value, size_t *length); JAYLINK_PRIV bool socket_set_option(int sock, int level, int option, const void *value, size_t length); +JAYLINK_PRIV bool socket_set_blocking(int sock, bool blocking); /*--- transport.c -----------------------------------------------------------*/ diff -Nru libjaylink-0.2.0/libjaylink/Makefile.am libjaylink-0.3.1/libjaylink/Makefile.am --- libjaylink-0.2.0/libjaylink/Makefile.am 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/Makefile.am 2022-08-27 08:10:29.000000000 +0000 @@ -30,6 +30,7 @@ libjaylink_la_SOURCES = \ buffer.c \ core.c \ + c2.c \ device.c \ discovery.c \ discovery_tcp.c \ @@ -40,6 +41,7 @@ list.c \ log.c \ socket.c \ + spi.c \ strutil.c \ swd.c \ swo.c \ diff -Nru libjaylink-0.2.0/libjaylink/socket.c libjaylink-0.3.1/libjaylink/socket.c --- libjaylink-0.2.0/libjaylink/socket.c 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/socket.c 2022-08-27 08:10:29.000000000 +0000 @@ -17,12 +17,14 @@ * along with this program. If not, see . */ +#include #ifdef _WIN32 #include #else #include #include #include +#include #endif #include "libjaylink.h" @@ -35,6 +37,73 @@ */ /** + * Initiate a connection on a socket. + * + * @param[in] sock Socket descriptor. + * @param[in] address Address to establish the connection. + * @param[in] length Length of the structure pointed to by @p address in bytes. + * @param[in] timeout Connection timeout in milliseconds, 0 for no timeout. + * + * @retval JAYLINK_OK Success. + * @retval JAYLINK_ERR_ARG Invalid arguments. + * @retval JAYLINK_ERR_TIMEOUT A timeout occurred. + * @retval JAYLINK_ERR Other error conditions. + */ +JAYLINK_PRIV int socket_connect(int sock, const struct sockaddr *address, + size_t address_length, size_t timeout) +{ + int ret; + fd_set fds; + struct timeval tv; + int socket_error; + size_t option_length; + + if (!address) + return JAYLINK_ERR_ARG; + + if (!socket_set_blocking(sock, false)) + return JAYLINK_ERR; +#ifdef _WIN32 + ret = connect(sock, address, address_length); + + if (ret != 0 && WSAGetLastError() != WSAEWOULDBLOCK) + return JAYLINK_ERR; +#else + errno = 0; + ret = connect(sock, address, address_length); + + if (ret != 0 && errno != EINPROGRESS) + return JAYLINK_ERR; +#endif + if (!ret) + return JAYLINK_OK; + + FD_ZERO(&fds); + FD_SET(sock, &fds); + + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + + ret = select(sock + 1, NULL, &fds, NULL, &tv); + + socket_set_blocking(sock, true); + + if (!ret) + return JAYLINK_ERR_TIMEOUT; + + option_length = sizeof(socket_error); + + if (!socket_get_option(sock, SOL_SOCKET, SO_ERROR, &socket_error, + &option_length)) + return JAYLINK_ERR; + + if (!socket_error) + return JAYLINK_OK; + + return JAYLINK_ERR; +} + +/** * Close a socket. * * @param[in] sock Socket descriptor. @@ -237,7 +306,27 @@ } /** - * Set an option on a socket. + * Get the value of a socket option. + * + * @param[in] sock Socket descriptor. + * @param[in] level Level at which the option is defined. + * @param[in] option Option to get the value for. + * @param[in] value Buffer to store the value. + * @param[in] length Length of the value buffer in bytes. + * + * @return Whether the option value was retrieved successfully. + */ +JAYLINK_PRIV bool socket_get_option(int sock, int level, int option, + void *value, size_t *length) +{ + if (!getsockopt(sock, level, option, value, (socklen_t *)length)) + return true; + + return false; +} + +/** + * Set the value of a socket option. * * @param[in] sock Socket descriptor. * @param[in] level Level at which the option is defined. @@ -245,7 +334,7 @@ * @param[in] value Buffer of the value to be set. * @param[in] length Length of the value buffer in bytes. * - * @return Whether the option was set successfully. + * @return Whether the option value was set successfully. */ JAYLINK_PRIV bool socket_set_option(int sock, int level, int option, const void *value, size_t length) @@ -255,3 +344,43 @@ return false; } + +/** + * Set the blocking mode of a socket. + * + * @param[in] sock Socket descriptor. + * @param[in] blocking Blocking mode. + * + * @return Whether the blocking mode was set successfully. + */ +JAYLINK_PRIV bool socket_set_blocking(int sock, bool blocking) +{ + int ret; +#ifdef _WIN32 + u_long mode; + + mode = !blocking; + ret = ioctlsocket(sock, FIONBIO, &mode); + + if (ret != NO_ERROR) + return false; +#else + int flags; + + flags = fcntl(sock, F_GETFL, 0); + + if (flags < 0) + return false; + + if (blocking) + flags &= ~O_NONBLOCK; + else + flags |= O_NONBLOCK; + + ret = fcntl(sock, F_SETFL, flags); + + if (ret != 0) + return false; +#endif + return true; +} diff -Nru libjaylink-0.2.0/libjaylink/spi.c libjaylink-0.3.1/libjaylink/spi.c --- libjaylink-0.2.0/libjaylink/spi.c 1970-01-01 00:00:00.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/spi.c 2022-08-27 08:10:29.000000000 +0000 @@ -0,0 +1,148 @@ +/* + * This file is part of the libjaylink project. + * + * Copyright (C) 2016-2020 Marc Schink + * + * 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 2 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, see . + */ + +#include + +#include "libjaylink.h" +#include "libjaylink-internal.h" + +/** + * @file + * + * Serial Peripheral Interface (SPI) functions. + */ + +/** @cond PRIVATE */ +#define CMD_SPI 0x15 + +#define SPI_CMD_IO 0x01 +/** @endcond */ + +/** + * Perform SPI I/O operation. + * + * The device acts as master and operates in mode 3 (CPOL = 1, CPHA = 1). Data + * is transferred with the most significant bit (MSB) first. + * + * @note This function must only be used if the device has the + * #JAYLINK_DEV_CAP_SPI capability and if the #JAYLINK_TIF_SPI interface + * is available and selected. + * + * @param[in,out] devh Device handle. + * @param[in] mosi Buffer to read MOSI data from. Can be NULL. + * @param[out] miso Buffer to store MISO data on success. Its content + * is undefined on failure. The buffer must be large enough to + * contain at least the specified number of bytes to transfer. + * Can be NULL. + * @param[in] length Number of bytes to transfer. + * @param[in] flags Flags, see #jaylink_spi_flag for more details. + * + * @retval JAYLINK_OK Success. + * @retval JAYLINK_ERR_ARG Invalid arguments. + * @retval JAYLINK_ERR_TIMEOUT A timeout occurred. + * @retval JAYLINK_ERR_PROTO Protocol violation. + * @retval JAYLINK_ERR Other error conditions. + * + * @since 0.3.0 + */ +JAYLINK_API int jaylink_spi_io(struct jaylink_device_handle *devh, + const uint8_t *mosi, uint8_t *miso, uint32_t length, + uint32_t flags) +{ + int ret; + struct jaylink_context *ctx; + uint8_t buf[20]; + uint32_t mosi_length; + uint32_t miso_length; + uint32_t num_transferred_bytes; + + if (!devh || !length) + return JAYLINK_ERR_ARG; + + if (!mosi && !miso) + return JAYLINK_ERR_ARG; + + mosi_length = (mosi) ? length : 0; + miso_length = (miso) ? length : 0; + ctx = devh->dev->ctx; + + buf[0] = CMD_SPI; + buf[1] = SPI_CMD_IO; + buf[2] = 0x00; + buf[3] = 0x00; + + buffer_set_u32(buf, mosi_length + 8, 4); + buffer_set_u32(buf, miso_length + 4, 8); + buffer_set_u32(buf, length * 8, 12); + buffer_set_u32(buf, flags, 16); + + ret = transport_start_write_read(devh, 20 + mosi_length, + miso_length + 4, true); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_start_write_read() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + ret = transport_write(devh, buf, 20); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_write() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + if (mosi) { + ret = transport_write(devh, mosi, mosi_length); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_write() failed: %s", + jaylink_strerror(ret)); + return ret; + } + } + + if (miso) { + ret = transport_read(devh, miso, miso_length); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_read() failed: %s", + jaylink_strerror(ret)); + return ret; + } + } + + ret = transport_read(devh, buf, 4); + + if (ret != JAYLINK_OK) { + log_err(ctx, "transport_read() failed: %s", + jaylink_strerror(ret)); + return ret; + } + + num_transferred_bytes = buffer_get_u32(buf, 0); + + if (num_transferred_bytes != length) { + log_err(ctx, "Unexpected number of transferred bytes"); + return JAYLINK_ERR_PROTO; + } + + return JAYLINK_OK; +} diff -Nru libjaylink-0.2.0/libjaylink/strutil.c libjaylink-0.3.1/libjaylink/strutil.c --- libjaylink-0.2.0/libjaylink/strutil.c 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/strutil.c 2022-08-27 08:10:29.000000000 +0000 @@ -64,3 +64,67 @@ return JAYLINK_OK; } + +/** + * Get the string representation of a hardware type. + * + * @param[in] type Hardware type. + * + * @return The string representation of the given hardware type, or NULL + * for an unknown type. + * + * @since 0.3.0 + */ +JAYLINK_API const char *jaylink_hardware_type_string( + enum jaylink_hardware_type type) +{ + switch (type) { + case JAYLINK_HW_TYPE_JLINK: + return "J-Link"; + case JAYLINK_HW_TYPE_FLASHER: + return "Flasher"; + case JAYLINK_HW_TYPE_JLINK_PRO: + return "J-Link PRO"; + default: + break; + } + + return NULL; +} + +/** + * Get the string representation of a target interface. + * + * @param[in] iface Target interface. + * + * @return The string representation of the given target interface, or NULL + * for an unknown interface. + * + * @since 0.3.0 + */ +JAYLINK_API const char *jaylink_target_interface_string( + enum jaylink_target_interface iface) +{ + switch (iface) { + case JAYLINK_TIF_JTAG: + return "JTAG"; + case JAYLINK_TIF_SWD: + return "SWD"; + case JAYLINK_TIF_BDM3: + return "BDM3"; + case JAYLINK_TIF_FINE: + return "FINE"; + case JAYLINK_TIF_2W_JTAG_PIC32: + return "2-wire JTAG for PIC32"; + case JAYLINK_TIF_SPI: + return "SPI"; + case JAYLINK_TIF_C2: + return "C2"; + case JAYLINK_TIF_CJTAG: + return "cJTAG"; + default: + break; + } + + return NULL; +} diff -Nru libjaylink-0.2.0/libjaylink/swd.c libjaylink-0.3.1/libjaylink/swd.c --- libjaylink-0.2.0/libjaylink/swd.c 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/swd.c 2022-08-27 08:10:29.000000000 +0000 @@ -88,7 +88,7 @@ num_bytes + 1, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -100,7 +100,7 @@ ret = transport_write(devh, buf, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -108,7 +108,7 @@ ret = transport_write(devh, direction, num_bytes); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -116,7 +116,7 @@ ret = transport_write(devh, out, num_bytes); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -124,7 +124,7 @@ ret = transport_read(devh, in, num_bytes); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -132,7 +132,7 @@ ret = transport_read(devh, &status, 1); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -140,7 +140,7 @@ if (status == SWD_IO_ERR_NO_MEMORY) { return JAYLINK_ERR_DEV_NO_MEMORY; } else if (status > 0) { - log_err(ctx, "SWD I/O operation failed: 0x%x.", status); + log_err(ctx, "SWD I/O operation failed: 0x%x", status); return JAYLINK_ERR_DEV; } diff -Nru libjaylink-0.2.0/libjaylink/swo.c libjaylink-0.3.1/libjaylink/swo.c --- libjaylink-0.2.0/libjaylink/swo.c 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/swo.c 2022-08-27 08:10:29.000000000 +0000 @@ -86,7 +86,7 @@ ret = transport_start_write_read(devh, 21, 4, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -111,7 +111,7 @@ ret = transport_write(devh, buf, 21); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -119,7 +119,7 @@ ret = transport_read(devh, buf, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -127,7 +127,7 @@ status = buffer_get_u32(buf, 0); if (status > 0) { - log_err(ctx, "Failed to start capture: 0x%x.", status); + log_err(ctx, "Failed to start capture: 0x%x", status); return JAYLINK_ERR_DEV; } @@ -167,7 +167,7 @@ ret = transport_start_write_read(devh, 3, 4, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -179,7 +179,7 @@ ret = transport_write(devh, buf, 3); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -187,7 +187,7 @@ ret = transport_read(devh, buf, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -195,7 +195,7 @@ status = buffer_get_u32(buf, 0); if (status > 0) { - log_err(ctx, "Failed to stop capture: 0x%x.", status); + log_err(ctx, "Failed to stop capture: 0x%x", status); return JAYLINK_ERR_DEV; } @@ -243,7 +243,7 @@ ret = transport_start_write_read(devh, 9, 8, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -260,7 +260,7 @@ ret = transport_write(devh, buf, 9); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -268,7 +268,7 @@ ret = transport_read(devh, buf, 8); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -278,7 +278,7 @@ if (tmp > *length) { log_err(ctx, "Received %u bytes but only %u bytes were " - "requested.", tmp, *length); + "requested", tmp, *length); return JAYLINK_ERR_PROTO; } @@ -288,7 +288,7 @@ ret = transport_start_read(devh, tmp); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_read() failed: %s.", + log_err(ctx, "transport_start_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -296,14 +296,14 @@ ret = transport_read(devh, buffer, tmp); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } } if (status > 0) { - log_err(ctx, "Failed to read data: 0x%x.", status); + log_err(ctx, "Failed to read data: 0x%x", status); return JAYLINK_ERR_DEV; } @@ -361,7 +361,7 @@ ret = transport_start_write_read(devh, 9, 4, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -378,7 +378,7 @@ ret = transport_write(devh, buf, 9); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -386,7 +386,7 @@ ret = transport_read(devh, buf, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -394,7 +394,7 @@ tmp = buffer_get_u32(buf, 0); if (tmp & SWO_ERR) { - log_err(ctx, "Failed to retrieve speed information: 0x%x.", + log_err(ctx, "Failed to retrieve speed information: 0x%x", tmp); return JAYLINK_ERR_DEV; } @@ -402,7 +402,7 @@ length = tmp; if (length != 28) { - log_err(ctx, "Unexpected number of bytes received: %u.", + log_err(ctx, "Unexpected number of bytes received: %u", length); return JAYLINK_ERR_PROTO; } @@ -411,7 +411,7 @@ ret = transport_start_read(devh, length); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_read() failed: %s.", + log_err(ctx, "transport_start_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -419,7 +419,7 @@ ret = transport_read(devh, buf, length); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -428,7 +428,7 @@ speed->min_div = buffer_get_u32(buf, 8); if (!speed->min_div) { - log_err(ctx, "Minimum frequency divider is zero."); + log_err(ctx, "Minimum frequency divider is zero"); return JAYLINK_ERR_PROTO; } @@ -436,7 +436,7 @@ if (speed->max_div < speed->min_div) { log_err(ctx, "Maximum frequency divider is less than minimum " - "frequency divider."); + "frequency divider"); return JAYLINK_ERR_PROTO; } @@ -445,7 +445,7 @@ if (speed->max_prescaler < speed->min_prescaler) { log_err(ctx, "Maximum prescaler is less than minimum " - "prescaler."); + "prescaler"); return JAYLINK_ERR_PROTO; } diff -Nru libjaylink-0.2.0/libjaylink/target.c libjaylink-0.3.1/libjaylink/target.c --- libjaylink-0.2.0/libjaylink/target.c 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/target.c 2022-08-27 08:10:29.000000000 +0000 @@ -74,7 +74,7 @@ ret = transport_start_write(devh, 3, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write() failed: %s.", + log_err(ctx, "transport_start_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -85,7 +85,7 @@ ret = transport_write(devh, buf, 3); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -140,7 +140,7 @@ ret = transport_start_write_read(devh, 1, 6, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -150,7 +150,7 @@ ret = transport_write(devh, buf, 1); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -158,7 +158,7 @@ ret = transport_read(devh, buf, 6); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -166,7 +166,7 @@ div = buffer_get_u16(buf, 4); if (!div) { - log_err(ctx, "Minimum frequency divider is zero."); + log_err(ctx, "Minimum frequency divider is zero"); return JAYLINK_ERR_PROTO; } @@ -217,6 +217,9 @@ case JAYLINK_TIF_BDM3: case JAYLINK_TIF_FINE: case JAYLINK_TIF_2W_JTAG_PIC32: + case JAYLINK_TIF_SPI: + case JAYLINK_TIF_C2: + case JAYLINK_TIF_CJTAG: break; default: return JAYLINK_ERR_ARG; @@ -226,7 +229,7 @@ ret = transport_start_write_read(devh, 2, 4, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -237,7 +240,7 @@ ret = transport_write(devh, buf, 2); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -245,7 +248,7 @@ ret = transport_read(devh, buf, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -294,7 +297,7 @@ ret = transport_start_write_read(devh, 2, 4, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -305,7 +308,7 @@ ret = transport_write(devh, buf, 2); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -313,7 +316,7 @@ ret = transport_read(devh, buf, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -361,7 +364,7 @@ ret = transport_start_write_read(devh, 2, 4, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write_read() failed: %s.", + log_err(ctx, "transport_start_write_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -372,7 +375,7 @@ ret = transport_write(devh, buf, 2); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -380,7 +383,7 @@ ret = transport_read(devh, buf, 4); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_read() failed: %s.", + log_err(ctx, "transport_read() failed: %s", jaylink_strerror(ret)); return ret; } @@ -416,7 +419,7 @@ ret = transport_start_write(devh, 1, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write() failed: %s.", + log_err(ctx, "transport_start_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -426,7 +429,7 @@ ret = transport_write(devh, buf, 1); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -460,7 +463,7 @@ ret = transport_start_write(devh, 1, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_write() failed: %s.", + log_err(ctx, "transport_start_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -470,7 +473,7 @@ ret = transport_write(devh, buf, 1); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } @@ -513,7 +516,7 @@ ret = transport_start_write(devh, 2, true); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_start_wrte() failed: %s.", + log_err(ctx, "transport_start_wrte() failed: %s", jaylink_strerror(ret)); return ret; } @@ -524,7 +527,7 @@ ret = transport_write(devh, buf, 2); if (ret != JAYLINK_OK) { - log_err(ctx, "transport_write() failed: %s.", + log_err(ctx, "transport_write() failed: %s", jaylink_strerror(ret)); return ret; } diff -Nru libjaylink-0.2.0/libjaylink/transport.c libjaylink-0.3.1/libjaylink/transport.c --- libjaylink-0.2.0/libjaylink/transport.c 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/transport.c 2022-08-27 08:10:29.000000000 +0000 @@ -60,7 +60,7 @@ ret = transport_tcp_open(devh); break; default: - log_err(devh->dev->ctx, "BUG: Invalid host interface: %u.", + log_err(devh->dev->ctx, "BUG: Invalid host interface: %u", devh->dev->iface); return JAYLINK_ERR; } @@ -93,7 +93,7 @@ ret = transport_tcp_close(devh); break; default: - log_err(devh->dev->ctx, "BUG: Invalid host interface: %u.", + log_err(devh->dev->ctx, "BUG: Invalid host interface: %u", devh->dev->iface); return JAYLINK_ERR; } @@ -131,7 +131,7 @@ ret = transport_tcp_start_write(devh, length, has_command); break; default: - log_err(devh->dev->ctx, "BUG: Invalid host interface: %u.", + log_err(devh->dev->ctx, "BUG: Invalid host interface: %u", devh->dev->iface); return JAYLINK_ERR; } @@ -167,7 +167,7 @@ ret = transport_tcp_start_read(devh, length); break; default: - log_err(devh->dev->ctx, "BUG: Invalid host interface: %u.", + log_err(devh->dev->ctx, "BUG: Invalid host interface: %u", devh->dev->iface); return JAYLINK_ERR; } @@ -212,7 +212,7 @@ read_length, has_command); break; default: - log_err(devh->dev->ctx, "BUG: Invalid host interface: %u.", + log_err(devh->dev->ctx, "BUG: Invalid host interface: %u", devh->dev->iface); return JAYLINK_ERR; } @@ -258,7 +258,7 @@ ret = transport_tcp_write(devh, buffer, length); break; default: - log_err(devh->dev->ctx, "BUG: Invalid host interface: %u.", + log_err(devh->dev->ctx, "BUG: Invalid host interface: %u", devh->dev->iface); return JAYLINK_ERR; } @@ -300,7 +300,7 @@ ret = transport_tcp_read(devh, buffer, length); break; default: - log_err(devh->dev->ctx, "BUG: Invalid host interface: %u.", + log_err(devh->dev->ctx, "BUG: Invalid host interface: %u", devh->dev->iface); return JAYLINK_ERR; } diff -Nru libjaylink-0.2.0/libjaylink/transport_tcp.c libjaylink-0.3.1/libjaylink/transport_tcp.c --- libjaylink-0.2.0/libjaylink/transport_tcp.c 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/transport_tcp.c 2022-08-27 08:10:29.000000000 +0000 @@ -55,6 +55,8 @@ /** Buffer size in bytes. */ #define BUFFER_SIZE 2048 +/** Timeout for connection establishment in milliseconds. */ +#define CONNECT_TIMEOUT 5000 /** Timeout of a receive operation in milliseconds. */ #define RECV_TIMEOUT 5000 /** Timeout of a send operation in milliseconds. */ @@ -82,7 +84,7 @@ devh->buffer = malloc(devh->buffer_size); if (!devh->buffer) { - log_err(ctx, "Transport buffer malloc failed."); + log_err(ctx, "Transport buffer malloc failed"); return JAYLINK_ERR_MALLOC; } @@ -113,18 +115,18 @@ tmp = length; if (!socket_recv(devh->sock, buffer, &tmp, 0)) { - log_err(ctx, "Failed to receive data from device."); + log_err(ctx, "Failed to receive data from device"); return JAYLINK_ERR_IO; } else if (!tmp) { log_err(ctx, "Failed to receive data from device: " - "remote connection closed."); + "remote connection closed"); return JAYLINK_ERR_IO; } buffer += tmp; length -= tmp; - log_dbgio(ctx, "Received %zu bytes from device.", tmp); + log_dbgio(ctx, "Received %zu bytes from device", tmp); } return JAYLINK_OK; @@ -144,35 +146,35 @@ ret = _recv(devh, buf, sizeof(buf)); if (ret != JAYLINK_OK) { - log_err(ctx, "Failed to receive hello message."); + log_err(ctx, "Failed to receive hello message"); return ret; } if (buf[0] == RESP_MAX_CONNECTIONS) { - log_err(ctx, "Maximum number of connections reached."); + log_err(ctx, "Maximum number of connections reached"); return JAYLINK_ERR; } if (buf[0] != CMD_SERVER) { - log_err(ctx, "Invalid hello message received."); + log_err(ctx, "Invalid hello message received"); return JAYLINK_ERR_PROTO; } proto_version = buffer_get_u16(buf, 1); - log_dbg(ctx, "Protocol version: 0x%04x.", proto_version); + log_dbg(ctx, "Protocol version: 0x%04x", proto_version); length = buf[3]; ret = _recv(devh, (uint8_t *)name, length); if (ret != JAYLINK_OK) { - log_err(ctx, "Failed to receive server name."); + log_err(ctx, "Failed to receive server name"); return ret; } name[length] = '\0'; - log_dbg(ctx, "Server name: %s.", name); + log_dbg(ctx, "Server name: %s", name); return JAYLINK_OK; } @@ -189,7 +191,7 @@ if (!socket_set_option(devh->sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout))) { - log_err(ctx, "Failed to set socket receive timeout."); + log_err(ctx, "Failed to set socket receive timeout"); return JAYLINK_ERR; } @@ -197,7 +199,7 @@ if (!socket_set_option(devh->sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout))) { - log_err(ctx, "Failed to set socket send timeout."); + log_err(ctx, "Failed to set socket send timeout"); return JAYLINK_ERR; } #else @@ -208,7 +210,7 @@ if (!socket_set_option(devh->sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval))) { - log_err(ctx, "Failed to set socket receive timeout."); + log_err(ctx, "Failed to set socket receive timeout"); return JAYLINK_ERR; } @@ -217,7 +219,7 @@ if (!socket_set_option(devh->sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval))) { - log_err(ctx, "Failed to set socket send timeout."); + log_err(ctx, "Failed to set socket send timeout"); return JAYLINK_ERR; } #endif @@ -236,13 +238,13 @@ dev = devh->dev; ctx = dev->ctx; - log_dbg(ctx, "Trying to open device (IPv4 address = %s).", + log_dbg(ctx, "Trying to open device (IPv4 address = %s)", dev->ipv4_address); ret = initialize_handle(devh); if (ret != JAYLINK_OK) { - log_err(ctx, "Initialize device handle failed."); + log_err(ctx, "Initialize device handle failed"); return ret; } @@ -254,7 +256,7 @@ ret = getaddrinfo(dev->ipv4_address, PORT_STRING, &hints, &info); if (ret != 0) { - log_err(ctx, "Address lookup failed."); + log_err(ctx, "Address lookup failed"); cleanup_handle(devh); return JAYLINK_ERR; } @@ -267,8 +269,16 @@ if (sock < 0) continue; - if (!connect(sock, info->ai_addr, info->ai_addrlen)) + ret = socket_connect(sock, info->ai_addr, info->ai_addrlen, + CONNECT_TIMEOUT); + + if (ret == JAYLINK_ERR_TIMEOUT) { + freeaddrinfo(info); + cleanup_handle(devh); + return JAYLINK_ERR_TIMEOUT; + } else if (ret == JAYLINK_OK) { break; + } socket_close(sock); sock = -1; @@ -277,12 +287,12 @@ freeaddrinfo(info); if (sock < 0) { - log_err(ctx, "Failed to open device."); + log_err(ctx, "Failed to open device"); cleanup_handle(devh); return JAYLINK_ERR; } - log_dbg(ctx, "Device opened successfully."); + log_dbg(ctx, "Device opened successfully"); devh->sock = sock; ret = set_socket_timeouts(devh); @@ -310,12 +320,12 @@ ctx = devh->dev->ctx; - log_dbg(ctx, "Closing device (IPv4 address = %s).", + log_dbg(ctx, "Closing device (IPv4 address = %s)", devh->dev->ipv4_address); cleanup_handle(devh); - log_dbg(ctx, "Device closed successfully."); + log_dbg(ctx, "Device closed successfully"); return JAYLINK_OK; } @@ -330,15 +340,15 @@ ctx = devh->dev->ctx; - log_dbgio(ctx, "Starting write operation (length = %zu bytes).", + log_dbgio(ctx, "Starting write operation (length = %zu bytes)", length); if (devh->write_pos > 0) log_warn(ctx, "Last write operation left %zu bytes in the " - "buffer.", devh->write_pos); + "buffer", devh->write_pos); if (devh->write_length > 0) - log_warn(ctx, "Last write operation was not performed."); + log_warn(ctx, "Last write operation was not performed"); devh->write_length = length; devh->write_pos = 0; @@ -361,15 +371,15 @@ ctx = devh->dev->ctx; - log_dbgio(ctx, "Starting read operation (length = %zu bytes).", + log_dbgio(ctx, "Starting read operation (length = %zu bytes)", length); if (devh->bytes_available > 0) log_dbg(ctx, "Last read operation left %zu bytes in the " - "buffer.", devh->bytes_available); + "buffer", devh->bytes_available); if (devh->read_length > 0) - log_warn(ctx, "Last read operation left %zu bytes.", + log_warn(ctx, "Last read operation left %zu bytes", devh->read_length); devh->read_length = length; @@ -389,21 +399,21 @@ ctx = devh->dev->ctx; log_dbgio(ctx, "Starting write / read operation (length = " - "%zu / %zu bytes).", write_length, read_length); + "%zu / %zu bytes)", write_length, read_length); if (devh->write_pos > 0) log_warn(ctx, "Last write operation left %zu bytes in the " - "buffer.", devh->write_pos); + "buffer", devh->write_pos); if (devh->write_length > 0) - log_warn(ctx, "Last write operation was not performed."); + log_warn(ctx, "Last write operation was not performed"); if (devh->bytes_available > 0) log_warn(ctx, "Last read operation left %zu bytes in the " - "buffer.", devh->bytes_available); + "buffer", devh->bytes_available); if (devh->read_length > 0) - log_warn(ctx, "Last read operation left %zu bytes.", + log_warn(ctx, "Last read operation left %zu bytes", devh->read_length); devh->write_length = write_length; @@ -433,14 +443,14 @@ tmp = length; if (!socket_send(devh->sock, buffer, &tmp, 0)) { - log_err(ctx, "Failed to send data to device."); + log_err(ctx, "Failed to send data to device"); return JAYLINK_ERR_IO; } buffer += tmp; length -= tmp; - log_dbgio(ctx, "Sent %zu bytes to device.", tmp); + log_dbgio(ctx, "Sent %zu bytes to device", tmp); } return JAYLINK_OK; @@ -464,7 +474,7 @@ buffer = realloc(devh->buffer, size); if (!buffer) { - log_err(ctx, "Failed to adjust buffer size to %zu bytes.", + log_err(ctx, "Failed to adjust buffer size to %zu bytes", size); return false; } @@ -472,7 +482,7 @@ devh->buffer = buffer; devh->buffer_size = size; - log_dbg(ctx, "Adjusted buffer size to %zu bytes.", size); + log_dbg(ctx, "Adjusted buffer size to %zu bytes", size); return true; } @@ -488,7 +498,7 @@ if (length > devh->write_length) { log_err(ctx, "Requested to write %zu bytes but only %zu bytes " - "are expected for the write operation.", length, + "are expected for the write operation", length, devh->write_length); return JAYLINK_ERR_ARG; } @@ -508,7 +518,7 @@ devh->write_length -= length; devh->write_pos += length; - log_dbgio(ctx, "Wrote %zu bytes into buffer.", length); + log_dbgio(ctx, "Wrote %zu bytes into buffer", length); return JAYLINK_OK; } @@ -533,7 +543,7 @@ length -= tmp; buffer += tmp; - log_dbgio(ctx, "Buffer filled up with %zu bytes.", tmp); + log_dbgio(ctx, "Buffer filled up with %zu bytes", tmp); ret = _send(devh, devh->buffer, devh->write_pos + tmp); @@ -558,7 +568,7 @@ if (length > devh->read_length) { log_err(ctx, "Requested to read %zu bytes but only %zu bytes " - "are expected for the read operation.", length, + "are expected for the read operation", length, devh->read_length); return JAYLINK_ERR_ARG; } @@ -570,7 +580,7 @@ devh->bytes_available -= length; devh->read_pos += length; - log_dbgio(ctx, "Read %zu bytes from buffer.", length); + log_dbgio(ctx, "Read %zu bytes from buffer", length); return JAYLINK_OK; } @@ -582,7 +592,7 @@ length -= devh->bytes_available; devh->read_length -= devh->bytes_available; - log_dbgio(ctx, "Read %zu bytes from buffer to flush it.", + log_dbgio(ctx, "Read %zu bytes from buffer to flush it", devh->bytes_available); devh->bytes_available = 0; diff -Nru libjaylink-0.2.0/libjaylink/transport_usb.c libjaylink-0.3.1/libjaylink/transport_usb.c --- libjaylink-0.2.0/libjaylink/transport_usb.c 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/libjaylink/transport_usb.c 2022-08-27 08:10:29.000000000 +0000 @@ -65,7 +65,7 @@ ret = libusb_get_active_config_descriptor(devh->dev->usb_dev, &config); if (ret != LIBUSB_SUCCESS) { - log_err(ctx, "Failed to get configuration descriptor: %s.", + log_err(ctx, "Failed to get configuration descriptor: %s", libusb_error_name(ret)); return JAYLINK_ERR; } @@ -91,7 +91,7 @@ } if (!found_interface) { - log_err(ctx, "No suitable interface found."); + log_err(ctx, "No suitable interface found"); libusb_free_config_descriptor(config); return JAYLINK_ERR; } @@ -114,16 +114,16 @@ libusb_free_config_descriptor(config); if (!found_endpoint_in) { - log_err(ctx, "Interface IN endpoint not found."); + log_err(ctx, "Interface IN endpoint not found"); return JAYLINK_ERR; } if (!found_endpoint_out) { - log_err(ctx, "Interface OUT endpoint not found."); + log_err(ctx, "Interface OUT endpoint not found"); return JAYLINK_ERR; } - log_dbg(ctx, "Using endpoint %02x (IN) and %02x (OUT).", + log_dbg(ctx, "Using endpoint %02x (IN) and %02x (OUT)", devh->endpoint_in, devh->endpoint_out); /* Buffer size must be a multiple of CHUNK_SIZE bytes. */ @@ -131,7 +131,7 @@ devh->buffer = malloc(devh->buffer_size); if (!devh->buffer) { - log_err(ctx, "Transport buffer malloc failed."); + log_err(ctx, "Transport buffer malloc failed"); return JAYLINK_ERR_MALLOC; } @@ -160,21 +160,21 @@ dev = devh->dev; ctx = dev->ctx; - log_dbg(ctx, "Trying to open device (bus:address = %03u:%03u).", + log_dbg(ctx, "Trying to open device (bus:address = %03u:%03u)", libusb_get_bus_number(dev->usb_dev), libusb_get_device_address(dev->usb_dev)); ret = initialize_handle(devh); if (ret != JAYLINK_OK) { - log_err(ctx, "Initialize device handle failed."); + log_err(ctx, "Initialize device handle failed"); return ret; } ret = libusb_open(dev->usb_dev, &usb_devh); if (ret != LIBUSB_SUCCESS) { - log_err(ctx, "Failed to open device: %s.", + log_err(ctx, "Failed to open device: %s", libusb_error_name(ret)); cleanup_handle(devh); return JAYLINK_ERR; @@ -183,14 +183,14 @@ ret = libusb_claim_interface(usb_devh, devh->interface_number); if (ret != LIBUSB_SUCCESS) { - log_err(ctx, "Failed to claim interface: %s.", + log_err(ctx, "Failed to claim interface: %s", libusb_error_name(ret)); cleanup_handle(devh); libusb_close(usb_devh); return JAYLINK_ERR; } - log_dbg(ctx, "Device opened successfully."); + log_dbg(ctx, "Device opened successfully"); devh->usb_devh = usb_devh; @@ -206,7 +206,7 @@ dev = devh->dev; ctx = dev->ctx; - log_dbg(ctx, "Closing device (bus:address = %03u:%03u).", + log_dbg(ctx, "Closing device (bus:address = %03u:%03u)", libusb_get_bus_number(dev->usb_dev), libusb_get_device_address(dev->usb_dev)); @@ -216,12 +216,12 @@ cleanup_handle(devh); if (ret != LIBUSB_SUCCESS) { - log_err(ctx, "Failed to release interface: %s.", + log_err(ctx, "Failed to release interface: %s", libusb_error_name(ret)); return JAYLINK_ERR; } - log_dbg(ctx, "Device closed successfully."); + log_dbg(ctx, "Device closed successfully"); return JAYLINK_OK; } @@ -238,14 +238,14 @@ ctx = devh->dev->ctx; - log_dbgio(ctx, "Starting write operation (length = %zu bytes).", length); + log_dbgio(ctx, "Starting write operation (length = %zu bytes)", length); if (devh->write_pos > 0) log_warn(ctx, "Last write operation left %zu bytes in the " - "buffer.", devh->write_pos); + "buffer", devh->write_pos); if (devh->write_length > 0) - log_warn(ctx, "Last write operation was not performed."); + log_warn(ctx, "Last write operation was not performed"); devh->write_length = length; devh->write_pos = 0; @@ -263,15 +263,15 @@ ctx = devh->dev->ctx; - log_dbgio(ctx, "Starting read operation (length = %zu bytes).", + log_dbgio(ctx, "Starting read operation (length = %zu bytes)", length); if (devh->bytes_available > 0) log_dbg(ctx, "Last read operation left %zu bytes in the " - "buffer.", devh->bytes_available); + "buffer", devh->bytes_available); if (devh->read_length > 0) - log_warn(ctx, "Last read operation left %zu bytes.", + log_warn(ctx, "Last read operation left %zu bytes", devh->read_length); devh->read_length = length; @@ -293,21 +293,21 @@ ctx = devh->dev->ctx; log_dbgio(ctx, "Starting write / read operation (length = " - "%zu / %zu bytes).", write_length, read_length); + "%zu / %zu bytes)", write_length, read_length); if (devh->write_pos > 0) log_warn(ctx, "Last write operation left %zu bytes in the " - "buffer.", devh->write_pos); + "buffer", devh->write_pos); if (devh->write_length > 0) - log_warn(ctx, "Last write operation was not performed."); + log_warn(ctx, "Last write operation was not performed"); if (devh->bytes_available > 0) log_warn(ctx, "Last read operation left %zu bytes in the " - "buffer.", devh->bytes_available); + "buffer", devh->bytes_available); if (devh->read_length > 0) - log_warn(ctx, "Last read operation left %zu bytes.", + log_warn(ctx, "Last read operation left %zu bytes", devh->read_length); devh->write_length = write_length; @@ -341,16 +341,16 @@ if (ret == LIBUSB_ERROR_TIMEOUT) { log_warn(ctx, "Failed to receive data from " - "device: %s.", libusb_error_name(ret)); + "device: %s", libusb_error_name(ret)); tries--; continue; } else if (ret != LIBUSB_SUCCESS) { log_err(ctx, "Failed to receive data from " - "device: %s.", libusb_error_name(ret)); + "device: %s", libusb_error_name(ret)); return JAYLINK_ERR; } - log_dbgio(ctx, "Received %i bytes from device.", transferred); + log_dbgio(ctx, "Received %i bytes from device", transferred); } /* Ignore a possible timeout if at least one byte was received. */ @@ -359,7 +359,7 @@ return JAYLINK_OK; } - log_err(ctx, "Receiving data from device timed out."); + log_err(ctx, "Receiving data from device timed out"); return JAYLINK_ERR_TIMEOUT; } @@ -382,7 +382,7 @@ buffer = realloc(devh->buffer, size); if (!buffer) { - log_err(ctx, "Failed to adjust buffer size to %zu bytes.", + log_err(ctx, "Failed to adjust buffer size to %zu bytes", size); return false; } @@ -390,7 +390,7 @@ devh->buffer = buffer; devh->buffer_size = size; - log_dbg(ctx, "Adjusted buffer size to %zu bytes.", size); + log_dbg(ctx, "Adjusted buffer size to %zu bytes", size); return true; } @@ -415,11 +415,11 @@ if (ret == LIBUSB_SUCCESS) { tries = NUM_TIMEOUTS; } else if (ret == LIBUSB_ERROR_TIMEOUT) { - log_warn(ctx, "Failed to send data to device: %s.", + log_warn(ctx, "Failed to send data to device: %s", libusb_error_name(ret)); tries--; } else { - log_err(ctx, "Failed to send data to device: %s.", + log_err(ctx, "Failed to send data to device: %s", libusb_error_name(ret)); return JAYLINK_ERR; } @@ -427,13 +427,13 @@ buffer += transferred; length -= transferred; - log_dbgio(ctx, "Sent %i bytes to device.", transferred); + log_dbgio(ctx, "Sent %i bytes to device", transferred); } if (!length) return JAYLINK_OK; - log_err(ctx, "Sending data to device timed out."); + log_err(ctx, "Sending data to device timed out"); return JAYLINK_ERR_TIMEOUT; } @@ -451,7 +451,7 @@ if (length > devh->write_length) { log_err(ctx, "Requested to write %zu bytes but only %zu bytes " - "are expected for the write operation.", length, + "are expected for the write operation", length, devh->write_length); return JAYLINK_ERR_ARG; } @@ -471,7 +471,7 @@ devh->write_length -= length; devh->write_pos += length; - log_dbgio(ctx, "Wrote %zu bytes into buffer.", length); + log_dbgio(ctx, "Wrote %zu bytes into buffer", length); return JAYLINK_OK; } @@ -506,7 +506,7 @@ length -= tmp; buffer += tmp; - log_dbgio(ctx, "Buffer filled up with %zu bytes.", tmp); + log_dbgio(ctx, "Buffer filled up with %zu bytes", tmp); } /* Send buffered data to the device. */ @@ -535,7 +535,7 @@ if (length > devh->read_length) { log_err(ctx, "Requested to read %zu bytes but only %zu bytes " - "are expected for the read operation.", length, + "are expected for the read operation", length, devh->read_length); return JAYLINK_ERR_ARG; } @@ -547,7 +547,7 @@ devh->bytes_available -= length; devh->read_pos += length; - log_dbgio(ctx, "Read %zu bytes from buffer.", length); + log_dbgio(ctx, "Read %zu bytes from buffer", length); return JAYLINK_OK; } @@ -559,7 +559,7 @@ length -= devh->bytes_available; devh->read_length -= devh->bytes_available; - log_dbgio(ctx, "Read %zu bytes from buffer to flush it.", + log_dbgio(ctx, "Read %zu bytes from buffer to flush it", devh->bytes_available); devh->bytes_available = 0; @@ -599,7 +599,7 @@ length -= tmp; devh->read_length -= tmp; - log_dbgio(ctx, "Read %zu bytes from buffer.", tmp); + log_dbgio(ctx, "Read %zu bytes from buffer", tmp); } else { ret = usb_recv(devh, buffer, &bytes_received); @@ -610,7 +610,7 @@ length -= bytes_received; devh->read_length -= bytes_received; - log_dbgio(ctx, "Read %zu bytes from device.", + log_dbgio(ctx, "Read %zu bytes from device", bytes_received); } } diff -Nru libjaylink-0.2.0/m4/jaylink.m4 libjaylink-0.3.1/m4/jaylink.m4 --- libjaylink-0.2.0/m4/jaylink.m4 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/m4/jaylink.m4 2022-08-27 08:10:29.000000000 +0000 @@ -24,22 +24,14 @@ m4_define([_JAYLINK_SET_PACKAGE_VERSION], [ m4_assert([$# == 5]) - # Get the short Git revision hash of the current commit. - git_version=`git --git-dir="$srcdir/.git" rev-parse \ - --short HEAD 2> /dev/null` + # Get the Git repository description. Ensure that we use our Git + # repository even when there is a parent Git repository. + git_version=`git -C "$srcdir" --git-dir=.git describe --dirty 2> /dev/null` - # Try to get the release tag for the package version from the current - # commit. - tag=`git --git-dir="$srcdir/.git" describe --match "$2" \ - --exact-match 2> /dev/null` - - version=$2 - - # If Git is available, append the short Git revision hash of the - # current commit to the version string if there is no release tag for - # the package version on it. - AS_IF([test -n "$git_version" && test -z "$tag"], - [version="$version-git-$git_version"]) + # If available, use the Git description as package version. Otherwise, + # use the version provided by Autoconf. + AS_IF([test -n "$git_version"], [version="$git_version"], + [version="$2"]) AC_SUBST([$1_MAJOR], [$3]) AC_SUBST([$1_MINOR], [$4]) diff -Nru libjaylink-0.2.0/NEWS libjaylink-0.3.1/NEWS --- libjaylink-0.2.0/NEWS 2020-07-11 11:41:36.000000000 +0000 +++ libjaylink-0.3.1/NEWS 2022-08-27 08:10:29.000000000 +0000 @@ -1,6 +1,26 @@ News ==== +0.3.1 (2022-08-24) +------------------ + + * Fix building with Autoconf < 2.7 + +0.3.0 (2022-08-15) +------------------ + + * New package version scheme + * New supported target interfaces: + - Silicon Labs 2-wire interface (C2) + - Serial peripheral interface (SPI) + - Compact JTAG (cJTAG) + * Add support for querying USB voltage + * jtag: Add functions to set/clear the TCK and TMS signals + * New string utility functions: + - jaylink_target_interface_string() + - jaylink_hardware_type_string() + * transport/tcp: Implement connection timeout + 0.2.0 (2020-07-11) ------------------