diff options
| author | Dave Hylands | 2014-03-11 23:55:41 -0700 |
|---|---|---|
| committer | Dave Hylands | 2014-03-11 23:55:41 -0700 |
| commit | dd38d907244bc0e483c3d760f2ba464a394ec229 (patch) | |
| tree | 05869a4757c5a1b11b8baf206595551c7650f6e7 /stmhal/usbhost/Class/MTP | |
| parent | 8bfec2b53822e2b62c4577b32e0beae398a16297 (diff) | |
Initial checkin with STM HAL
This compiles and links, but hasn't been tested on a board
yet and even if it was run, it doesn't currently do anything.
Diffstat (limited to 'stmhal/usbhost/Class/MTP')
| -rw-r--r-- | stmhal/usbhost/Class/MTP/Inc/usbh_mtp.h | 263 | ||||
| -rw-r--r-- | stmhal/usbhost/Class/MTP/Inc/usbh_mtp_ptp.h | 1038 | ||||
| -rw-r--r-- | stmhal/usbhost/Class/MTP/Src/usbh_mtp.c | 1065 | ||||
| -rw-r--r-- | stmhal/usbhost/Class/MTP/Src/usbh_mtp_ptp.c | 1769 |
4 files changed, 4135 insertions, 0 deletions
diff --git a/stmhal/usbhost/Class/MTP/Inc/usbh_mtp.h b/stmhal/usbhost/Class/MTP/Inc/usbh_mtp.h new file mode 100644 index 000000000..704a410fd --- /dev/null +++ b/stmhal/usbhost/Class/MTP/Inc/usbh_mtp.h @@ -0,0 +1,263 @@ +/**
+ ******************************************************************************
+ * @file usbh_mtp.h
+ * @author MCD Application Team
+ * @version V3.0.0
+ * @date 18-February-2014
+ * @brief This file contains all the prototypes for the usbh_mtp.c
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive ----------------------------------------------*/
+#ifndef __USBH_MTP_CORE_H
+#define __USBH_MTP_CORE_H
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_mtp_ptp.h"
+#include "usbh_core.h"
+
+
+/** @addtogroup USBH_LIB
+* @{
+*/
+
+/** @addtogroup USBH_CLASS
+* @{
+*/
+
+/** @addtogroup USBH_MTP_CLASS
+* @{
+*/
+
+/** @defgroup USBH_MTP_CORE
+* @brief This file is the Header file for USBH_MTP_CORE.c
+* @{
+*/
+
+
+
+
+/*Communication Class codes*/
+#define USB_MTP_CLASS 0x06 /* Still Image Class)*/
+#define MTP_MAX_STORAGE_UNITS_NBR PTP_MAX_STORAGE_UNITS_NBR
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MTP_CORE_Exported_Types
+* @{
+*/
+typedef enum
+{
+ MTP_IDLE = 0,
+ MTP_GETDEVICEINFO ,
+ MTP_OPENSESSION ,
+ MTP_CLOSESESSION ,
+ MTP_GETSTORAGEIDS ,
+ MTP_GETSTORAGEINFO ,
+}
+MTP_StateTypeDef;
+
+
+typedef enum
+{
+ MTP_EVENTS_INIT = 0,
+ MTP_EVENTS_GETDATA ,
+}
+MTP_EventsStateTypeDef;
+
+
+typedef struct
+{
+ MTP_EventsStateTypeDef state;
+ uint32_t timer;
+ uint16_t poll;
+ PTP_EventContainerTypedef container;
+}
+MTP_EventHandleTypedef;
+
+typedef struct
+{
+
+ uint32_t CurrentStorageId;
+ uint32_t ObjectFormatCode;
+ uint32_t CurrentObjectHandler;
+ uint8_t ObjectHandlerNbr;
+ uint32_t Objdepth;
+}
+MTP_ParamsTypedef;
+
+
+typedef struct
+{
+ PTP_DeviceInfoTypedef devinfo;
+ PTP_StorageIDsTypedef storids;
+ PTP_StorageInfoTypedef storinfo[MTP_MAX_STORAGE_UNITS_NBR];
+ PTP_ObjectHandlesTypedef Handles;
+}
+MTP_InfoTypedef;
+
+/* Structure for MTP process */
+typedef struct _MTP_Process
+{
+ MTP_InfoTypedef info;
+ MTP_ParamsTypedef params;
+
+ uint8_t DataInPipe;
+ uint8_t DataOutPipe;
+ uint8_t NotificationPipe;
+
+ uint8_t DataOutEp;
+ uint8_t DataInEp;
+ uint8_t NotificationEp;
+
+ uint16_t DataOutEpSize;
+ uint16_t DataInEpSize;
+ uint16_t NotificationEpSize;
+ MTP_StateTypeDef state;
+ MTP_EventHandleTypedef events;
+ PTP_HandleTypeDef ptp;
+ uint32_t current_storage_unit;
+ uint32_t is_ready;
+}
+MTP_HandleTypeDef;
+
+#define MTP_StorageInfoTypedef PTP_StorageInfoTypedef
+#define MTP_ObjectHandlesTypedef PTP_ObjectHandlesTypedef
+#define MTP_ObjectInfoTypedef PTP_ObjectInfoTypedef
+/**
+* @}
+*/
+
+/** @defgroup USBH_MTP_CORE_Exported_Defines
+* @{
+*/
+
+/**
+* @}
+*/
+
+/** @defgroup USBH_MTP_CORE_Exported_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+/** @defgroup USBH_MTP_CORE_Exported_Variables
+* @{
+*/
+extern USBH_ClassTypeDef MTP_Class;
+#define USBH_MTP_CLASS &MTP_Class
+
+/**
+* @}
+*/
+
+/** @defgroup USBH_MTP_CORE_Exported_FunctionsPrototype
+* @{
+*/
+uint8_t USBH_MTP_IsReady (USBH_HandleTypeDef *phost);
+USBH_StatusTypeDef USBH_MTP_SelectStorage (USBH_HandleTypeDef *phost, uint8_t storage_idx);
+USBH_StatusTypeDef USBH_MTP_GetNumStorage (USBH_HandleTypeDef *phost, uint8_t *storage_num);
+USBH_StatusTypeDef USBH_MTP_GetNumObjects (USBH_HandleTypeDef *phost,
+ uint32_t storage_id,
+ uint32_t objectformatcode,
+ uint32_t associationOH,
+ uint32_t* numobs);
+USBH_StatusTypeDef USBH_MTP_GetStorageInfo (USBH_HandleTypeDef *phost,
+ uint8_t storage_idx,
+ MTP_StorageInfoTypedef *info);
+
+USBH_StatusTypeDef USBH_MTP_GetObjectHandles (USBH_HandleTypeDef *phost,
+ uint32_t storage_id,
+ uint32_t objectformatcode,
+ uint32_t associationOH,
+ PTP_ObjectHandlesTypedef* objecthandles);
+
+USBH_StatusTypeDef USBH_MTP_GetObjectInfo (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ PTP_ObjectInfoTypedef* objectinfo);
+
+USBH_StatusTypeDef USBH_MTP_DeleteObject (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ uint32_t objectformatcode);
+
+USBH_StatusTypeDef USBH_MTP_GetObject (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ uint8_t *object);
+
+USBH_StatusTypeDef USBH_MTP_GetPartialObject(USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ uint32_t offset,
+ uint32_t maxbytes,
+ uint8_t *object,
+ uint32_t *len);
+
+USBH_StatusTypeDef USBH_MTP_GetObjectPropsSupported (USBH_HandleTypeDef *phost,
+ uint16_t ofc,
+ uint32_t *propnum,
+ uint16_t *props);
+
+USBH_StatusTypeDef USBH_MTP_GetObjectPropDesc (USBH_HandleTypeDef *phost,
+ uint16_t opc,
+ uint16_t ofc,
+ PTP_ObjectPropDescTypeDef *opd);
+
+USBH_StatusTypeDef USBH_MTP_GetObjectPropList (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ MTP_PropertiesTypedef *pprops,
+ uint32_t *nrofprops);
+
+USBH_StatusTypeDef USBH_MTP_SendObject (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ uint8_t *object,
+ uint32_t size);
+
+USBH_StatusTypeDef USBH_MTP_GetDevicePropDesc (USBH_HandleTypeDef *phost,
+ uint16_t propcode,
+ PTP_DevicePropDescTypdef* devicepropertydesc);
+
+void USBH_MTP_EventsCallback(USBH_HandleTypeDef *phost, uint32_t event, uint32_t param);
+/**
+* @}
+*/
+
+
+#endif /* __USBH_MTP_CORE_H */
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/stmhal/usbhost/Class/MTP/Inc/usbh_mtp_ptp.h b/stmhal/usbhost/Class/MTP/Inc/usbh_mtp_ptp.h new file mode 100644 index 000000000..3fbddd87b --- /dev/null +++ b/stmhal/usbhost/Class/MTP/Inc/usbh_mtp_ptp.h @@ -0,0 +1,1038 @@ +/**
+ ******************************************************************************
+ * @file usbh_mtp_ptp.h
+ * @author MCD Application Team
+ * @version V3.0.0
+ * @date 18-February-2014
+ * @brief Header file for usbh_mtp_ptp.c
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive ----------------------------------------------*/
+#ifndef __USBH_MTP_PTP_H__
+#define __USBH_MTP_PTP_H__
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_core.h"
+
+/** @addtogroup USBH_LIB
+ * @{
+ */
+
+/** @addtogroup USBH_CLASS
+ * @{
+ */
+
+/** @addtogroup USBH_MTP_PTP_CLASS
+ * @{
+ */
+
+/** @defgroup USBH_MTP_PTP
+ * @brief This file is the Header file for usbh_mtp_ptp.c
+ * @{
+ */
+
+
+/* Operation Codes */
+
+/* PTP v1.0 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
+
+/* PTP v1.1 operation codes */
+#define PTP_OC_StartEnumHandles 0x101D
+#define PTP_OC_EnumHandles 0x101E
+#define PTP_OC_StopEnumHandles 0x101F
+#define PTP_OC_GetVendorExtensionMaps 0x1020
+#define PTP_OC_GetVendorDeviceInfo 0x1021
+#define PTP_OC_GetResizedImageObject 0x1022
+#define PTP_OC_GetFilesystemManifest 0x1023
+#define PTP_OC_GetStreamInfo 0x1024
+#define PTP_OC_GetStream 0x1025
+
+ /* Microsoft / MTP extension codes */
+#define PTP_OC_GetObjectPropsSupported 0x9801
+#define PTP_OC_GetObjectPropDesc 0x9802
+#define PTP_OC_GetObjectPropValue 0x9803
+#define PTP_OC_SetObjectPropValue 0x9804
+#define PTP_OC_GetObjPropList 0x9805
+#define PTP_OC_SetObjPropList 0x9806
+#define PTP_OC_GetInterdependendPropdesc 0x9807
+#define PTP_OC_SendObjectPropList 0x9808
+#define PTP_OC_GetObjectReferences 0x9810
+#define PTP_OC_SetObjectReferences 0x9811
+#define PTP_OC_UpdateDeviceFirmware 0x9812
+#define PTP_OC_Skip 0x9820
+
+
+/* Response Codes */
+
+/* PTP v1.0 response codes */
+#define PTP_RC_Undefined 0x2000
+#define PTP_RC_OK 0x2001
+#define PTP_RC_GeneralError 0x2002
+#define PTP_RC_SessionNotOpen 0x2003
+#define PTP_RC_InvalidTransactionID 0x2004
+#define PTP_RC_OperationNotSupported 0x2005
+#define PTP_RC_ParameterNotSupported 0x2006
+#define PTP_RC_IncompleteTransfer 0x2007
+#define PTP_RC_InvalidStorageId 0x2008
+#define PTP_RC_InvalidObjectHandle 0x2009
+#define PTP_RC_DevicePropNotSupported 0x200A
+#define PTP_RC_InvalidObjectFormatCode 0x200B
+#define PTP_RC_StoreFull 0x200C
+#define PTP_RC_ObjectWriteProtected 0x200D
+#define PTP_RC_StoreReadOnly 0x200E
+#define PTP_RC_AccessDenied 0x200F
+#define PTP_RC_NoThumbnailPresent 0x2010
+#define PTP_RC_SelfTestFailed 0x2011
+#define PTP_RC_PartialDeletion 0x2012
+#define PTP_RC_StoreNotAvailable 0x2013
+#define PTP_RC_SpecificationByFormatUnsupported 0x2014
+#define PTP_RC_NoValidObjectInfo 0x2015
+#define PTP_RC_InvalidCodeFormat 0x2016
+#define PTP_RC_UnknownVendorCode 0x2017
+#define PTP_RC_CaptureAlreadyTerminated 0x2018
+#define PTP_RC_DeviceBusy 0x2019
+#define PTP_RC_InvalidParentObject 0x201A
+#define PTP_RC_InvalidDevicePropFormat 0x201B
+#define PTP_RC_InvalidDevicePropValue 0x201C
+#define PTP_RC_InvalidParameter 0x201D
+#define PTP_RC_SessionAlreadyOpened 0x201E
+#define PTP_RC_TransactionCanceled 0x201F
+#define PTP_RC_SpecificationOfDestinationUnsupported 0x2020
+/* PTP v1.1 response codes */
+#define PTP_RC_InvalidEnumHandle 0x2021
+#define PTP_RC_NoStreamEnabled 0x2022
+#define PTP_RC_InvalidDataSet 0x2023
+
+/* 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
+
+/* PTP/IP definitions */
+#define PTPIP_INIT_COMMAND_REQUEST 1
+#define PTPIP_INIT_COMMAND_ACK 2
+#define PTPIP_INIT_EVENT_REQUEST 3
+#define PTPIP_INIT_EVENT_ACK 4
+#define PTPIP_INIT_FAIL 5
+#define PTPIP_CMD_REQUEST 6
+#define PTPIP_CMD_RESPONSE 7
+#define PTPIP_EVENT 8
+#define PTPIP_START_DATA_PACKET 9
+#define PTPIP_DATA_PACKET 10
+#define PTPIP_CANCEL_TRANSACTION 11
+#define PTPIP_END_DATA_PACKET 12
+#define PTPIP_PING 13
+#define PTPIP_PONG 14
+
+/* 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 */
+
+/** @defgroup USBH_MTP_PTP_Exported_Types
+ * @{
+ */
+
+typedef enum
+{
+ PTP_REQ_IDLE = 0,
+ PTP_REQ_SEND = 1,
+ PTP_REQ_WAIT,
+ PTP_REQ_ERROR,
+}
+PTP_RequestStateTypeDef;
+
+typedef enum
+{
+ PTP_IDLE = 0,
+ PTP_OP_REQUEST_STATE,
+ PTP_OP_REQUEST_WAIT_STATE,
+ PTP_DATA_OUT_PHASE_STATE,
+ PTP_DATA_OUT_PHASE_WAIT_STATE,
+ PTP_DATA_IN_PHASE_STATE,
+ PTP_DATA_IN_PHASE_WAIT_STATE,
+ PTP_RESPONSE_STATE,
+ PTP_RESPONSE_WAIT_STATE,
+ PTP_ERROR,
+}
+PTP_ProcessStateTypeDef;
+
+/* PTP request/response/event general PTP container (transport independent) */
+typedef struct
+{
+ uint16_t Code;
+ uint32_t SessionID;
+ uint32_t Transaction_ID;
+ /* params may be of any type of size less or equal to uint32_t */
+ uint32_t Param1;
+ uint32_t Param2;
+ uint32_t Param3;
+ /* events can only have three parameters */
+ uint32_t Param4;
+ uint32_t Param5;
+ /* the number of meaningfull parameters */
+ uint8_t Nparam;
+}
+PTP_ContainerTypedef;
+
+#define PTP_USB_BULK_HS_MAX_PACKET_LEN_WRITE 1024
+#define PTP_USB_BULK_HS_MAX_PACKET_LEN_READ 1024
+#define PTP_USB_BULK_HDR_LEN (2*sizeof(uint32_t)+2*sizeof(uint16_t))
+#define PTP_USB_BULK_PAYLOAD_LEN_WRITE (PTP_USB_BULK_HS_MAX_PACKET_LEN_WRITE-PTP_USB_BULK_HDR_LEN)
+#define PTP_USB_BULK_PAYLOAD_LEN_READ (PTP_USB_BULK_HS_MAX_PACKET_LEN_READ-PTP_USB_BULK_HDR_LEN)
+#define PTP_USB_BULK_REQ_LEN (PTP_USB_BULK_HDR_LEN+5*sizeof(uint32_t))
+#define PTP_USB_BULK_REQ_RESP_MAX_LEN 63
+
+typedef struct
+{
+ uint32_t length;
+ uint16_t type;
+ uint16_t code;
+ uint32_t trans_id;
+ uint32_t param1;
+ uint32_t param2;
+ uint32_t param3;
+ uint32_t param4;
+ uint32_t param5;
+}
+PTP_RespContainerTypedef;
+
+
+typedef struct
+{
+ uint32_t length;
+ uint16_t type;
+ uint16_t code;
+ uint32_t trans_id;
+ uint32_t param1;
+ uint32_t param2;
+ uint32_t param3;
+ uint32_t param4;
+ uint32_t param5;
+}
+PTP_OpContainerTypedef;
+
+typedef struct
+{
+ uint32_t length;
+ uint16_t type;
+ uint16_t code;
+ uint32_t trans_id;
+ union {
+ struct {
+ uint32_t param1;
+ uint32_t param2;
+ uint32_t param3;
+ uint32_t param4;
+ uint32_t param5;
+ } params;
+ uint8_t data[PTP_USB_BULK_PAYLOAD_LEN_READ];
+ }payload;
+}
+PTP_DataContainerTypedef;
+
+/* PTP USB Asynchronous Event Interrupt Data Format */
+typedef struct
+{
+ uint32_t length;
+ uint16_t type;
+ uint16_t code;
+ uint32_t trans_id;
+ uint32_t param1;
+ uint32_t param2;
+ uint32_t param3;
+}
+PTP_EventContainerTypedef;
+
+/* Structure for PTP Transport process */
+typedef struct
+{
+ PTP_ProcessStateTypeDef state;
+ PTP_RequestStateTypeDef req_state;
+ PTP_OpContainerTypedef op_container;
+ PTP_DataContainerTypedef data_container;
+ PTP_RespContainerTypedef resp_container;
+
+ /* ptp transaction ID */
+ uint32_t transaction_id;
+
+ /* ptp session ID */
+ uint32_t session_id;
+
+ /* device flags */
+ uint32_t flags;
+
+ /****** PTP transfer control *******/
+
+ /* Data pointer */
+ uint8_t *data_ptr;
+
+ /* Data length */
+ int32_t data_length;
+
+ /* Data length */
+ uint32_t data_packet;
+
+ /* Data length */
+ uint32_t iteration;
+
+ /* Packet Index */
+ uint32_t data_packet_counter;
+
+ /****** Object transfer control *******/
+
+ /* object pointer */
+ uint8_t *object_ptr;
+
+}
+PTP_HandleTypeDef;
+
+/* DeviceInfo data offset */
+#define PTP_di_StandardVersion 0
+#define PTP_di_VendorExtensionID 2
+#define PTP_di_VendorExtensionVersion 6
+#define PTP_di_VendorExtensionDesc 8
+#define PTP_di_FunctionalMode 8
+#define PTP_di_OperationsSupported 10
+
+/* Max info items size */
+#define PTP_SUPPORTED_OPERATIONS_NBR 100
+#define PTP_SUPPORTED_EVENTS_NBR 100
+#define PTP_SUPPORTED_PROPRIETIES_NBR 100
+#define PTP_CAPTURE_FORMATS_NBR 100
+#define PTP_IMAGE_FORMATS_NBR 100
+#define PTP_MAX_STR_SIZE 255
+/* PTP device info structure */
+typedef struct
+{
+ uint16_t StandardVersion;
+ uint32_t VendorExtensionID;
+ uint16_t VendorExtensionVersion;
+ uint8_t VendorExtensionDesc[PTP_MAX_STR_SIZE];
+ uint16_t FunctionalMode;
+ uint32_t OperationsSupported_len;
+ uint16_t OperationsSupported[PTP_SUPPORTED_OPERATIONS_NBR];
+ uint32_t EventsSupported_len;
+ uint16_t EventsSupported[PTP_SUPPORTED_EVENTS_NBR];
+ uint32_t DevicePropertiesSupported_len;
+ uint16_t DevicePropertiesSupported[PTP_SUPPORTED_PROPRIETIES_NBR];
+ uint32_t CaptureFormats_len;
+ uint16_t CaptureFormats[PTP_CAPTURE_FORMATS_NBR];
+ uint32_t ImageFormats_len;
+ uint16_t ImageFormats[PTP_IMAGE_FORMATS_NBR];
+ uint8_t Manufacturer[PTP_MAX_STR_SIZE];
+ uint8_t Model[PTP_MAX_STR_SIZE];
+ uint8_t DeviceVersion[PTP_MAX_STR_SIZE];
+ uint8_t SerialNumber[PTP_MAX_STR_SIZE];
+}
+PTP_DeviceInfoTypedef;
+
+#define PTP_MAX_STORAGE_UNITS_NBR 5
+/* PTP storageIDs structute (returned by GetStorageIDs) */
+typedef struct
+{
+ uint32_t n;
+ uint32_t Storage [PTP_MAX_STORAGE_UNITS_NBR];
+}
+PTP_StorageIDsTypedef;
+
+/* PTP StorageInfo structure (returned by GetStorageInfo) */
+
+#define PTP_si_StorageType 0
+#define PTP_si_FilesystemType 2
+#define PTP_si_AccessCapability 4
+#define PTP_si_MaxCapability 6
+#define PTP_si_FreeSpaceInBytes 14
+#define PTP_si_FreeSpaceInImages 22
+#define PTP_si_StorageDescription 26
+
+
+/* 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
+
+typedef struct
+{
+ uint16_t StorageType;
+ uint16_t FilesystemType;
+ uint16_t AccessCapability;
+ uint64_t MaxCapability;
+ uint64_t FreeSpaceInBytes;
+ uint32_t FreeSpaceInImages;
+ uint8_t StorageDescription[PTP_MAX_STR_SIZE];
+ uint8_t VolumeLabel[PTP_MAX_STR_SIZE];
+}
+PTP_StorageInfoTypedef;
+
+/* PTP Object Format Codes */
+
+/* ancillary formats */
+#define PTP_OFC_Undefined 0x3000
+#define PTP_OFC_Defined 0x3800
+#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 v1.1 has only DNG new */
+#define PTP_OFC_DNG 0x3811
+
+/* MTP extensions */
+#define PTP_OFC_MTP_MediaCard 0xb211
+#define PTP_OFC_MTP_MediaCardGroup 0xb212
+#define PTP_OFC_MTP_Encounter 0xb213
+#define PTP_OFC_MTP_EncounterBox 0xb214
+#define PTP_OFC_MTP_M4A 0xb215
+#define PTP_OFC_MTP_ZUNEUNDEFINED 0xb217 /* Unknown file type */
+#define PTP_OFC_MTP_Firmware 0xb802
+#define PTP_OFC_MTP_WindowsImageFormat 0xb881
+#define PTP_OFC_MTP_UndefinedAudio 0xb900
+#define PTP_OFC_MTP_WMA 0xb901
+#define PTP_OFC_MTP_OGG 0xb902
+#define PTP_OFC_MTP_AAC 0xb903
+#define PTP_OFC_MTP_AudibleCodec 0xb904
+#define PTP_OFC_MTP_FLAC 0xb906
+#define PTP_OFC_MTP_SamsungPlaylist 0xb909
+#define PTP_OFC_MTP_UndefinedVideo 0xb980
+#define PTP_OFC_MTP_WMV 0xb981
+#define PTP_OFC_MTP_MP4 0xb982
+#define PTP_OFC_MTP_MP2 0xb983
+#define PTP_OFC_MTP_3GP 0xb984
+#define PTP_OFC_MTP_UndefinedCollection 0xba00
+#define PTP_OFC_MTP_AbstractMultimediaAlbum 0xba01
+#define PTP_OFC_MTP_AbstractImageAlbum 0xba02
+#define PTP_OFC_MTP_AbstractAudioAlbum 0xba03
+#define PTP_OFC_MTP_AbstractVideoAlbum 0xba04
+#define PTP_OFC_MTP_AbstractAudioVideoPlaylist 0xba05
+#define PTP_OFC_MTP_AbstractContactGroup 0xba06
+#define PTP_OFC_MTP_AbstractMessageFolder 0xba07
+#define PTP_OFC_MTP_AbstractChapteredProduction 0xba08
+#define PTP_OFC_MTP_AbstractAudioPlaylist 0xba09
+#define PTP_OFC_MTP_AbstractVideoPlaylist 0xba0a
+#define PTP_OFC_MTP_AbstractMediacast 0xba0b
+#define PTP_OFC_MTP_WPLPlaylist 0xba10
+#define PTP_OFC_MTP_M3UPlaylist 0xba11
+#define PTP_OFC_MTP_MPLPlaylist 0xba12
+#define PTP_OFC_MTP_ASXPlaylist 0xba13
+#define PTP_OFC_MTP_PLSPlaylist 0xba14
+#define PTP_OFC_MTP_UndefinedDocument 0xba80
+#define PTP_OFC_MTP_AbstractDocument 0xba81
+#define PTP_OFC_MTP_XMLDocument 0xba82
+#define PTP_OFC_MTP_MSWordDocument 0xba83
+#define PTP_OFC_MTP_MHTCompiledHTMLDocument 0xba84
+#define PTP_OFC_MTP_MSExcelSpreadsheetXLS 0xba85
+#define PTP_OFC_MTP_MSPowerpointPresentationPPT 0xba86
+#define PTP_OFC_MTP_UndefinedMessage 0xbb00
+#define PTP_OFC_MTP_AbstractMessage 0xbb01
+#define PTP_OFC_MTP_UndefinedContact 0xbb80
+#define PTP_OFC_MTP_AbstractContact 0xbb81
+#define PTP_OFC_MTP_vCard2 0xbb82
+#define PTP_OFC_MTP_vCard3 0xbb83
+#define PTP_OFC_MTP_UndefinedCalendarItem 0xbe00
+#define PTP_OFC_MTP_AbstractCalendarItem 0xbe01
+#define PTP_OFC_MTP_vCalendar1 0xbe02
+#define PTP_OFC_MTP_vCalendar2 0xbe03
+#define PTP_OFC_MTP_UndefinedWindowsExecutable 0xbe80
+#define PTP_OFC_MTP_MediaCast 0xbe81
+#define PTP_OFC_MTP_Section 0xbe82
+
+/* MTP specific Object Properties */
+#define PTP_OPC_StorageID 0xDC01
+#define PTP_OPC_ObjectFormat 0xDC02
+#define PTP_OPC_ProtectionStatus 0xDC03
+#define PTP_OPC_ObjectSize 0xDC04
+#define PTP_OPC_AssociationType 0xDC05
+#define PTP_OPC_AssociationDesc 0xDC06
+#define PTP_OPC_ObjectFileName 0xDC07
+#define PTP_OPC_DateCreated 0xDC08
+#define PTP_OPC_DateModified 0xDC09
+#define PTP_OPC_Keywords 0xDC0A
+#define PTP_OPC_ParentObject 0xDC0B
+#define PTP_OPC_AllowedFolderContents 0xDC0C
+#define PTP_OPC_Hidden 0xDC0D
+#define PTP_OPC_SystemObject 0xDC0E
+#define PTP_OPC_PersistantUniqueObjectIdentifier 0xDC41
+#define PTP_OPC_SyncID 0xDC42
+#define PTP_OPC_PropertyBag 0xDC43
+#define PTP_OPC_Name 0xDC44
+#define PTP_OPC_CreatedBy 0xDC45
+#define PTP_OPC_Artist 0xDC46
+#define PTP_OPC_DateAuthored 0xDC47
+#define PTP_OPC_Description 0xDC48
+#define PTP_OPC_URLReference 0xDC49
+#define PTP_OPC_LanguageLocale 0xDC4A
+#define PTP_OPC_CopyrightInformation 0xDC4B
+#define PTP_OPC_Source 0xDC4C
+#define PTP_OPC_OriginLocation 0xDC4D
+#define PTP_OPC_DateAdded 0xDC4E
+#define PTP_OPC_NonConsumable 0xDC4F
+#define PTP_OPC_CorruptOrUnplayable 0xDC50
+#define PTP_OPC_ProducerSerialNumber 0xDC51
+#define PTP_OPC_RepresentativeSampleFormat 0xDC81
+#define PTP_OPC_RepresentativeSampleSize 0xDC82
+#define PTP_OPC_RepresentativeSampleHeight 0xDC83
+#define PTP_OPC_RepresentativeSampleWidth 0xDC84
+#define PTP_OPC_RepresentativeSampleDuration 0xDC85
+#define PTP_OPC_RepresentativeSampleData 0xDC86
+#define PTP_OPC_Width 0xDC87
+#define PTP_OPC_Height 0xDC88
+#define PTP_OPC_Duration 0xDC89
+#define PTP_OPC_Rating 0xDC8A
+#define PTP_OPC_Track 0xDC8B
+#define PTP_OPC_Genre 0xDC8C
+#define PTP_OPC_Credits 0xDC8D
+#define PTP_OPC_Lyrics 0xDC8E
+#define PTP_OPC_SubscriptionContentID 0xDC8F
+#define PTP_OPC_ProducedBy 0xDC90
+#define PTP_OPC_UseCount 0xDC91
+#define PTP_OPC_SkipCount 0xDC92
+#define PTP_OPC_LastAccessed 0xDC93
+#define PTP_OPC_ParentalRating 0xDC94
+#define PTP_OPC_MetaGenre 0xDC95
+#define PTP_OPC_Composer 0xDC96
+#define PTP_OPC_EffectiveRating 0xDC97
+#define PTP_OPC_Subtitle 0xDC98
+#define PTP_OPC_OriginalReleaseDate 0xDC99
+#define PTP_OPC_AlbumName 0xDC9A
+#define PTP_OPC_AlbumArtist 0xDC9B
+#define PTP_OPC_Mood 0xDC9C
+#define PTP_OPC_DRMStatus 0xDC9D
+#define PTP_OPC_SubDescription 0xDC9E
+#define PTP_OPC_IsCropped 0xDCD1
+#define PTP_OPC_IsColorCorrected 0xDCD2
+#define PTP_OPC_ImageBitDepth 0xDCD3
+#define PTP_OPC_Fnumber 0xDCD4
+#define PTP_OPC_ExposureTime 0xDCD5
+#define PTP_OPC_ExposureIndex 0xDCD6
+#define PTP_OPC_DisplayName 0xDCE0
+#define PTP_OPC_BodyText 0xDCE1
+#define PTP_OPC_Subject 0xDCE2
+#define PTP_OPC_Priority 0xDCE3
+#define PTP_OPC_GivenName 0xDD00
+#define PTP_OPC_MiddleNames 0xDD01
+#define PTP_OPC_FamilyName 0xDD02
+#define PTP_OPC_Prefix 0xDD03
+#define PTP_OPC_Suffix 0xDD04
+#define PTP_OPC_PhoneticGivenName 0xDD05
+#define PTP_OPC_PhoneticFamilyName 0xDD06
+#define PTP_OPC_EmailPrimary 0xDD07
+#define PTP_OPC_EmailPersonal1 0xDD08
+#define PTP_OPC_EmailPersonal2 0xDD09
+#define PTP_OPC_EmailBusiness1 0xDD0A
+#define PTP_OPC_EmailBusiness2 0xDD0B
+#define PTP_OPC_EmailOthers 0xDD0C
+#define PTP_OPC_PhoneNumberPrimary 0xDD0D
+#define PTP_OPC_PhoneNumberPersonal 0xDD0E
+#define PTP_OPC_PhoneNumberPersonal2 0xDD0F
+#define PTP_OPC_PhoneNumberBusiness 0xDD10
+#define PTP_OPC_PhoneNumberBusiness2 0xDD11
+#define PTP_OPC_PhoneNumberMobile 0xDD12
+#define PTP_OPC_PhoneNumberMobile2 0xDD13
+#define PTP_OPC_FaxNumberPrimary 0xDD14
+#define PTP_OPC_FaxNumberPersonal 0xDD15
+#define PTP_OPC_FaxNumberBusiness 0xDD16
+#define PTP_OPC_PagerNumber 0xDD17
+#define PTP_OPC_PhoneNumberOthers 0xDD18
+#define PTP_OPC_PrimaryWebAddress 0xDD19
+#define PTP_OPC_PersonalWebAddress 0xDD1A
+#define PTP_OPC_BusinessWebAddress 0xDD1B
+#define PTP_OPC_InstantMessengerAddress 0xDD1C
+#define PTP_OPC_InstantMessengerAddress2 0xDD1D
+#define PTP_OPC_InstantMessengerAddress3 0xDD1E
+#define PTP_OPC_PostalAddressPersonalFull 0xDD1F
+#define PTP_OPC_PostalAddressPersonalFullLine1 0xDD20
+#define PTP_OPC_PostalAddressPersonalFullLine2 0xDD21
+#define PTP_OPC_PostalAddressPersonalFullCity 0xDD22
+#define PTP_OPC_PostalAddressPersonalFullRegion 0xDD23
+#define PTP_OPC_PostalAddressPersonalFullPostalCode 0xDD24
+#define PTP_OPC_PostalAddressPersonalFullCountry 0xDD25
+#define PTP_OPC_PostalAddressBusinessFull 0xDD26
+#define PTP_OPC_PostalAddressBusinessLine1 0xDD27
+#define PTP_OPC_PostalAddressBusinessLine2 0xDD28
+#define PTP_OPC_PostalAddressBusinessCity 0xDD29
+#define PTP_OPC_PostalAddressBusinessRegion 0xDD2A
+#define PTP_OPC_PostalAddressBusinessPostalCode 0xDD2B
+#define PTP_OPC_PostalAddressBusinessCountry 0xDD2C
+#define PTP_OPC_PostalAddressOtherFull 0xDD2D
+#define PTP_OPC_PostalAddressOtherLine1 0xDD2E
+#define PTP_OPC_PostalAddressOtherLine2 0xDD2F
+#define PTP_OPC_PostalAddressOtherCity 0xDD30
+#define PTP_OPC_PostalAddressOtherRegion 0xDD31
+#define PTP_OPC_PostalAddressOtherPostalCode 0xDD32
+#define PTP_OPC_PostalAddressOtherCountry 0xDD33
+#define PTP_OPC_OrganizationName 0xDD34
+#define PTP_OPC_PhoneticOrganizationName 0xDD35
+#define PTP_OPC_Role 0xDD36
+#define PTP_OPC_Birthdate 0xDD37
+#define PTP_OPC_MessageTo 0xDD40
+#define PTP_OPC_MessageCC 0xDD41
+#define PTP_OPC_MessageBCC 0xDD42
+#define PTP_OPC_MessageRead 0xDD43
+#define PTP_OPC_MessageReceivedTime 0xDD44
+#define PTP_OPC_MessageSender 0xDD45
+#define PTP_OPC_ActivityBeginTime 0xDD50
+#define PTP_OPC_ActivityEndTime 0xDD51
+#define PTP_OPC_ActivityLocation 0xDD52
+#define PTP_OPC_ActivityRequiredAttendees 0xDD54
+#define PTP_OPC_ActivityOptionalAttendees 0xDD55
+#define PTP_OPC_ActivityResources 0xDD56
+#define PTP_OPC_ActivityAccepted 0xDD57
+#define PTP_OPC_Owner 0xDD5D
+#define PTP_OPC_Editor 0xDD5E
+#define PTP_OPC_Webmaster 0xDD5F
+#define PTP_OPC_URLSource 0xDD60
+#define PTP_OPC_URLDestination 0xDD61
+#define PTP_OPC_TimeBookmark 0xDD62
+#define PTP_OPC_ObjectBookmark 0xDD63
+#define PTP_OPC_ByteBookmark 0xDD64
+#define PTP_OPC_LastBuildDate 0xDD70
+#define PTP_OPC_TimetoLive 0xDD71
+#define PTP_OPC_MediaGUID 0xDD72
+#define PTP_OPC_TotalBitRate 0xDE91
+#define PTP_OPC_BitRateType 0xDE92
+#define PTP_OPC_SampleRate 0xDE93
+#define PTP_OPC_NumberOfChannels 0xDE94
+#define PTP_OPC_AudioBitDepth 0xDE95
+#define PTP_OPC_ScanDepth 0xDE97
+#define PTP_OPC_AudioWAVECodec 0xDE99
+#define PTP_OPC_AudioBitRate 0xDE9A
+#define PTP_OPC_VideoFourCCCodec 0xDE9B
+#define PTP_OPC_VideoBitRate 0xDE9C
+#define PTP_OPC_FramesPerThousandSeconds 0xDE9D
+#define PTP_OPC_KeyFrameDistance 0xDE9E
+#define PTP_OPC_BufferSize 0xDE9F
+#define PTP_OPC_EncodingQuality 0xDEA0
+#define PTP_OPC_EncodingProfile 0xDEA1
+#define PTP_OPC_BuyFlag 0xD901
+
+/* WiFi Provisioning MTP Extension property codes */
+#define PTP_OPC_WirelessConfigurationFile 0xB104
+
+
+/* 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
+
+#define PTP_MAX_HANDLER_NBR 0x255
+typedef struct
+{
+ uint32_t n;
+ uint32_t Handler[PTP_MAX_HANDLER_NBR];
+}
+PTP_ObjectHandlesTypedef;
+
+
+#define PTP_oi_StorageID 0
+#define PTP_oi_ObjectFormat 4
+#define PTP_oi_ProtectionStatus 6
+#define PTP_oi_ObjectCompressedSize 8
+#define PTP_oi_ThumbFormat 12
+#define PTP_oi_ThumbCompressedSize 14
+#define PTP_oi_ThumbPixWidth 18
+#define PTP_oi_ThumbPixHeight 22
+#define PTP_oi_ImagePixWidth 26
+#define PTP_oi_ImagePixHeight 30
+#define PTP_oi_ImageBitDepth 34
+#define PTP_oi_ParentObject 38
+#define PTP_oi_AssociationType 42
+#define PTP_oi_AssociationDesc 44
+#define PTP_oi_SequenceNumber 48
+#define PTP_oi_filenamelen 52
+#define PTP_oi_Filename 53
+
+typedef struct
+{
+ uint32_t StorageID;
+ uint16_t ObjectFormat;
+ uint16_t ProtectionStatus;
+ /* In the regular objectinfo this is 32bit, but we keep the general object size here
+ that also arrives via other methods and so use 64bit */
+ uint64_t ObjectCompressedSize;
+ uint16_t ThumbFormat;
+ uint32_t ThumbCompressedSize;
+ uint32_t ThumbPixWidth;
+ uint32_t ThumbPixHeight;
+ uint32_t ImagePixWidth;
+ uint32_t ImagePixHeight;
+ uint32_t ImageBitDepth;
+ uint32_t ParentObject;
+ uint16_t AssociationType;
+ uint32_t AssociationDesc;
+ uint32_t SequenceNumber;
+ uint8_t Filename[PTP_MAX_STR_SIZE];
+ uint32_t CaptureDate;
+ uint32_t ModificationDate;
+ uint8_t Keywords[PTP_MAX_STR_SIZE];
+}
+PTP_ObjectInfoTypedef;
+
+/* Object Property Describing Dataset (DevicePropDesc) */
+
+typedef union _PTP_PropertyValueTypedef
+{
+ char str[PTP_MAX_STR_SIZE];
+ uint8_t u8;
+ int8_t i8;
+ uint16_t u16;
+ int16_t i16;
+ uint32_t u32;
+ int32_t i32;
+ uint64_t u64;
+ int64_t i64;
+
+ struct array {
+ uint32_t count;
+ union _PTP_PropertyValueTypedef *v;
+ } a;
+}PTP_PropertyValueTypedef;
+
+typedef struct
+{
+ PTP_PropertyValueTypedef MinimumValue;
+ PTP_PropertyValueTypedef MaximumValue;
+ PTP_PropertyValueTypedef StepSize;
+}
+PTP_PropDescRangeFormTypedef;
+
+/* Property Describing Dataset, Enum Form */
+
+typedef struct
+{
+ uint16_t NumberOfValues;
+ PTP_PropertyValueTypedef SupportedValue[PTP_SUPPORTED_PROPRIETIES_NBR];
+}
+PTP_PropDescEnumFormTypedef;
+
+/* (MTP) Object Property pack/unpack */
+#define PTP_opd_ObjectPropertyCode 0
+#define PTP_opd_DataType 2
+#define PTP_opd_GetSet 4
+#define PTP_opd_FactoryDefaultValue 5
+
+typedef struct
+{
+ uint16_t ObjectPropertyCode;
+ uint16_t DataType;
+ uint8_t GetSet;
+ PTP_PropertyValueTypedef FactoryDefaultValue;
+ uint32_t GroupCode;
+ uint8_t FormFlag;
+ union {
+ PTP_PropDescEnumFormTypedef Enum;
+ PTP_PropDescRangeFormTypedef Range;
+ } FORM;
+}
+PTP_ObjectPropDescTypeDef;
+
+/* Metadata lists for MTP operations */
+typedef struct
+{
+ uint16_t property;
+ uint16_t datatype;
+ uint32_t ObjectHandle;
+ PTP_PropertyValueTypedef propval;
+}
+MTP_PropertiesTypedef;
+
+
+/* Device Property Form Flag */
+
+#define PTP_DPFF_None 0x00
+#define PTP_DPFF_Range 0x01
+#define PTP_DPFF_Enumeration 0x02
+
+/* Object Property Codes used by MTP (first 3 are same as DPFF codes) */
+#define PTP_OPFF_None 0x00
+#define PTP_OPFF_Range 0x01
+#define PTP_OPFF_Enumeration 0x02
+#define PTP_OPFF_DateTime 0x03
+#define PTP_OPFF_FixedLengthArray 0x04
+#define PTP_OPFF_RegularExpression 0x05
+#define PTP_OPFF_ByteArray 0x06
+#define PTP_OPFF_LongString 0xFF
+
+/* Device Property pack/unpack */
+
+#define PTP_dpd_DevicePropertyCode 0
+#define PTP_dpd_DataType 2
+#define PTP_dpd_GetSet 4
+#define PTP_dpd_FactoryDefaultValue 5
+
+/* Device Property Describing Dataset (DevicePropDesc) */
+
+typedef struct
+{
+ uint16_t DevicePropertyCode;
+ uint16_t DataType;
+ uint8_t GetSet;
+ PTP_PropertyValueTypedef FactoryDefaultValue;
+ PTP_PropertyValueTypedef CurrentValue;
+ uint8_t FormFlag;
+ union {
+ PTP_PropDescEnumFormTypedef Enum;
+ PTP_PropDescRangeFormTypedef Range;
+ } FORM;
+}
+PTP_DevicePropDescTypdef;
+
+/* 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_ARRAY_MASK 0x4000
+
+#define PTP_DTC_AINT8 (PTP_DTC_ARRAY_MASK | PTP_DTC_INT8)
+#define PTP_DTC_AUINT8 (PTP_DTC_ARRAY_MASK | PTP_DTC_UINT8)
+#define PTP_DTC_AINT16 (PTP_DTC_ARRAY_MASK | PTP_DTC_INT16)
+#define PTP_DTC_AUINT16 (PTP_DTC_ARRAY_MASK | PTP_DTC_UINT16)
+#define PTP_DTC_AINT32 (PTP_DTC_ARRAY_MASK | PTP_DTC_INT32)
+#define PTP_DTC_AUINT32 (PTP_DTC_ARRAY_MASK | PTP_DTC_UINT32)
+#define PTP_DTC_AINT64 (PTP_DTC_ARRAY_MASK | PTP_DTC_INT64)
+#define PTP_DTC_AUINT64 (PTP_DTC_ARRAY_MASK | PTP_DTC_UINT64)
+#define PTP_DTC_AINT128 (PTP_DTC_ARRAY_MASK | PTP_DTC_INT128)
+#define PTP_DTC_AUINT128 (PTP_DTC_ARRAY_MASK | PTP_DTC_UINT128)
+
+#define PTP_DTC_STR 0xFFFF
+
+/* 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
+
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MTP_PTP_Exported_Macros
+ * @{
+ */
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MTP_PTP_Exported_Variables
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup USBH_MTP_PTP_Exported_FunctionsPrototype
+ * @{
+ */
+USBH_StatusTypeDef USBH_PTP_Init(USBH_HandleTypeDef *phost);
+USBH_StatusTypeDef USBH_PTP_Process (USBH_HandleTypeDef *phost);
+
+USBH_StatusTypeDef USBH_PTP_SendRequest (USBH_HandleTypeDef *phost, PTP_ContainerTypedef *req);
+USBH_StatusTypeDef USBH_PTP_GetResponse (USBH_HandleTypeDef *phost, PTP_ContainerTypedef *req);
+
+USBH_StatusTypeDef USBH_PTP_OpenSession (USBH_HandleTypeDef *phost, uint32_t session);
+USBH_StatusTypeDef USBH_PTP_GetDeviceInfo (USBH_HandleTypeDef *phost, PTP_DeviceInfoTypedef *dev_info);
+USBH_StatusTypeDef USBH_PTP_GetStorageIds (USBH_HandleTypeDef *phost, PTP_StorageIDsTypedef *storage_ids);
+
+USBH_StatusTypeDef USBH_PTP_GetStorageInfo (USBH_HandleTypeDef *phost,
+ uint32_t storage_id,
+ PTP_StorageInfoTypedef *storage_info);
+
+USBH_StatusTypeDef USBH_PTP_GetNumObjects (USBH_HandleTypeDef *phost,
+ uint32_t storage_id,
+ uint32_t objectformatcode,
+ uint32_t associationOH,
+ uint32_t* numobs);
+
+USBH_StatusTypeDef USBH_PTP_GetObjectHandles (USBH_HandleTypeDef *phost,
+ uint32_t storage_id,
+ uint32_t objectformatcode,
+ uint32_t associationOH,
+ PTP_ObjectHandlesTypedef* objecthandles);
+
+USBH_StatusTypeDef USBH_PTP_GetObjectInfo (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ PTP_ObjectInfoTypedef* objectinfo);
+
+USBH_StatusTypeDef USBH_PTP_DeleteObject (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ uint32_t objectformatcode);
+
+USBH_StatusTypeDef USBH_PTP_GetObject (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ uint8_t *object);
+
+USBH_StatusTypeDef USBH_PTP_GetPartialObject(USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ uint32_t offset,
+ uint32_t maxbytes, uint8_t *object,
+ uint32_t *len);
+
+USBH_StatusTypeDef USBH_PTP_GetObjectPropsSupported (USBH_HandleTypeDef *phost,
+ uint16_t ofc,
+ uint32_t *propnum,
+ uint16_t *props);
+
+USBH_StatusTypeDef USBH_PTP_GetObjectPropDesc (USBH_HandleTypeDef *phost,
+ uint16_t opc,
+ uint16_t ofc,
+ PTP_ObjectPropDescTypeDef *opd);
+
+USBH_StatusTypeDef USBH_PTP_GetObjectPropList (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ MTP_PropertiesTypedef *pprops,
+ uint32_t *nrofprops);
+
+USBH_StatusTypeDef USBH_PTP_SendObject (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ uint8_t *object,
+ uint32_t size);
+
+USBH_StatusTypeDef USBH_PTP_GetDevicePropDesc (USBH_HandleTypeDef *phost,
+ uint16_t propcode,
+ PTP_DevicePropDescTypdef* devicepropertydesc);
+
+/**
+ * @}
+ */
+
+#endif //__USBH_MTP_PTP_H__
+
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
diff --git a/stmhal/usbhost/Class/MTP/Src/usbh_mtp.c b/stmhal/usbhost/Class/MTP/Src/usbh_mtp.c new file mode 100644 index 000000000..d93aa4238 --- /dev/null +++ b/stmhal/usbhost/Class/MTP/Src/usbh_mtp.c @@ -0,0 +1,1065 @@ +/**
+ ******************************************************************************
+ * @file usbh_mtp.c
+ * @author MCD Application Team
+ * @version V3.0.0
+ * @date 18-February-2014
+ * @brief This file is the MTP Layer Handlers for USB Host MTP class.
+ *
+ * @verbatim
+ *
+ * ===================================================================
+ * MTP Class Description
+ * ===================================================================
+ * This module manages the MSC class V1.11 following the "Device Class Definition
+ * for Human Interface Devices (MTP) Version 1.11 Jun 27, 2001".
+ * This driver implements the following aspects of the specification:
+ * - The Boot Interface Subclass
+ * - The Mouse and Keyboard protocols
+ *
+ * @endverbatim
+ *
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_mtp.h"
+
+/** @addtogroup USBH_LIB
+* @{
+*/
+
+/** @addtogroup USBH_CLASS
+* @{
+*/
+
+/** @addtogroup USBH_MTP_CLASS
+* @{
+*/
+
+/** @defgroup USBH_MTP_CORE
+* @brief This file includes MTP Layer Handlers for USB Host MTP class.
+* @{
+*/
+
+/** @defgroup USBH_MTP_CORE_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_MTP_CORE_Private_Defines
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_MTP_CORE_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_MTP_CORE_Private_Variables
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_MTP_CORE_Private_FunctionPrototypes
+* @{
+*/
+
+static USBH_StatusTypeDef USBH_MTP_InterfaceInit (USBH_HandleTypeDef *phost);
+
+static USBH_StatusTypeDef USBH_MTP_InterfaceDeInit (USBH_HandleTypeDef *phost);
+
+static USBH_StatusTypeDef USBH_MTP_Process(USBH_HandleTypeDef *phost);
+
+static USBH_StatusTypeDef USBH_MTP_ClassRequest (USBH_HandleTypeDef *phost);
+
+static uint8_t MTP_FindCtlEndpoint(USBH_HandleTypeDef *phost);
+
+static uint8_t MTP_FindDataOutEndpoint(USBH_HandleTypeDef *phost);
+
+static uint8_t MTP_FindDataInEndpoint(USBH_HandleTypeDef *phost);
+
+static USBH_StatusTypeDef USBH_MTP_SOFProcess (USBH_HandleTypeDef *phost);
+
+static USBH_StatusTypeDef USBH_MTP_Events (USBH_HandleTypeDef *phost);
+
+static void MTP_DecodeEvent (USBH_HandleTypeDef *phost) ;
+
+USBH_ClassTypeDef MTP_Class =
+{
+ "MTP",
+ USB_MTP_CLASS,
+ USBH_MTP_InterfaceInit,
+ USBH_MTP_InterfaceDeInit,
+ USBH_MTP_ClassRequest,
+ USBH_MTP_Process,
+ USBH_MTP_SOFProcess,
+ NULL,
+};
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_MTP_CORE_Private_Functions
+* @{
+*/
+
+/**
+ * @brief USBH_MTP_InterfaceInit
+ * The function init the MTP class.
+ * @param phost: Host handle
+ * @retval USBH Status
+ */
+static USBH_StatusTypeDef USBH_MTP_InterfaceInit (USBH_HandleTypeDef *phost)
+{
+ USBH_StatusTypeDef status = USBH_OK ;
+ uint8_t interface, endpoint;
+
+ MTP_HandleTypeDef *MTP_Handle;
+
+ interface = USBH_FindInterface(phost,
+ USB_MTP_CLASS,
+ 1,
+ 1);
+
+ if(interface == 0xFF) /* No Valid Interface */
+ {
+ status = USBH_FAIL;
+ USBH_DbgLog ("Cannot Find the interface for Still Image Class.");
+ }
+ else
+ {
+ USBH_SelectInterface (phost, interface);
+
+ endpoint = MTP_FindCtlEndpoint(phost);
+
+ phost->pActiveClass->pData = (MTP_HandleTypeDef *)USBH_malloc (sizeof(MTP_HandleTypeDef));
+ MTP_Handle = phost->pActiveClass->pData;
+
+ if( MTP_Handle == NULL)
+ {
+ status = USBH_FAIL;
+ USBH_DbgLog ("Cannot allocate RAM for MTP Handle");
+ }
+
+ /*Collect the control endpoint address and length*/
+ MTP_Handle->NotificationEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[endpoint].bEndpointAddress;
+ MTP_Handle->NotificationEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[endpoint].wMaxPacketSize;
+ MTP_Handle->NotificationPipe = USBH_AllocPipe(phost, MTP_Handle->NotificationEp);
+ MTP_Handle->events.poll = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[endpoint].bInterval;
+
+ /* Open pipe for Notification endpoint */
+ USBH_OpenPipe (phost,
+ MTP_Handle->NotificationPipe,
+ MTP_Handle->NotificationEp,
+ phost->device.address,
+ phost->device.speed,
+ USB_EP_TYPE_INTR,
+ MTP_Handle->NotificationEpSize);
+
+ USBH_LL_SetToggle (phost, MTP_Handle->NotificationPipe, 0);
+
+
+ endpoint = MTP_FindDataInEndpoint(phost);
+
+ /*Collect the control endpoint address and length*/
+ MTP_Handle->DataInEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[endpoint].bEndpointAddress;
+ MTP_Handle->DataInEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[endpoint].wMaxPacketSize;
+ MTP_Handle->DataInPipe = USBH_AllocPipe(phost, MTP_Handle->DataInEp);
+
+ /* Open pipe for DATA IN endpoint */
+ USBH_OpenPipe (phost,
+ MTP_Handle->DataInPipe,
+ MTP_Handle->DataInEp,
+ phost->device.address,
+ phost->device.speed,
+ USB_EP_TYPE_BULK,
+ MTP_Handle->DataInEpSize);
+
+ USBH_LL_SetToggle (phost, MTP_Handle->DataInPipe, 0);
+
+ endpoint = MTP_FindDataOutEndpoint(phost);
+
+ /*Collect the DATA OUT endpoint address and length*/
+ MTP_Handle->DataOutEp = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[endpoint].bEndpointAddress;
+ MTP_Handle->DataOutEpSize = phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[endpoint].wMaxPacketSize;
+ MTP_Handle->DataOutPipe = USBH_AllocPipe(phost, MTP_Handle->DataOutEp);
+
+ /* Open pipe for DATA OUT endpoint */
+ USBH_OpenPipe (phost,
+ MTP_Handle->DataOutPipe,
+ MTP_Handle->DataOutEp,
+ phost->device.address,
+ phost->device.speed,
+ USB_EP_TYPE_BULK,
+ MTP_Handle->DataOutEpSize);
+
+ USBH_LL_SetToggle (phost, MTP_Handle->DataOutPipe, 0);
+
+
+ MTP_Handle->state = MTP_OPENSESSION;
+ MTP_Handle->is_ready = 0;
+ MTP_Handle->events.state = MTP_EVENTS_INIT;
+ return USBH_PTP_Init(phost);
+
+ }
+ return status;
+}
+
+/**
+ * @brief Find MTP Ctl interface
+ * @param phost: Host handle
+ * @retval USBH Status
+ */
+static uint8_t MTP_FindCtlEndpoint(USBH_HandleTypeDef *phost)
+{
+ uint8_t interface, endpoint;
+
+ for (interface = 0; interface < USBH_MAX_NUM_INTERFACES ; interface ++ )
+ {
+ if(phost->device.CfgDesc.Itf_Desc[interface].bInterfaceClass == USB_MTP_CLASS)
+ {
+ for (endpoint = 0; endpoint < USBH_MAX_NUM_ENDPOINTS ; endpoint ++ )
+ {
+ if((phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[endpoint].bEndpointAddress & 0x80)&&
+ (phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[endpoint].wMaxPacketSize > 0)&&
+ ((phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[endpoint].bmAttributes & USBH_EP_INTERRUPT) == USBH_EP_INTERRUPT))
+ {
+ return endpoint;
+ }
+ }
+ }
+ }
+
+ return 0xFF; /* Invalid Endpoint */
+}
+
+
+/**
+ * @brief Find MTP DATA OUT interface
+ * @param phost: Host handle
+ * @retval USBH Status
+ */
+static uint8_t MTP_FindDataOutEndpoint(USBH_HandleTypeDef *phost)
+{
+ uint8_t interface, endpoint;
+
+ for (interface = 0; interface < USBH_MAX_NUM_INTERFACES ; interface ++ )
+ {
+ if(phost->device.CfgDesc.Itf_Desc[interface].bInterfaceClass == USB_MTP_CLASS)
+ {
+ for (endpoint = 0; endpoint < USBH_MAX_NUM_ENDPOINTS ; endpoint ++ )
+ {
+
+ if(((phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[endpoint].bEndpointAddress & 0x80) == 0)&&
+ (phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[endpoint].wMaxPacketSize > 0)&&
+ ((phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[endpoint].bmAttributes & USBH_EP_BULK) == USBH_EP_BULK))
+ {
+ return endpoint;
+ }
+ }
+ }
+ }
+
+ return 0xFF; /* Invalid Endpoint */
+}
+
+/**
+ * @brief Find MTP DATA IN interface
+ * @param phost: Host handle
+ * @retval USBH Status
+ */
+static uint8_t MTP_FindDataInEndpoint(USBH_HandleTypeDef *phost)
+{
+ uint8_t interface, endpoint;
+
+ for (interface = 0; interface < USBH_MAX_NUM_INTERFACES ; interface ++ )
+ {
+ if(phost->device.CfgDesc.Itf_Desc[interface].bInterfaceClass == USB_MTP_CLASS)
+ {
+ for (endpoint = 0; endpoint < USBH_MAX_NUM_ENDPOINTS ; endpoint ++ )
+ {
+
+ if((phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[endpoint].bEndpointAddress & 0x80)&&
+ (phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[endpoint].wMaxPacketSize > 0)&&
+ ((phost->device.CfgDesc.Itf_Desc[interface].Ep_Desc[endpoint].bmAttributes & USBH_EP_BULK) == USBH_EP_BULK))
+ {
+ return endpoint;
+ }
+ }
+ }
+ }
+
+ return 0xFF; /* Invalid Endpoint */
+}
+
+
+/**
+ * @brief USBH_MTP_InterfaceDeInit
+ * The function DeInit the Pipes used for the MTP class.
+ * @param phost: Host handle
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_MTP_InterfaceDeInit (USBH_HandleTypeDef *phost)
+{
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+
+ if (MTP_Handle->DataOutPipe)
+ {
+ USBH_ClosePipe(phost, MTP_Handle->DataOutPipe);
+ USBH_FreePipe (phost, MTP_Handle->DataOutPipe);
+ MTP_Handle->DataOutPipe = 0; /* Reset the Channel as Free */
+ }
+
+ if (MTP_Handle->DataInPipe)
+ {
+ USBH_ClosePipe(phost, MTP_Handle->DataInPipe);
+ USBH_FreePipe (phost, MTP_Handle->DataInPipe);
+ MTP_Handle->DataInPipe = 0; /* Reset the Channel as Free */
+ }
+
+ if (MTP_Handle->NotificationPipe)
+ {
+ USBH_ClosePipe(phost, MTP_Handle->NotificationPipe);
+ USBH_FreePipe (phost, MTP_Handle->NotificationPipe);
+ MTP_Handle->NotificationPipe = 0; /* Reset the Channel as Free */
+ }
+
+ if(phost->pActiveClass->pData)
+ {
+ USBH_free (phost->pActiveClass->pData);
+ phost->pActiveClass->pData = 0;
+ }
+ return USBH_OK;
+}
+
+/**
+ * @brief USBH_MTP_ClassRequest
+ * The function is responsible for handling Standard requests
+ * for MTP class.
+ * @param phost: Host handle
+ * @retval USBH Status
+ */
+static USBH_StatusTypeDef USBH_MTP_ClassRequest (USBH_HandleTypeDef *phost)
+{
+ return USBH_OK;;
+}
+
+
+/**
+ * @brief USBH_MTP_Process
+ * The function is for managing state machine for MTP data transfers
+ * @param phost: Host handle
+ * @retval USBH Status
+ */
+static USBH_StatusTypeDef USBH_MTP_Process (USBH_HandleTypeDef *phost)
+{
+ USBH_StatusTypeDef status = USBH_BUSY;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint32_t idx = 0;
+
+ switch(MTP_Handle->state)
+ {
+ case MTP_OPENSESSION:
+
+ status = USBH_PTP_OpenSession (phost, 1); /* Session '0' is not valid */
+
+ if(status == USBH_OK)
+ {
+ USBH_UsrLog("MTP Session #0 Opened");
+ MTP_Handle->state = MTP_GETDEVICEINFO;
+ }
+ break;
+
+ case MTP_GETDEVICEINFO:
+ status = USBH_PTP_GetDeviceInfo (phost, &(MTP_Handle->info.devinfo));
+
+ if(status == USBH_OK)
+ {
+ USBH_DbgLog(">>>>> MTP Device Information");
+ USBH_DbgLog("Standard version : %x", MTP_Handle->info.devinfo.StandardVersion);
+ USBH_DbgLog("Vendor ExtID : %s", (MTP_Handle->info.devinfo.VendorExtensionID == 6)?"MTP": "NOT SUPPORTED");
+ USBH_DbgLog("Functional mode : %s", (MTP_Handle->info.devinfo.FunctionalMode == 0) ? "Standard" : "Vendor");
+ USBH_DbgLog("Number of Supported Operation(s) : %d", MTP_Handle->info.devinfo.OperationsSupported_len);
+ USBH_DbgLog("Number of Supported Events(s) : %d", MTP_Handle->info.devinfo.EventsSupported_len);
+ USBH_DbgLog("Number of Supported Proprieties : %d", MTP_Handle->info.devinfo.DevicePropertiesSupported_len);
+ USBH_DbgLog("Manufacturer : %s", MTP_Handle->info.devinfo.Manufacturer);
+ USBH_DbgLog("Model : %s", MTP_Handle->info.devinfo.Model);
+ USBH_DbgLog("Device version : %s", MTP_Handle->info.devinfo.DeviceVersion);
+ USBH_DbgLog("Serial number : %s", MTP_Handle->info.devinfo.SerialNumber);
+
+ MTP_Handle->state = MTP_GETSTORAGEIDS;
+ }
+ break;
+
+ case MTP_GETSTORAGEIDS:
+ status = USBH_PTP_GetStorageIds (phost, &(MTP_Handle->info.storids));
+
+ if(status == USBH_OK)
+ {
+ USBH_DbgLog("Number of storage ID items : %d", MTP_Handle->info.storids.n);
+ for (idx = 0; idx < MTP_Handle->info.storids.n; idx ++)
+ {
+ USBH_DbgLog("storage#%d ID : %x", idx, MTP_Handle->info.storids.Storage[idx]);
+ }
+
+ MTP_Handle->current_storage_unit = 0;
+ MTP_Handle->state = MTP_GETSTORAGEINFO;
+ }
+ break;
+
+ case MTP_GETSTORAGEINFO:
+ status = USBH_PTP_GetStorageInfo (phost,
+ MTP_Handle->info.storids.Storage[MTP_Handle->current_storage_unit],
+ &((MTP_Handle->info.storinfo)[MTP_Handle->current_storage_unit]));
+
+ if(status == USBH_OK)
+ {
+ USBH_UsrLog("Volume#%lu: %s [%s]", MTP_Handle->current_storage_unit,
+ MTP_Handle->info.storinfo[MTP_Handle->current_storage_unit].StorageDescription,
+ MTP_Handle->info.storinfo[MTP_Handle->current_storage_unit].VolumeLabel);
+ if(++MTP_Handle->current_storage_unit >= MTP_Handle->info.storids.n)
+ {
+ MTP_Handle->state = MTP_IDLE;
+ MTP_Handle->is_ready = 1;
+ MTP_Handle->current_storage_unit = 0;
+ MTP_Handle->params.CurrentStorageId = MTP_Handle->info.storids.Storage[0];
+
+ USBH_UsrLog( "MTP Class initialized.");
+ USBH_UsrLog("%s is default storage unit", MTP_Handle->info.storinfo[0].StorageDescription);
+ phost->pUser(phost, HOST_USER_CLASS_ACTIVE);
+ }
+ }
+ break;
+
+ case MTP_IDLE:
+ USBH_MTP_Events(phost);
+ default:
+ status = USBH_OK;
+ break;
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_MTP_SOFProcess
+ * The function is for managing SOF callback
+ * @param phost: Host handle
+ * @retval USBH Status
+ */
+static USBH_StatusTypeDef USBH_MTP_SOFProcess (USBH_HandleTypeDef *phost)
+{
+ USBH_StatusTypeDef status = USBH_OK;
+
+ return status;
+}
+
+/**
+ * @brief USBH_MTP_IsReady
+ * Select the storage Unit to be used
+ * @param phost: Host handle
+ * @retval USBH Status
+ */
+uint8_t USBH_MTP_IsReady (USBH_HandleTypeDef *phost)
+{
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+
+ return (MTP_Handle->is_ready);
+}
+
+/**
+ * @brief USBH_MTP_GetNumStorage
+ * Select the storage Unit to be used
+ * @param phost: Host handle
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_MTP_GetNumStorage (USBH_HandleTypeDef *phost, uint8_t *storage_num)
+{
+ USBH_StatusTypeDef status = USBH_FAIL;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+
+ if(MTP_Handle->is_ready > 0)
+ {
+ *storage_num = MTP_Handle->info.storids.n;
+ status = USBH_OK;
+ }
+
+ return status;
+}
+
+/**
+ * @brief USBH_MTP_SelectStorage
+ * Select the storage Unit to be used
+ * @param phost: Host handle
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_MTP_SelectStorage (USBH_HandleTypeDef *phost, uint8_t storage_idx)
+{
+ USBH_StatusTypeDef status = USBH_FAIL;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+
+ if((storage_idx < MTP_Handle->info.storids.n) && (MTP_Handle->is_ready))
+ {
+ MTP_Handle->params.CurrentStorageId = MTP_Handle->info.storids.Storage[storage_idx];
+ status = USBH_OK;
+ }
+
+ return status;
+}
+
+/**
+ * @brief USBH_MTP_GetStorageInfo
+ * Get the storage Unit info
+ * @param phost: Host handle
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_MTP_GetStorageInfo (USBH_HandleTypeDef *phost, uint8_t storage_idx, MTP_StorageInfoTypedef *info)
+{
+ USBH_StatusTypeDef status = USBH_FAIL;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+
+ if((storage_idx < MTP_Handle->info.storids.n) && (MTP_Handle->is_ready))
+ {
+ *info = MTP_Handle->info.storinfo[storage_idx];
+ status = USBH_OK;
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_MTP_GetStorageInfo
+ * Get the storage Unit info
+ * @param phost: Host handle
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_MTP_GetNumObjects (USBH_HandleTypeDef *phost,
+ uint32_t storage_idx,
+ uint32_t objectformatcode,
+ uint32_t associationOH,
+ uint32_t* numobs)
+{
+ USBH_StatusTypeDef status = USBH_FAIL;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint32_t timeout = phost->Timer + 5000;
+ if((storage_idx < MTP_Handle->info.storids.n) && (MTP_Handle->is_ready))
+ {
+ while ((status = USBH_PTP_GetNumObjects (phost,
+ MTP_Handle->info.storids.Storage[storage_idx],
+ objectformatcode,
+ associationOH,
+ numobs)) == USBH_BUSY)
+ {
+ if((phost->Timer > timeout) || (phost->device.is_connected == 0))
+ {
+ return USBH_FAIL;
+ }
+ }
+ }
+ return status;
+}
+
+
+/**
+ * @brief USBH_MTP_GetStorageInfo
+ * Get the storage Unit info
+ * @param phost: Host handle
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_MTP_GetObjectHandles (USBH_HandleTypeDef *phost,
+ uint32_t storage_idx,
+ uint32_t objectformatcode,
+ uint32_t associationOH,
+ PTP_ObjectHandlesTypedef* objecthandles)
+{
+ USBH_StatusTypeDef status = USBH_FAIL;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint32_t timeout = phost->Timer + 5000;
+
+ if((storage_idx < MTP_Handle->info.storids.n) && (MTP_Handle->is_ready))
+ {
+ while ((status = USBH_PTP_GetObjectHandles (phost,
+ MTP_Handle->info.storids.Storage[storage_idx],
+ objectformatcode,
+ associationOH,
+ objecthandles)) == USBH_BUSY)
+ {
+ if((phost->Timer > timeout) || (phost->device.is_connected == 0))
+ {
+ return USBH_FAIL;
+ }
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_PTP_GetObjectInfo
+ * Gets objert info
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_MTP_GetObjectInfo (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ PTP_ObjectInfoTypedef* objectinfo)
+{
+ USBH_StatusTypeDef status = USBH_FAIL;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint32_t timeout = phost->Timer + 5000;
+
+ if(MTP_Handle->is_ready)
+ {
+ while ((status = USBH_PTP_GetObjectInfo (phost, handle, objectinfo)) == USBH_BUSY)
+ {
+ if((phost->Timer > timeout) || (phost->device.is_connected == 0))
+ {
+ return USBH_FAIL;
+ }
+ }
+ }
+ return status;
+}
+/**
+ * @brief USBH_MTP_DeleteObject
+ * Delete an object.
+ * @param phost: Host handle
+ * @param handle : Object Handle
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_MTP_DeleteObject (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ uint32_t objectformatcode)
+{
+ USBH_StatusTypeDef status = USBH_FAIL;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint32_t timeout = phost->Timer + 5000;
+
+ if(MTP_Handle->is_ready)
+ {
+ while ((status = USBH_PTP_DeleteObject (phost, handle, objectformatcode)) == USBH_BUSY)
+ {
+ if((phost->Timer > timeout) || (phost->device.is_connected == 0))
+ {
+ return USBH_FAIL;
+ }
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_MTP_GetObject
+ * Gets object
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_MTP_GetObject (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ uint8_t *object)
+{
+ USBH_StatusTypeDef status = USBH_FAIL;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint32_t timeout = phost->Timer + 5000;
+
+ if(MTP_Handle->is_ready)
+ {
+ while ((status = USBH_PTP_GetObject (phost, handle, object)) == USBH_BUSY)
+ {
+ if((phost->Timer > timeout) || (phost->device.is_connected == 0))
+ {
+ return USBH_FAIL;
+ }
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_MTP_GetPartialObject
+ * Gets object
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_MTP_GetPartialObject(USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ uint32_t offset,
+ uint32_t maxbytes,
+ uint8_t *object,
+ uint32_t *len)
+{
+ USBH_StatusTypeDef status = USBH_FAIL;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint32_t timeout = phost->Timer + 5000;
+
+ if(MTP_Handle->is_ready)
+ {
+ while ((status = USBH_PTP_GetPartialObject(phost,
+ handle,
+ offset,
+ maxbytes,
+ object,
+ len)) == USBH_BUSY)
+ {
+ if((phost->Timer > timeout) || (phost->device.is_connected == 0))
+ {
+ return USBH_FAIL;
+ }
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_MTP_GetObjectPropsSupported
+ * Gets object partially
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_MTP_GetObjectPropsSupported (USBH_HandleTypeDef *phost,
+ uint16_t ofc,
+ uint32_t *propnum,
+ uint16_t *props)
+{
+ USBH_StatusTypeDef status = USBH_FAIL;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint32_t timeout = phost->Timer + 5000;
+
+ if(MTP_Handle->is_ready)
+ {
+ while ((status = USBH_PTP_GetObjectPropsSupported (phost,
+ ofc,
+ propnum,
+ props)) == USBH_BUSY)
+ {
+ if((phost->Timer > timeout) || (phost->device.is_connected == 0))
+ {
+ return USBH_FAIL;
+ }
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_MTP_GetObjectPropDesc
+ * Gets object partially
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_MTP_GetObjectPropDesc (USBH_HandleTypeDef *phost,
+ uint16_t opc,
+ uint16_t ofc,
+ PTP_ObjectPropDescTypeDef *opd)
+{
+ USBH_StatusTypeDef status = USBH_FAIL;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint32_t timeout = phost->Timer + 5000;
+
+ if(MTP_Handle->is_ready)
+ {
+ while ((status = USBH_PTP_GetObjectPropDesc (phost,
+ opc,
+ ofc,
+ opd)) == USBH_BUSY)
+ {
+ if((phost->Timer > timeout) || (phost->device.is_connected == 0))
+ {
+ return USBH_FAIL;
+ }
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_MTP_GetObjectPropList
+ * Gets object partially
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_MTP_GetObjectPropList (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ MTP_PropertiesTypedef *pprops,
+ uint32_t *nrofprops)
+{
+ USBH_StatusTypeDef status = USBH_FAIL;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint32_t timeout = phost->Timer + 5000;
+
+ if(MTP_Handle->is_ready)
+ {
+ while ((status = USBH_PTP_GetObjectPropList (phost,
+ handle,
+ pprops,
+ nrofprops)) == USBH_BUSY)
+ {
+ if((phost->Timer > timeout) || (phost->device.is_connected == 0))
+ {
+ return USBH_FAIL;
+ }
+ }
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_MTP_SendObject
+ * Send an object
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_MTP_SendObject (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ uint8_t *object,
+ uint32_t size)
+{
+ USBH_StatusTypeDef status = USBH_FAIL;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint32_t timeout = phost->Timer + 5000;
+
+ if(MTP_Handle->is_ready)
+ {
+ while ((status = USBH_PTP_SendObject (phost, handle, object, size)) == USBH_BUSY)
+ {
+ if((phost->Timer > timeout) || (phost->device.is_connected == 0))
+ {
+ return USBH_FAIL;
+ }
+ }
+ }
+ return status;
+}
+
+ /**
+ * @brief Handle HID Control process
+ * @param phost: Host handle
+ * @retval USBH Status
+ */
+static USBH_StatusTypeDef USBH_MTP_Events (USBH_HandleTypeDef *phost)
+{
+ USBH_StatusTypeDef status = USBH_BUSY ;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+
+
+ switch(MTP_Handle->events.state)
+ {
+ case MTP_EVENTS_INIT:
+ if((phost->Timer & 1) == 0)
+ {
+ MTP_Handle->events.timer = phost->Timer;
+ USBH_InterruptReceiveData(phost,
+ (uint8_t *)&(MTP_Handle->events.container),
+ MTP_Handle->NotificationEpSize,
+ MTP_Handle->NotificationPipe);
+
+
+ MTP_Handle->events.state = MTP_EVENTS_GETDATA ;
+ }
+ break;
+ case MTP_EVENTS_GETDATA:
+ if(USBH_LL_GetURBState(phost , MTP_Handle->NotificationPipe) == USBH_URB_DONE)
+ {
+ MTP_DecodeEvent(phost);
+ }
+
+ if(( phost->Timer - MTP_Handle->events.timer) >= MTP_Handle->events.poll)
+ {
+ MTP_Handle->events.timer = phost->Timer;
+
+ USBH_InterruptReceiveData(phost,
+ (uint8_t *)&(MTP_Handle->events.container),
+ MTP_Handle->NotificationEpSize,
+ MTP_Handle->NotificationPipe);
+
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return status;
+}
+
+/**
+ * @brief MTP_DecodeEvent
+ * Decode device event sent by responder
+ * @param phost: Host handle
+ * @retval None
+ */
+static void MTP_DecodeEvent (USBH_HandleTypeDef *phost)
+{
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+
+ uint16_t code;
+ uint32_t param1;
+
+ /* Process the event */
+ code = MTP_Handle->events.container.code;
+ param1 = MTP_Handle->events.container.param1;
+
+ switch(code)
+ {
+ case PTP_EC_Undefined:
+ USBH_DbgLog("EVT: PTP_EC_Undefined in session %u", MTP_Handle->ptp.session_id);
+ break;
+ case PTP_EC_CancelTransaction:
+ USBH_DbgLog("EVT: PTP_EC_CancelTransaction in session %u", MTP_Handle->ptp.session_id);
+ break;
+ case PTP_EC_ObjectAdded:
+ USBH_DbgLog("EVT: PTP_EC_ObjectAdded in session %u", MTP_Handle->ptp.session_id);
+ break;
+
+ case PTP_EC_ObjectRemoved:
+ USBH_DbgLog("EVT: PTP_EC_ObjectRemoved in session %u", MTP_Handle->ptp.session_id);
+ break;
+
+ case PTP_EC_StoreAdded:
+ USBH_DbgLog("EVT: PTP_EC_StoreAdded in session %u", MTP_Handle->ptp.session_id);
+ break;
+
+ case PTP_EC_StoreRemoved:
+ USBH_DbgLog("EVT: PTP_EC_StoreRemoved in session %u", MTP_Handle->ptp.session_id);
+ break;
+
+ case PTP_EC_DevicePropChanged:
+ USBH_DbgLog("EVT: PTP_EC_DevicePropChanged in session %u", MTP_Handle->ptp.session_id);
+ break;
+
+ case PTP_EC_ObjectInfoChanged:
+ USBH_DbgLog("EVT: PTP_EC_ObjectInfoChanged in session %u", MTP_Handle->ptp.session_id);
+ break;
+
+ case PTP_EC_DeviceInfoChanged:
+ USBH_DbgLog("EVT: PTP_EC_DeviceInfoChanged in session %u", MTP_Handle->ptp.session_id);
+ break;
+
+ case PTP_EC_RequestObjectTransfer:
+ USBH_DbgLog("EVT: PTP_EC_RequestObjectTransfer in session %u", MTP_Handle->ptp.session_id);
+ break;
+
+ case PTP_EC_StoreFull:
+ USBH_DbgLog("EVT: PTP_EC_StoreFull in session %u", MTP_Handle->ptp.session_id);
+ break;
+
+ case PTP_EC_DeviceReset:
+ USBH_DbgLog("EVT: PTP_EC_DeviceReset in session %u", MTP_Handle->ptp.session_id);
+ break;
+
+ case PTP_EC_StorageInfoChanged :
+ USBH_DbgLog( "EVT: PTP_EC_StorageInfoChanged in session %u", MTP_Handle->ptp.session_id);
+ break;
+
+ case PTP_EC_CaptureComplete :
+ USBH_DbgLog( "EVT: PTP_EC_CaptureComplete in session %u", MTP_Handle->ptp.session_id);
+ break;
+
+ case PTP_EC_UnreportedStatus :
+ USBH_DbgLog( "EVT: PTP_EC_UnreportedStatus in session %u", MTP_Handle->ptp.session_id);
+ break;
+
+ default :
+ USBH_DbgLog( "Received unknown event in session %u", MTP_Handle->ptp.session_id);
+ break;
+ }
+
+ USBH_MTP_EventsCallback(phost, code, param1);
+}
+
+/**
+ * @brief USBH_MTP_GetDevicePropDesc
+ * Gets object partially
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_MTP_GetDevicePropDesc (USBH_HandleTypeDef *phost,
+ uint16_t propcode,
+ PTP_DevicePropDescTypdef* devicepropertydesc)
+
+{
+ USBH_StatusTypeDef status = USBH_FAIL;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint32_t timeout = phost->Timer + 5000;
+
+ if(MTP_Handle->is_ready)
+ {
+ while ((status = USBH_PTP_GetDevicePropDesc (phost, propcode, devicepropertydesc)) == USBH_BUSY)
+ {
+ if((phost->Timer > timeout) || (phost->device.is_connected == 0))
+ {
+ return USBH_FAIL;
+ }
+ }
+ }
+ return status;
+}
+/**
+ * @brief The function informs that host has rceived an event
+ * @param pdev: Selected device
+ * @retval None
+ */
+__weak void USBH_MTP_EventsCallback(USBH_HandleTypeDef *phost, uint32_t event, uint32_t param)
+{
+
+}
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/stmhal/usbhost/Class/MTP/Src/usbh_mtp_ptp.c b/stmhal/usbhost/Class/MTP/Src/usbh_mtp_ptp.c new file mode 100644 index 000000000..dd5a293e6 --- /dev/null +++ b/stmhal/usbhost/Class/MTP/Src/usbh_mtp_ptp.c @@ -0,0 +1,1769 @@ +/**
+ ******************************************************************************
+ * @file usbh_mtp_ptp.c
+ * @author MCD Application Team
+ * @version V3.0.0
+ * @date 18-February-2014
+ * @brief This file includes the PTP operations layer
+ ******************************************************************************
+ * @attention
+ *
+ * <h2><center>© COPYRIGHT 2014 STMicroelectronics</center></h2>
+ *
+ * Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
+ *
+ * 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.
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "usbh_mtp_ptp.h"
+#include "usbh_mtp.h"
+/** @addtogroup USBH_LIB
+* @{
+*/
+
+/** @addtogroup USBH_CLASS
+* @{
+*/
+
+/** @addtogroup USBH_MTP_CLASS
+* @{
+*/
+
+/** @defgroup USBH_MTP_PTP
+* @brief This file includes the mass storage related functions
+* @{
+*/
+
+
+/** @defgroup USBH_MTP_PTP_Private_TypesDefinitions
+* @{
+*/
+/**
+* @}
+*/
+
+/** @defgroup USBH_MTP_PTP_Private_Defines
+* @{
+*/
+/**
+* @}
+*/
+
+/** @defgroup USBH_MTP_PTP_Private_Macros
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_MTP_PTP_Private_Variables
+* @{
+*/
+
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_MTP_PTP_Private_FunctionPrototypes
+* @{
+*/
+static void PTP_DecodeDeviceInfo (USBH_HandleTypeDef *phost, PTP_DeviceInfoTypedef *dev_info);
+static void PTP_GetStorageIDs (USBH_HandleTypeDef *phost, PTP_StorageIDsTypedef *stor_ids);
+static void PTP_GetStorageInfo (USBH_HandleTypeDef *phost, uint32_t storage_id, PTP_StorageInfoTypedef *stor_info);
+static void PTP_GetObjectPropDesc (USBH_HandleTypeDef *phost, PTP_ObjectPropDescTypeDef *opd, uint32_t opdlen);
+static void PTP_DecodeDeviceInfo (USBH_HandleTypeDef *phost, PTP_DeviceInfoTypedef *dev_info);
+static void PTP_GetDevicePropValue(USBH_HandleTypeDef *phost,
+ uint32_t *offset,
+ uint32_t total,
+ PTP_PropertyValueTypedef* value,
+ uint16_t datatype);
+
+static uint32_t PTP_GetObjectPropList (USBH_HandleTypeDef *phost,
+ MTP_PropertiesTypedef *props,
+ uint32_t len);
+
+
+static void PTP_BufferFullCallback(USBH_HandleTypeDef *phost);
+static void PTP_GetString(uint8_t *str, uint8_t* data, uint16_t *len);
+static uint32_t PTP_GetArray16 (uint16_t *array, uint8_t *data, uint32_t offset);
+static uint32_t PTP_GetArray32 (uint32_t *array, uint8_t *data, uint32_t offset);
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_MTP_PTP_Exported_Variables
+* @{
+*/
+/**
+* @}
+*/
+
+
+/** @defgroup USBH_MTP_PTP_Private_Functions
+* @{
+*/
+/**
+ * @brief USBH_PTP_Init
+ * The function Initializes the BOT protocol.
+ * @param phost: Host handle
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_Init(USBH_HandleTypeDef *phost)
+{
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+
+ /* Set state to idle to be ready for operations */
+ MTP_Handle->ptp.state = PTP_IDLE;
+ MTP_Handle->ptp.req_state = PTP_REQ_SEND;
+
+ return USBH_OK;
+}
+
+/**
+ * @brief USBH_PTP_Process
+ * The function handle the BOT protocol.
+ * @param phost: Host handle
+ * @param lun: Logical Unit Number
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_Process (USBH_HandleTypeDef *phost)
+{
+ USBH_StatusTypeDef status = USBH_BUSY;
+ USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ PTP_ContainerTypedef ptp_container;
+ uint32_t len;
+
+ switch (MTP_Handle->ptp.state)
+ {
+ case PTP_IDLE:
+ /*Do Nothing */
+ break;
+
+ case PTP_OP_REQUEST_STATE:
+ USBH_BulkSendData (phost,
+ (uint8_t*)&(MTP_Handle->ptp.op_container),
+ MTP_Handle->ptp.op_container.length,
+ MTP_Handle->DataOutPipe,
+ 1);
+ MTP_Handle->ptp.state = PTP_OP_REQUEST_WAIT_STATE;
+ break;
+
+ case PTP_OP_REQUEST_WAIT_STATE:
+ URB_Status = USBH_LL_GetURBState(phost, MTP_Handle->DataOutPipe);
+
+ if(URB_Status == USBH_URB_DONE)
+ {
+ if(MTP_Handle->ptp.flags == PTP_DP_NODATA)
+ {
+ MTP_Handle->ptp.state = PTP_RESPONSE_STATE;
+ }
+ else if(MTP_Handle->ptp.flags == PTP_DP_SENDDATA)
+ {
+ MTP_Handle->ptp.state = PTP_DATA_OUT_PHASE_STATE;
+ }
+ else if(MTP_Handle->ptp.flags == PTP_DP_GETDATA)
+ {
+ MTP_Handle->ptp.state = PTP_DATA_IN_PHASE_STATE;
+ }
+#if (USBH_USE_OS == 1)
+ osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
+#endif
+ }
+ else if(URB_Status == USBH_URB_NOTREADY)
+ {
+ /* Re-send Request */
+ MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
+#if (USBH_USE_OS == 1)
+ osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
+#endif
+ }
+ else if(URB_Status == USBH_URB_STALL)
+ {
+ MTP_Handle->ptp.state = PTP_ERROR;
+#if (USBH_USE_OS == 1)
+ osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
+#endif
+ }
+ break;
+
+ case PTP_DATA_OUT_PHASE_STATE:
+
+ USBH_BulkSendData (phost,
+ MTP_Handle->ptp.data_ptr,
+ MTP_Handle->DataOutEpSize ,
+ MTP_Handle->DataOutPipe,
+ 1);
+
+
+ MTP_Handle->ptp.state = PTP_DATA_OUT_PHASE_WAIT_STATE;
+ break;
+
+ case PTP_DATA_OUT_PHASE_WAIT_STATE:
+ URB_Status = USBH_LL_GetURBState(phost, MTP_Handle->DataOutPipe);
+
+ if(URB_Status == USBH_URB_DONE)
+ {
+ /* Adjudt Data pointer and data length */
+ if(MTP_Handle->ptp.data_length > MTP_Handle->DataOutEpSize)
+ {
+ MTP_Handle->ptp.data_ptr += MTP_Handle->DataOutEpSize;
+ MTP_Handle->ptp.data_length -= MTP_Handle->DataOutEpSize;
+ MTP_Handle->ptp.data_packet += MTP_Handle->DataOutEpSize;
+
+ if(MTP_Handle->ptp.data_packet >= PTP_USB_BULK_PAYLOAD_LEN_READ)
+ {
+ PTP_BufferFullCallback (phost);
+ MTP_Handle->ptp.data_packet = 0;
+ MTP_Handle->ptp.iteration++;
+ }
+
+ }
+ else
+ {
+ MTP_Handle->ptp.data_length = 0;
+ }
+
+ /* More Data To be Sent */
+ if(MTP_Handle->ptp.data_length > 0)
+ {
+ USBH_BulkSendData (phost,
+ MTP_Handle->ptp.data_ptr,
+ MTP_Handle->DataOutEpSize ,
+ MTP_Handle->DataOutPipe,
+ 1);
+ }
+ else
+ {
+ /* If value was 0, and successful transfer, then change the state */
+ MTP_Handle->ptp.state = PTP_RESPONSE_STATE;
+ }
+#if (USBH_USE_OS == 1)
+ osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
+#endif
+ }
+
+ else if(URB_Status == USBH_URB_NOTREADY)
+ {
+ /* Re-send same data */
+ MTP_Handle->ptp.state = PTP_DATA_OUT_PHASE_STATE;
+#if (USBH_USE_OS == 1)
+ osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
+#endif
+ }
+
+ else if(URB_Status == USBH_URB_STALL)
+ {
+ MTP_Handle->ptp.state = PTP_ERROR;
+#if (USBH_USE_OS == 1)
+ osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
+#endif
+ }
+ break;
+
+ case PTP_DATA_IN_PHASE_STATE:
+ /* Send first packet */
+ USBH_BulkReceiveData (phost,
+ MTP_Handle->ptp.data_ptr,
+ MTP_Handle->DataInEpSize,
+ MTP_Handle->DataInPipe);
+
+ MTP_Handle->ptp.state = PTP_DATA_IN_PHASE_WAIT_STATE;
+ break;
+
+ case PTP_DATA_IN_PHASE_WAIT_STATE:
+ URB_Status = USBH_LL_GetURBState(phost, MTP_Handle->DataInPipe);
+
+ if(URB_Status == USBH_URB_DONE)
+ {
+ len = USBH_LL_GetLastXferSize (phost, MTP_Handle->DataInPipe);
+
+ if( MTP_Handle->ptp.data_packet_counter++ == 0)
+ {
+ /* This is the first packet; so retrieve exact data length from payload */
+ MTP_Handle->ptp.data_length = *(uint32_t*)(MTP_Handle->ptp.data_ptr);
+ MTP_Handle->ptp.iteration = 0;
+ }
+
+ if((len >= MTP_Handle->DataInEpSize) && (MTP_Handle->ptp.data_length > 0))
+ {
+ MTP_Handle->ptp.data_ptr += len;
+ MTP_Handle->ptp.data_length -= len;
+ MTP_Handle->ptp.data_packet += len;
+
+ if(MTP_Handle->ptp.data_packet >= PTP_USB_BULK_PAYLOAD_LEN_READ)
+ {
+ PTP_BufferFullCallback (phost);
+ MTP_Handle->ptp.data_packet = 0;
+ MTP_Handle->ptp.iteration++;
+ }
+
+ /* Continue receiving data*/
+ USBH_BulkReceiveData (phost,
+ MTP_Handle->ptp.data_ptr,
+ MTP_Handle->DataInEpSize,
+ MTP_Handle->DataInPipe);
+ }
+ else
+ {
+ MTP_Handle->ptp.data_length -= len;
+ MTP_Handle->ptp.state = PTP_RESPONSE_STATE;
+#if (USBH_USE_OS == 1)
+ osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
+#endif
+ }
+ }
+ else if(URB_Status == USBH_URB_STALL)
+ {
+ MTP_Handle->ptp.state = PTP_ERROR;
+#if (USBH_USE_OS == 1)
+ osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
+#endif
+ }
+ break;
+
+ case PTP_RESPONSE_STATE:
+
+ USBH_BulkReceiveData (phost,
+ (uint8_t*)&(MTP_Handle->ptp.resp_container),
+ PTP_USB_BULK_REQ_RESP_MAX_LEN ,
+ MTP_Handle->DataInPipe);
+
+ MTP_Handle->ptp.state = PTP_RESPONSE_WAIT_STATE;
+ break;
+
+ case PTP_RESPONSE_WAIT_STATE:
+ URB_Status = USBH_LL_GetURBState(phost, MTP_Handle->DataInPipe);
+
+ if(URB_Status == USBH_URB_DONE)
+ {
+ USBH_PTP_GetResponse (phost, &ptp_container);
+
+ if(ptp_container.Code == PTP_RC_OK)
+ {
+ status = USBH_OK;
+ }
+ else
+ {
+ status = USBH_FAIL;
+ }
+ MTP_Handle->ptp.req_state = PTP_REQ_SEND;
+ }
+ else if(URB_Status == USBH_URB_STALL)
+ {
+ MTP_Handle->ptp.state = PTP_ERROR;
+#if (USBH_USE_OS == 1)
+ osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
+#endif
+ }
+ break;
+
+ case PTP_ERROR:
+ MTP_Handle->ptp.req_state = PTP_REQ_SEND;
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_PTP_OpenSession
+ * Open a new session
+ * @param phost: Host handle
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_SendRequest (USBH_HandleTypeDef *phost, PTP_ContainerTypedef *req)
+{
+ USBH_StatusTypeDef status = USBH_OK;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+
+ /* Clear PTP Data container*/
+ USBH_memset(&(MTP_Handle->ptp.op_container), 0, sizeof(PTP_OpContainerTypedef));
+
+ /* build appropriate USB container */
+ MTP_Handle->ptp.op_container.length = PTP_USB_BULK_REQ_LEN- (sizeof(uint32_t)*(5-req->Nparam));
+ MTP_Handle->ptp.op_container.type = PTP_USB_CONTAINER_COMMAND;
+ MTP_Handle->ptp.op_container.code = req->Code;
+ MTP_Handle->ptp.op_container.trans_id = req->Transaction_ID;
+ MTP_Handle->ptp.op_container.param1 = req->Param1;
+ MTP_Handle->ptp.op_container.param2 = req->Param2;
+ MTP_Handle->ptp.op_container.param3 = req->Param3;
+ MTP_Handle->ptp.op_container.param4 = req->Param4;
+ MTP_Handle->ptp.op_container.param5 = req->Param5;
+
+ return status;
+}
+
+/**
+ * @brief USBH_PTP_OpenSession
+ * Open a new session
+ * @param phost: Host handle
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_GetResponse (USBH_HandleTypeDef *phost, PTP_ContainerTypedef *resp)
+{
+ USBH_StatusTypeDef status = USBH_OK;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+
+ /* build an appropriate PTPContainer */
+ resp->Code = MTP_Handle->ptp.resp_container.code;
+ resp->SessionID = MTP_Handle->ptp.session_id;
+ resp->Transaction_ID = MTP_Handle->ptp.resp_container.trans_id;
+ resp->Param1 = MTP_Handle->ptp.resp_container.param1;
+ resp->Param2 = MTP_Handle->ptp.resp_container.param2;
+ resp->Param3 = MTP_Handle->ptp.resp_container.param3;
+ resp->Param4 = MTP_Handle->ptp.resp_container.param4;
+ resp->Param5 = MTP_Handle->ptp.resp_container.param5;
+
+ return status;
+}
+
+/**
+ * @brief The function informs user that data buffer is full
+ * @param phost: host handle
+ * @retval None
+ */
+void PTP_BufferFullCallback(USBH_HandleTypeDef *phost)
+{
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+
+ switch (MTP_Handle->ptp.data_container.code)
+ {
+ case PTP_OC_GetDeviceInfo:
+ PTP_DecodeDeviceInfo (phost, &(MTP_Handle->info.devinfo));
+ break;
+
+ case PTP_OC_GetPartialObject:
+ case PTP_OC_GetObject:
+
+ /* first packet is in the PTP data payload buffer */
+ if(MTP_Handle->ptp.iteration == 0)
+ {
+ /* copy it to object */
+ USBH_memcpy(MTP_Handle->ptp.object_ptr, MTP_Handle->ptp.data_container.payload.data, PTP_USB_BULK_PAYLOAD_LEN_READ);
+
+ /* next packet should be directly copied to object */
+ MTP_Handle->ptp.data_ptr = (MTP_Handle->ptp.object_ptr + PTP_USB_BULK_PAYLOAD_LEN_READ);
+ }
+ break;
+
+ case PTP_OC_SendObject:
+ /* first packet is in the PTP data payload buffer */
+ if(MTP_Handle->ptp.iteration == 0)
+ {
+ /* next packet should be directly copied to object */
+ MTP_Handle->ptp.data_ptr = (MTP_Handle->ptp.object_ptr + PTP_USB_BULK_PAYLOAD_LEN_READ);
+ }
+ break;
+
+ default:
+ break;
+
+
+ }
+}
+
+/**
+ * @brief PTP_GetDeviceInfo
+ * Gets device info dataset and fills deviceinfo structure.
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval None
+ */
+static void PTP_DecodeDeviceInfo (USBH_HandleTypeDef *phost, PTP_DeviceInfoTypedef *dev_info)
+{
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint8_t *data = MTP_Handle->ptp.data_container.payload.data;
+ uint32_t totallen;
+ uint16_t len;
+
+ /* Max device info is PTP_USB_BULK_HS_MAX_PACKET_LEN_READ */
+ USBH_DbgLog (" MTP device info size exceeds internal buffer size.\
+ only available data are decoded.");
+
+ if(MTP_Handle->ptp.iteration == 0)
+ {
+ dev_info->StandardVersion = LE16(&data[PTP_di_StandardVersion]);
+ dev_info->VendorExtensionID = LE32(&data[PTP_di_VendorExtensionID]);
+ dev_info->VendorExtensionVersion = LE16(&data[PTP_di_VendorExtensionVersion]);
+ PTP_GetString(dev_info->VendorExtensionDesc, &data[PTP_di_VendorExtensionDesc], &len);
+
+ totallen=len*2+1;
+ dev_info->FunctionalMode = LE16(&data[PTP_di_FunctionalMode+totallen]);
+ dev_info->OperationsSupported_len = PTP_GetArray16 ((uint16_t *)&dev_info->OperationsSupported,
+ data,
+ PTP_di_OperationsSupported+totallen);
+
+ totallen=totallen+dev_info->OperationsSupported_len*sizeof(uint16_t)+sizeof(uint32_t);
+ dev_info->EventsSupported_len = PTP_GetArray16 ((uint16_t *)&dev_info->EventsSupported,
+ data,
+ PTP_di_OperationsSupported+totallen);
+
+ totallen=totallen+dev_info->EventsSupported_len*sizeof(uint16_t)+sizeof(uint32_t);
+ dev_info->DevicePropertiesSupported_len = PTP_GetArray16 ((uint16_t *)&dev_info->DevicePropertiesSupported,
+ data,
+ PTP_di_OperationsSupported+totallen);
+
+ totallen=totallen+dev_info->DevicePropertiesSupported_len*sizeof(uint16_t)+sizeof(uint32_t);
+
+ dev_info->CaptureFormats_len = PTP_GetArray16 ((uint16_t *)&dev_info->CaptureFormats,
+ data,
+ PTP_di_OperationsSupported+totallen);
+
+ totallen=totallen+dev_info->CaptureFormats_len*sizeof(uint16_t)+sizeof(uint32_t);
+ dev_info->ImageFormats_len = PTP_GetArray16 ((uint16_t *)&dev_info->ImageFormats,
+ data,
+ PTP_di_OperationsSupported+totallen);
+
+ totallen=totallen+dev_info->ImageFormats_len*sizeof(uint16_t)+sizeof(uint32_t);
+ PTP_GetString(dev_info->Manufacturer, &data[PTP_di_OperationsSupported+totallen], &len);
+
+ totallen+=len*2+1;
+ PTP_GetString(dev_info->Model, &data[PTP_di_OperationsSupported+totallen], &len);
+
+ totallen+=len*2+1;
+ PTP_GetString(dev_info->DeviceVersion, &data[PTP_di_OperationsSupported+totallen], &len);
+
+ totallen+=len*2+1;
+ PTP_GetString(dev_info->SerialNumber, &data[PTP_di_OperationsSupported+totallen], &len);
+ }
+}
+
+/**
+ * @brief PTP_GetStorageIDs
+ * Gets Storage Ids and fills stor_ids structure.
+ * @param phost: Host handle
+ * @param stor_ids: Storage IDsstructure
+ * @retval None
+ */
+static void PTP_GetStorageIDs (USBH_HandleTypeDef *phost, PTP_StorageIDsTypedef *stor_ids)
+{
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint8_t *data = MTP_Handle->ptp.data_container.payload.data;
+
+ stor_ids->n = PTP_GetArray32 (stor_ids->Storage, data, 0);
+}
+
+
+/**
+ * @brief PTP_GetStorageInfo
+ * Gets Storage Info and fills stor_info structure.
+ * @param phost: Host handle
+ * @param stor_ids: Storage IDsstructure
+ * @retval None
+ */
+static void PTP_GetStorageInfo (USBH_HandleTypeDef *phost, uint32_t storage_id, PTP_StorageInfoTypedef *stor_info)
+{
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint8_t *data = MTP_Handle->ptp.data_container.payload.data;
+
+ uint16_t len;
+
+ stor_info->StorageType=LE16(&data[PTP_si_StorageType]);
+ stor_info->FilesystemType=LE16(&data[PTP_si_FilesystemType]);
+ stor_info->AccessCapability=LE16(&data[PTP_si_AccessCapability]);
+ stor_info->MaxCapability=LE64(&data[PTP_si_MaxCapability]);
+ stor_info->FreeSpaceInBytes=LE64(&data[PTP_si_FreeSpaceInBytes]);
+ stor_info->FreeSpaceInImages=LE32(&data[PTP_si_FreeSpaceInImages]);
+
+ PTP_GetString(stor_info->StorageDescription, &data[PTP_si_StorageDescription], &len);
+ PTP_GetString(stor_info->VolumeLabel, &data[PTP_si_StorageDescription+len*2+1], &len);
+}
+
+/**
+ * @brief PTP_GetObjectInfo
+ * Gets objectInfo and fills object_info structure.
+ * @param phost: Host handle
+ * @param object_info: object info structure
+ * @retval None
+ */
+static void PTP_GetObjectInfo (USBH_HandleTypeDef *phost, PTP_ObjectInfoTypedef *object_info)
+{
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint8_t *data = MTP_Handle->ptp.data_container.payload.data;
+ uint16_t filenamelen;
+
+ object_info->StorageID=LE32(&data[PTP_oi_StorageID]);
+ object_info->ObjectFormat=LE16(&data[PTP_oi_ObjectFormat]);
+ object_info->ProtectionStatus=LE16(&data[PTP_oi_ProtectionStatus]);
+ object_info->ObjectCompressedSize=LE32(&data[PTP_oi_ObjectCompressedSize]);
+
+ /* For Samsung Galaxy */
+ if ((data[PTP_oi_filenamelen] == 0) && (data[PTP_oi_filenamelen+4] != 0))
+ {
+ data += 4;
+ }
+ object_info->ThumbFormat=LE16(&data[PTP_oi_ThumbFormat]);
+ object_info->ThumbCompressedSize=LE32(&data[PTP_oi_ThumbCompressedSize]);
+ object_info->ThumbPixWidth=LE32(&data[PTP_oi_ThumbPixWidth]);
+ object_info->ThumbPixHeight=LE32(&data[PTP_oi_ThumbPixHeight]);
+ object_info->ImagePixWidth=LE32(&data[PTP_oi_ImagePixWidth]);
+ object_info->ImagePixHeight=LE32(&data[PTP_oi_ImagePixHeight]);
+ object_info->ImageBitDepth=LE32(&data[PTP_oi_ImageBitDepth]);
+ object_info->ParentObject=LE32(&data[PTP_oi_ParentObject]);
+ object_info->AssociationType=LE16(&data[PTP_oi_AssociationType]);
+ object_info->AssociationDesc=LE32(&data[PTP_oi_AssociationDesc]);
+ object_info->SequenceNumber=LE32(&data[PTP_oi_SequenceNumber]);
+ PTP_GetString(object_info->Filename, &data[PTP_oi_filenamelen], &filenamelen);
+}
+
+
+/**
+ * @brief PTP_GetObjectPropDesc
+ * Gets objectInfo and fills object_info structure.
+ * @param phost: Host handle
+ * @param opd: object prop descriptor structure
+ * @retval None
+ */
+static void PTP_GetObjectPropDesc (USBH_HandleTypeDef *phost, PTP_ObjectPropDescTypeDef *opd, uint32_t opdlen)
+{
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint8_t *data = MTP_Handle->ptp.data_container.payload.data;
+ uint32_t offset = 0, i;
+
+ opd->ObjectPropertyCode=LE16(&data[PTP_opd_ObjectPropertyCode]);
+ opd->DataType=LE16(&data[PTP_opd_DataType]);
+ opd->GetSet=*(uint8_t *)(&data[PTP_opd_GetSet]);
+
+ offset = PTP_opd_FactoryDefaultValue;
+ PTP_GetDevicePropValue (phost, &offset, opdlen, &opd->FactoryDefaultValue, opd->DataType);
+
+ opd->GroupCode=LE32(&data[offset]);
+ offset+=sizeof(uint32_t);
+
+ opd->FormFlag=*(uint8_t *)(&data[offset]);
+ offset+=sizeof(uint8_t);
+
+ switch (opd->FormFlag)
+ {
+ case PTP_OPFF_Range:
+ PTP_GetDevicePropValue(phost, &offset, opdlen, &opd->FORM.Range.MinimumValue, opd->DataType);
+ PTP_GetDevicePropValue(phost, &offset, opdlen, &opd->FORM.Range.MaximumValue, opd->DataType);
+ PTP_GetDevicePropValue(phost, &offset, opdlen, &opd->FORM.Range.StepSize, opd->DataType);
+ break;
+
+ case PTP_OPFF_Enumeration:
+
+ opd->FORM.Enum.NumberOfValues = LE16(&data[offset]);
+ offset+=sizeof(uint16_t);
+
+ for (i=0 ; i < opd->FORM.Enum.NumberOfValues ; i++)
+ {
+ PTP_GetDevicePropValue(phost, &offset, opdlen, &opd->FORM.Enum.SupportedValue[i], opd->DataType);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief PTP_GetDevicePropValue
+ * Gets objectInfo and fills object_info structure.
+ * @param phost: Host handle
+ * @param opd: object prop descriptor structure
+ * @retval None
+ */
+static void PTP_GetDevicePropValue(USBH_HandleTypeDef *phost,
+ uint32_t *offset,
+ uint32_t total,
+ PTP_PropertyValueTypedef* value,
+ uint16_t datatype)
+{
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint8_t *data = MTP_Handle->ptp.data_container.payload.data;
+ uint16_t len;
+ switch (datatype)
+ {
+ case PTP_DTC_INT8:
+ value->i8 = *(uint8_t *)&(data[*offset]);
+ *offset += 1;
+ break;
+ case PTP_DTC_UINT8:
+ value->u8 = *(uint8_t *)&(data[*offset]);
+ *offset += 1;
+ break;
+ case PTP_DTC_INT16:
+
+ value->i16 = LE16(&(data[*offset]));
+ *offset += 2;
+ break;
+ case PTP_DTC_UINT16:
+ value->u16 = LE16(&(data[*offset]));
+ *offset += 2;
+ break;
+ case PTP_DTC_INT32:
+ value->i32 = LE32(&(data[*offset]));
+ *offset += 4;
+ break;
+ case PTP_DTC_UINT32:
+ value->u32 = LE32(&(data[*offset]));
+ *offset += 4;
+ break;
+ case PTP_DTC_INT64:
+ value->i64 = LE64(&(data[*offset]));
+ *offset += 8;
+ break;
+ case PTP_DTC_UINT64:
+ value->u64 = LE64(&(data[*offset]));
+ *offset += 8;
+ break;
+
+ case PTP_DTC_UINT128:
+ *offset += 16;
+ break;
+ case PTP_DTC_INT128:
+ *offset += 16;
+ break;
+
+ case PTP_DTC_STR:
+
+ PTP_GetString((uint8_t *)value->str, (uint8_t *)&(data[*offset]), &len);
+ *offset += len*2+1;
+ break;
+ default:
+ break;
+ }
+}
+
+
+/**
+ * @brief PTP_GetDevicePropValue
+ * Gets objectInfo and fills object_info structure.
+ * @param phost: Host handle
+ * @param opd: object prop descriptor structure
+ * @retval None
+ */
+static uint32_t PTP_GetObjectPropList (USBH_HandleTypeDef *phost,
+ MTP_PropertiesTypedef *props,
+ uint32_t len)
+{
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ uint8_t *data = MTP_Handle->ptp.data_container.payload.data;
+ uint32_t prop_count;
+ uint32_t offset = 0, i;
+
+ prop_count = LE32(data);
+
+
+ if (prop_count == 0)
+ {
+ return 0;
+ }
+
+ data += sizeof(uint32_t);
+ len -= sizeof(uint32_t);
+
+ for (i = 0; i < prop_count; i++)
+ {
+ if (len <= 0)
+ {
+ return 0;
+ }
+
+ props[i].ObjectHandle = LE32(data);
+ data += sizeof(uint32_t);
+ len -= sizeof(uint32_t);
+
+ props[i].property = LE16(data);
+ data += sizeof(uint16_t);
+ len -= sizeof(uint16_t);
+
+ props[i].datatype = LE16(data);
+ data += sizeof(uint16_t);
+ len -= sizeof(uint16_t);
+
+ offset = 0;
+
+ PTP_GetDevicePropValue(phost, &offset, len, &props[i].propval, props[i].datatype);
+
+ data += offset;
+ len -= offset;
+ }
+
+ return prop_count;
+}
+
+/**
+ * @brief PTP_GetString
+ * Gets SCII String from.
+ * @param str: ascii string
+ * @param data: Device info structure
+ * @retval None
+ */
+static void PTP_GetString (uint8_t *str, uint8_t* data, uint16_t *len)
+{
+ uint16_t strlength;
+ uint16_t idx;
+
+ *len = data[0];
+ strlength = 2 * data[0];
+ data ++; /* Adjust the offset ignoring the String Len */
+
+ for (idx = 0; idx < strlength; idx+=2 )
+ {
+ /* Copy Only the string and ignore the UNICODE ID, hence add the src */
+ *str = data[idx];
+ str++;
+ }
+ *str = 0; /* mark end of string */
+}
+
+/**
+ * @brief PTP_GetString
+ * Gets SCII String from.
+ * @param str: ascii string
+ * @param data: Device info structure
+ * @retval None
+ */
+
+static uint32_t PTP_GetArray16 (uint16_t *array, uint8_t *data, uint32_t offset)
+{
+ uint32_t size, idx = 0;
+
+ size=LE32(&data[offset]);
+ while (size > idx)
+ {
+ array[idx] = LE16(&data[offset+(sizeof(uint16_t)*(idx+2))]);
+ idx++;
+ }
+ return size;
+}
+
+/**
+ * @brief PTP_GetString
+ * Gets SCII String from.
+ * @param str: ascii string
+ * @param data: Device info structure
+ * @retval None
+ */
+
+static uint32_t PTP_GetArray32 (uint32_t *array, uint8_t *data, uint32_t offset)
+{
+ uint32_t size, idx = 0;
+
+ size=LE32(&data[offset]);
+ while (size > idx)
+ {
+ array[idx] = LE32(&data[offset+(sizeof(uint32_t)*(idx+1))]);
+ idx++;
+ }
+ return size;
+}
+
+/*******************************************************************************
+
+ PTP Requests
+
+*******************************************************************************/
+/**
+ * @brief USBH_PTP_OpenSession
+ * Open a new session
+ * @param phost: Host handle
+ * @param session: Session ID (MUST BE > 0)
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_OpenSession (USBH_HandleTypeDef *phost, uint32_t session)
+{
+ USBH_StatusTypeDef status = USBH_BUSY;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ PTP_ContainerTypedef ptp_container;
+
+ switch(MTP_Handle->ptp.req_state)
+ {
+ case PTP_REQ_SEND:
+
+ /* Init session params */
+ MTP_Handle->ptp.transaction_id = 0x00000000;
+ MTP_Handle->ptp.session_id = session;
+ MTP_Handle->ptp.flags = PTP_DP_NODATA;
+
+ /* Fill operation request params */
+ ptp_container.Code = PTP_OC_OpenSession;
+ ptp_container.SessionID = session;
+ ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
+ ptp_container.Param1 = session;
+ ptp_container.Nparam = 1;
+
+ /* convert request packet inti USB raw packet*/
+ USBH_PTP_SendRequest (phost, &ptp_container);
+
+ /* Setup State machine and start transfer */
+ MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
+ MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
+ status = USBH_BUSY;
+ break;
+
+ case PTP_REQ_WAIT:
+ status = USBH_PTP_Process(phost);
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_PTP_GetDevicePropDesc
+ * Gets object partially
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_GetDevicePropDesc (USBH_HandleTypeDef *phost,
+ uint16_t propcode,
+ PTP_DevicePropDescTypdef* devicepropertydesc)
+{
+ USBH_StatusTypeDef status = USBH_BUSY;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ PTP_ContainerTypedef ptp_container;
+ uint8_t *data = MTP_Handle->ptp.data_container.payload.data;
+ switch(MTP_Handle->ptp.req_state)
+ {
+ case PTP_REQ_SEND:
+
+ /* Set operation request type */
+ MTP_Handle->ptp.flags = PTP_DP_GETDATA;
+ MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
+ MTP_Handle->ptp.data_length = 0;
+ MTP_Handle->ptp.data_packet_counter = 0;
+ MTP_Handle->ptp.data_packet = 0;
+
+ /* Fill operation request params */
+ ptp_container.Code = PTP_OC_GetDevicePropDesc;
+ ptp_container.SessionID = MTP_Handle->ptp.session_id;
+ ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
+ ptp_container.Param1 = propcode;
+ ptp_container.Nparam = 1;
+
+ /* convert request packet into USB raw packet*/
+ USBH_PTP_SendRequest (phost, &ptp_container);
+
+ /* Setup State machine and start transfer */
+ MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
+ MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
+ status = USBH_BUSY;
+ break;
+
+ case PTP_REQ_WAIT:
+ status = USBH_PTP_Process(phost);
+
+ if(status == USBH_OK)
+ {
+ devicepropertydesc->DevicePropertyCode = LE16(&data[PTP_dpd_DevicePropertyCode]);
+ devicepropertydesc->DataType = LE16(&data[PTP_dpd_DataType]);
+ devicepropertydesc->GetSet = *(uint8_t *)(&data[PTP_dpd_GetSet]);
+ devicepropertydesc->FormFlag = PTP_DPFF_None;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+/**
+ * @brief USBH_PTP_GetDeviceInfo
+ * Gets device info dataset and fills deviceinfo structure.
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_GetDeviceInfo (USBH_HandleTypeDef *phost, PTP_DeviceInfoTypedef *dev_info)
+{
+ USBH_StatusTypeDef status = USBH_BUSY;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ PTP_ContainerTypedef ptp_container;
+
+ switch(MTP_Handle->ptp.req_state)
+ {
+ case PTP_REQ_SEND:
+
+ /* Set operation request type */
+ MTP_Handle->ptp.flags = PTP_DP_GETDATA;
+ MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
+ MTP_Handle->ptp.data_length = 0;
+ MTP_Handle->ptp.data_packet_counter = 0;
+ MTP_Handle->ptp.data_packet = 0;
+
+ /* Fill operation request params */
+ ptp_container.Code = PTP_OC_GetDeviceInfo;
+ ptp_container.SessionID = MTP_Handle->ptp.session_id;
+ ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
+ ptp_container.Nparam = 0;
+
+ /* convert request packet inti USB raw packet*/
+ USBH_PTP_SendRequest (phost, &ptp_container);
+
+ /* Setup State machine and start transfer */
+ MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
+ MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
+ status = USBH_BUSY;
+ break;
+
+ case PTP_REQ_WAIT:
+ status = USBH_PTP_Process(phost);
+
+ if(status == USBH_OK)
+ {
+ PTP_DecodeDeviceInfo (phost, dev_info);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_PTP_GetStorageIds
+ * Gets device info dataset and fills deviceinfo structure.
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_GetStorageIds (USBH_HandleTypeDef *phost, PTP_StorageIDsTypedef *storage_ids)
+{
+ USBH_StatusTypeDef status = USBH_BUSY;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ PTP_ContainerTypedef ptp_container;
+
+ switch(MTP_Handle->ptp.req_state)
+ {
+ case PTP_REQ_SEND:
+
+ /* Set operation request type */
+ MTP_Handle->ptp.flags = PTP_DP_GETDATA;
+ MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
+ MTP_Handle->ptp.data_length = 0;
+ MTP_Handle->ptp.data_packet_counter = 0;
+ MTP_Handle->ptp.data_packet = 0;
+
+ /* Fill operation request params */
+ ptp_container.Code = PTP_OC_GetStorageIDs;
+ ptp_container.SessionID = MTP_Handle->ptp.session_id;
+ ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
+ ptp_container.Nparam = 0;
+
+ /* convert request packet inti USB raw packet*/
+ USBH_PTP_SendRequest (phost, &ptp_container);
+
+ /* Setup State machine and start transfer */
+ MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
+ MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
+ status = USBH_BUSY;
+ break;
+
+ case PTP_REQ_WAIT:
+ status = USBH_PTP_Process(phost);
+
+ if(status == USBH_OK)
+ {
+ PTP_GetStorageIDs (phost, storage_ids);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_PTP_GetDeviceInfo
+ * Gets device info dataset and fills deviceinfo structure.
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_GetStorageInfo (USBH_HandleTypeDef *phost, uint32_t storage_id, PTP_StorageInfoTypedef *storage_info)
+{
+ USBH_StatusTypeDef status = USBH_BUSY;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ PTP_ContainerTypedef ptp_container;
+
+ switch(MTP_Handle->ptp.req_state)
+ {
+ case PTP_REQ_SEND:
+
+ /* Set operation request type */
+ MTP_Handle->ptp.flags = PTP_DP_GETDATA;
+ MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
+ MTP_Handle->ptp.data_length = 0;
+ MTP_Handle->ptp.data_packet_counter = 0;
+ MTP_Handle->ptp.data_packet = 0;
+
+ /* Fill operation request params */
+ ptp_container.Code = PTP_OC_GetStorageInfo;
+ ptp_container.SessionID = MTP_Handle->ptp.session_id;
+ ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
+ ptp_container.Param1 = storage_id;
+ ptp_container.Nparam = 1;
+
+ /* convert request packet inti USB raw packet*/
+ USBH_PTP_SendRequest (phost, &ptp_container);
+
+ /* Setup State machine and start transfer */
+ MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
+ MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
+ status = USBH_BUSY;
+ break;
+
+ case PTP_REQ_WAIT:
+ status = USBH_PTP_Process(phost);
+
+ if(status == USBH_OK)
+ {
+ PTP_GetStorageInfo (phost, storage_id, storage_info);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_PTP_GetNumObjects
+ * Gets device info dataset and fills deviceinfo structure.
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_GetNumObjects (USBH_HandleTypeDef *phost,
+ uint32_t storage_id,
+ uint32_t objectformatcode,
+ uint32_t associationOH,
+ uint32_t* numobs)
+{
+ USBH_StatusTypeDef status = USBH_BUSY;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ PTP_ContainerTypedef ptp_container;
+
+ switch(MTP_Handle->ptp.req_state)
+ {
+ case PTP_REQ_SEND:
+
+ /* Set operation request type */
+ MTP_Handle->ptp.flags = PTP_DP_NODATA;
+
+ /* Fill operation request params */
+ ptp_container.Code = PTP_OC_GetNumObjects;
+ ptp_container.SessionID = MTP_Handle->ptp.session_id;
+ ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
+ ptp_container.Param1 = storage_id;
+ ptp_container.Param2 = objectformatcode;
+ ptp_container.Param3 = associationOH;
+ ptp_container.Nparam = 3;
+
+ /* convert request packet into USB raw packet*/
+ USBH_PTP_SendRequest (phost, &ptp_container);
+
+ /* Setup State machine and start transfer */
+ MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
+ MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
+ status = USBH_BUSY;
+ break;
+
+ case PTP_REQ_WAIT:
+ status = USBH_PTP_Process(phost);
+
+ if(status == USBH_OK)
+ {
+ *numobs = MTP_Handle->ptp.resp_container.param1;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_PTP_GetObjectHandles
+ * Gets device info dataset and fills deviceinfo structure.
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_GetObjectHandles (USBH_HandleTypeDef *phost,
+ uint32_t storage_id,
+ uint32_t objectformatcode,
+ uint32_t associationOH,
+ PTP_ObjectHandlesTypedef* objecthandles)
+{
+ USBH_StatusTypeDef status = USBH_BUSY;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ PTP_ContainerTypedef ptp_container;
+
+ switch(MTP_Handle->ptp.req_state)
+ {
+ case PTP_REQ_SEND:
+
+ /* Set operation request type */
+ MTP_Handle->ptp.flags = PTP_DP_GETDATA;
+ MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
+ MTP_Handle->ptp.data_length = 0;
+ MTP_Handle->ptp.data_packet_counter = 0;
+ MTP_Handle->ptp.data_packet = 0;
+
+ /* Fill operation request params */
+ ptp_container.Code = PTP_OC_GetObjectHandles;
+ ptp_container.SessionID = MTP_Handle->ptp.session_id;
+ ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
+ ptp_container.Param1 = storage_id;
+ ptp_container.Param2 = objectformatcode;
+ ptp_container.Param3 = associationOH;
+ ptp_container.Nparam = 3;
+
+ /* convert request packet into USB raw packet*/
+ USBH_PTP_SendRequest (phost, &ptp_container);
+
+ /* Setup State machine and start transfer */
+ MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
+ MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
+ status = USBH_BUSY;
+ break;
+
+ case PTP_REQ_WAIT:
+ status = USBH_PTP_Process(phost);
+
+ if(status == USBH_OK)
+ {
+ objecthandles->n = PTP_GetArray32 (objecthandles->Handler,
+ MTP_Handle->ptp.data_container.payload.data,
+ 0);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_PTP_GetObjectInfo
+ * Gets objert info
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_GetObjectInfo (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ PTP_ObjectInfoTypedef* object_info)
+{
+ USBH_StatusTypeDef status = USBH_BUSY;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ PTP_ContainerTypedef ptp_container;
+
+ switch(MTP_Handle->ptp.req_state)
+ {
+ case PTP_REQ_SEND:
+
+ /* Set operation request type */
+ MTP_Handle->ptp.flags = PTP_DP_GETDATA;
+ MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
+ MTP_Handle->ptp.data_length = 0;
+ MTP_Handle->ptp.data_packet_counter = 0;
+ MTP_Handle->ptp.data_packet = 0;
+
+ /* Fill operation request params */
+ ptp_container.Code = PTP_OC_GetObjectInfo;
+ ptp_container.SessionID = MTP_Handle->ptp.session_id;
+ ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
+ ptp_container.Param1 = handle;
+ ptp_container.Nparam = 1;
+
+ /* convert request packet into USB raw packet*/
+ USBH_PTP_SendRequest (phost, &ptp_container);
+
+ /* Setup State machine and start transfer */
+ MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
+ MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
+ status = USBH_BUSY;
+ break;
+
+ case PTP_REQ_WAIT:
+ status = USBH_PTP_Process(phost);
+
+ if(status == USBH_OK)
+ {
+ PTP_GetObjectInfo (phost, object_info);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_PTP_DeleteObject
+ * Delete an object.
+ * @param phost: Host handle
+ * @param handle : Object Handle
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_DeleteObject (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ uint32_t objectformatcode)
+{
+ USBH_StatusTypeDef status = USBH_BUSY;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ PTP_ContainerTypedef ptp_container;
+
+ switch(MTP_Handle->ptp.req_state)
+ {
+ case PTP_REQ_SEND:
+
+ /* Set operation request type */
+ MTP_Handle->ptp.flags = PTP_DP_NODATA;
+
+ /* Fill operation request params */
+ ptp_container.Code = PTP_OC_DeleteObject;
+ ptp_container.SessionID = MTP_Handle->ptp.session_id;
+ ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
+ ptp_container.Param1 = handle;
+ ptp_container.Param2 = objectformatcode;
+ ptp_container.Nparam = 2;
+
+ /* convert request packet into USB raw packet*/
+ USBH_PTP_SendRequest (phost, &ptp_container);
+
+ /* Setup State machine and start transfer */
+ MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
+ MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
+ status = USBH_BUSY;
+ break;
+
+ case PTP_REQ_WAIT:
+ status = USBH_PTP_Process(phost);
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_PTP_GetObject
+ * Gets object
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_GetObject (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ uint8_t *object)
+{
+ USBH_StatusTypeDef status = USBH_BUSY;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ PTP_ContainerTypedef ptp_container;
+
+ switch(MTP_Handle->ptp.req_state)
+ {
+ case PTP_REQ_SEND:
+
+ /* Set operation request type */
+ MTP_Handle->ptp.flags = PTP_DP_GETDATA;
+ MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
+ MTP_Handle->ptp.data_length = 0;
+ MTP_Handle->ptp.data_packet_counter = 0;
+ MTP_Handle->ptp.data_packet = 0;
+
+ /* set object control params */
+ MTP_Handle->ptp.object_ptr = object;
+
+ /* Fill operation request params */
+ ptp_container.Code = PTP_OC_GetObject;
+ ptp_container.SessionID = MTP_Handle->ptp.session_id;
+ ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
+ ptp_container.Param1 = handle;
+ ptp_container.Nparam = 1;
+
+
+ /* convert request packet into USB raw packet*/
+ USBH_PTP_SendRequest (phost, &ptp_container);
+
+ /* Setup State machine and start transfer */
+ MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
+ MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
+ status = USBH_BUSY;
+ break;
+
+ case PTP_REQ_WAIT:
+ status = USBH_PTP_Process(phost);
+
+ if(status == USBH_OK)
+ {
+ /* first packet is in the PTP data payload buffer */
+ if(MTP_Handle->ptp.iteration == 0)
+ {
+ /* copy it to object */
+ USBH_memcpy(MTP_Handle->ptp.object_ptr, MTP_Handle->ptp.data_container.payload.data, PTP_USB_BULK_PAYLOAD_LEN_READ);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_PTP_GetPartialObject
+ * Gets object partially
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_GetPartialObject(USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ uint32_t offset,
+ uint32_t maxbytes,
+ uint8_t *object,
+ uint32_t *len)
+{
+ USBH_StatusTypeDef status = USBH_BUSY;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ PTP_ContainerTypedef ptp_container;
+
+ switch(MTP_Handle->ptp.req_state)
+ {
+ case PTP_REQ_SEND:
+
+ /* Set operation request type */
+ MTP_Handle->ptp.flags = PTP_DP_GETDATA;
+ MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
+ MTP_Handle->ptp.data_length = 0;
+ MTP_Handle->ptp.data_packet_counter = 0;
+ MTP_Handle->ptp.data_packet = 0;
+
+ /* set object control params */
+ MTP_Handle->ptp.object_ptr = object;
+
+ /* Fill operation request params */
+ ptp_container.Code = PTP_OC_GetPartialObject;
+ ptp_container.SessionID = MTP_Handle->ptp.session_id;
+ ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
+ ptp_container.Param1 = handle;
+ ptp_container.Param2 = offset;
+ ptp_container.Param3 = maxbytes;
+ ptp_container.Nparam = 3;
+
+ /* convert request packet into USB raw packet*/
+ USBH_PTP_SendRequest (phost, &ptp_container);
+
+ /* Setup State machine and start transfer */
+ MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
+ MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
+ status = USBH_BUSY;
+ break;
+
+ case PTP_REQ_WAIT:
+ status = USBH_PTP_Process(phost);
+
+ if(status == USBH_OK)
+ {
+ *len = MTP_Handle->ptp.resp_container.param1;
+ /* first packet is in the PTP data payload buffer */
+ if(MTP_Handle->ptp.iteration == 0)
+ {
+ /* copy it to object */
+ USBH_memcpy(MTP_Handle->ptp.object_ptr, MTP_Handle->ptp.data_container.payload.data, *len);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_PTP_GetObjectPropsSupported
+ * Gets object partially
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_GetObjectPropsSupported (USBH_HandleTypeDef *phost,
+ uint16_t ofc,
+ uint32_t *propnum,
+ uint16_t *props)
+{
+ USBH_StatusTypeDef status = USBH_BUSY;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ PTP_ContainerTypedef ptp_container;
+
+ switch(MTP_Handle->ptp.req_state)
+ {
+ case PTP_REQ_SEND:
+
+ /* Set operation request type */
+ MTP_Handle->ptp.flags = PTP_DP_GETDATA;
+ MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
+ MTP_Handle->ptp.data_length = 0;
+ MTP_Handle->ptp.data_packet_counter = 0;
+ MTP_Handle->ptp.data_packet = 0;
+
+ /* Fill operation request params */
+ ptp_container.Code = PTP_OC_GetObjectPropsSupported;
+ ptp_container.SessionID = MTP_Handle->ptp.session_id;
+ ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
+ ptp_container.Param1 = ofc;
+ ptp_container.Nparam = 1;
+
+ /* convert request packet into USB raw packet*/
+ USBH_PTP_SendRequest (phost, &ptp_container);
+
+ /* Setup State machine and start transfer */
+ MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
+ MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
+ status = USBH_BUSY;
+ break;
+
+ case PTP_REQ_WAIT:
+ status = USBH_PTP_Process(phost);
+
+ if(status == USBH_OK)
+ {
+ *propnum = PTP_GetArray16 (props, MTP_Handle->ptp.data_container.payload.data, 0);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_PTP_GetObjectPropDesc
+ * Gets object partially
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_GetObjectPropDesc (USBH_HandleTypeDef *phost,
+ uint16_t opc,
+ uint16_t ofc,
+ PTP_ObjectPropDescTypeDef *opd)
+{
+ USBH_StatusTypeDef status = USBH_BUSY;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ PTP_ContainerTypedef ptp_container;
+
+ switch(MTP_Handle->ptp.req_state)
+ {
+ case PTP_REQ_SEND:
+
+ /* Set operation request type */
+ MTP_Handle->ptp.flags = PTP_DP_GETDATA;
+ MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
+ MTP_Handle->ptp.data_length = 0;
+ MTP_Handle->ptp.data_packet_counter = 0;
+ MTP_Handle->ptp.data_packet = 0;
+
+ /* Fill operation request params */
+ ptp_container.Code = PTP_OC_GetObjectPropDesc;
+ ptp_container.SessionID = MTP_Handle->ptp.session_id;
+ ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
+ ptp_container.Param1 = opc;
+ ptp_container.Param2 = ofc;
+ ptp_container.Nparam = 2;
+
+ /* convert request packet into USB raw packet*/
+ USBH_PTP_SendRequest (phost, &ptp_container);
+
+ /* Setup State machine and start transfer */
+ MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
+ MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
+ status = USBH_BUSY;
+ break;
+
+ case PTP_REQ_WAIT:
+ status = USBH_PTP_Process(phost);
+
+ if(status == USBH_OK)
+ {
+ PTP_GetObjectPropDesc(phost, opd, MTP_Handle->ptp.data_length);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_PTP_GetObjectPropList
+ * Gets object partially
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_GetObjectPropList (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ MTP_PropertiesTypedef *pprops,
+ uint32_t *nrofprops)
+{
+ USBH_StatusTypeDef status = USBH_BUSY;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ PTP_ContainerTypedef ptp_container;
+
+ switch(MTP_Handle->ptp.req_state)
+ {
+ case PTP_REQ_SEND:
+
+ /* Set operation request type */
+ MTP_Handle->ptp.flags = PTP_DP_GETDATA;
+ MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
+ MTP_Handle->ptp.data_length = 0;
+ MTP_Handle->ptp.data_packet_counter = 0;
+ MTP_Handle->ptp.data_packet = 0;
+
+ /* copy first packet of the object into data container */
+ USBH_memcpy(MTP_Handle->ptp.data_container.payload.data, MTP_Handle->ptp.object_ptr, PTP_USB_BULK_PAYLOAD_LEN_READ);
+
+ /* Fill operation request params */
+ ptp_container.Code = PTP_OC_GetObjPropList;
+ ptp_container.SessionID = MTP_Handle->ptp.session_id;
+ ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
+ ptp_container.Param1 = handle;
+ ptp_container.Param2 = 0x00000000U; /* 0x00000000U should be "all formats" */
+ ptp_container.Param3 = 0xFFFFFFFFU; /* 0xFFFFFFFFU should be "all properties" */
+ ptp_container.Param4 = 0x00000000U;
+ ptp_container.Param5 = 0xFFFFFFFFU; /* Return full tree below the Param1 handle */
+ ptp_container.Nparam = 5;
+
+ /* convert request packet into USB raw packet*/
+ USBH_PTP_SendRequest (phost, &ptp_container);
+
+ /* Setup State machine and start transfer */
+ MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
+ MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
+ status = USBH_BUSY;
+ break;
+
+ case PTP_REQ_WAIT:
+ status = USBH_PTP_Process(phost);
+
+ if(status == USBH_OK)
+ {
+ PTP_GetObjectPropList (phost, pprops, MTP_Handle->ptp.data_length);
+ }
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+
+/**
+ * @brief USBH_PTP_SendObject
+ * Send an object
+ * @param phost: Host handle
+ * @param dev_info: Device info structure
+ * @retval USBH Status
+ */
+USBH_StatusTypeDef USBH_PTP_SendObject (USBH_HandleTypeDef *phost,
+ uint32_t handle,
+ uint8_t *object,
+ uint32_t size)
+{
+ USBH_StatusTypeDef status = USBH_BUSY;
+ MTP_HandleTypeDef *MTP_Handle = phost->pActiveClass->pData;
+ PTP_ContainerTypedef ptp_container;
+
+ switch(MTP_Handle->ptp.req_state)
+ {
+ case PTP_REQ_SEND:
+
+ /* Set operation request type */
+ MTP_Handle->ptp.flags = PTP_DP_SENDDATA;
+ MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
+ MTP_Handle->ptp.data_packet_counter = 0;
+ MTP_Handle->ptp.data_packet = 0;
+ MTP_Handle->ptp.iteration = 0;
+
+ /* set object control params */
+ MTP_Handle->ptp.object_ptr = object;
+ MTP_Handle->ptp.data_length = size;
+
+ /* Fill operation request params */
+ ptp_container.Code = PTP_OC_SendObject;
+ ptp_container.SessionID = MTP_Handle->ptp.session_id;
+ ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
+ ptp_container.Nparam = 0;
+
+
+ /* convert request packet into USB raw packet*/
+ USBH_PTP_SendRequest (phost, &ptp_container);
+
+ /* Setup State machine and start transfer */
+ MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
+ MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
+ status = USBH_BUSY;
+ break;
+
+ case PTP_REQ_WAIT:
+ status = USBH_PTP_Process(phost);
+ break;
+
+ default:
+ break;
+ }
+ return status;
+}
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/**
+* @}
+*/
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+
+
+
|
