/* * This file is part of the libjaylink project. * * Copyright (C) 2014-2015 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 #include #include #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "libjaylink.h" #include "libjaylink-internal.h" /** * @file * * Transport abstraction layer. */ /** * Open a device. * * This function must be called before any other function of the transport * abstraction layer for the given device handle is called. * * @param[in,out] devh Device handle. * * @retval JAYLINK_OK Success. * @retval JAYLINK_ERR_IO Input/output error. * @retval JAYLINK_ERR Other error conditions. */ JAYLINK_PRIV int transport_open(struct jaylink_device_handle *devh) { int ret; switch (devh->dev->iface) { #ifdef HAVE_LIBUSB case JAYLINK_HIF_USB: ret = transport_usb_open(devh); break; #endif case JAYLINK_HIF_TCP: ret = transport_tcp_open(devh); break; default: log_err(devh->dev->ctx, "BUG: Invalid host interface: %u", devh->dev->iface); return JAYLINK_ERR; } return ret; } /** * Close a device. * * After this function has been called no other function of the transport * abstraction layer for the given device handle must be called. * * @param[in,out] devh Device handle. * * @retval JAYLINK_OK Success. * @retval JAYLINK_ERR Other error conditions. */ JAYLINK_PRIV int transport_close(struct jaylink_device_handle *devh) { int ret; switch (devh->dev->iface) { #ifdef HAVE_LIBUSB case JAYLINK_HIF_USB: ret = transport_usb_close(devh); break; #endif case JAYLINK_HIF_TCP: ret = transport_tcp_close(devh); break; default: log_err(devh->dev->ctx, "BUG: Invalid host interface: %u", devh->dev->iface); return JAYLINK_ERR; } return ret; } /** * Start a write operation for a device. * * The data of a write operation must be written with at least one call of * transport_write(). It is required that all data of a write operation is * written before an other write and/or read operation is started. * * @param[in,out] devh Device handle. * @param[in] length Number of bytes of the write operation. * @param[in] has_command Determines whether the data of the write operation * contains the protocol command. * * @retval JAYLINK_OK Success. * @retval JAYLINK_ERR_ARG Invalid arguments. */ JAYLINK_PRIV int transport_start_write(struct jaylink_device_handle *devh, size_t length, bool has_command) { int ret; switch (devh->dev->iface) { #ifdef HAVE_LIBUSB case JAYLINK_HIF_USB: ret = transport_usb_start_write(devh, length, has_command); break; #endif case JAYLINK_HIF_TCP: ret = transport_tcp_start_write(devh, length, has_command); break; default: log_err(devh->dev->ctx, "BUG: Invalid host interface: %u", devh->dev->iface); return JAYLINK_ERR; } return ret; } /** * Start a read operation for a device. * * The data of a read operation must be read with at least one call of * transport_read(). It is required that all data of a read operation is read * before an other write and/or read operation is started. * * @param[in,out] devh Device handle. * @param[in] length Number of bytes of the read operation. * * @retval JAYLINK_OK Success. * @retval JAYLINK_ERR_ARG Invalid arguments. */ JAYLINK_PRIV int transport_start_read(struct jaylink_device_handle *devh, size_t length) { int ret; switch (devh->dev->iface) { #ifdef HAVE_LIBUSB case JAYLINK_HIF_USB: ret = transport_usb_start_read(devh, length); break; #endif case JAYLINK_HIF_TCP: ret = transport_tcp_start_read(devh, length); break; default: log_err(devh->dev->ctx, "BUG: Invalid host interface: %u", devh->dev->iface); return JAYLINK_ERR; } return ret; } /** * Start a write and read operation for a device. * * This function starts a write and read operation as the consecutive call of * transport_start_write() and transport_start_read() but has a different * meaning from the protocol perspective and can therefore not be replaced by * these functions and vice versa. * * @note The write operation must be completed first before the read operation * must be processed. * * @param[in,out] devh Device handle. * @param[in] write_length Number of bytes of the write operation. * @param[in] read_length Number of bytes of the read operation. * @param[in] has_command Determines whether the data of the write operation * contains the protocol command. * * @retval JAYLINK_OK Success. * @retval JAYLINK_ERR_ARG Invalid arguments. */ JAYLINK_PRIV int transport_start_write_read(struct jaylink_device_handle *devh, size_t write_length, size_t read_length, bool has_command) { int ret; switch (devh->dev->iface) { #ifdef HAVE_LIBUSB case JAYLINK_HIF_USB: ret = transport_usb_start_write_read(devh, write_length, read_length, has_command); break; #endif case JAYLINK_HIF_TCP: ret = transport_tcp_start_write_read(devh, write_length, read_length, has_command); break; default: log_err(devh->dev->ctx, "BUG: Invalid host interface: %u", devh->dev->iface); return JAYLINK_ERR; } return ret; } /** * Write data to a device. * * Before this function is used transport_start_write() or * transport_start_write_read() must be called to start a write operation. The * total number of written bytes must not exceed the number of bytes of the * write operation. * * @note A write operation will be performed and the data will be sent to the * device when the number of written bytes reaches the number of bytes of * the write operation. Before that the data will be written into a * buffer. * * @param[in,out] devh Device handle. * @param[in] buffer Buffer to write data from. * @param[in] length Number of bytes to write. * * @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. */ JAYLINK_PRIV int transport_write(struct jaylink_device_handle *devh, const uint8_t *buffer, size_t length) { int ret; switch (devh->dev->iface) { #ifdef HAVE_LIBUSB case JAYLINK_HIF_USB: ret = transport_usb_write(devh, buffer, length); break; #endif case JAYLINK_HIF_TCP: ret = transport_tcp_write(devh, buffer, length); break; default: log_err(devh->dev->ctx, "BUG: Invalid host interface: %u", devh->dev->iface); return JAYLINK_ERR; } return ret; } /** * Read data from a device. * * Before this function is used transport_start_read() or * transport_start_write_read() must be called to start a read operation. The * total number of read bytes must not exceed the number of bytes of the read * operation. * * @param[in,out] devh Device handle. * @param[out] buffer Buffer to read data into on success. Its content is * undefined on failure. * @param[in] length Number of bytes to read. * * @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. */ JAYLINK_PRIV int transport_read(struct jaylink_device_handle *devh, uint8_t *buffer, size_t length) { int ret; switch (devh->dev->iface) { #ifdef HAVE_LIBUSB case JAYLINK_HIF_USB: ret = transport_usb_read(devh, buffer, length); break; #endif case JAYLINK_HIF_TCP: ret = transport_tcp_read(devh, buffer, length); break; default: log_err(devh->dev->ctx, "BUG: Invalid host interface: %u", devh->dev->iface); return JAYLINK_ERR; } return ret; }