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

📄 ptp.c

📁 Linux平台。一个好用的ptp传输工具。用来从相机向pc传输照片
💻 C
📖 第 1 页 / 共 4 页
字号:
/* ptp.c * * Copyright (C) 2001-2005 Mariusz Woloszyn <emsi@ipartners.pl> * *  This file is part of libptp2. * *  libptp2 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. * *  libptp2 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 libptp2; 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 <stdlib.h>#include <stdarg.h>#include <stdio.h>#include <string.h>#ifdef ENABLE_NLS#  include <libintl.h>#  undef _#  define _(String) dgettext (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#define CHECK_PTP_RC(result)	{uint16_t r=(result); if (r!=PTP_RC_OK) return r;}#define PTP_CNT_INIT(cnt) {memset(&cnt,0,sizeof(cnt));}static voidptp_debug (PTPParams *params, const char *format, ...){          va_list args;        va_start (args, format);        if (params->debug_func!=NULL)                params->debug_func (params->data, format, args);        else	{                vfprintf (stderr, format, args);		fprintf (stderr,"\n");		fflush (stderr);	}        va_end (args);}  static voidptp_error (PTPParams *params, const char *format, ...){          va_list args;        va_start (args, format);        if (params->error_func!=NULL)                params->error_func (params->data, format, args);        else	{                vfprintf (stderr, format, args);		fprintf (stderr,"\n");		fflush (stderr);	}        va_end (args);}/* Pack / unpack functions */#include "ptp-pack.c"/* send / receive functions */uint16_tptp_usb_sendreq (PTPParams* params, PTPContainer* req){	static uint16_t ret;	static PTPUSBBulkContainer usbreq;	PTP_CNT_INIT(usbreq);	/* build appropriate USB container */	usbreq.length=htod32(PTP_USB_BULK_REQ_LEN-		(sizeof(uint32_t)*(5-req->Nparam)));	usbreq.type=htod16(PTP_USB_CONTAINER_COMMAND);	usbreq.code=htod16(req->Code);	usbreq.trans_id=htod32(req->Transaction_ID);	usbreq.payload.params.param1=htod32(req->Param1);	usbreq.payload.params.param2=htod32(req->Param2);	usbreq.payload.params.param3=htod32(req->Param3);	usbreq.payload.params.param4=htod32(req->Param4);	usbreq.payload.params.param5=htod32(req->Param5);	/* send it to responder */	ret=params->write_func((unsigned char *)&usbreq,		PTP_USB_BULK_REQ_LEN-(sizeof(uint32_t)*(5-req->Nparam)),		params->data);	if (ret!=PTP_RC_OK) {		ret = PTP_ERROR_IO;/*		ptp_error (params,			"PTP: request code 0x%04x sending req error 0x%04x",			req->Code,ret); */	}	return ret;}uint16_tptp_usb_senddata (PTPParams* params, PTPContainer* ptp,			unsigned char *data, unsigned int size){	static uint16_t ret;	static PTPUSBBulkContainer usbdata;	/* build appropriate USB container */	usbdata.length=htod32(PTP_USB_BULK_HDR_LEN+size);	usbdata.type=htod16(PTP_USB_CONTAINER_DATA);	usbdata.code=htod16(ptp->Code);	usbdata.trans_id=htod32(ptp->Transaction_ID);	memcpy(usbdata.payload.data,data,		(size<PTP_USB_BULK_PAYLOAD_LEN)?size:PTP_USB_BULK_PAYLOAD_LEN);	/* send first part of data */	ret=params->write_func((unsigned char *)&usbdata, PTP_USB_BULK_HDR_LEN+		((size<PTP_USB_BULK_PAYLOAD_LEN)?size:PTP_USB_BULK_PAYLOAD_LEN),		params->data);	if (ret!=PTP_RC_OK) {		ret = PTP_ERROR_IO;/*		ptp_error (params,		"PTP: request code 0x%04x sending data error 0x%04x",			ptp->Code,ret);*/		return ret;	}	if (size<=PTP_USB_BULK_PAYLOAD_LEN) return ret;	/* if everything OK send the rest */	ret=params->write_func (data+PTP_USB_BULK_PAYLOAD_LEN,				size-PTP_USB_BULK_PAYLOAD_LEN, params->data);	if (ret!=PTP_RC_OK) {		ret = PTP_ERROR_IO;/*		ptp_error (params,		"PTP: request code 0x%04x sending data error 0x%04x",			ptp->Code,ret); */	}	return ret;}uint16_tptp_usb_getdata (PTPParams* params, PTPContainer* ptp,		unsigned char **data){	static uint16_t ret;	static PTPUSBBulkContainer usbdata;	PTP_CNT_INIT(usbdata);#if 0	if (*data!=NULL) return PTP_ERROR_BADPARAM;#endif	do {		static uint32_t len;		/* read first(?) part of data */		ret=params->read_func((unsigned char *)&usbdata,				sizeof(usbdata), params->data);		if (ret!=PTP_RC_OK) {			ret = PTP_ERROR_IO;			break;		} else		if (dtoh16(usbdata.type)!=PTP_USB_CONTAINER_DATA) {			ret = PTP_ERROR_DATA_EXPECTED;			break;		} else		if (dtoh16(usbdata.code)!=ptp->Code) {			ret = dtoh16(usbdata.code);			break;		}		/* evaluate data length */		len=dtoh32(usbdata.length)-PTP_USB_BULK_HDR_LEN;		/* allocate memory for data if not allocated already */		if (*data==NULL) *data=calloc(1,len);		/* copy first part of data to 'data' */		memcpy(*data,usbdata.payload.data,			PTP_USB_BULK_PAYLOAD_LEN<len?			PTP_USB_BULK_PAYLOAD_LEN:len);		/* is that all of data? */		if (len+PTP_USB_BULK_HDR_LEN<=sizeof(usbdata)) break;		/* if not finaly read the rest of it */		ret=params->read_func(((unsigned char *)(*data))+					PTP_USB_BULK_PAYLOAD_LEN,					len-PTP_USB_BULK_PAYLOAD_LEN,					params->data);		if (ret!=PTP_RC_OK) {			ret = PTP_ERROR_IO;			break;		}	} while (0);/*	if (ret!=PTP_RC_OK) {		ptp_error (params,		"PTP: request code 0x%04x getting data error 0x%04x",			ptp->Code, ret);	}*/	return ret;}uint16_tptp_usb_getresp (PTPParams* params, PTPContainer* resp){	static uint16_t ret;	static PTPUSBBulkContainer usbresp;	PTP_CNT_INIT(usbresp);	/* read response, it should never be longer than sizeof(usbresp) */	ret=params->read_func((unsigned char *)&usbresp,				sizeof(usbresp), params->data);	if (ret!=PTP_RC_OK) {		ret = PTP_ERROR_IO;	} else	if (dtoh16(usbresp.type)!=PTP_USB_CONTAINER_RESPONSE) {		ret = PTP_ERROR_RESP_EXPECTED;	} else	if (dtoh16(usbresp.code)!=resp->Code) {		ret = dtoh16(usbresp.code);	}	if (ret!=PTP_RC_OK) {/*		ptp_error (params,		"PTP: request code 0x%04x getting resp error 0x%04x",			resp->Code, ret);*/		return ret;	}	/* build an appropriate PTPContainer */	resp->Code=dtoh16(usbresp.code);	resp->SessionID=params->session_id;	resp->Transaction_ID=dtoh32(usbresp.trans_id);	resp->Param1=dtoh32(usbresp.payload.params.param1);	resp->Param2=dtoh32(usbresp.payload.params.param2);	resp->Param3=dtoh32(usbresp.payload.params.param3);	resp->Param4=dtoh32(usbresp.payload.params.param4);	resp->Param5=dtoh32(usbresp.payload.params.param5);	return ret;}/* major PTP functions *//* Transaction data phase description */#define PTP_DP_NODATA		0x0000	/* no data phase */#define PTP_DP_SENDDATA		0x0001	/* sending data */#define PTP_DP_GETDATA		0x0002	/* receiving data */#define PTP_DP_DATA_MASK	0x00ff	/* data phase mask *//* Number of PTP Request phase parameters */#define PTP_RQ_PARAM0		0x0000	/* zero parameters */#define PTP_RQ_PARAM1		0x0100	/* one parameter */#define PTP_RQ_PARAM2		0x0200	/* two parameters */#define PTP_RQ_PARAM3		0x0300	/* three parameters */#define PTP_RQ_PARAM4		0x0400	/* four parameters */#define PTP_RQ_PARAM5		0x0500	/* five parameters *//** * ptp_transaction: * params:	PTPParams* * 		PTPContainer* ptp	- general ptp container * 		uint16_t flags		- lower 8 bits - data phase description * 		unsigned int sendlen	- senddata phase data length * 		char** data		- send or receive data buffer pointer * * Performs PTP transaction. ptp is a PTPContainer with appropriate fields * filled in (i.e. operation code and parameters). It's up to caller to do * so. * The flags decide whether the transaction has a data phase and what is its * direction (send or receive).  * If transaction is sending data the sendlen should contain its length in * bytes, otherwise it's ignored. * The data should contain an address of a pointer to data going to be sent * or is filled with such a pointer address if data are received depending * od dataphase direction (send or received) or is beeing ignored (no * dataphase). * The memory for a pointer should be preserved by the caller, if data are * beeing retreived the appropriate amount of memory is beeing allocated * (the caller should handle that!). * * Return values: Some PTP_RC_* code. * Upon success PTPContainer* ptp contains PTP Response Phase container with * all fields filled in. **/static uint16_tptp_transaction (PTPParams* params, PTPContainer* ptp, 			uint16_t flags, unsigned int sendlen, char** data){	if ((params==NULL) || (ptp==NULL)) 		return PTP_ERROR_BADPARAM;		ptp->Transaction_ID=params->transaction_id++;	ptp->SessionID=params->session_id;	/* send request */	CHECK_PTP_RC(params->sendreq_func (params, ptp));	/* is there a dataphase? */	switch (flags&PTP_DP_DATA_MASK) {		case PTP_DP_SENDDATA:			CHECK_PTP_RC(params->senddata_func(params, ptp,				(unsigned char*)*data, sendlen));			break;		case PTP_DP_GETDATA:			CHECK_PTP_RC(params->getdata_func(params, ptp,				(unsigned char**)data));			break;		case PTP_DP_NODATA:			break;		default:		return PTP_ERROR_BADPARAM;	}	/* get response */	CHECK_PTP_RC(params->getresp_func(params, ptp));	return PTP_RC_OK;}/* Enets handling functions *//* PTP Events wait for or check mode */#define PTP_EVENT_CHECK			0x0000	/* waits for */#define PTP_EVENT_CHECK_FAST		0x0001	/* checks */#define CHECK_INT(usbevent, size)  {	\	    switch(wait) {		\		case PTP_EVENT_CHECK:	\		     result+=params->check_int_func((unsigned char*)&usbevent+result, \			    size-result, params->data);    \		    break;			    \		case PTP_EVENT_CHECK_FAST:	\		     result+=params->check_int_fast_func((unsigned char*)&usbevent+result,  \			    size-result, params->data);    \		    break;			    \		default:			    \		    return PTP_ERROR_BADPARAM;	    \	    }\	}					static inline uint16_tptp_usb_event (PTPParams* params, PTPContainer* event, int wait){	int result=0, size=0;	static PTPUSBEventContainer usbevent;	PTP_CNT_INIT(usbevent);	if ((params==NULL) || (event==NULL)) 		return PTP_ERROR_BADPARAM;	CHECK_INT(usbevent, PTP_USB_INT_PACKET_LEN);	if (result<0)	    return PTP_ERROR_IO;	size=dtoh32(usbevent.length);	while (result<size) {	    CHECK_INT(usbevent, size);	    if (result<0)		return PTP_ERROR_IO;	}	/* if we read anything over interrupt endpoint it must be an event */	/* build an appropriate PTPContainer */	event->Code=dtoh16(usbevent.code);	event->SessionID=params->session_id;	event->Transaction_ID=dtoh32(usbevent.trans_id);	event->Param1=dtoh32(usbevent.param1);	event->Param2=dtoh32(usbevent.param2);	event->Param3=dtoh32(usbevent.param3);	return PTP_RC_OK;}uint16_tptp_usb_event_check (PTPParams* params, PTPContainer* event) {	ptp_debug(params,"PTP: Checking for Event");	return ptp_usb_event (params, event, PTP_EVENT_CHECK_FAST);}uint16_tptp_usb_event_wait (PTPParams* params, PTPContainer* event) {	ptp_debug(params,"PTP: Waiting for Event");	return ptp_usb_event (params, event, PTP_EVENT_CHECK);}/** * PTP operation functions * * all ptp_ functions should take integer parameters * in host byte order! **//** * ptp_getdeviceinfo: * params:	PTPParams* * * Gets device info dataset and fills deviceinfo structure. * * Return values: Some PTP_RC_* code. **/uint16_tptp_getdeviceinfo (PTPParams* params, PTPDeviceInfo* deviceinfo){	uint16_t ret;	PTPContainer ptp;	char* di=NULL;

⌨️ 快捷键说明

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