/********************************************************************* * Software License Agreement (BSD License) * * Copyright (C) 2010-2012 Ken Tossell * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials provided * with the distribution. * * Neither the name of the author nor other contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. *********************************************************************/ /** * @defgroup ctrl Video capture and processing controls * @brief Functions for manipulating device settings and stream parameters * * The `uvc_get_*` and `uvc_set_*` functions are used to read and write the settings associated * with the device's input, processing and output units. */ #include "libuvc/libuvc.h" #include "libuvc/libuvc_internal.h" static const int REQ_TYPE_SET = 0x21; static const int REQ_TYPE_GET = 0xa1; /***** GENERIC CONTROLS *****/ /** * @brief Get the length of a control on a terminal or unit. * * @param devh UVC device handle * @param unit Unit or Terminal ID; obtain this from the uvc_extension_unit_t describing the extension unit * @param ctrl Vendor-specific control number to query * @return On success, the length of the control as reported by the device. Otherwise, * a uvc_error_t error describing the error encountered. * @ingroup ctrl */ int uvc_get_ctrl_len(uvc_device_handle_t *devh, uint8_t unit, uint8_t ctrl) { unsigned char buf[2]; int ret = libusb_control_transfer( devh->usb_devh, REQ_TYPE_GET, UVC_GET_LEN, ctrl << 8, unit << 8 | devh->info->ctrl_if.bInterfaceNumber, // XXX saki buf, 2, 0 /* timeout */); if (ret < 0) return ret; else return (unsigned short)SW_TO_SHORT(buf); } /** * @brief Perform a GET_* request from an extension unit. * * @param devh UVC device handle * @param unit Unit ID; obtain this from the uvc_extension_unit_t describing the extension unit * @param ctrl Control number to query * @param data Data buffer to be filled by the device * @param len Size of data buffer * @param req_code GET_* request to execute * @return On success, the number of bytes actually transferred. Otherwise, * a uvc_error_t error describing the error encountered. * @ingroup ctrl */ int uvc_get_ctrl(uvc_device_handle_t *devh, uint8_t unit, uint8_t ctrl, void *data, int len, enum uvc_req_code req_code) { return libusb_control_transfer( devh->usb_devh, REQ_TYPE_GET, req_code, ctrl << 8, unit << 8 | devh->info->ctrl_if.bInterfaceNumber, // XXX saki data, len, 0 /* timeout */); } /** * @brief Perform a SET_CUR request to a terminal or unit. * * @param devh UVC device handle * @param unit Unit or Terminal ID * @param ctrl Control number to set * @param data Data buffer to be sent to the device * @param len Size of data buffer * @return On success, the number of bytes actually transferred. Otherwise, * a uvc_error_t error describing the error encountered. * @ingroup ctrl */ int uvc_set_ctrl(uvc_device_handle_t *devh, uint8_t unit, uint8_t ctrl, void *data, int len) { return libusb_control_transfer( devh->usb_devh, REQ_TYPE_SET, UVC_SET_CUR, ctrl << 8, unit << 8 | devh->info->ctrl_if.bInterfaceNumber, // XXX saki data, len, 0 /* timeout */); } /***** INTERFACE CONTROLS *****/ uvc_error_t uvc_get_power_mode(uvc_device_handle_t *devh, enum uvc_device_power_mode *mode, enum uvc_req_code req_code) { uint8_t mode_char; uvc_error_t ret; ret = libusb_control_transfer( devh->usb_devh, REQ_TYPE_GET, req_code, UVC_VC_VIDEO_POWER_MODE_CONTROL << 8, devh->info->ctrl_if.bInterfaceNumber, // XXX saki &mode_char, sizeof(mode_char), 0); if (ret == 1) { *mode = mode_char; return UVC_SUCCESS; } else { return ret; } } uvc_error_t uvc_set_power_mode(uvc_device_handle_t *devh, enum uvc_device_power_mode mode) { uint8_t mode_char = mode; uvc_error_t ret; ret = libusb_control_transfer( devh->usb_devh, REQ_TYPE_SET, UVC_SET_CUR, UVC_VC_VIDEO_POWER_MODE_CONTROL << 8, devh->info->ctrl_if.bInterfaceNumber, // XXX saki &mode_char, sizeof(mode_char), 0); if (ret == 1) return UVC_SUCCESS; else return ret; } /** @todo Request Error Code Control (UVC 1.5, 4.2.1.2) */