ptpcam.c

来自「USB Host 开发中支持数码相机的源码。即Picture To Pictur」· C语言 代码 · 共 1,104 行 · 第 1/2 页

C
1,104
字号
/* ptpcam.c * * Copyright (C) 2001-2004 Mariusz Woloszyn <emsi@ipartners.pl> * *  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, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <getopt.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/mman.h>#include <usb.h>#ifdef ENABLE_NLS#  include <libintl.h>#  undef _#  define _(String) dgettext (GETTEXT_PACKAGE, String)#  ifdef gettext_noop#    define N_(String) gettext_noop (String)#  else#    define N_(String) (String)#  endif#else#  define textdomain(String) (String)#  define gettext(String) (String)#  define dgettext(Domain,Message) (Message)#  define dcgettext(Domain,Message,Type) (Message)#  define bindtextdomain(Domain,Directory) (Domain)#  define _(String) (String)#  define N_(String) (String)#endif#include "ptp.h"/* some defines comes here *//* USB interface class */#ifndef USB_CLASS_PTP#define USB_CLASS_PTP		6#endif/* USB control message data phase direction */#ifndef USB_DP_HTD#define USB_DP_HTD		(0x00 << 7)	// host to device#endif#ifndef USB_DP_DTH#define USB_DP_DTH		(0x01 << 7)	// device to host#endif/* PTP class specific requests */#ifndef USB_REQ_DEVICE_RESET#define USB_REQ_DEVICE_RESET		0x66#endif#ifndef USB_REQ_GET_DEVICE_STATUS#define USB_REQ_GET_DEVICE_STATUS	0x67#endif/* USB Feature selector HALT */#ifndef USB_FEATURE_HALT#define USB_FEATURE_HALT	0x00#endif/* Check value and Return on error */#define CR(result,error) {						\			if((result)!=PTP_RC_OK) {			\				fprintf(stderr,"ERROR: "error);		\				close_usb(&ptp_usb, dev);		\				return;					\			}						\}/* Check value and Return -1 on error */#define CRR(result) {							\			if((result)!=PTP_RC_OK) {			\				return -1;				\			}						\}/* Check value and Report (PTP) Error if needed */#define CRE(result) {							\			uint16_t r;					\			r=(result);					\			if (r!=PTP_RC_OK)				\				ptp_perror(&params,r);			\}/* Check value and Continue on error */#define CC(result,error) {						\			if((result)!=PTP_RC_OK) {			\				fprintf(stderr,"ERROR: "error);		\				usb_release_interface(ptp_usb.handle,	\		dev->config->interface->altsetting->bInterfaceNumber);	\				continue;					\			}						\}/* error reporting macro */#define ERROR(error) fprintf(stderr,"ERROR: "error);				/* printing value type */#define PTPCAM_PRINT_HEX	00#define PTPCAM_PRINT_DEC	01/* property value printing macros */#define PRINT_PROPVAL_DEC(value)	\		print_propval(dpd.DataType, value,			\		PTPCAM_PRINT_DEC)#define PRINT_PROPVAL_HEX(value)					\		print_propval(dpd.DataType, value,			\		PTPCAM_PRINT_HEX)/* requested actions */#define ACT_DEVICE_RESET	0x1#define ACT_LIST_DEVICES	0x2#define ACT_LIST_PROPERTIES	0x3#define ACT_LIST_OPERATIONS	0x4#define ACT_GETSET_PROPERTY	0x5#define ACT_SHOW_INFO		0x6#define ACT_LIST_FILES		0x7#define ACT_GET_FILE		0x8			typedef struct _PTP_USB PTP_USB;struct _PTP_USB {	usb_dev_handle* handle;	int inep;	int outep;	int intep;};/* some functions declarations to avoid warnings *///void talk (struct usb_device*, int , int , int );void usage(void);void help(void);struct usb_bus* init_usb(void);void init_ptp_usb (PTPParams*, PTP_USB*, struct usb_device*);void list_devices(short force);void list_properties (int dev, int bus, short force);// one global variable (yes, I know it sucks)short verbose=0;voidusage(){	printf("USAGE: ptpcam [OPTION]\n\n");}voidhelp(){	printf("USAGE: ptpcam [OPTION]\n\n");	printf("Options:\n"	"  -h, --help                   Print this help message\n"	"  -B, --bus=BUS-NUMBER         USB bus number\n"	"  -D, --dev=DEV-NUMBER         USB assigned device number\n"	"  -r, --reset                  Reset the device\n"	"  -l, --list-devices           List all PTP devices\n"	"  -i, --info                   Show device info\n"	"  -o, --list-operations        List supported operations\n"	"  -p, --list-properties        List all PTP device properties\n"	"                               "				"(e.g. focus mode, focus distance, etc.)\n"	"  -s, --show-property=NUMBER   Display property details "					"(or set its value,\n"	"                               if used in conjunction with --val)\n"	"  --set-property=NUMBER        Set property value (--val required)\n"	"  --val=VALUE                  Property value\n"	"  -L, --list-files             List all files\n"	"  -g, --get-file=HANDLE        Get file by given handler\n"	"  -f, --force                  Talk to non PTP devices\n"	"  -v, --verbose                Be verbosive (print more debug)\n"	"\n");}static shortptp_read_func (unsigned char *bytes, unsigned int size, void *data){	int result;	PTP_USB *ptp_usb=(PTP_USB *)data;	result=usb_bulk_read(ptp_usb->handle, ptp_usb->inep, bytes, size,3000);	if (result==0)	result=usb_bulk_read(ptp_usb->handle, ptp_usb->inep, bytes, size,3000);	if (result >= 0)		return (PTP_RC_OK);	else 	{		if (verbose) perror("usb_bulk_read");		return PTP_ERROR_IO;	}}static shortptp_write_func (unsigned char *bytes, unsigned int size, void *data){	int result;	PTP_USB *ptp_usb=(PTP_USB *)data;	result=usb_bulk_write(ptp_usb->handle,ptp_usb->outep,bytes,size,3000);	if (result >= 0)		return (PTP_RC_OK);	else 	{		if (verbose) perror("usb_bulk_write");		return PTP_ERROR_IO;	}}static shortptp_check_int (unsigned char *bytes, unsigned int size, void *data){	int result;	PTP_USB *ptp_usb=(PTP_USB *)data;	result=usb_bulk_read(ptp_usb->handle, ptp_usb->intep,bytes,size,100);	if (result==0)		result = usb_bulk_read(ptp_usb->handle, ptp_usb->intep, bytes, size, 100);	return (result);}voiddebug (void *data, const char *format, va_list args);voiddebug (void *data, const char *format, va_list args){	if (verbose<2) return;	vfprintf (stderr, format, args);	fprintf (stderr,"\n");	fflush(stderr);}voiderror (void *data, const char *format, va_list args);voiderror (void *data, const char *format, va_list args){/*	if (!verbose) return; */	vfprintf (stderr, format, args);	fprintf (stderr,"\n");	fflush(stderr);}voidinit_ptp_usb (PTPParams* params, PTP_USB* ptp_usb, struct usb_device* dev){	usb_dev_handle *device_handle;	params->write_func=ptp_write_func;	params->read_func=ptp_read_func;	params->check_int_func=ptp_check_int;	params->check_int_fast_func=ptp_check_int;	params->error_func=error;	params->debug_func=debug;	params->sendreq_func=ptp_usb_sendreq;	params->senddata_func=ptp_usb_senddata;	params->getresp_func=ptp_usb_getresp;	params->getdata_func=ptp_usb_getdata;	params->data=ptp_usb;	params->transaction_id=0;	params->byteorder = PTP_DL_LE;	if ((device_handle=usb_open(dev))){		if (!device_handle) {			perror("usb_open()");			exit(0);		}		ptp_usb->handle=device_handle;		usb_claim_interface(device_handle,			dev->config->interface->altsetting->bInterfaceNumber);	}}void close_usb(PTP_USB* ptp_usb, struct usb_device* dev){        usb_clear_halt(ptp_usb->handle,ptp_usb->inep);        usb_clear_halt(ptp_usb->handle,ptp_usb->outep);        usb_clear_halt(ptp_usb->handle,ptp_usb->intep);        usb_release_interface(ptp_usb->handle,                dev->config->interface->altsetting->bInterfaceNumber);        usb_close(ptp_usb->handle);}struct usb_bus*init_usb(){	usb_init();	usb_find_busses();	usb_find_devices();	return (usb_get_busses());}/*   find_device() returns the pointer to a usb_device structure matching   given busn, devicen numbers. If any or both of arguments are 0 then the   first matching PTP device structure is returned. */struct usb_device*find_device (int busn, int devicen, short force);struct usb_device*find_device (int busn, int devn, short force){	struct usb_bus *bus;	struct usb_device *dev;	bus=init_usb();	for (; bus; bus = bus->next)	for (dev = bus->devices; dev; dev = dev->next)	if ((dev->config->interface->altsetting->bInterfaceClass==		USB_CLASS_PTP)||force)	if (dev->descriptor.bDeviceClass!=USB_CLASS_HUB)	{		int curbusn, curdevn;		curbusn=strtol(bus->dirname,NULL,10);		curdevn=strtol(dev->filename,NULL,10);		if (devn==0) {			if (busn==0) return dev;			if (curbusn==busn) return dev;		} else {			if ((busn==0)&&(curdevn==devn)) return dev;			if ((curbusn==busn)&&(curdevn==devn)) return dev;		}	}	return NULL;}voidfind_endpoints(struct usb_device *dev, int* inep, int* outep, int* intep);voidfind_endpoints(struct usb_device *dev, int* inep, int* outep, int* intep){	int i,n;	struct usb_endpoint_descriptor *ep;	ep = dev->config->interface->altsetting->endpoint;	n=dev->config->interface->altsetting->bNumEndpoints;	for (i=0;i<n;i++) {	if (ep[i].bmAttributes==USB_ENDPOINT_TYPE_BULK)	{		if ((ep[i].bEndpointAddress&USB_ENDPOINT_DIR_MASK)==			USB_ENDPOINT_DIR_MASK)			*inep=ep[i].bEndpointAddress;		if ((ep[i].bEndpointAddress&USB_ENDPOINT_DIR_MASK)==0)			*outep=ep[i].bEndpointAddress;		} else if (ep[i].bmAttributes==USB_ENDPOINT_TYPE_INTERRUPT){			if ((ep[i].bEndpointAddress&USB_ENDPOINT_DIR_MASK)==				USB_ENDPOINT_DIR_MASK)				*intep=ep[i].bEndpointAddress;		}	}}voidlist_devices(short force){	struct usb_bus *bus;	struct usb_device *dev;	int found=0;	bus=init_usb();  	for (; bus; bus = bus->next)    	for (dev = bus->devices; dev; dev = dev->next) {		/* if it's a PTP device try to talk to it */		if ((dev->config->interface->altsetting->bInterfaceClass==			USB_CLASS_PTP)||force)		if (dev->descriptor.bDeviceClass!=USB_CLASS_HUB)		{			int n;			struct usb_endpoint_descriptor *ep;			PTPParams params;			PTP_USB ptp_usb;			PTPDeviceInfo deviceinfo;			if (!found){				printf("\nListing devices...\n");				printf("bus/dev\tvendorID/prodID\tdevice model\n");				found=1;			}			ep = dev->config->interface->altsetting->endpoint;			n=dev->config->interface->altsetting->bNumEndpoints;			find_endpoints(dev,&ptp_usb.inep,&ptp_usb.outep,				&ptp_usb.intep);			init_ptp_usb(&params, &ptp_usb, dev);			CC(ptp_opensession (&params,1),				"Could not open session!\n"				"Try to reset the camera.\n");			CC(ptp_getdeviceinfo (&params, &deviceinfo),				"Could not get device info!\n");      			printf("%s/%s\t0x%04X/0x%04X\t%s\n",				bus->dirname, dev->filename,				dev->descriptor.idVendor,				dev->descriptor.idProduct, deviceinfo.Model);			CC(ptp_closesession(&params),				"Could not close session!\n");			close_usb(&ptp_usb, dev);		}	}	if (!found) printf("\nFound no PTP devices\n");	printf("\n");}voidshow_info (int busn, int devn, short force){	PTPParams params;	PTP_USB ptp_usb;	struct usb_device *dev;	int i;	const char* name;	printf("\nCamera information\n");	printf("==================\n");#ifdef DEBUG	printf("dev %i\tbus %i\n",devn,busn);#endif	dev=find_device(busn,devn,force);	if (dev==NULL) {		fprintf(stderr,"could not find any device matching given "		"bus/dev numbers\n");		exit(-1);	}	find_endpoints(dev,&ptp_usb.inep,&ptp_usb.outep,&ptp_usb.intep);	init_ptp_usb(&params, &ptp_usb, dev);	CR(ptp_opensession (&params,1),		"Could not open session!\n");	CR(ptp_getdeviceinfo (&params, &params.deviceinfo),		"Could not get device info\n");	printf("Model: %s\n",params.deviceinfo.Model);	printf("  manufacturer: %s\n",params.deviceinfo.Manufacturer);	printf("  serial number: '%s'\n",params.deviceinfo.SerialNumber);	printf("  device version: %s\n",params.deviceinfo.DeviceVersion);	printf("  extension ID: 0x%08x\n",					params.deviceinfo.VendorExtensionID);	printf("  extension description: %s\n",					params.deviceinfo.VendorExtensionDesc);	printf("  extension version: 0x%04x\n",				params.deviceinfo.VendorExtensionVersion);	printf("\n");	CR(ptp_closesession(&params), "Could not close session!\n");	close_usb(&ptp_usb, dev);}voidlist_files (int busn, int devn, short force){	PTPParams params;	PTP_USB ptp_usb;	struct usb_device *dev;	int i;	PTPObjectInfo oi;	printf("\nListing files...\n");#ifdef DEBUG	printf("dev %i\tbus %i\n",devn,busn);#endif	dev=find_device(busn,devn,force);	if (dev==NULL) {		fprintf(stderr,"could not find any device matching given "		"bus/dev numbers\n");		exit(-1);	}	find_endpoints(dev,&ptp_usb.inep,&ptp_usb.outep,&ptp_usb.intep);	init_ptp_usb(&params, &ptp_usb, dev);	CR(ptp_opensession (&params,1),		"Could not open session!\n");	CR(ptp_getdeviceinfo (&params, &params.deviceinfo),		"Could not get device info\n");	printf("Camera: %s\n",params.deviceinfo.Model);	CR(ptp_getobjecthandles (&params,0xffffffff, 0x000000, 0x000000,		&params.handles),"Could not get object handles\n");	printf("Handler:        size: \tname:\n");	for (i = 0; i < params.handles.n; i++) {		CR(ptp_getobjectinfo(&params,params.handles.Handler[i],			&oi),"Could not get object info\n");		if (oi.ObjectFormat == PTP_OFC_Association)			continue;		printf("0x%08x: % 9i\t%s\n",params.handles.Handler[i],			oi.ObjectCompressedSize, oi.Filename);	}	printf("\n");	CR(ptp_closesession(&params), "Could not close session!\n");	close_usb(&ptp_usb, dev);}voidget_file (int busn, int devn, short force, uint32_t handle, char* filename){	PTPParams params;	PTP_USB ptp_usb;	struct usb_device *dev;	int i;	int file;	PTPObjectInfo oi;	char *image;	int ret;	printf("\nDownloading file...\n");#ifdef DEBUG	printf("dev %i\tbus %i\n",devn,busn);#endif	dev=find_device(busn,devn,force);	if (dev==NULL) {		fprintf(stderr,"could not find any device matching given "		"bus/dev numbers\n");		exit(-1);	}	find_endpoints(dev,&ptp_usb.inep,&ptp_usb.outep,&ptp_usb.intep);	init_ptp_usb(&params, &ptp_usb, dev);	CR(ptp_opensession (&params,1),		"Could not open session!\n");	CR(ptp_getdeviceinfo (&params, &params.deviceinfo),		"Could not get device info\n");

⌨️ 快捷键说明

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