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

📄 ptpcam.c

📁 Linux平台。一个好用的ptp传输工具。用来从相机向pc传输照片
💻 C
📖 第 1 页 / 共 4 页
字号:
/* ptpcam.c * * Copyright (C) 2001-2005 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 <config.h>#include "ptp.h"#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <getopt.h>#include <unistd.h>#include <signal.h>#include <sys/types.h>#include <utime.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 "ptpcam.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/* OUR APPLICATION USB URB (2MB) ;) */#define PTPCAM_USB_URB		2097152#define USB_TIMEOUT		5000#define USB_CAPTURE_TIMEOUT	20000/* one global variable (yes, I know it sucks) */short verbose=0;/* the other one, it sucks definitely ;) */int ptpcam_usb_timeout = USB_TIMEOUT;/* we need it for a proper signal handling :/ */PTPParams* globalparams;voidusage(){	printf("USAGE: ptpcam [OPTION]\n\n");}voidhelp(){	printf("USAGE: ptpcam [OPTION]\n\n");	printf("Options:\n"	"  --bus=BUS-NUMBER             USB bus number\n"	"  --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"	"  --set=PROP-NAME              Set property by name (abbreviations allowed)\n"	"  --val=VALUE                  Property value (numeric for --set-property and\n"	"                               string or numeric for --set)\n"	"  --show-all-properties        Show all properties values\n"	"  --show-unknown-properties    Show unknown properties values\n"	"  -L, --list-files             List all files\n"	"  -g, --get-file=HANDLE        Get file by given handler\n"	"  -G, --get-all-files          Get all files\n"	"  --overwrite                  Force file overwrite while saving"					"to disk\n"	"  -d, --delete-object=HANDLE   Delete object (file) by given handle\n"	"  -D, --delete-all-files       Delete all files form camera\n"	"  -c, --capture                Initiate capture\n"	"  --nikon-ic, --nic            Initiate Nikon Direct Capture (no download!)\n"	"  --nikon-dc, --ndc            Initiate Nikon Direct Capture and download\n"	"  --loop-capture=N             Perform N times capture/get/delete\n"	"  -f, --force                  Talk to non PTP devices\n"	"  -v, --verbose                Be verbose (print more debug)\n"	"  -h, --help                   Print this help message\n"	"\n");}voidptpcam_siginthandler(int signum){    PTP_USB* ptp_usb=(PTP_USB *)globalparams->data;    struct usb_device *dev=usb_device(ptp_usb->handle);    if (signum==SIGINT)    {	/* hey it's not that easy though... but at least we can try! */	printf("Got SIGINT, trying to clean up and close...\n");	usleep(5000);	close_camera (ptp_usb, globalparams, dev);	exit (-1);    }}static shortptp_read_func (unsigned char *bytes, unsigned int size, void *data){	int result=-1;	PTP_USB *ptp_usb=(PTP_USB *)data;	int toread=0;	signed long int rbytes=size;	do {		bytes+=toread;		if (rbytes>PTPCAM_USB_URB) 			toread = PTPCAM_USB_URB;		else			toread = rbytes;		result=USB_BULK_READ(ptp_usb->handle, ptp_usb->inep,(char *)bytes, toread,ptpcam_usb_timeout);		/* sometimes retry might help */		if (result==0)			result=USB_BULK_READ(ptp_usb->handle, ptp_usb->inep,(char *)bytes, toread,ptpcam_usb_timeout);		if (result < 0)			break;		rbytes-=PTPCAM_USB_URB;	} while (rbytes>0);	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,(char *)bytes,size,ptpcam_usb_timeout);	if (result >= 0)		return (PTP_RC_OK);	else 	{		if (verbose) perror("usb_bulk_write");		return PTP_ERROR_IO;	}}/* XXX this one is suposed to return the number of bytes read!!! */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,(char *)bytes,size,ptpcam_usb_timeout);	if (result==0)	    result=USB_BULK_READ(ptp_usb->handle, ptp_usb->intep,(char *)bytes,size,ptpcam_usb_timeout);	if (verbose>2) fprintf (stderr, "USB_BULK_READ returned %i, size=%i\n", result, size);	if (result >= 0) {		return result;	} else {		if (verbose) perror("ptp_check_int");		return result;	}}voidptpcam_debug (void *data, const char *format, va_list args);voidptpcam_debug (void *data, const char *format, va_list args){	if (verbose<2) return;	vfprintf (stderr, format, args);	fprintf (stderr,"\n");	fflush(stderr);}voidptpcam_error (void *data, const char *format, va_list args);voidptpcam_error (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=ptpcam_error;	params->debug_func=ptpcam_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_set_configuration(device_handle, dev->config->bConfigurationValue);		usb_claim_interface(device_handle,			dev->config->interface->altsetting->bInterfaceNumber);	}	globalparams=params;}voidclear_stall(PTP_USB* ptp_usb){	uint16_t status=0;	int ret;	/* check the inep status */	ret=usb_get_endpoint_status(ptp_usb,ptp_usb->inep,&status);	if (ret<0) perror ("inep: usb_get_endpoint_status()");	/* and clear the HALT condition if happend */	else if (status) {		printf("Resetting input pipe!\n");		ret=usb_clear_stall_feature(ptp_usb,ptp_usb->inep);        	/*usb_clear_halt(ptp_usb->handle,ptp_usb->inep); */		if (ret<0)perror ("usb_clear_stall_feature()");	}	status=0;	/* check the outep status */	ret=usb_get_endpoint_status(ptp_usb,ptp_usb->outep,&status);	if (ret<0) perror ("outep: usb_get_endpoint_status()");	/* and clear the HALT condition if happend */	else if (status) {		printf("Resetting output pipe!\n");        	ret=usb_clear_stall_feature(ptp_usb,ptp_usb->outep);		/*usb_clear_halt(ptp_usb->handle,ptp_usb->outep); */		if (ret<0)perror ("usb_clear_stall_feature()");	}        /*usb_clear_halt(ptp_usb->handle,ptp_usb->intep); */}voidclose_usb(PTP_USB* ptp_usb, struct usb_device* dev){	//clear_stall(ptp_usb);        usb_release_interface(ptp_usb->handle,                dev->config->interface->altsetting->bInterfaceNumber);	usb_reset(ptp_usb->handle);        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)	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 (verbose>1)				fprintf(stderr, "Found inep: 0x%02x\n",*inep);		}		if ((ep[i].bEndpointAddress&USB_ENDPOINT_DIR_MASK)==0)		{			*outep=ep[i].bEndpointAddress;			if (verbose>1)				fprintf(stderr, "Found outep: 0x%02x\n",*outep);		}		} else if ((ep[i].bmAttributes==USB_ENDPOINT_TYPE_INTERRUPT) &&			((ep[i].bEndpointAddress&USB_ENDPOINT_DIR_MASK)==				USB_ENDPOINT_DIR_MASK))		{			*intep=ep[i].bEndpointAddress;			if (verbose>1)				fprintf(stderr, "Found intep: 0x%02x\n",*intep);		}	}}intopen_camera (int busn, int devn, short force, PTP_USB *ptp_usb, PTPParams *params, struct usb_device **dev){#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);	if (ptp_opensession(params,1)!=PTP_RC_OK) {		fprintf(stderr,"ERROR: Could not open session!\n");		close_usb(ptp_usb, *dev);		return -1;	}	if (ptp_getdeviceinfo(params,&params->deviceinfo)!=PTP_RC_OK) {		fprintf(stderr,"ERROR: Could not get device info!\n");		close_usb(ptp_usb, *dev);		return -1;	}	return 0;}voidclose_camera (PTP_USB *ptp_usb, PTPParams *params, struct usb_device *dev){	if (ptp_closesession(params)!=PTP_RC_OK)		fprintf(stderr,"ERROR: Could not close session!\n");	close_usb(ptp_usb, dev);}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)		if ((dev->config->interface->altsetting->bInterfaceClass==			USB_CLASS_PTP)||force)		if (dev->descriptor.bDeviceClass!=USB_CLASS_HUB)		{			PTPParams params;			PTP_USB ptp_usb;			PTPDeviceInfo deviceinfo;			if (!found){				printf("\nListing devices...\n");				printf("bus/dev\tvendorID/prodID\tdevice model\n");				found=1;			}			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;	printf("\nCamera information\n");	printf("==================\n");	if (open_camera(busn, devn, force, &ptp_usb, &params, &dev)<0)		return;	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%08lx\n",(long unsigned)					params.deviceinfo.VendorExtensionID);	printf("  extension description: %s\n",					params.deviceinfo.VendorExtensionDesc);	printf("  extension version: 0x%04x\n",				params.deviceinfo.VendorExtensionVersion);	printf("\n");	close_camera(&ptp_usb, &params, dev);}voidcapture_image (int busn, int devn, short force){	PTPParams params;

⌨️ 快捷键说明

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