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(¶ms,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(¶ms, &ptp_usb, dev); CC(ptp_opensession (¶ms,1), "Could not open session!\n" "Try to reset the camera.\n"); CC(ptp_getdeviceinfo (¶ms, &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(¶ms), "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(¶ms, &ptp_usb, dev); CR(ptp_opensession (¶ms,1), "Could not open session!\n"); CR(ptp_getdeviceinfo (¶ms, ¶ms.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(¶ms), "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(¶ms, &ptp_usb, dev); CR(ptp_opensession (¶ms,1), "Could not open session!\n"); CR(ptp_getdeviceinfo (¶ms, ¶ms.deviceinfo), "Could not get device info\n"); printf("Camera: %s\n",params.deviceinfo.Model); CR(ptp_getobjecthandles (¶ms,0xffffffff, 0x000000, 0x000000, ¶ms.handles),"Could not get object handles\n"); printf("Handler: size: \tname:\n"); for (i = 0; i < params.handles.n; i++) { CR(ptp_getobjectinfo(¶ms,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(¶ms), "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(¶ms, &ptp_usb, dev); CR(ptp_opensession (¶ms,1), "Could not open session!\n"); CR(ptp_getdeviceinfo (¶ms, ¶ms.deviceinfo), "Could not get device info\n");
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?