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

📄 usbobex.c

📁 这是Linux环境下的openobex
💻 C
字号:
/*************************************<******************************** *                 * Filename:      usbobex.c * Version:       0.1 * Description:   USB OBEX, USB transport for OBEX * Status:        Experimental. * Author:        Alex Kanavin <ak@sensi.org> *  *     Copyright (c) 2005 Alex Kanavin, All Rights Reserved. * *     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 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., 59 Temple Place, Suite 330, Boston,  *     MA  02111-1307  USA *      ********************************************************************/#ifdef HAVE_CONFIG_H#include <config.h>#endif#ifdef HAVE_USB/* Linux case */#include <string.h>#include <unistd.h>#include <stdio.h>		/* perror */#include <errno.h>		/* errno and EADDRNOTAVAIL */#include <netinet/in.h>#include <sys/socket.h>#include <usb.h>#include "obex_main.h"#include "usbobex.h"/* * Function usbobex_prepare_connect (self, interface) * *    Prepare for USB OBEX connect * */void usbobex_prepare_connect(obex_t *self, struct obex_usb_intf_transport_t *intf){#ifndef _WIN32	self->trans.self.usb = *intf;#endif /* _WIN32 */}/* * Helper function to usbobex_find_interfaces  */static void find_eps(struct obex_usb_intf_transport_t *intf, struct usb_interface_descriptor data_intf, int *found_active, int *found_idle){	struct usb_endpoint_descriptor *ep0, *ep1;	if (data_intf.bNumEndpoints == 2) {		ep0 = data_intf.endpoint;		ep1 = data_intf.endpoint + 1;		if ((ep0->bEndpointAddress & USB_ENDPOINT_IN) && 		    ((ep0->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK) && 		    !(ep1->bEndpointAddress & USB_ENDPOINT_IN) && 		    ((ep1->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK)) {			*found_active = 1;			intf->data_active_setting = data_intf.bAlternateSetting;			intf->data_interface_active_description = data_intf.iInterface;			intf->data_endpoint_read = ep0->bEndpointAddress;			intf->data_endpoint_write = ep1->bEndpointAddress;		}		if (!(ep0->bEndpointAddress & USB_ENDPOINT_IN) && 		    ((ep0->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK) && 		    (ep1->bEndpointAddress & USB_ENDPOINT_IN) && 		    ((ep1->bmAttributes & USB_ENDPOINT_TYPE_MASK) == USB_ENDPOINT_TYPE_BULK)) {			*found_active = 1;			intf->data_active_setting = data_intf.bAlternateSetting;			intf->data_interface_active_description = data_intf.iInterface;			intf->data_endpoint_read = ep1->bEndpointAddress;			intf->data_endpoint_write = ep0->bEndpointAddress;		}	}	if (data_intf.bNumEndpoints == 0) {		*found_idle = 1;		intf->data_idle_setting = data_intf.bAlternateSetting;		intf->data_interface_idle_description = data_intf.iInterface;	}}/* * Helper function to usbobex_find_interfaces  */static int find_obex_data_interface(unsigned char *buffer, int buflen, struct usb_config_descriptor config, struct obex_usb_intf_transport_t *intf){	struct cdc_union_desc *union_header = NULL;	int i, a;	int found_active = 0;	int found_idle = 0;	if (!buffer) {		DEBUG(2,"Weird descriptor references");		return -EINVAL;	}	while (buflen > 0) {		if (buffer [1] != USB_DT_CS_INTERFACE) {			DEBUG(2,"skipping garbage");			goto next_desc;		}		switch (buffer [2]) {		case CDC_UNION_TYPE: /* we've found it */			if (union_header) {				DEBUG(2,"More than one union descriptor, skiping ...");				goto next_desc;			}			union_header = (struct cdc_union_desc *)buffer;			break;		case CDC_OBEX_TYPE: /* maybe check version */		case CDC_HEADER_TYPE:			break; /* for now we ignore it */		default:			DEBUG(2, "Ignoring extra header, type %d, length %d", buffer[2], buffer[0]);			break;		}next_desc:		buflen -= buffer[0];		buffer += buffer[0];	}	if (!union_header) {		DEBUG(2,"No union descriptor, giving up\n");		return -ENODEV;	}	/* Found the slave interface, now find active/idle settings and endpoints */	intf->data_interface = union_header->bSlaveInterface0;	/* Loop through all of the interfaces */	for (i = 0; i < config.bNumInterfaces; i++) {		/* Loop through all of the alternate settings */		for (a = 0; a < config.interface[i].num_altsetting; a++) {			/* Check if this interface is OBEX data interface*/			/* and find endpoints */			if (config.interface[i].altsetting[a].bInterfaceNumber == intf->data_interface) {				find_eps(intf, config.interface[i].altsetting[a], &found_active, &found_idle);			}		}	}	if (!found_idle) {		DEBUG(2,"No idle setting\n");		return -ENODEV;	}	if (!found_active) {		DEBUG(2,"No active setting\n");		return -ENODEV;	}	return 0;}/* * Helper function to usbobex_find_interfaces */static int get_intf_string(struct usb_dev_handle *usb_handle, char **string, int id){	if (id) {		if ((*string = malloc(USB_MAX_STRING_SIZE)) == NULL)			return -ENOMEM;		*string[0] = '\0';		return usb_get_string_simple(usb_handle, id, *string, USB_MAX_STRING_SIZE);	}	return 0;}/* * Helper function to usbobex_find_interfaces  */static struct obex_usb_intf_transport_t *check_intf(struct usb_device *dev, int c, int i, int a, struct obex_usb_intf_transport_t *current){	struct obex_usb_intf_transport_t *next = NULL;	if ((dev->config[c].interface[i].altsetting[a].bInterfaceClass == USB_CDC_CLASS) 	    && (dev->config[c].interface[i].altsetting[a].bInterfaceSubClass == USB_CDC_OBEX_SUBCLASS)) { 		int err;		unsigned char *buffer = dev->config[c].interface[i].altsetting[a].extra;		int buflen = dev->config[c].interface[i].altsetting[a].extralen;		next = malloc(sizeof(struct obex_usb_intf_transport_t));		if (next == NULL)			return current;		next->device = dev;		next->configuration = dev->config[c].bConfigurationValue;		next->configuration_description = dev->config[c].iConfiguration;		next->control_interface = dev->config[c].interface[i].altsetting[a].bInterfaceNumber;		next->control_interface_description = dev->config[c].interface[i].altsetting[a].iInterface;		next->control_setting = dev->config[c].interface[i].altsetting[a].bAlternateSetting;		err = find_obex_data_interface(buffer, buflen, dev->config[c], next);		if (err)			free(next);		else {			if (current)				current->next = next;			next->prev = current;			next->next = NULL;			current = next;		}	}	return current;}/* * Function usbobex_find_interfaces () * *    Find available USBOBEX interfaces on the system */int usbobex_find_interfaces(obex_interface_t **interfaces){	struct usb_bus *busses;	struct usb_bus *bus;	struct usb_device *dev;	int c, i, a, num;	struct obex_usb_intf_transport_t *current = NULL;	struct obex_usb_intf_transport_t *tmp = NULL;	obex_interface_t *intf_array = NULL; 		struct usb_dev_handle *usb_handle;		usb_init();	usb_find_busses();	usb_find_devices();	busses = usb_get_busses();	for (bus = busses; bus; bus = bus->next) {		for (dev = bus->devices; dev; dev = dev->next) {			/* Loop through all of the configurations */			for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {				/* Loop through all of the interfaces */				for (i = 0; i < dev->config[c].bNumInterfaces; i++) {					/* Loop through all of the alternate settings */					for (a = 0; a < dev->config[c].interface[i].num_altsetting; a++) {						/* Check if this interface is OBEX */						/* and find data interface */						current = check_intf(dev, c, i, a, current);					}				}			}		}	}	num = 0;	if (current) 		num++;	while (current && current->prev) {		current = current->prev;		num++;	}	intf_array = malloc(sizeof(obex_interface_t) * num);	if (intf_array == NULL)		goto cleanup_list;	memset(intf_array, 0, sizeof(obex_interface_t) * num);	num = 0;	while (current) {		intf_array[num].usb.interface = current;		usb_handle = usb_open(current->device);		get_intf_string(usb_handle, &intf_array[num].usb.manufacturer, 			current->device->descriptor.iManufacturer);		get_intf_string(usb_handle, &intf_array[num].usb.product, 			current->device->descriptor.iProduct);		get_intf_string(usb_handle, &intf_array[num].usb.serial, 			current->device->descriptor.iSerialNumber);		get_intf_string(usb_handle, &intf_array[num].usb.configuration, 			current->configuration_description);		get_intf_string(usb_handle, &intf_array[num].usb.control_interface, 			current->control_interface_description);		get_intf_string(usb_handle, &intf_array[num].usb.data_interface_idle, 			current->data_interface_idle_description);		get_intf_string(usb_handle, &intf_array[num].usb.data_interface_active, 			current->data_interface_active_description);		usb_close(usb_handle);		current = current->next; num++;	}	*interfaces = intf_array;	return num;cleanup_list:	while (current) {		tmp = current->next;		free(current);		current = tmp;	}	return 0;}/* * Function usbobex_free_interfaces () * *    Free the list of discovered USBOBEX interfaces on the system */void usbobex_free_interfaces(int num, obex_interface_t *intf){	int i;	if (intf == NULL)		return;	for (i = 0; i < num; i++) {		free(intf[i].usb.manufacturer);		free(intf[i].usb.product);		free(intf[i].usb.serial);		free(intf[i].usb.configuration);		free(intf[i].usb.control_interface);		free(intf[i].usb.data_interface_idle);		free(intf[i].usb.data_interface_active);		free(intf[i].usb.interface);	}	free(intf);}/* * Function usbobex_connect_request (self) * *    Open the USB connection * */int usbobex_connect_request(obex_t *self){	int ret;#ifndef _WIN32	DEBUG(4, "\n");	self->trans.self.usb.dev_control = usb_open(self->trans.self.usb.device);	self->trans.self.usb.dev_data = usb_open(self->trans.self.usb.device);	ret = usb_set_configuration(self->trans.self.usb.dev_control, self->trans.self.usb.configuration);	if (ret < 0) {		DEBUG(4, "Can't set configuration %d", ret);	}	ret = usb_claim_interface(self->trans.self.usb.dev_control, self->trans.self.usb.control_interface);	if (ret < 0) {		DEBUG(4, "Can't claim control interface %d", ret);		goto err1;	}	ret = usb_set_altinterface(self->trans.self.usb.dev_control, self->trans.self.usb.control_setting);	if (ret < 0) {		DEBUG(4, "Can't set control setting %d", ret);		goto err2;	}	ret = usb_claim_interface(self->trans.self.usb.dev_data, self->trans.self.usb.data_interface);	if (ret < 0) {		DEBUG(4, "Can't claim data interface %d", ret);		goto err2;	}	ret = usb_set_altinterface(self->trans.self.usb.dev_data, self->trans.self.usb.data_active_setting);	if (ret < 0) {		DEBUG(4, "Can't set data active setting %d", ret);		goto err3;	}	self->trans.mtu = OBEX_MAXIMUM_MTU;	DEBUG(2, "transport mtu=%d\n", self->trans.mtu);	return 1;err3:	usb_release_interface(self->trans.self.usb.dev_data, self->trans.self.usb.data_interface);	err2:	usb_release_interface(self->trans.self.usb.dev_control, self->trans.self.usb.control_interface);err1:	usb_close(self->trans.self.usb.dev_data);	usb_close(self->trans.self.usb.dev_control);	return ret;#endif /* _WIN32 */}/* * Function usbobex_link_disconnect_request (self) * *    Shutdown the USB link * */int usbobex_disconnect_request(obex_t *self){	int ret;	if (self->trans.connected == FALSE)		return 0;#ifndef _WIN32	DEBUG(4, "\n");	ret = usb_set_altinterface(self->trans.self.usb.dev_data, self->trans.self.usb.data_idle_setting);	if (ret < 0)		DEBUG(4, "Can't set data idle setting %d", ret);	ret = usb_release_interface(self->trans.self.usb.dev_data, self->trans.self.usb.data_interface);	if (ret < 0) 		DEBUG(4, "Can't release data interface %d", ret);	ret = usb_release_interface(self->trans.self.usb.dev_control, self->trans.self.usb.control_interface);	if (ret < 0) 		DEBUG(4, "Can't release control interface %d", ret);	ret = usb_close(self->trans.self.usb.dev_data);	if (ret < 0)		DEBUG(4, "Can't close data interface %d", ret);	ret = usb_close(self->trans.self.usb.dev_control);	if (ret < 0)		DEBUG(4, "Can't close control interface %d", ret);#endif /* _WIN32 */	return ret;	}#endif /* HAVE_USB */

⌨️ 快捷键说明

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