📄 ptp.c
字号:
/* get response */ CHECK_PTP_RC(params->getresp_func(params, ptp)); if (ptp->Transaction_ID != params->transaction_id-1) { ptp_error (params, "PTP: Sequence number mismatch %d vs expected %d.", ptp->Transaction_ID, params->transaction_id-1 ); return PTP_ERROR_BADPARAM; } return ptp->Code;}static uint16_tptp_transaction (PTPParams* params, PTPContainer* ptp, uint16_t flags, unsigned int sendlen, unsigned char** data, unsigned int *recvlen){ return _ptp_transaction(params, ptp, flags, sendlen, data, -1, recvlen);}static uint16_tptp_transaction_fd (PTPParams* params, PTPContainer* ptp, uint16_t flags, unsigned int sendlen, int fd, unsigned int *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 *//* PTP Events wait for or check mode */#define PTP_EVENT_CHECK 0x0000 /* waits for */#define PTP_EVENT_CHECK_FAST 0x0001 /* checks */static inline uint16_tptp_usb_event (PTPParams* params, PTPContainer* event, int wait){ uint16_t ret; unsigned int rlen; PTPUSBEventContainer usbevent; PTP_CNT_INIT(usbevent); if ((params==NULL) || (event==NULL)) return PTP_ERROR_BADPARAM; switch(wait) { case PTP_EVENT_CHECK: ret=params->check_int_func((unsigned char*)&usbevent, sizeof(usbevent), params->data, &rlen); break; case PTP_EVENT_CHECK_FAST: ret=params->check_int_fast_func((unsigned char*) &usbevent, sizeof(usbevent), params->data, &rlen); break; default: ret=PTP_ERROR_BADPARAM; } if (ret!=PTP_RC_OK) { ptp_error (params, "PTP: reading event an error 0x%04x occurred", ret); ret = PTP_ERROR_IO; /* reading event error is nonfatal (for example timeout) */ } /* Only do the additional reads for "events". Canon IXUS 2 likes to * send unrelated data. */ if (dtoh16(usbevent.type) == PTP_USB_CONTAINER_EVENT) { while (dtoh32(usbevent.length) > rlen) { unsigned int newrlen = 0; ret=params->check_int_fast_func(((unsigned char*)&usbevent)+rlen, dtoh32(usbevent.length)-rlen,params->data,&newrlen ); if (ret != PTP_RC_OK) break; rlen+=newrlen; } } /* 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 ret;}uint16_tptp_usb_event_check (PTPParams* params, PTPContainer* event) { return ptp_usb_event (params, event, PTP_EVENT_CHECK_FAST);}uint16_tptp_usb_event_wait (PTPParams* params, PTPContainer* 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; unsigned int len; PTPContainer ptp; unsigned char* di=NULL; PTP_CNT_INIT(ptp); ptp.Code=PTP_OC_GetDeviceInfo; ptp.Nparam=0; len=0; ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &di, &len); if (ret == PTP_RC_OK) ptp_unpack_DI(params, di, deviceinfo, len); free(di); return ret;}/** * ptp_opensession: * params: PTPParams* * session - session number * * Establishes a new session. * * Return values: Some PTP_RC_* code. **/uint16_tptp_opensession (PTPParams* params, uint32_t session){ uint16_t ret; PTPContainer ptp; ptp_debug(params,"PTP: Opening session"); /* SessonID field of the operation dataset should always be set to 0 for OpenSession request! */ params->session_id=0x00000000; /* TransactionID should be set to 0 also! */ params->transaction_id=0x0000000; /* zero out response packet buffer */ params->response_packet = NULL; params->response_packet_size = 0; PTP_CNT_INIT(ptp); ptp.Code=PTP_OC_OpenSession; ptp.Param1=session; ptp.Nparam=1; ret=ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL); /* now set the global session id to current session number */ params->session_id=session; return ret;}/** * ptp_closesession: * params: PTPParams* * * Closes session. * * Return values: Some PTP_RC_* code. **/uint16_tptp_closesession (PTPParams* params){ PTPContainer ptp; ptp_debug(params,"PTP: Closing session"); /* free any dangling response packet */ if (params->response_packet_size > 0) { free(params->response_packet); params->response_packet = NULL; params->response_packet_size = 0; } PTP_CNT_INIT(ptp); ptp.Code=PTP_OC_CloseSession; ptp.Nparam=0; return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);}/** * ptp_getststorageids: * params: PTPParams* * * Gets array of StorageIDs and fills the storageids structure. * * Return values: Some PTP_RC_* code. **/uint16_tptp_getstorageids (PTPParams* params, PTPStorageIDs* storageids){ uint16_t ret; PTPContainer ptp; unsigned int len; unsigned char* sids=NULL; PTP_CNT_INIT(ptp); ptp.Code=PTP_OC_GetStorageIDs; ptp.Nparam=0; len=0; ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &sids, &len); if (ret == PTP_RC_OK) ptp_unpack_SIDs(params, sids, storageids, len); free(sids); return ret;}/** * ptp_getststorageinfo: * params: PTPParams* * storageid - StorageID * * Gets StorageInfo dataset of desired storage and fills storageinfo * structure. * * Return values: Some PTP_RC_* code. **/uint16_tptp_getstorageinfo (PTPParams* params, uint32_t storageid, PTPStorageInfo* storageinfo){ uint16_t ret; PTPContainer ptp; unsigned char* si=NULL; unsigned int len; PTP_CNT_INIT(ptp); ptp.Code=PTP_OC_GetStorageInfo; ptp.Param1=storageid; ptp.Nparam=1; len=0; ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &si, &len); if (ret == PTP_RC_OK) ptp_unpack_SI(params, si, storageinfo, len); free(si); return ret;}/** * ptp_formatstore: * params: PTPParams* * storageid - StorageID * * Formats the storage on the device. * * Return values: Some PTP_RC_* code. **/uint16_tptp_formatstore (PTPParams* params, uint32_t storageid){ PTPContainer ptp; PTP_CNT_INIT(ptp); ptp.Code=PTP_OC_FormatStore; ptp.Param1=storageid; ptp.Param2=PTP_FST_Undefined; ptp.Nparam=2; return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);}/** * ptp_getobjecthandles: * params: PTPParams* * storage - StorageID * objectformatcode - ObjectFormatCode (optional) * associationOH - ObjectHandle of Association for * wich a list of children is desired * (optional) * objecthandles - pointer to structute * * Fills objecthandles with structure returned by device. * * Return values: Some PTP_RC_* code. **/uint16_tptp_getobjecthandles (PTPParams* params, uint32_t storage, uint32_t objectformatcode, uint32_t associationOH, PTPObjectHandles* objecthandles){ uint16_t ret; PTPContainer ptp; unsigned char* oh=NULL; unsigned int len; PTP_CNT_INIT(ptp); ptp.Code=PTP_OC_GetObjectHandles; ptp.Param1=storage; ptp.Param2=objectformatcode; ptp.Param3=associationOH; ptp.Nparam=3; len=0; ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &oh, &len); if (ret == PTP_RC_OK) ptp_unpack_OH(params, oh, objecthandles, len); free(oh); return ret;}/** * ptp_getnumobjects: * params: PTPParams* * storage - StorageID * objectformatcode - ObjectFormatCode (optional) * associationOH - ObjectHandle of Association for * wich a list of children is desired * (optional) * numobs - pointer to uint32_t that takes number of objects * * Fills numobs with number of objects on device. * * Return values: Some PTP_RC_* code. **/uint16_tptp_getnumobjects (PTPParams* params, uint32_t storage, uint32_t objectformatcode, uint32_t associationOH, uint32_t* numobs){ uint16_t ret; PTPContainer ptp; int len; PTP_CNT_INIT(ptp); ptp.Code=PTP_OC_GetObjectHandles; ptp.Param1=storage; ptp.Param2=objectformatcode; ptp.Param3=associationOH; ptp.Nparam=3; len=0; ret=ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL); if (ret == PTP_RC_OK) { if (ptp.Nparam >= 1) *numobs = ptp.Param1; else ret = PTP_RC_GeneralError; } return ret;}/** * ptp_getobjectinfo: * params: PTPParams* * handle - Object handle * objectinfo - pointer to objectinfo that is returned * * Get objectinfo structure for handle from device. * * Return values: Some PTP_RC_* code. **/uint16_tptp_getobjectinfo (PTPParams* params, uint32_t handle, PTPObjectInfo* objectinfo){ uint16_t ret; PTPContainer ptp; unsigned char* oi=NULL; unsigned int len; PTP_CNT_INIT(ptp); ptp.Code=PTP_OC_GetObjectInfo; ptp.Param1=handle; ptp.Nparam=1; len=0; ret=ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, &oi, &len); if (ret == PTP_RC_OK) ptp_unpack_OI(params, oi, objectinfo, len); free(oi); return ret;}/** * ptp_getobject: * params: PTPParams* * handle - Object handle * object - pointer to data area * * Get object 'handle' from device and store the data in newly * allocated 'object'. * * Return values: Some PTP_RC_* code. **/uint16_tptp_getobject (PTPParams* params, uint32_t handle, unsigned char** object){ PTPContainer ptp; unsigned int len; PTP_CNT_INIT(ptp); ptp.Code=PTP_OC_GetObject; ptp.Param1=handle; ptp.Nparam=1; len=0; return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, &len);}/** * ptp_getobject_tofd: * params: PTPParams* * handle - Object handle * fd - File descriptor to write() to * * Get object 'handle' from device and write the data to the * given file descriptor. * * Return values: Some PTP_RC_* code. **/uint16_tptp_getobject_tofd (PTPParams* params, uint32_t handle, int fd){ PTPContainer ptp; unsigned int len; PTP_CNT_INIT(ptp); ptp.Code=PTP_OC_GetObject; ptp.Param1=handle; ptp.Nparam=1; len=0; return ptp_transaction_fd(params, &ptp, PTP_DP_GETDATA, 0, fd, &len);}/** * ptp_getpartialobject: * params: PTPParams* * handle - Object handle * offset - Offset into object * maxbytes - Maximum of bytes to read * object - pointer to data area * * Get object 'handle' from device and store the data in newly * allocated 'object'. Start from offset and read at most maxbytes. * * Return values: Some PTP_RC_* code. **/uint16_tptp_getpartialobject (PTPParams* params, uint32_t handle, uint32_t offset, uint32_t maxbytes, unsigned char** object){ PTPContainer ptp; unsigned int len; PTP_CNT_INIT(ptp); ptp.Code=PTP_OC_GetPartialObject; ptp.Param1=handle; ptp.Param2=offset; ptp.Param3=maxbytes; ptp.Nparam=3; len=0; return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, &len);}/** * ptp_getthumb: * params: PTPParams* * handle - Object handle * object - pointer to data area * * Get thumb for object 'handle' from device and store the data in newly * allocated 'object'. * * Return values: Some PTP_RC_* code. **/uint16_tptp_getthumb (PTPParams* params, uint32_t handle, unsigned char** object){ PTPContainer ptp; unsigned int len; PTP_CNT_INIT(ptp); ptp.Code=PTP_OC_GetThumb; ptp.Param1=handle; ptp.Nparam=1; return ptp_transaction(params, &ptp, PTP_DP_GETDATA, 0, object, &len);}/** * ptp_deleteobject: * params: PTPParams* * handle - object handle * ofc - object format code (optional) * * Deletes desired objects. * * Return values: Some PTP_RC_* code. **/uint16_tptp_deleteobject (PTPParams* params, uint32_t handle, uint32_t ofc){ PTPContainer ptp; PTP_CNT_INIT(ptp); ptp.Code=PTP_OC_DeleteObject; ptp.Param1=handle; ptp.Param2=ofc; ptp.Nparam=2; return ptp_transaction(params, &ptp, PTP_DP_NODATA, 0, NULL, NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -