| Webcam Library Reference Documentation | ![]() |
Dynamic control support for the Linux UVC driver. More...
#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <limits.h>#include <ctype.h>#include <unistd.h>#include <stdarg.h>#include <sys/ioctl.h>#include <errno.h>#include <iconv.h>#include "webcam.h"#include "libwebcam.h"#include "compat.h"#include <libxml/parser.h>#include <libxml/tree.h>Data Structures | |
| struct | _Constant |
| Constant read from the XML configuration file. More... | |
| struct | _UVCXUControl |
| UVC extension unit control for use with UVCIOC_CTRL_ADD. More... | |
| struct | _ParseContext |
| Helper structure that contains handles and information useful during the XML parsing process. More... | |
Macros | |
| #define | _GNU_SOURCE |
| #define | HEX_DECODE_CHAR(c) ((c) >= '0' && (c) <= '9' ? (c) - '0' : (tolower(c)) - 'a' + 0xA) |
| Convert a single hex character into its numeric value. | |
| #define | HEX_DECODE_BYTE(cc) ((HEX_DECODE_CHAR((cc)[0]) << 4) + HEX_DECODE_CHAR((cc)[1])) |
| Convert two hex characters into their byte value. | |
| #define | UNICODE_TO_ASCII(s) (unicode_to_ascii(s, ctx)) |
| Helper macro to convert the UTF-8 strings used by libxml2 into ASCII. | |
| #define | UNICODE_TO_NORM_ASCII(s) (unicode_to_normalized_ascii(s, ctx)) |
| Helper macro to convert the UTF-8 strings used by libxml2 into whitespace normalized ASCII. | |
Typedefs | |
| typedef enum _ConstantType | ConstantType |
| Type of constants that are allowed in the XML configuration file. | |
| typedef struct _Constant | Constant |
| Constant read from the XML configuration file. | |
| typedef struct _UVCXUControl | UVCXUControl |
| UVC extension unit control for use with UVCIOC_CTRL_ADD. | |
| typedef struct _ParseContext | ParseContext |
| Helper structure that contains handles and information useful during the XML parsing process. | |
Enumerations | |
| enum | _ConstantType { CT_INVALID = 0, CT_INTEGER, CT_GUID } |
| Type of constants that are allowed in the XML configuration file. More... | |
Functions | |
| static void | guid_to_byte_array (const char *guid, __u8 *array) |
| Converts a GUID string into a GUID byte array. More... | |
| static int | is_valid_integer_string (const char *string, int *value) |
| Checks whether a given string contains a valid integer value. More... | |
| static int | is_valid_size (int value, int max) |
| Checks whether a given value represents a valid size. More... | |
| static int | is_valid_size_string (const char *string, int *value, int max) |
| Checks whether a given string represents a valid size. More... | |
| static int | is_valid_guid (const char *string) |
| Checks whether a given string represents a valid GUID. | |
| static int | string_to_version (const char *string, unsigned int *major, unsigned int *minor) |
| Converts a string to a version consisting of major and minor version. More... | |
| static __u32 | get_uvc_request_by_name (const xmlChar *name) |
| Converts the name of a UVC request into its corresponding constant. More... | |
| static enum uvc_control_data_type | get_uvc_ctrl_type_by_name (const xmlChar *name) |
| Converts the name of a UVC data type constant into its corresponding numerical value. More... | |
| static enum v4l2_ctrl_type | get_v4l2_ctrl_type_by_name (const xmlChar *name) |
| Converts the name of a V4L2 data type constant into its corresponding numerical value. More... | |
| static char * | normalize_string (const char *input) |
| Normalizes a string in terms of whitespace. More... | |
| static char * | unicode_to_ascii (const xmlChar *unicode, ParseContext *ctx) |
| Converts a UTF-8 string to ASCII. More... | |
| static char * | unicode_to_normalized_ascii (const xmlChar *unicode, ParseContext *ctx) |
| Converts a UTF-8 string to ASCII and then normalizes the string's whitespace. More... | |
| static const xmlChar * | xml_get_node_text (const xmlNode *node) |
| Returns the text content of the given node. More... | |
| static xmlNode * | xml_get_first_child_by_name (const xmlNode *node, const char *name) |
| Returns the first child node with a given name. More... | |
| static xmlNode * | xml_get_next_sibling_by_name (const xmlNode *node, const char *name) |
| Returns the next sibling node with a given name. More... | |
| static Constant * | lookup_constant (const char *find_name, ConstantType find_type, ParseContext *ctx) |
| Look up a constant by its name. More... | |
| static CResult | lookup_or_convert_to_integer (const xmlChar *text, int *value, ParseContext *ctx) |
| Convert the given string to an integer or look up a constant with the given name. More... | |
| static CResult | lookup_or_convert_to_guid (const xmlChar *text, __u8 *guid, ParseContext *ctx) |
| Convert the given string to a GUID or look up a constant with the given name. More... | |
| static UVCXUControl * | lookup_control (const xmlChar *name, ParseContext *ctx) |
| Lookup a UVC extension unit control with the given name. | |
| static CResult | resize_message_buffer (ParseContext *ctx, CDynctrlMessage *msg) |
| Reorganize the buffer that is used to store the messages that are logged during parsing. More... | |
| static CResult | add_message_v (ParseContext *ctx, int line, int col, CDynctrlMessageSeverity severity, const char *format, va_list va) |
| Adds a new message to the message list. More... | |
| static CResult | add_message (ParseContext *ctx, int line, int col, CDynctrlMessageSeverity severity, const char *format,...) |
| Adds a new message to the message list. More... | |
| static CResult | add_info (ParseContext *ctx, const char *format,...) |
| Adds a new informational message to the message list. | |
| static CResult | add_error (ParseContext *ctx, const char *format,...) |
| Adds a new error message to the message list. | |
| static CResult | add_error_at_node (ParseContext *ctx, const xmlNode *node, const char *format,...) |
| Adds a new error message concerning a given xmlNode to the message list. More... | |
| static CResult | parse_dynctrl_file (const char *file_name, xmlDoc **xml_doc, ParseContext *ctx) |
| Parse a dynamic controls configuration XML file and return an XML document tree. More... | |
| static CResult | process_mapping (const xmlNode *node_mapping, ParseContext *ctx) |
Process a mapping node and add the contained mapping to the UVC driver. | |
| static CResult | process_mappings (const xmlNode *node_mappings, ParseContext *ctx) |
Process a mappings node. | |
| static CResult | process_control (xmlNode *node_control, ParseContext *ctx) |
Process a control node by adding the contained control to the UVC driver. | |
| static CResult | process_controls (const xmlNode *node_controls, ParseContext *ctx) |
Process a controls node. | |
| static CResult | process_device (const xmlNode *node_device, ParseContext *ctx) |
Process a device node. More... | |
| static CResult | process_devices (const xmlNode *node_devices, ParseContext *ctx) |
Process a devices node. | |
| static CResult | process_constant (xmlNode *node_constant, ParseContext *ctx) |
Process a constant node by adding the contained constant to an internal list. | |
| static CResult | process_constants (const xmlNode *node_constants, ParseContext *ctx) |
Process a constants node. | |
| static CResult | process_meta (const xmlNode *node_meta, ParseContext *ctx) |
Process a meta node by filling in the corresponding info structure. | |
| static CResult | process_dynctrl_doc (xmlDoc *xml_doc, ParseContext *ctx) |
| Process an XML document tree representing a dynamic controls configuration file. | |
| static CResult | device_supports_dynctrl (ParseContext *ctx) |
| Checks whether the driver behind the current device supports dynamic controls. More... | |
| static CResult | add_control_mappings (xmlDoc *xml_doc, ParseContext *ctx) |
| Adds controls and control mappings contained in the given XML tree to the UVC driver. More... | |
| CResult | c_add_control_mappings_from_file (const char *file_name, CDynctrlInfo *info) |
| Parses a dynamic controls configuration file and adds the contained controls and control mappings to the UVC driver. More... | |
Dynamic control support for the Linux UVC driver.
| enum _ConstantType |
|
static |
Adds controls and control mappings contained in the given XML tree to the UVC driver.
| xml_doc | XML document tree corresponding to the dynctrl format |
| ctx | current parse context |
References C_INVALID_DEVICE, C_SUCCESS, device_supports_dynctrl(), GET_HANDLE, _ParseContext::handle, HANDLE_OPEN, HANDLE_VALID, open_v4l2_device(), process_dynctrl_doc(), and _ParseContext::v4l2_handle.
Referenced by c_add_control_mappings_from_file().
|
static |
Adds a new error message concerning a given xmlNode to the message list.
The node is used to extract the line number.
References add_message_v(), and CD_SEVERITY_ERROR.
Referenced by process_constant(), process_control(), and process_mapping().
|
static |
Adds a new message to the message list.
| ctx | current parse context |
| line | line number that the message concerns (e.g. line of the syntax error) |
| col | column number that the message concerns |
| severity | severity level of the message (warning, error, etc.) |
| format | a printf compatible format to print the variable parameter list |
References add_message_v().
Referenced by parse_dynctrl_file().
|
static |
Adds a new message to the message list.
This function works like add_message() but takes a va_list argument instead of a parameter list.
References C_INVALID_ARG, C_NO_MEMORY, C_SUCCESS, CD_REPORT_ERRORS, _CDynctrlMessage::col, _CDynctrlInfo::flags, _ParseContext::info, _CDynctrlMessage::line, resize_message_buffer(), _CDynctrlMessage::severity, and _CDynctrlMessage::text.
Referenced by add_error(), add_error_at_node(), add_info(), and add_message().
| CResult c_add_control_mappings_from_file | ( | const char * | file_name, |
| CDynctrlInfo * | info | ||
| ) |
Parses a dynamic controls configuration file and adds the contained controls and control mappings to the UVC driver.
Notes:
| file_name | name of the device to open. |
| info | structure to pass operation flags and retrieve status information. Can be NULL. |
References add_control_mappings(), add_error(), add_info(), C_BUFFER_TOO_SMALL, C_CANNOT_WRITE, c_close_device(), c_enum_devices(), c_get_handle_error_text(), C_INIT_ERROR, C_INVALID_ARG, C_INVALID_DEVICE, C_NO_MEMORY, C_NOT_IMPLEMENTED, c_open_device(), C_SUCCESS, _ParseContext::cd, _ParseContext::constants, _ParseContext::controls, _CDevice::driver, _ParseContext::handle, _UVCXUControl::id, _ParseContext::info, initialized, _Constant::name, _Constant::next, _UVCXUControl::next, parse_dynctrl_file(), and _CDevice::shortName.
|
static |
Checks whether the driver behind the current device supports dynamic controls.
The check is done by redefining the brightness control which is hardcoded in the UVC driver. If the driver supports dynamic controls, it will return EEXIST. If the driver does not support dynamic controls, the ioctl will fail with EINVAL.
| ctx | current parse context |
References C_CANNOT_WRITE, C_NOT_IMPLEMENTED, C_SUCCESS, and _ParseContext::v4l2_handle.
Referenced by add_control_mappings().
|
static |
Converts the name of a UVC data type constant into its corresponding numerical value.
| name | data type string to be converted. Can be NULL. |
Referenced by process_mapping().
|
static |
Converts the name of a UVC request into its corresponding constant.
| name | request string to be converted. Can be NULL. |
Referenced by process_control().
|
static |
Converts the name of a V4L2 data type constant into its corresponding numerical value.
Note that not all V4L2 data types are recognized. Only the ones relevant for libwebcam and allowed by the schema are considered valid.
| name | data type string to be converted. Can be NULL. |
Referenced by process_mapping().
|
static |
Converts a GUID string into a GUID byte array.
This function assumes that guid is a valid GUID string. No validation is performed.
References HEX_DECODE_BYTE.
Referenced by lookup_or_convert_to_guid(), and process_constant().
|
static |
Checks whether a given string contains a valid integer value.
This function considers all integers recognized by strtol() as valid. This includes hexadecimal numbers with a '0x' prefix and octal numbers with a leading zero.
| string | String containing an integer. Can be NULL. |
| value | A pointer in which the converted value will be stored. Can be NULL if conversion is not required. |
Referenced by is_valid_size_string(), lookup_or_convert_to_integer(), and process_constant().
|
inlinestatic |
Checks whether a given value represents a valid size.
Only positive numbers are considered valid size values. In addition, an upper threshold can be specified, above which values will be considered invalid.
| value | value to be checked |
| max | upper threshold for the validity of value. If the threshold is negative, no threshold check is performed, i.e. max == INT_MAX is assumed. |
Referenced by is_valid_size_string(), and process_control().
|
static |
Checks whether a given string represents a valid size.
This function works just like is_valid_size() but accepts an input string and a buffer to store the converted value.
References is_valid_integer_string(), and is_valid_size().
Referenced by process_mapping().
|
static |
Look up a constant by its name.
| ctx | current parse context |
| find_name | name of the constant to look up |
| find_type | only search for constants with this type. Specify CT_INVALID to disable the type filter. |
References _ParseContext::constants, CT_INVALID, _Constant::name, _Constant::next, and _Constant::type.
Referenced by lookup_or_convert_to_guid(), lookup_or_convert_to_integer(), and process_constant().
|
static |
Convert the given string to a GUID or look up a constant with the given name.
This function works like lookup_or_convert_to_integer() except that it looks for GUIDs instead of integers.
References C_PARSE_ERROR, C_SUCCESS, CT_GUID, _Constant::guid, GUID_SIZE, guid_to_byte_array(), is_valid_guid(), and lookup_constant().
Referenced by process_control().
|
static |
Convert the given string to an integer or look up a constant with the given name.
The function first tries to convert the given string to an integer. If successful, the converted value is returned. If the conversion fails, the string is interpreted as a name and a constant with that name is looked up. If the lookup is successful, the value of the constant is returned.
| text | pointer to the name or integer value. Can be NULL. |
| value | pointer to an integer to receive the converted or constant value |
| ctx | current parse context |
References C_PARSE_ERROR, C_SUCCESS, CT_INTEGER, is_valid_integer_string(), lookup_constant(), and _Constant::value.
Referenced by process_control(), and process_mapping().
|
static |
Normalizes a string in terms of whitespace.
The function returns a copy of the input string with leading and trailing whitespace removed and all internal whitespace reduced to simple spaces. Examples: " text " => "text" " Multi\nline text" => "Multi line text"
This function allocates a new buffer that needs to be freed by the caller.
| input | input string to be normalized. This string is not modified. |
Referenced by unicode_to_normalized_ascii().
|
static |
Parse a dynamic controls configuration XML file and return an XML document tree.
Note that the pointer stored in *xml_doc must be freed using xmlFreeDoc() if the return value of this functino is C_SUCCESS.
| file_name | name (with an optional path) of the file to be parsed |
| xml_doc | address of a pointer to store the XML document tree |
| ctx | current parse context |
References add_message(), C_NO_MEMORY, C_PARSE_ERROR, C_SUCCESS, CD_DONT_VALIDATE, CD_SEVERITY_ERROR, _CDynctrlInfo::flags, and _ParseContext::info.
Referenced by c_add_control_mappings_from_file().
|
static |
Process a device node.
Note that the contained match sections are currently ignored.
References C_SUCCESS, process_controls(), and xml_get_first_child_by_name().
Referenced by process_devices().
|
static |
Reorganize the buffer that is used to store the messages that are logged during parsing.
The buffer that is used to store the messages is completely self-contained. It consists of an array of CDynctrlMessage structures and an area for "dynamics" which stores dynamic data like strings. All string pointers in the array point to strings in the dynamics area, so for clean up only a single buffer needs to be freed.
Every time a new array element is added, the buffer has to be enlarged, and a new array element has to be inserted between the current last element and the dynamics area. The dynamics area is moved by sizeof(CDynctrlMessage) bytes and all pointers to it are updated to point to the new direction.
| ctx | current parse context |
| msg | pointer to the new message to be added. Note that this is only a temporary buffer. Its content (including its strings) is copied into the message buffer and the temporary buffer is no longer required after the function returns. |
References C_NO_MEMORY, C_SUCCESS, _ParseContext::info, _CDynctrlInfo::message_count, _CDynctrlInfo::messages, _ParseContext::messages_size, and _CDynctrlMessage::text.
Referenced by add_message_v().
|
static |
Converts a string to a version consisting of major and minor version.
Accepted formats are "x.y" and "x" where x is the major and y the minor version.
| string | version string to be converted |
| major | pointer to an integer where the major version number should be stored |
| minor | pointer to an integer where the minor version number should be stored |
Referenced by process_meta().
|
static |
Converts a UTF-8 string to ASCII.
The function may convert some characters in a non-reversible way.
| unicode | input string to be converted. |
| ctx | current parse context |
References _ParseContext::cd.
Referenced by process_meta(), and unicode_to_normalized_ascii().
|
static |
Converts a UTF-8 string to ASCII and then normalizes the string's whitespace.
This function is effectively a combination of unicode_to_ascii() and normalize_string(). Note that the caller must free the returned string.
References normalize_string(), and unicode_to_ascii().
Referenced by process_meta().
|
static |
Returns the first child node with a given name.
| node | pointer to the parent node whose children are to be searched |
| name | the name of the child node to be searched for |
Referenced by process_constant(), process_constants(), process_control(), process_controls(), process_device(), process_devices(), process_dynctrl_doc(), process_mapping(), process_mappings(), and process_meta().
|
static |
Returns the next sibling node with a given name.
| node | pointer to the node whose siblings are to be searched |
| name | the name of the sibling node to be searched for |
Referenced by process_constants(), process_control(), process_controls(), process_devices(), process_dynctrl_doc(), and process_mappings().
|
static |
Returns the text content of the given node.
| node | Pointer to a node. May be NULL. |
Referenced by process_constant(), process_control(), process_mapping(), and process_meta().