⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 libusbi.h

📁 最新的libusb库
💻 H
📖 第 1 页 / 共 2 页
字号:
/* * Internal header for libusb * Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org> * Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */#ifndef __LIBUSBI_H__#define __LIBUSBI_H__#include <config.h>#include <poll.h>#include <pthread.h>#include <stddef.h>#include <time.h>#include <libusb.h>#define DEVICE_DESC_LENGTH		18#define USB_MAXENDPOINTS	32#define USB_MAXINTERFACES	32#define USB_MAXCONFIG		8struct list_head {	struct list_head *prev, *next;};/* Get an entry from the list  * 	ptr - the address of this list_head element in "type"  * 	type - the data type that contains "member" * 	member - the list_head element in "type"  */#define list_entry(ptr, type, member) \	((type *)((char *)(ptr) - (unsigned long)(&((type *)0L)->member)))/* Get each entry from a list *	pos - A structure pointer has a "member" element *	head - list head *	member - the list_head element in "pos" */#define list_for_each_entry(pos, head, member)				\	for (pos = list_entry((head)->next, typeof(*pos), member);	\	     &pos->member != (head);					\	     pos = list_entry(pos->member.next, typeof(*pos), member))#define list_for_each_entry_safe(pos, n, head, member)			\        for (pos = list_entry((head)->next, typeof(*pos), member),	\		n = list_entry(pos->member.next, typeof(*pos), member);	\	     &pos->member != (head);					\	     pos = n, n = list_entry(n->member.next, typeof(*n), member))#define list_empty(entry) ((entry)->next == (entry))static inline void list_init(struct list_head *entry){	entry->prev = entry->next = entry;}static inline void list_add(struct list_head *entry, struct list_head *head){	entry->next = head->next;	entry->prev = head;	head->next->prev = entry;	head->next = entry;}static inline void list_add_tail(struct list_head *entry,	struct list_head *head){	entry->next = head;	entry->prev = head->prev;	head->prev->next = entry;	head->prev = entry;}static inline void list_del(struct list_head *entry){	entry->next->prev = entry->prev;	entry->prev->next = entry->next;}#define container_of(ptr, type, member) ({                      \        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \        (type *)( (char *)__mptr - offsetof(type,member) );})#define MIN(a, b)	((a) < (b) ? (a) : (b))#define MAX(a, b)	((a) > (b) ? (a) : (b))#define TIMESPEC_IS_SET(ts) ((ts)->tv_sec != 0 || (ts)->tv_nsec != 0)enum usbi_log_level {	LOG_LEVEL_DEBUG,	LOG_LEVEL_INFO,	LOG_LEVEL_WARNING,	LOG_LEVEL_ERROR,};void usbi_log(struct libusb_context *ctx, enum usbi_log_level,	const char *function, const char *format, ...);#ifdef ENABLE_LOGGING#define _usbi_log(ctx, level, fmt...) usbi_log(ctx, level, __FUNCTION__, fmt)#else#define _usbi_log(ctx, level, fmt...)#endif#ifdef ENABLE_DEBUG_LOGGING#define usbi_dbg(fmt...) _usbi_log(NULL, LOG_LEVEL_DEBUG, fmt)#else#define usbi_dbg(fmt...)#endif#define usbi_info(ctx, fmt...) _usbi_log(ctx, LOG_LEVEL_INFO, fmt)#define usbi_warn(ctx, fmt...) _usbi_log(ctx, LOG_LEVEL_WARNING, fmt)#define usbi_err(ctx, fmt...) _usbi_log(ctx, LOG_LEVEL_ERROR, fmt)#define USBI_GET_CONTEXT(ctx) if (!(ctx)) (ctx) = usbi_default_context#define DEVICE_CTX(dev) ((dev)->ctx)#define HANDLE_CTX(handle) (DEVICE_CTX((handle)->dev))#define TRANSFER_CTX(transfer) (HANDLE_CTX((transfer)->dev_handle))#define ITRANSFER_CTX(transfer) \	(TRANSFER_CTX(__USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer)))extern struct libusb_context *usbi_default_context;struct libusb_context {	int debug;	int debug_fixed;	struct list_head usb_devs;	pthread_mutex_t usb_devs_lock;	/* A list of open handles. Backends are free to traverse this if required.	 */	struct list_head open_devs;	pthread_mutex_t open_devs_lock;	/* this is a list of in-flight transfer handles, sorted by timeout 	 * expiration. URBs to timeout the soonest are placed at the beginning of	 * the list, URBs that will time out later are placed after, and urbs with	 * infinite timeout are always placed at the very end. */	struct list_head flying_transfers;	pthread_mutex_t flying_transfers_lock;	/* list of poll fd's */	struct list_head pollfds;	pthread_mutex_t pollfds_lock;	/* user callbacks for pollfd changes */	libusb_pollfd_added_cb fd_added_cb;	libusb_pollfd_removed_cb fd_removed_cb;	void *fd_cb_user_data;	/* ensures that only one thread is handling events at any one time */	pthread_mutex_t events_lock;	/* used to see if there is an active thread doing event handling */	int event_handler_active;	/* used to wait for event completion in threads other than the one that is	 * event handling */	pthread_mutex_t event_waiters_lock;	pthread_cond_t event_waiters_cond;};struct libusb_device {	/* lock protects refcnt, everything else is finalized at initialization	 * time */	pthread_mutex_t lock;	int refcnt;	struct libusb_context *ctx;	uint8_t bus_number;	uint8_t device_address;	uint8_t num_configurations;	struct list_head list;	unsigned long session_data;	unsigned char os_priv[0];};struct libusb_device_handle {	/* lock protects claimed_interfaces */	pthread_mutex_t lock;	unsigned long claimed_interfaces;	struct list_head list;	struct libusb_device *dev;	unsigned char os_priv[0];};#define USBI_TRANSFER_TIMED_OUT	 			(1<<0)/* in-memory transfer layout: * * 1. struct usbi_transfer * 2. struct libusb_transfer (which includes iso packets) [variable size] * 3. os private data [variable size] * * from a libusb_transfer, you can get the usbi_transfer by rewinding the * appropriate number of bytes. * the usbi_transfer includes the number of allocated packets, so you can * determine the size of the transfer and hence the start and length of the * OS-private data. */struct usbi_transfer {	int num_iso_packets;	struct list_head list;	struct timeval timeout;	int transferred;	uint8_t flags;};#define __USBI_TRANSFER_TO_LIBUSB_TRANSFER(transfer) \	((struct libusb_transfer *)(((void *)(transfer)) \		+ sizeof(struct usbi_transfer)))#define __LIBUSB_TRANSFER_TO_USBI_TRANSFER(transfer) \	((struct usbi_transfer *)(((void *)(transfer)) \		- sizeof(struct usbi_transfer)))static inline void *usbi_transfer_get_os_priv(struct usbi_transfer *transfer){	return ((void *)transfer) + sizeof(struct usbi_transfer)		+ sizeof(struct libusb_transfer)		+ (transfer->num_iso_packets			* sizeof(struct libusb_iso_packet_descriptor));}/* bus structures *//* All standard descriptors have these 2 fields in common */struct usb_descriptor_header {	uint8_t  bLength;	uint8_t  bDescriptorType;};/* shared data and functions */void usbi_io_init(struct libusb_context *ctx);struct libusb_device *usbi_alloc_device(struct libusb_context *ctx,	unsigned long session_id);struct libusb_device *usbi_get_device_by_session_id(struct libusb_context *ctx,	unsigned long session_id);int usbi_sanitize_device(struct libusb_device *dev);void usbi_handle_disconnect(struct libusb_device_handle *handle);void usbi_handle_transfer_completion(struct usbi_transfer *itransfer,	enum libusb_transfer_status status);void usbi_handle_transfer_cancellation(struct usbi_transfer *transfer);int usbi_parse_descriptor(unsigned char *source, char *descriptor, void *dest,	int host_endian);int usbi_get_config_index_by_value(struct libusb_device *dev,	uint8_t bConfigurationValue, int *idx);/* polling */struct usbi_pollfd {	/* must come first */	struct libusb_pollfd pollfd;	struct list_head list;};int usbi_add_pollfd(struct libusb_context *ctx, int fd, short events);void usbi_remove_pollfd(struct libusb_context *ctx, int fd);/* device discovery *//* we traverse usbfs without knowing how many devices we are going to find. * so we create this discovered_devs model which is similar to a linked-list * which grows when required. it can be freed once discovery has completed, * eliminating the need for a list node in the libusb_device structure * itself. */struct discovered_devs {	size_t len;	size_t capacity;	struct libusb_device *devices[0];};struct discovered_devs *discovered_devs_append(	struct discovered_devs *discdevs, struct libusb_device *dev);/* OS abstraction *//* This is the interface that OS backends need to implement. * All fields are mandatory, except ones explicitly noted as optional. */struct usbi_os_backend {	/* A human-readable name for your backend, e.g. "Linux usbfs" */	const char *name;	/* Perform initialization of your backend. You might use this function	 * to determine specific capabilities of the system, allocate required	 * data structures for later, etc.	 *	 * This function is called when a libusb user initializes the library	 * prior to use.	 *	 * Return 0 on success, or a LIBUSB_ERROR code on failure.	 */	int (*init)(struct libusb_context *ctx);	/* Deinitialization. Optional. This function should destroy anything	 * that was set up by init.	 *	 * This function is called when the user deinitializes the library.	 */	void (*exit)(void);	/* Enumerate all the USB devices on the system, returning them in a list	 * of discovered devices.	 *	 * Your implementation should enumerate all devices on the system,	 * regardless of whether they have been seen before or not.	 *	 * When you have found a device, compute a session ID for it. The session	 * ID should uniquely represent that particular device for that particular	 * connection session since boot (i.e. if you disconnect and reconnect a	 * device immediately after, it should be assigned a different session ID).	 * If your OS cannot provide a unique session ID as described above,	 * presenting a session ID of (bus_number << 8 | device_address) should	 * be sufficient. Bus numbers and device addresses wrap and get reused,	 * but that is an unlikely case.	 *	 * After computing a session ID for a device, call	 * usbi_get_device_by_session_id(). This function checks if libusb already	 * knows about the device, and if so, it provides you with a libusb_device	 * structure for it.	 *	 * If usbi_get_device_by_session_id() returns NULL, it is time to allocate	 * a new device structure for the device. Call usbi_alloc_device() to	 * obtain a new libusb_device structure with reference count 1. Populate	 * the bus_number and device_address attributes of the new device, and	 * perform any other internal backend initialization you need to do. At	 * this point, you should be ready to provide device descriptors and so	 * on through the get_*_descriptor functions. Finally, call	 * usbi_sanitize_device() to perform some final sanity checks on the	 * device. Assuming all of the above succeeded, we can now continue.	 * If any of the above failed, remember to unreference the device that	 * was returned by usbi_alloc_device().	 *	 * At this stage we have a populated libusb_device structure (either one	 * that was found earlier, or one that we have just allocated and	 * populated). This can now be added to the discovered devices list	 * using discovered_devs_append(). Note that discovered_devs_append()	 * may reallocate the list, returning a new location for it, and also	 * note that reallocation can fail. Your backend should handle these	 * error conditions appropriately.	 *

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -