Library to allo USB PTP device to be hosted by the mbed platform
Dependents: class_project_main
Revision 0:98cf19bcd828, committed 2013-08-23
- Comitter:
- jakowisp
- Date:
- Fri Aug 23 00:52:52 2013 +0000
- Child:
- 1:71c0e9dc153d
- Commit message:
- Fix for a buffer overrun and refactored the Tranactoion code.
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PIMA15740/PIMA15740_types.h Fri Aug 23 00:52:52 2013 +0000 @@ -0,0 +1,52 @@ +#include "PIMAconst.h" +#include "PIMAArray.h" +#include "PIMAString.h" + + +typedef __packed struct { + uint32_t len; + uint16_t type; + uint16_t opcode; + uint32_t TransactionID; + uint32_t param[5]; + } PIMAContainer; + +typedef struct { + uint16_t standardVersion; + uint32_t vendorExtensionID; + uint16_t vendorExtensionVersion; + PIMAString vendorExtensionDesc; + uint16_t functionMode; + PIMAArray operationsSupported; + PIMAArray eventsSupported; + PIMAArray devicePropertiesSupported; + PIMAArray captureFormats; + PIMAArray imageFormats; + PIMAString manufacturer; + PIMAString model; + PIMAString deviceVersion; + PIMAString serialNumber; +} DeviceInfoStruct; + +typedef struct { + uint32_t storageID; //0x0 + uint16_t objectFormat; //0x4 + uint16_t protectionStatus; //0x6 + uint32_t objectCompressSize; //0x8 + uint16_t thumbFormat; //0xc + uint32_t thumbCompressedSize; //0xd + uint32_t thumbPixWidth; //0x12 + uint32_t thumbPixHeight; //0x16 + uint32_t imagePixWidth; //0x1a + uint32_t imagePixHeight; //0x1e + uint32_t imageBitDepth; //0x22 + uint32_t parentObject; //0x26 + uint16_t associationType; //0x2a + uint32_t associationDesc; //0x2c + uint32_t sequenceNumber; //0x30 + PIMAString filename; //0x34 + PIMAString captureDate; + PIMAString modificationDate; + PIMAString keywords; +} ObjectInfoStruct; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PIMA15740/PIMAArray.h Fri Aug 23 00:52:52 2013 +0000 @@ -0,0 +1,48 @@ + +#include "mallocdebug.h" + +/** +* Class PIMA array +* +* +* +*/ +class PIMAArray { +public: + /** + * Constructor + * @params: None + * + */ + PIMAArray() { + numberOfElements=0; + codes=NULL; + }; + + ~PIMAArray() { + if( codes !=NULL) + free(codes); + }; + + int FillArray(uint8_t *currentPtr) { + SetNumberOfElements(*((uint32_t *)currentPtr)); + SetCodes((uint16_t *)(currentPtr+4)); + return (2*numberOfElements) + 4; +} + + void SetNumberOfElements(uint8_t length) { + this->numberOfElements=length; + if( codes !=NULL) + free(codes); + codes = (uint16_t *) malloc(sizeof(uint16_t)*length); + }; + + void SetCodes(uint16_t *buffer){ + if(buffer!=NULL && codes !=NULL) + for(int i=0;i<this->numberOfElements;i++) + codes[i]=buffer[i]; + }; + + uint32_t numberOfElements; + uint16_t *codes; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PIMA15740/PIMAString.h Fri Aug 23 00:52:52 2013 +0000 @@ -0,0 +1,63 @@ + +#include "mallocdebug.h" + +class PIMAString { +public: + + PIMAString() { + length=0; + StringChars=NULL; + vals=NULL; + }; + + ~PIMAString() { + if( StringChars !=NULL) + free(StringChars); + if(vals!=NULL) + free(vals); + }; + + int FillString(uint8_t *currentPtr) { + setLength(*currentPtr); + setStringChars((uint16_t *)(currentPtr+1)); + return 2*length +1; + }; + + + char * getString() { + if(vals!=NULL) + free(vals); + vals=(char *) malloc(sizeof(char)*(this->length+1)); + for(int i=0;i<this->length;i++) + vals[i]=StringChars[i]; //NOTE: Truncates the uint16_t value. + vals[length]='\0'; + return vals; + } + + uint8_t getLength() { + return this->length; + } + + private: + void setLength(uint8_t length) { + if(length > this->length) { + if( StringChars !=NULL) + free(StringChars); + StringChars = (uint16_t *) malloc(sizeof(uint16_t)*length); + } + this->length=length; + + }; + + void setStringChars(uint16_t *buffer){ + if(buffer!=NULL && StringChars !=NULL) + for(int i=0;i<this->length;i++) + StringChars[i]=buffer[i]; + }; + + + uint8_t length; + uint16_t *StringChars; + char *vals; + +}; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PIMA15740/PIMAconst.h Fri Aug 23 00:52:52 2013 +0000 @@ -0,0 +1,293 @@ +/* Copyright (C) 2010-2011 Circuits At Home, LTD. All rights reserved. + +This software may be distributed and modified under the terms of the GNU +General Public License version 2 (GPL2) as published by the Free Software +Foundation and appearing in the file GPL2.TXT included in the packaging of +this file. Please note that GPL2 Section 2[b] requires that all works based +on this software must also be made publicly available under the terms of +the GPL2 ("Copyleft"). + +Contact information +------------------- + +Circuits At Home, LTD +Web : http://www.circuitsathome.com +e-mail : support@circuitsathome.com +*/ +#ifndef __PTPCONST_H__ +#define __PTPCONST_H__ + +#include <inttypes.h> + +/* PTP USB Bulk-Pipe container */ +/* USB bulk max max packet length for full speed endpoints */ +//#define PTP_USB_BULK_FS_MAX_PACKET_LEN 64 +//#define PTP_USB_BULK_HDR_LEN (2*sizeof(uint32_t)+2*sizeof(uint16_t)) +//#define PTP_USB_BULK_PAYLOAD_LEN (PTP_USB_BULK_FS_MAX_PACKET_LEN-PTP_USB_BULK_HDR_LEN) +//#define PTP_USB_BULK_REQ_LEN (PTP_USB_BULK_HDR_LEN+5*sizeof(uint32_t)) + +#define PIMAContainerHeaderLength 0xc + + +#define PTP_USB_INT_PACKET_LEN 8 + +/* USB container types */ +#define PTP_USB_CONTAINER_UNDEFINED 0x0000 +#define PTP_USB_CONTAINER_COMMAND 0x0001 +#define PTP_USB_CONTAINER_DATA 0x0002 +#define PTP_USB_CONTAINER_RESPONSE 0x0003 +#define PTP_USB_CONTAINER_EVENT 0x0004 + +/* Vendor IDs */ +#define PTP_VENDOR_EASTMAN_KODAK 0x00000001 +#define PTP_VENDOR_SEIKO_EPSON 0x00000002 +#define PTP_VENDOR_AGILENT 0x00000003 +#define PTP_VENDOR_POLAROID 0x00000004 +#define PTP_VENDOR_AGFA_GEVAERT 0x00000005 +#define PTP_VENDOR_MICROSOFT 0x00000006 +#define PTP_VENDOR_EQUINOX 0x00000007 +#define PTP_VENDOR_VIEWQUEST 0x00000008 +#define PTP_VENDOR_STMICROELECTRONICS 0x00000009 +#define PTP_VENDOR_NIKON 0x0000000A +#define PTP_VENDOR_CANON 0x0000000B +#define PTP_VENDOR_FOTONATION 0x0000000C +#define PTP_VENDOR_PENTAX 0x0000000D +#define PTP_VENDOR_FUJI 0x0000000E + +/* Operation Codes */ +#define PTP_OC_Undefined 0x1000 +#define PTP_OC_GetDeviceInfo 0x1001 +#define PTP_OC_OpenSession 0x1002 +#define PTP_OC_CloseSession 0x1003 +#define PTP_OC_GetStorageIDs 0x1004 +#define PTP_OC_GetStorageInfo 0x1005 +#define PTP_OC_GetNumObjects 0x1006 +#define PTP_OC_GetObjectHandles 0x1007 +#define PTP_OC_GetObjectInfo 0x1008 +#define PTP_OC_GetObject 0x1009 +#define PTP_OC_GetThumb 0x100A +#define PTP_OC_DeleteObject 0x100B +#define PTP_OC_SendObjectInfo 0x100C +#define PTP_OC_SendObject 0x100D +#define PTP_OC_InitiateCapture 0x100E +#define PTP_OC_FormatStore 0x100F +#define PTP_OC_ResetDevice 0x1010 +#define PTP_OC_SelfTest 0x1011 +#define PTP_OC_SetObjectProtection 0x1012 +#define PTP_OC_PowerDown 0x1013 +#define PTP_OC_GetDevicePropDesc 0x1014 +#define PTP_OC_GetDevicePropValue 0x1015 +#define PTP_OC_SetDevicePropValue 0x1016 +#define PTP_OC_ResetDevicePropValue 0x1017 +#define PTP_OC_TerminateOpenCapture 0x1018 +#define PTP_OC_MoveObject 0x1019 +#define PTP_OC_CopyObject 0x101A +#define PTP_OC_GetPartialObject 0x101B +#define PTP_OC_InitiateOpenCapture 0x101C + +/* Proprietary vendor extension operations mask */ +#define PTP_OC_EXTENSION_MASK 0xF000 +#define PTP_OC_EXTENSION 0x9000 + +/* Response Codes */ +#define PIMAReturnCodeUndefined 0x2000 +#define PIMAReturnCodeOK 0x2001 +#define PIMAReturnCodeGeneralError 0x2002 +#define PIMAReturnCodeSessionNotOpen 0x2003 +#define PIMAReturnCodeInvalidTransactionID 0x2004 +#define PIMAReturnCodeOperationNotSupported 0x2005 +#define PIMAReturnCodeParameterNotSupported 0x2006 +#define PIMAReturnCodeIncompleteTransfer 0x2007 +#define PIMAReturnCodeInvalidStorageId 0x2008 +#define PIMAReturnCodeInvalidObjectHandle 0x2009 +#define PIMAReturnCodeDevicePropertyNotSupported 0x200A +#define PIMAReturnCodeInvalidObjectFormatCode 0x200B +#define PIMAReturnCodeStoreFull 0x200C +#define PIMAReturnCodeObjectWriteProtected 0x200D +#define PIMAReturnCodeStoreReadOnly 0x200E +#define PIMAReturnCodeAccessDenied 0x200F +#define PIMAReturnCodeNoThumbnailPresent 0x2010 +#define PIMAReturnCodeSelfTestFailed 0x2011 +#define PIMAReturnCodePartialDeletion 0x2012 +#define PIMAReturnCodeStoreNotAvailable 0x2013 +#define PIMAReturnCodeSpecificationByFormatUnsupported 0x2014 +#define PIMAReturnCodeNoValidObjectInfo 0x2015 +#define PIMAReturnCodeInvalidCodeFormat 0x2016 +#define PIMAReturnCodeUnknownVendorCode 0x2017 +#define PIMAReturnCodeCaptureAlreadyTerminated 0x2018 +#define PIMAReturnCodeDeviceBusy 0x2019 +#define PIMAReturnCodeInvalidParentObject 0x201A +#define PIMAReturnCodeInvalidDevicePropFormat 0x201B +#define PIMAReturnCodeInvalidDevicePropValue 0x201C +#define PIMAReturnCodeInvalidParameter 0x201D +#define PIMAReturnCodeSessionAlreadyOpened 0x201E +#define PIMAReturnCodeTransactionCanceled 0x201F +#define PIMAReturnCodeSpecificationOfDestinationUnsupported 0x2020 + +/* Proprietary vendor extension response code mask */ +#define PIMAReturnCodeEXTENSION_MASK 0xF000 +#define PIMAReturnCodeEXTENSION 0xA000 + +/* PTP Event Codes */ +#define PTP_EC_Undefined 0x4000 +#define PTP_EC_CancelTransaction 0x4001 +#define PTP_EC_ObjectAdded 0x4002 +#define PTP_EC_ObjectRemoved 0x4003 +#define PTP_EC_StoreAdded 0x4004 +#define PTP_EC_StoreRemoved 0x4005 +#define PTP_EC_DevicePropChanged 0x4006 +#define PTP_EC_ObjectInfoChanged 0x4007 +#define PTP_EC_DeviceInfoChanged 0x4008 +#define PTP_EC_RequestObjectTransfer 0x4009 +#define PTP_EC_StoreFull 0x400A +#define PTP_EC_DeviceReset 0x400B +#define PTP_EC_StorageInfoChanged 0x400C +#define PTP_EC_CaptureComplete 0x400D +#define PTP_EC_UnreportedStatus 0x400E + +#define PTP_HANDLER_SPECIAL 0xffffffff +#define PTP_HANDLER_ROOT 0x00000000 + +/* max ptp string length INCLUDING terminating null character */ +#define PTP_MAXSTRLEN 255 + +/* PTP Object Format Codes */ + +/* ancillary formats */ +#define PTP_OFC_Undefined 0x3000 +#define PTP_OFC_Association 0x3001 +#define PTP_OFC_Script 0x3002 +#define PTP_OFC_Executable 0x3003 +#define PTP_OFC_Text 0x3004 +#define PTP_OFC_HTML 0x3005 +#define PTP_OFC_DPOF 0x3006 +#define PTP_OFC_AIFF 0x3007 +#define PTP_OFC_WAV 0x3008 +#define PTP_OFC_MP3 0x3009 +#define PTP_OFC_AVI 0x300A +#define PTP_OFC_MPEG 0x300B +#define PTP_OFC_ASF 0x300C +#define PTP_OFC_QT 0x300D /* guessing */ + +/* image formats */ +#define PTP_OFC_EXIF_JPEG 0x3801 +#define PTP_OFC_TIFF_EP 0x3802 +#define PTP_OFC_FlashPix 0x3803 +#define PTP_OFC_BMP 0x3804 +#define PTP_OFC_CIFF 0x3805 +#define PTP_OFC_Undefined_0x3806 0x3806 +#define PTP_OFC_GIF 0x3807 +#define PTP_OFC_JFIF 0x3808 +#define PTP_OFC_PCD 0x3809 +#define PTP_OFC_PICT 0x380A +#define PTP_OFC_PNG 0x380B +#define PTP_OFC_Undefined_0x380C 0x380C +#define PTP_OFC_TIFF 0x380D +#define PTP_OFC_TIFF_IT 0x380E +#define PTP_OFC_JP2 0x380F +#define PTP_OFC_JPX 0x3810 + +/* PTP Association Types */ +#define PTP_AT_Undefined 0x0000 +#define PTP_AT_GenericFolder 0x0001 +#define PTP_AT_Album 0x0002 +#define PTP_AT_TimeSequence 0x0003 +#define PTP_AT_HorizontalPanoramic 0x0004 +#define PTP_AT_VerticalPanoramic 0x0005 +#define PTP_AT_2DPanoramic 0x0006 +#define PTP_AT_AncillaryData 0x0007 + +/* PTP Protection Status */ +#define PTP_PS_NoProtection 0x0000 +#define PTP_PS_ReadOnly 0x0001 + +/* PTP Storage Types */ +#define PTP_ST_Undefined 0x0000 +#define PTP_ST_FixedROM 0x0001 +#define PTP_ST_RemovableROM 0x0002 +#define PTP_ST_FixedRAM 0x0003 +#define PTP_ST_RemovableRAM 0x0004 + +/* PTP FilesystemType Values */ +#define PTP_FST_Undefined 0x0000 +#define PTP_FST_GenericFlat 0x0001 +#define PTP_FST_GenericHierarchical 0x0002 +#define PTP_FST_DCF 0x0003 + +/* PTP StorageInfo AccessCapability Values */ +#define PTP_AC_ReadWrite 0x0000 +#define PTP_AC_ReadOnly 0x0001 +#define PTP_AC_ReadOnly_with_Object_Deletion 0x0002 + +/* DataType Codes */ +#define PTP_DTC_UNDEF 0x0000 +#define PTP_DTC_INT8 0x0001 +#define PTP_DTC_UINT8 0x0002 +#define PTP_DTC_INT16 0x0003 +#define PTP_DTC_UINT16 0x0004 +#define PTP_DTC_INT32 0x0005 +#define PTP_DTC_UINT32 0x0006 +#define PTP_DTC_INT64 0x0007 +#define PTP_DTC_UINT64 0x0008 +#define PTP_DTC_INT128 0x0009 +#define PTP_DTC_UINT128 0x000A +#define PTP_DTC_AINT8 0x4001 +#define PTP_DTC_AUINT8 0x4002 +#define PTP_DTC_AINT16 0x4003 +#define PTP_DTC_AUINT16 0x4004 +#define PTP_DTC_AINT32 0x4005 +#define PTP_DTC_AUINT32 0x4006 +#define PTP_DTC_AINT64 0x4007 +#define PTP_DTC_AUINT64 0x4008 +#define PTP_DTC_AINT128 0x4009 +#define PTP_DTC_AUINT128 0x400A +#define PTP_DTC_STR 0xFFFF + +/* Device Properties Codes */ +#define PTP_DPC_Undefined 0x5000 +#define PTP_DPC_BatteryLevel 0x5001 +#define PTP_DPC_FunctionalMode 0x5002 +#define PTP_DPC_ImageSize 0x5003 +#define PTP_DPC_CompressionSetting 0x5004 +#define PTP_DPC_WhiteBalance 0x5005 +#define PTP_DPC_RGBGain 0x5006 +#define PTP_DPC_FNumber 0x5007 +#define PTP_DPC_FocalLength 0x5008 +#define PTP_DPC_FocusDistance 0x5009 +#define PTP_DPC_FocusMode 0x500A +#define PTP_DPC_ExposureMeteringMode 0x500B +#define PTP_DPC_FlashMode 0x500C +#define PTP_DPC_ExposureTime 0x500D +#define PTP_DPC_ExposureProgramMode 0x500E +#define PTP_DPC_ExposureIndex 0x500F +#define PTP_DPC_ExposureBiasCompensation 0x5010 +#define PTP_DPC_DateTime 0x5011 +#define PTP_DPC_CaptureDelay 0x5012 +#define PTP_DPC_StillCaptureMode 0x5013 +#define PTP_DPC_Contrast 0x5014 +#define PTP_DPC_Sharpness 0x5015 +#define PTP_DPC_DigitalZoom 0x5016 +#define PTP_DPC_EffectMode 0x5017 +#define PTP_DPC_BurstNumber 0x5018 +#define PTP_DPC_BurstInterval 0x5019 +#define PTP_DPC_TimelapseNumber 0x501A +#define PTP_DPC_TimelapseInterval 0x501B +#define PTP_DPC_FocusMeteringMode 0x501C +#define PTP_DPC_UploadURL 0x501D +#define PTP_DPC_Artist 0x501E +#define PTP_DPC_CopyrightInfo 0x501F + +/* Proprietary vendor extension device property mask */ +#define PTP_DPC_EXTENSION_MASK 0xF000 +#define PTP_DPC_EXTENSION 0xD000 + +/* Device Property Form Flag */ +#define PTP_DPFF_None 0x00 +#define PTP_DPFF_Range 0x01 +#define PTP_DPFF_Enumeration 0x02 + +/* Device Property GetSet type */ +#define PTP_DPGS_Get 0x00 +#define PTP_DPGS_GetSet 0x01 + +#endif //__PTPCONST_H__
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBHostPTP.cpp Fri Aug 23 00:52:52 2013 +0000 @@ -0,0 +1,803 @@ +/* mbed USBHost Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "USBHostPTP.h" + +#if 1 +//USBHOST_PTP + +#include "dbg.h" + +#define DEVICE_TO_HOST 0x80 +#define HOST_TO_DEVICE 0x00 + + +USBHostPTP::USBHostPTP( void ) +{ + host = USBHost::getHostInst(); + initializeClassData(); +} + +void USBHostPTP::initializeClassData() { + deviceConnected = false; + pointerToDevice = NULL; + bulk_in = NULL; + bulk_out = NULL; + int_in=NULL; + deviceFound = false; + deviceConnected = false; + ptp_intf = -1; + numberOfEndpoints = 0; + transactionCnt=0; + commandContainer.type=PTP_USB_CONTAINER_COMMAND; + sessionID=1; + dataLeftToTransfer=0; +} + + +bool USBHostPTP::connected() +{ + return deviceConnected; +} + +bool USBHostPTP::connect() +{ + + if (deviceConnected) { + return true; + } + + for (uint8_t i = 0; i < MAX_DEVICE_CONNECTED; i++) { + if ((pointerToDevice = host->getDevice(i)) != NULL) { + + USB_DBG("Trying to connect PTP device\r\n"); + + if(host->enumerate(pointerToDevice, this)) + break; + + if (deviceFound) { + bulk_in = pointerToDevice->getEndpoint(ptp_intf, BULK_ENDPOINT, IN); + bulk_out = pointerToDevice->getEndpoint(ptp_intf, BULK_ENDPOINT, OUT); + int_in = pointerToDevice->getEndpoint(ptp_intf, INTERRUPT_ENDPOINT, IN); + + if (!bulk_in || !bulk_out || !int_in) + continue; + + USB_INFO("New PTP device: VID:%04x PID:%04x [dev: %p - intf: %d]", pointerToDevice->getVid(), + pointerToDevice->getPid(), + pointerToDevice, ptp_intf); + pointerToDevice->setName("PTP", ptp_intf); + host->registerDriver(pointerToDevice, ptp_intf, this, &USBHostPTP::initializeClassData); + + deviceConnected = true; + return true; + } + } //if() + } //for() + initializeClassData(); + return false; +} + +/*virtual*/ void USBHostPTP::setVidPid(uint16_t vid, uint16_t pid) +{ + // we don't check VID/PID for PTP driver +} + +/*virtual*/ bool USBHostPTP::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed +{ + + if ((ptp_intf == -1) && + (intf_class == USB_PTP_CLASS_CODE) && + (intf_subclass == 0x01) && + (intf_protocol == 0x01)) { + ptp_intf = intf_nb; + return true; + } + return false; +} + +/*virtual*/ bool USBHostPTP::useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir) //Must return true if the endpoint will be used +{ + + if (intf_nb == ptp_intf) { + if (type == INTERRUPT_ENDPOINT) { + numberOfEndpoints++; + } + if (type == BULK_ENDPOINT) { + numberOfEndpoints++; + } + if (numberOfEndpoints == 3) + deviceFound = true; + return true; + } + return false; +} + + + + + + + + +bool USBHostPTP::CancelRequest(unsigned int TransactionID) { + unsigned char buffer[6]; + int res = 0; + + buffer[0] =0x01; //Cancellation Code 0x4001 + buffer[1] =0x40; + buffer[2]= TransactionID & 0xff; + buffer[3]= (TransactionID>>8) & 0xff; + buffer[4]= (TransactionID>>16) & 0xff;; + buffer[5]= (TransactionID>>24) & 0xff;; + + res = host->controlWrite( pointerToDevice, + USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD, + USB_PTP_CLASS_REQUEST_CANCELREQEUST, + 0, 0, buffer, 6); + return res==0?true:false; +} + +bool USBHostPTP::DeviceResetRequest(void) { + + int res = 0; + + res = host->controlWrite( pointerToDevice, + USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD, + USB_PTP_CLASS_REQUEST_DEVICE_RESET, + 0, 0, NULL, 0); + return res==0?true:false; +} + + +bool USBHostPTP::GetDeviceStatus(void) { + unsigned char buffer[6]; + int res = 0; + + //TODO: DetermineBuffer size + + res = host->controlWrite( pointerToDevice, + USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD, + USB_PTP_CLASS_REQUEST_GET_DEVICE_STATUS, + 0, 0, buffer, sizeof(buffer)); + return res==0?true:false; +} + +bool USBHostPTP::GetExtendedEventData(void) { + unsigned char buffer[6]; + int res = 0; + + //TODO: DetermineBuffer size + + res = host->controlWrite( pointerToDevice, + USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD, + USB_PTP_CLASS_REQUEST_GET_EXTENDED_EVENT_DATA, + 0, 0, buffer, sizeof(buffer)); + return res==0?true:false; +} + +bool USBHostPTP::CheckEvent(){ + int res=0; + + memset(&eventContainer, 0, sizeof(PIMAContainer)); + + res = host->interruptRead(pointerToDevice, int_in,(uint8_t *)&eventContainer, sizeof(PIMAContainer)); + + if(res!=USB_TYPE_OK) + return false; + + return true; +} + +int USBHostPTP::checkResult(uint8_t res, USBEndpoint * ep) { + // if ep stalled: send clear feature + if (res == USB_TYPE_STALL_ERROR) { + res = host->controlWrite( pointerToDevice, + USB_RECIPIENT_ENDPOINT | USB_HOST_TO_DEVICE | USB_REQUEST_TYPE_STANDARD, + CLEAR_FEATURE, + 0, ep->getAddress(), NULL, 0); + // set state to IDLE if clear feature successful + if (res == USB_TYPE_OK) { + ep->setState(USB_TYPE_IDLE); + } + } + + if (res != USB_TYPE_OK) + return -1; + + return 0; +} + + +uint16_t USBHostPTP::Transaction(uint16_t operationCode, + OperFlags *operationFlags, + uint32_t *parameters, + void *dataHandlerFunctionCastToVoid){ + + + int transferResult=0; + int i=0; + uint8_t *pointerToUint8tData; + uint32_t bytesReceived=0; + uint32_t bytesRemaining=0; + uint32_t dataToBeHandled=0; + uint32_t responseLength=0; + DataHandler dataHandler1 = (DataHandler) dataHandlerFunctionCastToVoid; + bool firstDataBlockReceived=true; + + if(IsCommandSupported(operationCode)==false) + return PIMAReturnCodeOperationNotSupported; + + commandContainer.len = PIMAContainerHeaderLength + operationFlags->opParams*4; + responseLength = PIMAContainerHeaderLength + operationFlags->rsParams*4; + responseContainer.len = responseLength; + commandContainer.opcode = operationCode; + commandContainer.TransactionID = transactionCnt++; + for (i=0; i<operationFlags->opParams; i++) + commandContainer.param[i]=parameters[i]; + + #ifdef USDBPTPDEBUG + printf("PTPCommandContainer:\r\n"); + DumpBuffer((uint8_t *)&commandContainer,commandContainer.len); + #endif + + transferResult = host->bulkWrite(pointerToDevice, bulk_out,(uint8_t *)&commandContainer, commandContainer.len); + if (checkResult(transferResult, bulk_out)) + return PIMAReturnCodeIncompleteTransfer; + #ifdef USDBPTPDEBUG + printf("Command bulkWrite result: %d\r\n",transferResult); + #endif + if(operationFlags->dataStage==1) { + if(operationFlags->txOperation==0) { + do { + transferResult = host->bulkRead(pointerToDevice, bulk_in, buffer, 1024); + #ifdef USDBPTPDEBUG + printf("Data stage bulkRead result: %d\r\n",transferResult); + #endif + if ( checkResult(transferResult, bulk_in)) + return PIMAReturnCodeIncompleteTransfer; + bytesReceived = bulk_in->getLengthTransferred(); + if(firstDataBlockReceived==true) { + pointerToUint8tData=(uint8_t *)&dataContainer; + for(i=0; i<PIMAContainerHeaderLength; i++){ + pointerToUint8tData[i]=buffer[i]; + } + #ifdef USDBPTPDEBUG + DumpBuffer(pointerToUint8tData,PIMAContainerHeaderLength); + #endif + firstDataBlockReceived = false; + pointerToUint8tData = buffer+PIMAContainerHeaderLength; + bytesRemaining = dataContainer.len - PIMAContainerHeaderLength; + this->totalDataToTransfer = bytesRemaining; + if(dataContainer.type==0x0002) + bytesReceived -= PIMAContainerHeaderLength; + #ifdef USDBPTPDEBUG + DumpBuffer(pointerToUint8tData,bytesReceived); + #endif + } else { + pointerToUint8tData=buffer; + } + + if(bytesReceived<=bytesRemaining) + dataToBeHandled=bytesReceived; + else { + dataToBeHandled=bytesRemaining; + } + + #ifdef USDBPTPDEBUG + printf("Calling Datahandler\r\n"); + printf("DataToBeHandled: %ld\r\n",dataToBeHandled); + #endif + if( dataHandler1!=NULL && dataToBeHandled !=0 ) + (*dataHandler1)(this,pointerToUint8tData,dataToBeHandled); + + #ifdef USDBPTPDEBUG + DumpBuffer(buffer,bytesReceived); + #endif + + //IF the Response got appended to Data block + if(bytesReceived<=bytesRemaining) { + bytesRemaining-=bytesReceived; + } else { + #ifdef USDBPTPDEBUG + printf("Handling Response Packet in data container\r\n"); + #endif + if(bytesReceived-bytesRemaining==responseLength) { + pointerToUint8tData=(uint8_t *)&responseContainer; + for(i=0;i<responseLength;i++){ + pointerToUint8tData[i]=buffer[bytesRemaining+i]; + } + + return responseContainer.opcode; + } else { + + return PIMAReturnCodeIncompleteTransfer; + } + } + this->dataLeftToTransfer = bytesRemaining; + #ifdef USDBPTPDEBUG + printf("Loopcheck: %ld\r\n",bytesRemaining); + #endif + } while( bytesRemaining>0 ); + } else { + printf("DataOut not coded\r\n"); + } + } + transferResult = host->bulkRead(pointerToDevice, bulk_in,(uint8_t *)&responseContainer, sizeof(responseContainer)); + if (checkResult(transferResult, bulk_in)) + return PIMAReturnCodeIncompleteTransfer; + #ifdef USDBPTPDEBUG + printf("Response bulkRead result: %d\r\n",transferResult); + printf("PTPResponseContainer:\r\n"); + DumpBuffer((uint8_t *)&responseContainer,responseContainer.len); + if(responseContainer.opcode==PIMAReturnCodeOK) { + printf("PIMAReturnCodeOK\r\n"); + } else { + printf("Response Length: %x\r\n",responseContainer.len); + printf("Response type: %x\r\n",responseContainer.type); + printf("Response code: %x\r\n",responseContainer.opcode); + printf("Response ID: %d\r\n",responseContainer.TransactionID); + } + #endif + + return responseContainer.opcode; +} + + + + + +uint16_t USBHostPTP::Operation(uint16_t opcode, uint8_t nparams, uint32_t *params){ + OperFlags flags = {0,0,0,0,0,0}; + flags.opParams = nparams; + + return Transaction(opcode,&flags,params); +} + +uint16_t USBHostPTP::OpenSession(void) { + OperFlags flags = {1,0,0,0,0,0}; + + return Transaction(PTP_OC_OpenSession,&flags,&sessionID); +} + +uint16_t USBHostPTP::CloseSession(void) { + OperFlags flags = {1,0,0,0,0,0}; + + return Transaction(PTP_OC_CloseSession,&flags,&sessionID); +} + +uint16_t USBHostPTP::GetDeviceInfo(void) +{ + OperFlags flags = { 0, 0, 0, 1, 1, 0 }; + return Transaction(PTP_OC_GetDeviceInfo, &flags,NULL,(void*)&USBHostPTP::ParseDeviceInfoDataBlock); +} + + +uint16_t USBHostPTP::PowerDown() +{ + OperFlags flags = { 0, 0, 0, 0, 0, 0 }; + return Transaction(PTP_OC_PowerDown, &flags); +} + +uint16_t USBHostPTP::SelfTest(uint16_t type) +{ + OperFlags flags = { 1, 0, 0, 0, 0, 0 }; + uint32_t params[1]; + params[0] = type; + + return Transaction(PTP_OC_SelfTest, &flags, params); +} + +uint16_t USBHostPTP::GetObjectHandles(uint32_t storage_id, uint16_t format, uint16_t assoc, void *parser) +{ + OperFlags flags = { 3, 0, 0, 1, 1, 0 }; + uint32_t params[3]; + + params[0] = storage_id; + params[1] = (uint32_t)format; + params[2] = (uint32_t)assoc; + + return Transaction(PTP_OC_GetObjectHandles, &flags, params, parser); +} + +uint16_t USBHostPTP::GetNumObjects(uint32_t *retval, uint32_t storage_id, uint16_t format, uint32_t assoc) +{ + uint16_t ptp_error = PIMAReturnCodeGeneralError; + OperFlags flags = { 3, 1, 0, 0, 0, 0 }; + uint32_t params[3]; + + params[0] = storage_id; + params[1] = (uint32_t)format; + params[2] = (uint32_t)assoc; + + if ( (ptp_error = Transaction(PTP_OC_GetNumObjects, &flags, params)) == PIMAReturnCodeOK) + *retval = responseContainer.param[0]; + + return ptp_error; +} + +uint16_t USBHostPTP::GetObjectInfo(uint32_t handle) +{ + OperFlags flags = { 1, 0, 0, 1, 1, 0 }; + uint32_t params[1]; + params[0] = handle; + + //Clear any previous data, incase a Reponse packet is returned instead of a data packet + memset((uint8_t *)&objectInfo,0,0x34); + + return Transaction(PTP_OC_GetObjectInfo, &flags, params, (void*)&USBHostPTP::ParseObjectInfoDataBlock); +} + +uint16_t USBHostPTP::GetThumb(uint32_t handle, void *parser) +{ + OperFlags flags = { 1, 0, 0, 1, 1, 0 }; + uint32_t params[1]; + + params[0] = handle; + + return Transaction(PTP_OC_GetThumb, &flags, params, parser); +} + + +uint16_t USBHostPTP::GetObject(uint32_t handle, void *parser) +{ + OperFlags flags = { 1, 0, 0, 1, 1, 0 }; + uint32_t params[1]; + + params[0] = handle; + + return Transaction(PTP_OC_GetObject, &flags, params, parser); +} + +uint16_t USBHostPTP::GetStorageIDs(void *parser) +{ + OperFlags flags = { 0, 0, 0, 1, 1, 0 }; + return Transaction(PTP_OC_GetStorageIDs, &flags, NULL, parser); +} + +uint16_t USBHostPTP::GetStorageInfo(uint32_t storage_id, void *parser) +{ + OperFlags flags = { 1, 0, 0, 1, 1, 0 }; + + uint32_t params[1]; + params[0] = storage_id; + + return Transaction(PTP_OC_GetStorageInfo, &flags, params, parser); +} + +uint16_t USBHostPTP::CopyObject(uint32_t handle, uint32_t storage_id, uint32_t parent, uint32_t *new_handle) +{ + uint16_t ptp_error = PIMAReturnCodeGeneralError; + OperFlags flags = { 3, 1, 0, 0, 0, 0 }; + uint32_t params[3]; + + params[0] = handle; + params[1] = storage_id; + params[2] = parent; + + if ( (ptp_error = Transaction(PTP_OC_CopyObject, &flags, params)) == PIMAReturnCodeOK) + *new_handle = responseContainer.param[0]; + + return ptp_error; +} + + +uint16_t USBHostPTP::DeleteObject(uint32_t handle, uint16_t format) +{ + OperFlags flags = { 2, 0, 0, 0, 0, 0 }; + uint32_t params[2]; + + params[0] = handle; + params[1] = (uint32_t)format; + + return Transaction(PTP_OC_DeleteObject, &flags, params); +} + + +uint16_t USBHostPTP::SetObjectProtection(uint32_t handle, uint16_t attrib) +{ + OperFlags flags = { 2, 0, 0, 0, 0, 0 }; + uint32_t params[2]; + + params[0] = handle; + params[1] = (uint32_t)attrib; + + return Transaction(PTP_OC_SetObjectProtection, &flags, params); +} + + +uint16_t USBHostPTP::MoveObject(uint32_t handle, uint32_t storage_id, uint32_t parent) +{ + OperFlags flags = { 3, 0, 0, 0, 0, 0 }; + uint32_t params[3]; + + params[0] = handle; + params[1] = storage_id; + params[2] = parent; + + return Transaction(PTP_OC_MoveObject, &flags, params); +} + + +uint16_t USBHostPTP::GetDevicePropDesc(const uint16_t pcode, void *parser) +{ + OperFlags flags = { 1, 0, 0, 1, 1, 0 }; + uint32_t params[1]; + + params[0] = (uint32_t)pcode; + + if(IsPropertySupported(pcode)==false) + return PIMAReturnCodeDevicePropertyNotSupported; + + return Transaction(PTP_OC_GetDevicePropDesc, &flags, params, parser); +} + + +uint16_t USBHostPTP::GetDevicePropValue(const uint16_t pcode, void *parser) +{ + OperFlags flags = { 1, 0, 0, 1, 1, 0 }; + uint32_t params[1]; + + params[0] = (uint32_t)pcode; + if(IsPropertySupported(pcode)==false) + return PIMAReturnCodeDevicePropertyNotSupported; + + return Transaction(PTP_OC_GetDevicePropValue, &flags, params, parser); +} + + +uint16_t USBHostPTP::SetDevicePropValue(uint16_t pcode, uint32_t val) +{ + OperFlags flags = { 1, 0, 1, 1, 3, 4 }; + uint32_t params[1]; + uint32_t value; + + params[0] = (uint32_t)pcode; + value = val; + + if(IsPropertySupported(pcode)==false) + return PIMAReturnCodeDevicePropertyNotSupported; + + return Transaction(PTP_OC_SetDevicePropValue, &flags, params, (void*)&value); +} + + +uint16_t USBHostPTP::ResetDevicePropValue(const uint16_t pcode) +{ + OperFlags flags = { 1, 0, 0, 0 }; + uint32_t params[1]; + + params[0] = (uint32_t)pcode; + + if(IsPropertySupported(pcode)==false) + return PIMAReturnCodeDevicePropertyNotSupported; + + return Transaction(PTP_OC_ResetDevicePropValue, &flags, params); +} + + +uint16_t USBHostPTP::FormatStore(uint32_t storage_id, uint32_t fsformat) +{ + OperFlags flags = { 2, 0, 0, 0, 0, 0 }; + + uint32_t params[2]; + params[0] = storage_id; + params[1] = fsformat; + + return Transaction(PTP_OC_FormatStore, &flags, params); +} + +uint16_t USBHostPTP::InitiateCapture(uint32_t storage_id, uint16_t format) +{ + uint16_t ptp_error = PIMAReturnCodeGeneralError; + OperFlags flags = { 2, 0, 0, 0, 0, 0 }; + uint32_t params[2]; + + params[0] = storage_id; + params[1] = (uint32_t)format; + + if ( (ptp_error = Transaction(PTP_OC_InitiateCapture, &flags, params)) == PIMAReturnCodeOK){ + } + + return ptp_error; +} + +uint16_t USBHostPTP::InitiateOpenCapture(uint32_t storage_id, uint16_t format) +{ + uint16_t ptp_error = PIMAReturnCodeGeneralError; + OperFlags flags = { 2, 0, 0, 0, 0, 0 }; + uint32_t params[2]; + + params[0] = storage_id; + params[1] = (uint32_t)format; + + if ( (ptp_error = Transaction(PTP_OC_InitiateOpenCapture, &flags, params)) == PIMAReturnCodeOK){ + } + + return ptp_error; +} + +uint16_t USBHostPTP::TerminateOpenCapture(uint32_t trans_id) +{ + OperFlags flags = { 1, 0, 0, 0, 0, 0 }; + uint32_t params[1]; + + params[0] = trans_id; + + return Transaction(PTP_OC_TerminateOpenCapture, &flags, params); +} + + + +void USBHostPTP::ParseDeviceInfoDataBlock(void *ptp,uint8_t *buffer,uint16_t length){ + uint8_t *currentPtr; + USBHostPTP *dev=(USBHostPTP *)ptp; + + currentPtr=buffer; + dev->deviceInfo.standardVersion=*((uint16_t *)currentPtr); + currentPtr+=2; + dev->deviceInfo.vendorExtensionID=*((uint32_t *)currentPtr); + currentPtr+=4; + dev->deviceInfo.vendorExtensionVersion=*((uint16_t *)currentPtr); + currentPtr+=2; + + currentPtr+=dev->deviceInfo.vendorExtensionDesc.FillString(currentPtr); + + dev->deviceInfo.functionMode=*((uint16_t *)currentPtr); + currentPtr+=2; + + currentPtr+=dev->deviceInfo.operationsSupported.FillArray(currentPtr); + currentPtr+=dev->deviceInfo.eventsSupported.FillArray(currentPtr); + currentPtr+=dev->deviceInfo.devicePropertiesSupported.FillArray(currentPtr); + currentPtr+=dev->deviceInfo.captureFormats.FillArray(currentPtr); + currentPtr+=dev->deviceInfo.imageFormats.FillArray(currentPtr); + + currentPtr+=dev->deviceInfo.manufacturer.FillString(currentPtr); + currentPtr+=dev->deviceInfo.model.FillString(currentPtr); + currentPtr+=dev->deviceInfo.deviceVersion.FillString(currentPtr); + currentPtr+=dev->deviceInfo.serialNumber.FillString(currentPtr); + +} + +void USBHostPTP::ParseObjectInfoDataBlock(void *ptp,uint8_t *buffer,uint16_t length){ + uint8_t *ptr,*structptr; + USBHostPTP *obj=(USBHostPTP *)ptp; + + structptr=(uint8_t *) &(obj->objectInfo); + ptr=buffer; + for(int i=0;i<0x34;i++) + structptr[i]=ptr[i]; + ptr+=0x34; + ptr+=obj->objectInfo.filename.FillString(ptr); + ptr+=obj->objectInfo.captureDate.FillString(ptr); + ptr+=obj->objectInfo.modificationDate.FillString(ptr); + ptr+=obj->objectInfo.keywords.FillString(ptr); + #ifdef USDBPTPDEBUG + obj->DumpObjectInfo(); + #endif +} + + +bool USBHostPTP::IsCommandSupported(uint16_t opcode){ + bool res=false; + + if(opcode==PTP_OC_OpenSession || opcode==PTP_OC_GetDeviceInfo) + res=true; + else + res = CheckValueInArray(&deviceInfo.operationsSupported,opcode); + return res; +} + +bool USBHostPTP::IsPropertySupported(uint16_t code){ + + return CheckValueInArray(&deviceInfo.devicePropertiesSupported, code); + +} + +bool USBHostPTP::CheckValueInArray(PIMAArray *array, uint16_t code) { + bool res=false; + for(int i=0; i<array->numberOfElements;i++) + if(code == array->codes[i]) + res=true; + return res; +} + + +void USBHostPTP::DumpBuffer(uint8_t *buffer,uint32_t length){ + for(int i=0;i<length;i++) { + printf("%02x ",buffer[i]); + if(i % 16 == 15 ) + printf("\r\n"); + } + printf("\r\n"); +} + + +void USBHostPTP::DumpDeviceInfo(){ + int i; + + printf("PIMA standard version: %x\r\n",deviceInfo.standardVersion); + printf("Vendor Extension ID: %x\r\n",deviceInfo.vendorExtensionID); + printf("Vendor Extension Version: %x\r\n",deviceInfo.vendorExtensionVersion); + printf("Vendor Extension Description: \r\n"); + printf("%s\r\n",(deviceInfo.vendorExtensionDesc.getString())); + printf("Functional Mode: %x\r\n",deviceInfo.functionMode); + printf("Supported Operations: \r\n"); + for(i=0;i<deviceInfo.operationsSupported.numberOfElements;i++) { + printf("0x%04x\r\n",deviceInfo.operationsSupported.codes[i]); + } + printf("Supported Events: \r\n"); + for(i=0;i<deviceInfo.eventsSupported.numberOfElements;i++) { + printf("0x%04x\r\n",deviceInfo.eventsSupported.codes[i]); + } + printf("Supported Device Properties: \r\n"); + for(i=0;i<deviceInfo.devicePropertiesSupported.numberOfElements;i++) { + printf("0x%04x\r\n",deviceInfo.devicePropertiesSupported.codes[i]); + } + printf("Supported Capture Formats: \r\n"); + for(i=0;i<deviceInfo.captureFormats.numberOfElements;i++) { + printf("0x%04x\r\n",deviceInfo.captureFormats.codes[i]); + } + printf("Supported Image Formats: \r\n"); + for(i=0;i<deviceInfo.imageFormats.numberOfElements;i++) { + printf("0x%04x\r\n",deviceInfo.imageFormats.codes[i]); + } + + printf("Manufacturer: \r\n"); + printf("%s\r\n",deviceInfo.manufacturer.getString()); + printf("Model: \r\n"); + printf("%s\r\n",deviceInfo.model.getString()); + printf("Device Version: \r\n"); + printf("%s\r\n",deviceInfo.deviceVersion.getString()); + printf("Serial Number: \r\n"); + printf("%s\r\n",deviceInfo.serialNumber.getString()); + +} + +void USBHostPTP::DumpObjectInfo(){ + + + printf("-----------------------ObjectInfo--------------\r\n"); + printf("Storage ID: %08x\r\n",objectInfo.storageID); + printf("Object Format: %04x\r\n",objectInfo.objectFormat); + printf("Protection Status: %04x\r\n",objectInfo.protectionStatus); + printf("Compressed Size: %ld\r\n",objectInfo.objectCompressSize); + printf("Thumbnail format: %04x\r\n",objectInfo.thumbFormat); + printf("Thumbnail Compressed size: %04x\r\n",objectInfo.thumbCompressedSize); + printf("Thumbnail Width %ld\r\n",objectInfo.thumbPixWidth); + printf("Thumbnail Height: %ld\r\n",objectInfo.thumbPixHeight); + printf("Image Width: %ld\r\n",objectInfo.imagePixWidth); + printf("Image Height: %ld\r\n",objectInfo.imagePixHeight); + printf("Image BitDepth: %ld\r\n",objectInfo.imageBitDepth); + printf("Parent Object: %04x\r\n",objectInfo.parentObject); + printf("Assosiaction Type: %02x\r\n",objectInfo.associationType); + printf("Assosiaction Description: %04x\r\n",objectInfo.associationDesc); + printf("Sequence Number: %ld\r\n",objectInfo.sequenceNumber); + + printf("Filename: \r\n"); + printf("%s\r\n",objectInfo.filename.getString()); + printf("Capture Date: \r\n"); + printf("%s\r\n",objectInfo.captureDate.getString()); + printf("Modification Date: \r\n"); + printf("%s\r\n",objectInfo.modificationDate.getString()); + printf("Keywords: \r\n"); + printf("%s\r\n",objectInfo.keywords.getString()); +} + + + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBHostPTP.h Fri Aug 23 00:52:52 2013 +0000 @@ -0,0 +1,169 @@ +/* mbed USBHost Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef USBHOSTPTP_H +#define USBHOSTPTP_H + +#include "USBHostConf.h" +#include "USBHost.h" +#include "PIMA15740_types.h" + +//#define USDBPTPDEBUG 1 + + #ifdef USDBPTPDEBUG + #define PTPTRACE(s) (Notify((s)) + #define PTPTRACE2(s,r) (Message((s),(r)) + #else + #define PTPTRACE(s) ((void)0) + #define PTPTRACE2(s,r) (wait_us(1)) + #endif + +/** + * USB PTP definitions + * + */ +#define USB_PTP_CLASS_CODE 0x06 +#define USB_PTP_CLASS_REQUEST_CANCELREQEUST 0x64 +#define USB_PTP_CLASS_REQUEST_GET_EXTENDED_EVENT_DATA 0x65 +#define USB_PTP_CLASS_REQUEST_DEVICE_RESET 0x66 +#define USB_PTP_CLASS_REQUEST_GET_DEVICE_STATUS 0x67 + + +typedef void (*DataHandler)(void *object, uint8_t *bufffer, uint16_t length); + +/** + * USBHostPTP class + * + */ +class USBHostPTP : public IUSBEnumerator { +public: + struct OperFlags + { + uint16_t opParams : 3; // 7 - maximum number of operation parameters + uint16_t rsParams : 3; // 7 - maximum number of response parameters + uint16_t txOperation : 1; // I->R operation if the flag is set + uint16_t dataStage : 1; // operation has data stage if the flag is set + uint16_t typeOfVoid : 2; // 0 - NULL, 1 - PTPReadParser/PTPDataSupplyer, 2 - WRITEPARSER, 3 - buffer pointer + uint16_t dataSize : 6; // size of data buffer (64 bytes maximum) + }; + + /** + * Constructor + * + * @param None + */ + USBHostPTP(void); + + /** + * Check if a PTP device is connected + * + * @return true if a PTP device is connected + */ + bool connected(); + + /** + * Try to connect to a PTP device + * + * @return true if connection was successful + */ + bool connect(); + + bool CancelRequest(unsigned int TransactionID); + bool DeviceResetRequest(void); + bool GetDeviceStatus(void); + bool GetExtendedEventData(void); + + uint16_t Transaction(uint16_t operationCode, OperFlags *flags, uint32_t *params = NULL, void *pVoid = NULL); + uint32_t transactionCnt; + uint32_t sessionID; + + DeviceInfoStruct deviceInfo; + ObjectInfoStruct objectInfo; + + uint32_t dataLeftToTransfer; + uint32_t totalDataToTransfer; + + // Simple PTP operation which has no data stage. Any number of uint32_t params can be supplied. + uint16_t Operation(uint16_t opcode, uint8_t nparams = 0, uint32_t *params = NULL); + uint16_t OpenSession(); + uint16_t CloseSession(); + uint16_t GetDeviceInfo(); + + uint16_t PowerDown(); + uint16_t SelfTest(uint16_t type = 0); + uint16_t GetNumObjects(uint32_t *retval, uint32_t storage_id=0xffffffff, uint16_t format=0x0000, uint32_t assoc=0x0000); + uint16_t GetObjectHandles(uint32_t storage_id=0xffffffff, uint16_t format=0x0000, uint16_t assoc=0x0000, void *parser=NULL); + uint16_t GetObjectInfo(uint32_t handle); + uint16_t GetThumb(uint32_t handle, void *parser=NULL); + uint16_t GetObject(uint32_t handle, void *parser=NULL); + uint16_t GetStorageIDs(void *parser=NULL); + uint16_t GetStorageInfo(uint32_t storage_id, void *parser=NULL); + uint16_t CopyObject(uint32_t handle, uint32_t storage_id, uint32_t parent, uint32_t *new_handle); + uint16_t DeleteObject(uint32_t handle, uint16_t format); + uint16_t SetObjectProtection(uint32_t handle, uint16_t attrib); + uint16_t MoveObject(uint32_t handle, uint32_t storage_id, uint32_t parent); + uint16_t GetDevicePropDesc(const uint16_t pcode, void *parser=NULL); + uint16_t GetDevicePropValue(const uint16_t pcode, void *parser=NULL); + uint16_t SetDevicePropValue(uint16_t pcode, uint32_t val); + uint16_t ResetDevicePropValue(const uint16_t pcode); + uint16_t FormatStore(uint32_t storage_id, uint32_t fsformat); + uint16_t InitiateCapture(uint32_t storage_id, uint16_t format); + uint16_t InitiateOpenCapture(uint32_t storage_id, uint16_t format); + uint16_t TerminateOpenCapture(uint32_t trans_id); + void DumpDeviceInfo(void); + void DumpObjectInfo(void); + +protected: + //From IUSBEnumerator + virtual void setVidPid(uint16_t vid, uint16_t pid); + virtual bool parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol); //Must return true if the interface should be parsed + virtual bool useEndpoint(uint8_t intf_nb, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir); //Must return true if the endpoint will be used + + //This is a generic function should belong to some other class or namespance. + void DumpBuffer(uint8_t *buffer,uint32_t length); + +private: + USBHost * host; + USBDeviceConnected * pointerToDevice; + bool deviceFound; + bool deviceConnected; + USBEndpoint * bulk_in; + USBEndpoint * bulk_out; + USBEndpoint * int_in; + uint8_t numberOfEndpoints; + + PIMAContainer commandContainer; + PIMAContainer responseContainer; + PIMAContainer dataContainer; + PIMAContainer eventContainer; + uint8_t buffer[1024]; + int ptp_intf; + + void initializeClassData(); + int checkResult(uint8_t res, USBEndpoint * ep); + bool IsCommandSupported(uint16_t opcode); + bool IsPropertySupported(uint16_t code); + bool CheckValueInArray(PIMAArray *array, uint16_t code); + bool CheckEvent(void); + static void ParseDeviceInfoDataBlock(void *ptp, uint8_t *buffer,uint16_t length); + static void ParseObjectInfoDataBlock(void *ptp, uint8_t *buffer,uint16_t length); +}; + +#endif + + + +