From eb0a79d89cfc9bafcb8bcef04223cd2a0966ea76 Mon Sep 17 00:00:00 2001 From: Marcus Meissner Date: Sun, 27 Aug 2006 19:31:05 +0000 Subject: [PATCH] sendtofd git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@9118 67ed7778-7388-44ab-90cf-0a291f65f57c --- camlibs/ptp2/ChangeLog | 6 +++ camlibs/ptp2/ptp.c | 101 ++++++++++++++++++++++++++++++++++------- camlibs/ptp2/ptp.h | 12 +++-- camlibs/ptp2/ptpip.c | 7 ++- 4 files changed, 105 insertions(+), 21 deletions(-) diff --git a/camlibs/ptp2/ChangeLog b/camlibs/ptp2/ChangeLog index edbbec6f6..904e2545b 100644 --- a/camlibs/ptp2/ChangeLog +++ b/camlibs/ptp2/ChangeLog @@ -1,3 +1,9 @@ +2006-08-25 Marcus Meissner + Linus Walleij + + * ptp.c,ptp.h,ptpip.c: Merged upload from fd patch + from libmtp folks (Linus Walleij). + 2006-08-20 Marcus Meissner * library.c: Do not download 0 sized objects. diff --git a/camlibs/ptp2/ptp.c b/camlibs/ptp2/ptp.c index b663ffd37..fcbe1626b 100644 --- a/camlibs/ptp2/ptp.c +++ b/camlibs/ptp2/ptp.c @@ -121,12 +121,17 @@ ptp_usb_sendreq (PTPParams* params, PTPContainer* req) return ret; } +/* Used for file transactions */ +#define FILE_BUFFER_SIZE 0x10000 + uint16_t ptp_usb_senddata (PTPParams* params, PTPContainer* ptp, - unsigned char *data, unsigned int size) + unsigned char *data, unsigned int size, + int from_fd) { uint16_t ret; int wlen, datawlen; + size_t written; PTPUSBBulkContainer usbdata; /* build appropriate USB container */ @@ -142,8 +147,13 @@ ptp_usb_senddata (PTPParams* params, PTPContainer* ptp, /* For all camera devices. */ datawlen = (sizewrite_func((unsigned char *)&usbdata, wlen, params->data); @@ -156,7 +166,38 @@ ptp_usb_senddata (PTPParams* params, PTPContainer* ptp, } if (size <= datawlen) return ret; /* if everything OK send the rest */ - ret=params->write_func (data + datawlen, size - datawlen, params->data); + if (from_fd == -1) { + ret=params->write_func (data + datawlen, size - datawlen, params->data); + } else { + uint32_t bytes_to_transfer; + uint32_t bytes_left_to_transfer; + void *temp_buf; + + written = 0; + bytes_left_to_transfer = size-datawlen; + + temp_buf = malloc(FILE_BUFFER_SIZE); + if (temp_buf == NULL) + return PTP_ERROR_IO; + + ret = PTP_RC_OK; + while(bytes_left_to_transfer > 0) { + if (bytes_left_to_transfer > FILE_BUFFER_SIZE) { + bytes_to_transfer = FILE_BUFFER_SIZE; + } else { + bytes_to_transfer = bytes_left_to_transfer; + } + written = read(from_fd, temp_buf, bytes_to_transfer); + if (written != bytes_to_transfer) { + ret = PTP_ERROR_IO; + break; + } + ret=params->write_func (temp_buf, bytes_to_transfer, params->data); + bytes_left_to_transfer -= bytes_to_transfer; + } + free(temp_buf); + + } if (ret!=PTP_RC_OK) { ret = PTP_ERROR_IO; /* ptp_error (params, @@ -238,7 +279,6 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, } else { uint32_t bytes_to_write, written; uint32_t bytes_left_to_transfer; - uint32_t temp_buf_size = 0x100000; void *temp_buf; if (readlen) @@ -255,7 +295,7 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, if (len + PTP_USB_BULK_HDR_LEN <= rlen) break; - temp_buf = malloc(temp_buf_size); + temp_buf = malloc(FILE_BUFFER_SIZE); if (temp_buf == NULL) { ret = PTP_ERROR_IO; break; @@ -265,8 +305,8 @@ ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, bytes_left_to_transfer = len - (rlen - PTP_USB_BULK_HDR_LEN); while (bytes_left_to_transfer > 0) { - bytes_to_write = ((bytes_left_to_transfer > temp_buf_size) ? - temp_buf_size : bytes_left_to_transfer); + bytes_to_write = ((bytes_left_to_transfer > FILE_BUFFER_SIZE) ? + FILE_BUFFER_SIZE : bytes_left_to_transfer); ret = params->read_func(temp_buf, bytes_to_write, @@ -382,11 +422,11 @@ ptp_usb_getresp (PTPParams* params, PTPContainer* resp) static uint16_t _ptp_transaction (PTPParams* params, PTPContainer* ptp, uint16_t flags, unsigned int sendlen, unsigned char** data, - int to_fd, unsigned int *recvlen) + int fd, unsigned int *recvlen) { if ((params==NULL) || (ptp==NULL)) return PTP_ERROR_BADPARAM; - + ptp->Transaction_ID=params->transaction_id++; ptp->SessionID=params->session_id; /* send request */ @@ -395,11 +435,11 @@ _ptp_transaction (PTPParams* params, PTPContainer* ptp, switch (flags&PTP_DP_DATA_MASK) { case PTP_DP_SENDDATA: CHECK_PTP_RC(params->senddata_func(params, ptp, - *data, sendlen)); + *data, sendlen, fd)); break; case PTP_DP_GETDATA: CHECK_PTP_RC(params->getdata_func(params, ptp, - (unsigned char**)data, recvlen, to_fd)); + (unsigned char**)data, recvlen, fd)); break; case PTP_DP_NODATA: break; @@ -421,11 +461,17 @@ ptp_transaction (PTPParams* params, PTPContainer* ptp, } static uint16_t -ptp_transaction_tofd (PTPParams* params, PTPContainer* ptp, +ptp_transaction_fd (PTPParams* params, PTPContainer* ptp, uint16_t flags, unsigned int sendlen, - int to_fd, unsigned int *recvlen) + int fd, unsigned int *recvlen) { - return _ptp_transaction(params, ptp, flags, sendlen, NULL, to_fd, recvlen); + /* + * This dummy data needed since _ptp_transaction() + * will dereference the data argument + */ + unsigned char *dummydata = NULL; + + return _ptp_transaction(params, ptp, flags, sendlen, &dummydata, fd, recvlen); } /* Enets handling functions */ @@ -786,7 +832,7 @@ ptp_getobject_tofd (PTPParams* params, uint32_t handle, int fd) ptp.Param1=handle; ptp.Nparam=1; len=0; - return ptp_transaction_tofd(params, &ptp, PTP_DP_GETDATA, 0, fd, &len); + return ptp_transaction_fd(params, &ptp, PTP_DP_GETDATA, 0, fd, &len); } /** @@ -932,6 +978,29 @@ ptp_sendobject (PTPParams* params, unsigned char* object, uint32_t size) return ptp_transaction(params, &ptp, PTP_DP_SENDDATA, size, &object, NULL); } +/** + * ptp_sendobject_fromfd: + * params: PTPParams* + * fd - File descriptor to read() object from + * uint32_t size - File/object size + * + * Sends object from file descriptor by consecutive reads from this + * descriptor. + * + * Return values: Some PTP_RC_* code. + **/ +uint16_t +ptp_sendobject_fromfd (PTPParams* params, int fd, uint32_t size) +{ + PTPContainer ptp; + + PTP_CNT_INIT(ptp); + ptp.Code=PTP_OC_SendObject; + ptp.Nparam=0; + + return ptp_transaction_fd(params, &ptp, PTP_DP_SENDDATA, size, fd, NULL); +} + /** * ptp_initiatecapture: diff --git a/camlibs/ptp2/ptp.h b/camlibs/ptp2/ptp.h index e1e82e366..3f50a9b15 100644 --- a/camlibs/ptp2/ptp.h +++ b/camlibs/ptp2/ptp.h @@ -1042,7 +1042,8 @@ typedef short (* PTPIOWriteFunc)(unsigned char *bytes, unsigned int size, */ typedef uint16_t (* PTPIOSendReq) (PTPParams* params, PTPContainer* req); typedef uint16_t (* PTPIOSendData) (PTPParams* params, PTPContainer* ptp, - unsigned char *data, unsigned int size); + unsigned char *data, unsigned int size, + int from_fd); typedef uint16_t (* PTPIOGetResp) (PTPParams* params, PTPContainer* resp); typedef uint16_t (* PTPIOGetData) (PTPParams* params, PTPContainer* ptp, unsigned char **data, unsigned int *recvlen, @@ -1112,7 +1113,8 @@ struct _PTPParams { /* last, but not least - ptp functions */ uint16_t ptp_usb_sendreq (PTPParams* params, PTPContainer* req); uint16_t ptp_usb_senddata (PTPParams* params, PTPContainer* ptp, - unsigned char *data, unsigned int size); + unsigned char *data, unsigned int size, + int from_fd); uint16_t ptp_usb_getresp (PTPParams* params, PTPContainer* resp); uint16_t ptp_usb_getdata (PTPParams* params, PTPContainer* ptp, unsigned char **data, unsigned int *readlen, @@ -1123,7 +1125,8 @@ uint16_t ptp_usb_event_wait (PTPParams* params, PTPContainer* event); int ptp_ptpip_connect (PTPParams* params, const char *port); uint16_t ptp_ptpip_sendreq (PTPParams* params, PTPContainer* req); uint16_t ptp_ptpip_senddata (PTPParams* params, PTPContainer* ptp, - unsigned char *data, unsigned int size); + unsigned char *data, unsigned int size, + int to_fd); uint16_t ptp_ptpip_getresp (PTPParams* params, PTPContainer* resp); uint16_t ptp_ptpip_getdata (PTPParams* params, PTPContainer* ptp, unsigned char **data, unsigned int *readlen, @@ -1168,7 +1171,8 @@ uint16_t ptp_sendobjectinfo (PTPParams* params, uint32_t* store, uint32_t* parenthandle, uint32_t* handle, PTPObjectInfo* objectinfo); uint16_t ptp_sendobject (PTPParams* params, unsigned char* object, - uint32_t size); + uint32_t size); +uint16_t ptp_sendobject_fromfd (PTPParams* params, int fd, uint32_t size); uint16_t ptp_initiatecapture (PTPParams* params, uint32_t storageid, uint32_t ofc); diff --git a/camlibs/ptp2/ptpip.c b/camlibs/ptp2/ptpip.c index 4ba0a190e..b99a42691 100644 --- a/camlibs/ptp2/ptpip.c +++ b/camlibs/ptp2/ptpip.c @@ -210,12 +210,17 @@ ptp_ptpip_check_event (PTPParams* params) { #define WRITE_BLOCKSIZE 65536 uint16_t ptp_ptpip_senddata (PTPParams* params, PTPContainer* ptp, - unsigned char *data, unsigned int size) + unsigned char *data, unsigned int size, + int to_fd) { unsigned char request[16]; int ret, curwrite, towrite; unsigned char* xdata; + if (to_fd != -1) { + gp_log (GP_LOG_ERROR, "ptpip/senddata", "fd transfers not supported."); + return PTP_RC_GeneralError; + } htod32a(&request[ptpip_type],PTPIP_START_DATA_PACKET); htod32a(&request[ptpip_len],sizeof(request)); htod32a(&request[ptpip_startdata_transid + 8],ptp->Transaction_ID);