Nirvana Jay / Mbed 2 deprecated F7DISCO_Demo

Dependencies:   BSP_DISCO_F746NG_patch mbed-rtos mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers usbh_mtp_ptp.c Source File

usbh_mtp_ptp.c

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    usbh_mtp_ptp.c 
00004   * @author  MCD Application Team
00005   * @version V3.2.2
00006   * @date    07-July-2015
00007   * @brief   This file includes the PTP operations layer
00008   ******************************************************************************
00009   * @attention
00010   *
00011   * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
00012   *
00013   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
00014   * You may not use this file except in compliance with the License.
00015   * You may obtain a copy of the License at:
00016   *
00017   *        http://www.st.com/software_license_agreement_liberty_v2
00018   *
00019   * Unless required by applicable law or agreed to in writing, software 
00020   * distributed under the License is distributed on an "AS IS" BASIS, 
00021   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00022   * See the License for the specific language governing permissions and
00023   * limitations under the License.
00024   *
00025   ******************************************************************************
00026   */ 
00027 
00028 /* Includes ------------------------------------------------------------------*/
00029 #include "usbh_mtp_ptp.h"
00030 #include "usbh_mtp.h"
00031 /** @addtogroup USBH_LIB
00032 * @{
00033 */
00034 
00035 /** @addtogroup USBH_CLASS
00036 * @{
00037 */
00038 
00039 /** @addtogroup USBH_MTP_CLASS
00040 * @{
00041 */
00042 
00043 /** @defgroup USBH_MTP_PTP
00044 * @brief    This file includes the mass storage related functions
00045 * @{
00046 */ 
00047 
00048 
00049 /** @defgroup USBH_MTP_PTP_Private_TypesDefinitions
00050 * @{
00051 */ 
00052 /**
00053 * @}
00054 */ 
00055 
00056 /** @defgroup USBH_MTP_PTP_Private_Defines
00057 * @{
00058 */ 
00059 /**
00060 * @}
00061 */ 
00062 
00063 /** @defgroup USBH_MTP_PTP_Private_Macros
00064 * @{
00065 */ 
00066 /**
00067 * @}
00068 */ 
00069 
00070 
00071 /** @defgroup USBH_MTP_PTP_Private_Variables
00072 * @{
00073 */ 
00074 
00075 /**
00076 * @}
00077 */ 
00078 
00079 
00080 /** @defgroup USBH_MTP_PTP_Private_FunctionPrototypes
00081 * @{
00082 */ 
00083 static void PTP_DecodeDeviceInfo (USBH_HandleTypeDef *phost, PTP_DeviceInfoTypedef *dev_info);
00084 static void PTP_GetStorageIDs (USBH_HandleTypeDef *phost, PTP_StorageIDsTypedef *stor_ids);
00085 static void PTP_GetStorageInfo (USBH_HandleTypeDef *phost, uint32_t storage_id, PTP_StorageInfoTypedef *stor_info);
00086 static void PTP_GetObjectPropDesc (USBH_HandleTypeDef *phost, PTP_ObjectPropDescTypeDef *opd, uint32_t opdlen);
00087 static void PTP_DecodeDeviceInfo (USBH_HandleTypeDef *phost, PTP_DeviceInfoTypedef *dev_info);
00088 static void PTP_GetDevicePropValue(USBH_HandleTypeDef *phost, 
00089                                    uint32_t *offset, 
00090                                    uint32_t total, 
00091                                    PTP_PropertyValueTypedef* value, 
00092                                    uint16_t datatype);
00093 
00094 static uint32_t PTP_GetObjectPropList (USBH_HandleTypeDef *phost, 
00095                                        MTP_PropertiesTypedef *props, 
00096                                        uint32_t len);
00097 
00098 
00099 static void PTP_BufferFullCallback(USBH_HandleTypeDef *phost);
00100 static void PTP_GetString(uint8_t *str, uint8_t* data, uint16_t *len);
00101 static uint32_t PTP_GetArray16 (uint16_t *array, uint8_t *data, uint32_t offset);
00102 static uint32_t PTP_GetArray32 (uint32_t *array, uint8_t *data, uint32_t offset);
00103 /**
00104 * @}
00105 */ 
00106 
00107 
00108 /** @defgroup USBH_MTP_PTP_Exported_Variables
00109 * @{
00110 */ 
00111 /**
00112 * @}
00113 */ 
00114 
00115 
00116 /** @defgroup USBH_MTP_PTP_Private_Functions
00117 * @{
00118 */ 
00119 /**
00120   * @brief  USBH_PTP_Init 
00121   *         The function Initializes the BOT protocol.
00122   * @param  phost: Host handle
00123   * @retval USBH Status
00124   */
00125 USBH_StatusTypeDef USBH_PTP_Init(USBH_HandleTypeDef *phost)
00126 {
00127   MTP_HandleTypeDef *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData;
00128   
00129   /* Set state to idle to be ready for operations */
00130   MTP_Handle->ptp.state = PTP_IDLE;
00131   MTP_Handle->ptp.req_state = PTP_REQ_SEND;
00132   
00133   return USBH_OK;
00134 }
00135 
00136 /**
00137   * @brief  USBH_PTP_Process 
00138   *         The function handle the BOT protocol.
00139   * @param  phost: Host handle
00140   * @param  lun: Logical Unit Number
00141   * @retval USBH Status
00142   */
00143 USBH_StatusTypeDef USBH_PTP_Process (USBH_HandleTypeDef *phost)
00144 {
00145   USBH_StatusTypeDef   status = USBH_BUSY;
00146   USBH_URBStateTypeDef URB_Status = USBH_URB_IDLE;  
00147   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
00148   PTP_ContainerTypedef  ptp_container;  
00149   uint32_t  len;
00150   
00151   switch (MTP_Handle->ptp.state)
00152   {
00153   case PTP_IDLE:
00154     /*Do Nothing */
00155     break;
00156     
00157   case PTP_OP_REQUEST_STATE:  
00158     USBH_BulkSendData (phost,
00159                        (uint8_t*)&(MTP_Handle->ptp.op_container),
00160                        MTP_Handle->ptp.op_container.length, 
00161                        MTP_Handle->DataOutPipe,
00162                        1);
00163     MTP_Handle->ptp.state = PTP_OP_REQUEST_WAIT_STATE;
00164     break;
00165     
00166   case PTP_OP_REQUEST_WAIT_STATE:
00167     URB_Status = USBH_LL_GetURBState(phost, MTP_Handle->DataOutPipe);
00168     
00169     if(URB_Status == USBH_URB_DONE)
00170     {
00171        if(MTP_Handle->ptp.flags == PTP_DP_NODATA)
00172        {
00173          MTP_Handle->ptp.state = PTP_RESPONSE_STATE;
00174        }
00175        else  if(MTP_Handle->ptp.flags == PTP_DP_SENDDATA)
00176        {
00177          MTP_Handle->ptp.state = PTP_DATA_OUT_PHASE_STATE;
00178        }
00179        else  if(MTP_Handle->ptp.flags == PTP_DP_GETDATA)
00180        {
00181          MTP_Handle->ptp.state = PTP_DATA_IN_PHASE_STATE;
00182        }
00183 #if (USBH_USE_OS == 1)
00184     osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
00185 #endif  
00186     }
00187     else if(URB_Status == USBH_URB_NOTREADY)
00188     {
00189       /* Resend Request */
00190       MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
00191 #if (USBH_USE_OS == 1)
00192     osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
00193 #endif       
00194     }     
00195     else if(URB_Status == USBH_URB_STALL)
00196     {
00197       MTP_Handle->ptp.state  = PTP_ERROR;
00198 #if (USBH_USE_OS == 1)
00199      osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
00200 #endif 
00201     }
00202     break;
00203     
00204   case PTP_DATA_OUT_PHASE_STATE:
00205     
00206     USBH_BulkSendData (phost,
00207                        MTP_Handle->ptp.data_ptr,
00208                        MTP_Handle->DataOutEpSize , 
00209                        MTP_Handle->DataOutPipe,
00210                        1);
00211     
00212     
00213     MTP_Handle->ptp.state  = PTP_DATA_OUT_PHASE_WAIT_STATE;    
00214     break;
00215     
00216   case PTP_DATA_OUT_PHASE_WAIT_STATE:
00217     URB_Status = USBH_LL_GetURBState(phost, MTP_Handle->DataOutPipe);     
00218     
00219     if(URB_Status == USBH_URB_DONE)
00220     {
00221       /* Adjust Data pointer and data length */
00222       if(MTP_Handle->ptp.data_length > MTP_Handle->DataOutEpSize)
00223       {
00224         MTP_Handle->ptp.data_ptr += MTP_Handle->DataOutEpSize;
00225         MTP_Handle->ptp.data_length -= MTP_Handle->DataOutEpSize; 
00226         MTP_Handle->ptp.data_packet += MTP_Handle->DataOutEpSize;
00227         
00228         if(MTP_Handle->ptp.data_packet >= PTP_USB_BULK_PAYLOAD_LEN_READ)
00229         {
00230           PTP_BufferFullCallback (phost);
00231           MTP_Handle->ptp.data_packet = 0;
00232           MTP_Handle->ptp.iteration++;            
00233         }
00234         
00235       }
00236       else
00237       {
00238         MTP_Handle->ptp.data_length = 0;
00239       } 
00240       
00241       /* More Data To be Sent */
00242       if(MTP_Handle->ptp.data_length > 0)
00243       {
00244         USBH_BulkSendData (phost,
00245                            MTP_Handle->ptp.data_ptr,
00246                            MTP_Handle->DataOutEpSize , 
00247                            MTP_Handle->DataOutPipe,
00248                            1);
00249       }
00250       else
00251       {
00252         /* If value was 0, and successful transfer, then change the state */
00253         MTP_Handle->ptp.state  = PTP_RESPONSE_STATE;
00254       }  
00255 #if (USBH_USE_OS == 1)
00256     osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
00257 #endif       
00258     }
00259     
00260     else if(URB_Status == USBH_URB_NOTREADY)
00261     {
00262       /* Resend same data */      
00263       MTP_Handle->ptp.state = PTP_DATA_OUT_PHASE_STATE;
00264 #if (USBH_USE_OS == 1)
00265     osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
00266 #endif       
00267     }
00268     
00269     else if(URB_Status == USBH_URB_STALL)
00270     {
00271       MTP_Handle->ptp.state  = PTP_ERROR;    
00272 #if (USBH_USE_OS == 1)
00273     osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
00274 #endif       
00275     }
00276     break;
00277     
00278   case PTP_DATA_IN_PHASE_STATE:
00279     /* Send first packet */        
00280     USBH_BulkReceiveData (phost,
00281                           MTP_Handle->ptp.data_ptr, 
00282                           MTP_Handle->DataInEpSize, 
00283                           MTP_Handle->DataInPipe);
00284     
00285     MTP_Handle->ptp.state  = PTP_DATA_IN_PHASE_WAIT_STATE;    
00286     break;
00287     
00288   case PTP_DATA_IN_PHASE_WAIT_STATE:
00289     URB_Status = USBH_LL_GetURBState(phost, MTP_Handle->DataInPipe);
00290     
00291     if(URB_Status == USBH_URB_DONE)
00292     {
00293       len = USBH_LL_GetLastXferSize (phost, MTP_Handle->DataInPipe);
00294       
00295       if( MTP_Handle->ptp.data_packet_counter++ == 0)
00296       {
00297         /* This is the first packet; so retrieve exact data length from payload */ 
00298         MTP_Handle->ptp.data_length = *(uint32_t*)(MTP_Handle->ptp.data_ptr);
00299         MTP_Handle->ptp.iteration = 0;
00300       }
00301       
00302       if((len >=  MTP_Handle->DataInEpSize) && (MTP_Handle->ptp.data_length > 0))
00303       {
00304         MTP_Handle->ptp.data_ptr += len;
00305         MTP_Handle->ptp.data_length -= len;
00306         MTP_Handle->ptp.data_packet += len;
00307 
00308         if(MTP_Handle->ptp.data_packet >= PTP_USB_BULK_PAYLOAD_LEN_READ)
00309         {
00310           PTP_BufferFullCallback (phost);
00311           MTP_Handle->ptp.data_packet = 0;
00312           MTP_Handle->ptp.iteration++;            
00313         }
00314         
00315         /* Continue receiving data*/        
00316         USBH_BulkReceiveData (phost,
00317                               MTP_Handle->ptp.data_ptr, 
00318                               MTP_Handle->DataInEpSize, 
00319                               MTP_Handle->DataInPipe);
00320       }
00321       else
00322       {
00323         MTP_Handle->ptp.data_length -= len;
00324         MTP_Handle->ptp.state = PTP_RESPONSE_STATE;
00325 #if (USBH_USE_OS == 1)
00326     osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
00327 #endif          
00328       }
00329     }
00330     else if(URB_Status == USBH_URB_STALL)     
00331     {
00332       MTP_Handle->ptp.state  = PTP_ERROR;
00333 #if (USBH_USE_OS == 1)
00334     osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
00335 #endif       
00336     }
00337     break;
00338     
00339   case PTP_RESPONSE_STATE:
00340     
00341     USBH_BulkReceiveData (phost,
00342                           (uint8_t*)&(MTP_Handle->ptp.resp_container), 
00343                           PTP_USB_BULK_REQ_RESP_MAX_LEN , 
00344                           MTP_Handle->DataInPipe);
00345     
00346     MTP_Handle->ptp.state  = PTP_RESPONSE_WAIT_STATE;
00347     break;
00348     
00349   case PTP_RESPONSE_WAIT_STATE:
00350     URB_Status = USBH_LL_GetURBState(phost, MTP_Handle->DataInPipe);
00351     
00352     if(URB_Status == USBH_URB_DONE)
00353     {
00354        USBH_PTP_GetResponse (phost, &ptp_container);
00355        
00356        if(ptp_container.Code == PTP_RC_OK)
00357        {
00358          status = USBH_OK;
00359        }
00360        else
00361        {
00362          status = USBH_FAIL;
00363        }
00364        MTP_Handle->ptp.req_state = PTP_REQ_SEND;
00365     }
00366     else if(URB_Status == USBH_URB_STALL)     
00367     {
00368       MTP_Handle->ptp.state  = PTP_ERROR;
00369 #if (USBH_USE_OS == 1)
00370     osMessagePut ( phost->os_event, USBH_URB_EVENT, 0);
00371 #endif       
00372     }
00373     break;
00374     
00375   case PTP_ERROR:
00376       MTP_Handle->ptp.req_state = PTP_REQ_SEND;
00377       break;
00378       
00379   default:
00380     break;
00381   }
00382   return status;
00383 }
00384 
00385 /**
00386   * @brief  USBH_PTP_OpenSession
00387   *         Open a new session
00388   * @param  phost: Host handle
00389   * @retval USBH Status
00390   */
00391 USBH_StatusTypeDef USBH_PTP_SendRequest (USBH_HandleTypeDef *phost, PTP_ContainerTypedef  *req)
00392 {
00393   USBH_StatusTypeDef            status = USBH_OK; 
00394   MTP_HandleTypeDef             *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
00395   
00396   /* Clear PTP Data container*/
00397   USBH_memset(&(MTP_Handle->ptp.op_container), 0, sizeof(PTP_OpContainerTypedef));
00398   
00399   /* build appropriate USB container */
00400   MTP_Handle->ptp.op_container.length = PTP_USB_BULK_REQ_LEN- (sizeof(uint32_t)*(5-req->Nparam));
00401   MTP_Handle->ptp.op_container.type = PTP_USB_CONTAINER_COMMAND;
00402   MTP_Handle->ptp.op_container.code = req->Code;
00403   MTP_Handle->ptp.op_container.trans_id = req->Transaction_ID;
00404   MTP_Handle->ptp.op_container.param1 = req->Param1;
00405   MTP_Handle->ptp.op_container.param2 = req->Param2;
00406   MTP_Handle->ptp.op_container.param3 = req->Param3;
00407   MTP_Handle->ptp.op_container.param4 = req->Param4;
00408   MTP_Handle->ptp.op_container.param5 = req->Param5;
00409   
00410   return status;
00411 }
00412 
00413 /**
00414   * @brief  USBH_PTP_OpenSession
00415   *         Open a new session
00416   * @param  phost: Host handle
00417   * @retval USBH Status
00418   */
00419 USBH_StatusTypeDef USBH_PTP_GetResponse (USBH_HandleTypeDef *phost, PTP_ContainerTypedef  *resp)
00420 {
00421   USBH_StatusTypeDef            status = USBH_OK; 
00422   MTP_HandleTypeDef             *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
00423       
00424   /* build an appropriate PTPContainer */
00425   resp->Code = MTP_Handle->ptp.resp_container.code;
00426   resp->SessionID = MTP_Handle->ptp.session_id;
00427   resp->Transaction_ID = MTP_Handle->ptp.resp_container.trans_id;
00428   resp->Param1 = MTP_Handle->ptp.resp_container.param1;
00429   resp->Param2 = MTP_Handle->ptp.resp_container.param2;
00430   resp->Param3 = MTP_Handle->ptp.resp_container.param3;
00431   resp->Param4 = MTP_Handle->ptp.resp_container.param4;
00432   resp->Param5 = MTP_Handle->ptp.resp_container.param5;
00433   
00434   return status;
00435 }
00436 
00437 /**
00438   * @brief  The function informs user that data buffer is full
00439   *  @param  phost: host handle
00440   * @retval None
00441   */
00442 void PTP_BufferFullCallback(USBH_HandleTypeDef *phost)
00443 {
00444   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
00445   
00446   switch (MTP_Handle->ptp.data_container.code)
00447   {
00448   case PTP_OC_GetDeviceInfo:
00449     PTP_DecodeDeviceInfo (phost, &(MTP_Handle->info.devinfo));
00450     break;
00451     
00452   case PTP_OC_GetPartialObject:    
00453   case PTP_OC_GetObject:
00454 
00455     /* first packet is in the PTP data payload buffer */
00456     if(MTP_Handle->ptp.iteration == 0)
00457     {
00458        /* copy it to object */
00459        USBH_memcpy(MTP_Handle->ptp.object_ptr, MTP_Handle->ptp.data_container.payload.data, PTP_USB_BULK_PAYLOAD_LEN_READ);
00460        
00461        /* next packet should be directly copied to object */
00462        MTP_Handle->ptp.data_ptr = (MTP_Handle->ptp.object_ptr + PTP_USB_BULK_PAYLOAD_LEN_READ); 
00463     }
00464     break;
00465 
00466   case PTP_OC_SendObject:    
00467     /* first packet is in the PTP data payload buffer */
00468     if(MTP_Handle->ptp.iteration == 0)
00469     {
00470        /* next packet should be directly copied to object */
00471        MTP_Handle->ptp.data_ptr = (MTP_Handle->ptp.object_ptr + PTP_USB_BULK_PAYLOAD_LEN_READ); 
00472     }
00473     break;    
00474     
00475   default:
00476     break;
00477     
00478     
00479   }
00480 }
00481 
00482 /**
00483   * @brief  PTP_GetDeviceInfo
00484   *         Gets device info dataset and fills deviceinfo structure.
00485   * @param  phost: Host handle
00486   * @param  dev_info: Device info structure
00487   * @retval None
00488   */
00489 static void PTP_DecodeDeviceInfo (USBH_HandleTypeDef *phost, PTP_DeviceInfoTypedef *dev_info)
00490 {
00491   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData;   
00492   uint8_t *data = MTP_Handle->ptp.data_container.payload.data;
00493   uint32_t totallen; 
00494   uint16_t len;
00495   
00496   /* Max device info is PTP_USB_BULK_HS_MAX_PACKET_LEN_READ */
00497   USBH_DbgLog (" MTP device info size exceeds internal buffer size.\
00498                only available data are decoded.");
00499                    
00500   if(MTP_Handle->ptp.iteration == 0)
00501   {
00502     dev_info->StandardVersion = LE16(&data[PTP_di_StandardVersion]);
00503     dev_info->VendorExtensionID = LE32(&data[PTP_di_VendorExtensionID]);
00504     dev_info->VendorExtensionVersion = LE16(&data[PTP_di_VendorExtensionVersion]);
00505     PTP_GetString(dev_info->VendorExtensionDesc, &data[PTP_di_VendorExtensionDesc], &len);
00506     
00507     totallen=len*2+1;
00508     dev_info->FunctionalMode = LE16(&data[PTP_di_FunctionalMode+totallen]);
00509     dev_info->OperationsSupported_len = PTP_GetArray16 ((uint16_t *)&dev_info->OperationsSupported, 
00510                                                       data, 
00511                                                       PTP_di_OperationsSupported+totallen);
00512     
00513     totallen=totallen+dev_info->OperationsSupported_len*sizeof(uint16_t)+sizeof(uint32_t);
00514     dev_info->EventsSupported_len = PTP_GetArray16 ((uint16_t *)&dev_info->EventsSupported, 
00515                                                       data, 
00516                                                       PTP_di_OperationsSupported+totallen);
00517     
00518     totallen=totallen+dev_info->EventsSupported_len*sizeof(uint16_t)+sizeof(uint32_t);
00519     dev_info->DevicePropertiesSupported_len = PTP_GetArray16 ((uint16_t *)&dev_info->DevicePropertiesSupported, 
00520                                                       data, 
00521                                                       PTP_di_OperationsSupported+totallen);
00522       
00523     totallen=totallen+dev_info->DevicePropertiesSupported_len*sizeof(uint16_t)+sizeof(uint32_t);
00524       
00525     dev_info->CaptureFormats_len = PTP_GetArray16 ((uint16_t *)&dev_info->CaptureFormats, 
00526                                                       data, 
00527                                                       PTP_di_OperationsSupported+totallen);
00528       
00529     totallen=totallen+dev_info->CaptureFormats_len*sizeof(uint16_t)+sizeof(uint32_t);
00530     dev_info->ImageFormats_len =  PTP_GetArray16 ((uint16_t *)&dev_info->ImageFormats, 
00531                                                       data, 
00532                                                       PTP_di_OperationsSupported+totallen);
00533       
00534     totallen=totallen+dev_info->ImageFormats_len*sizeof(uint16_t)+sizeof(uint32_t); 
00535     PTP_GetString(dev_info->Manufacturer, &data[PTP_di_OperationsSupported+totallen], &len);
00536 
00537     totallen+=len*2+1;
00538     PTP_GetString(dev_info->Model, &data[PTP_di_OperationsSupported+totallen], &len);
00539     
00540     totallen+=len*2+1;
00541     PTP_GetString(dev_info->DeviceVersion, &data[PTP_di_OperationsSupported+totallen], &len);
00542 
00543     totallen+=len*2+1;
00544     PTP_GetString(dev_info->SerialNumber, &data[PTP_di_OperationsSupported+totallen], &len);
00545   }
00546 }
00547                  
00548 /**
00549   * @brief  PTP_GetStorageIDs
00550   *         Gets Storage Ids and fills stor_ids structure.
00551   * @param  phost: Host handle
00552   * @param  stor_ids: Storage IDsstructure
00553   * @retval None
00554   */
00555 static void PTP_GetStorageIDs (USBH_HandleTypeDef *phost, PTP_StorageIDsTypedef *stor_ids)
00556 {
00557   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData;   
00558   uint8_t *data = MTP_Handle->ptp.data_container.payload.data;
00559 
00560   stor_ids->n = PTP_GetArray32 (stor_ids->Storage, data, 0); 
00561 }
00562 
00563                                   
00564 /**
00565   * @brief  PTP_GetStorageInfo
00566   *         Gets Storage Info and fills stor_info structure.
00567   * @param  phost: Host handle
00568   * @param  stor_ids: Storage IDsstructure
00569   * @retval None
00570   */
00571 static void PTP_GetStorageInfo (USBH_HandleTypeDef *phost, uint32_t storage_id, PTP_StorageInfoTypedef *stor_info)
00572 {
00573   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData;   
00574   uint8_t *data = MTP_Handle->ptp.data_container.payload.data;
00575 
00576   uint16_t len;
00577   
00578   stor_info->StorageType=LE16(&data[PTP_si_StorageType]);
00579   stor_info->FilesystemType=LE16(&data[PTP_si_FilesystemType]);
00580   stor_info->AccessCapability=LE16(&data[PTP_si_AccessCapability]);
00581   stor_info->MaxCapability=LE64(&data[PTP_si_MaxCapability]);
00582   stor_info->FreeSpaceInBytes=LE64(&data[PTP_si_FreeSpaceInBytes]);
00583   stor_info->FreeSpaceInImages=LE32(&data[PTP_si_FreeSpaceInImages]);
00584   
00585   PTP_GetString(stor_info->StorageDescription, &data[PTP_si_StorageDescription], &len);
00586   PTP_GetString(stor_info->VolumeLabel, &data[PTP_si_StorageDescription+len*2+1], &len);   
00587 }
00588 
00589 /**
00590   * @brief  PTP_GetObjectInfo
00591   *         Gets objectInfo and fills object_info structure.
00592   * @param  phost: Host handle
00593   * @param  object_info: object info structure
00594   * @retval None
00595   */
00596 static void PTP_GetObjectInfo (USBH_HandleTypeDef *phost, PTP_ObjectInfoTypedef *object_info)
00597 {
00598   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData;   
00599   uint8_t *data = MTP_Handle->ptp.data_container.payload.data;
00600   uint16_t filenamelen;
00601   
00602   object_info->StorageID=LE32(&data[PTP_oi_StorageID]);
00603   object_info->ObjectFormat=LE16(&data[PTP_oi_ObjectFormat]);
00604   object_info->ProtectionStatus=LE16(&data[PTP_oi_ProtectionStatus]);
00605   object_info->ObjectCompressedSize=LE32(&data[PTP_oi_ObjectCompressedSize]);
00606   
00607   /* For Samsung Galaxy */
00608   if ((data[PTP_oi_filenamelen] == 0) && (data[PTP_oi_filenamelen+4] != 0)) 
00609   {
00610     data += 4;
00611   }
00612   object_info->ThumbFormat=LE16(&data[PTP_oi_ThumbFormat]);
00613   object_info->ThumbCompressedSize=LE32(&data[PTP_oi_ThumbCompressedSize]);
00614   object_info->ThumbPixWidth=LE32(&data[PTP_oi_ThumbPixWidth]);
00615   object_info->ThumbPixHeight=LE32(&data[PTP_oi_ThumbPixHeight]);
00616   object_info->ImagePixWidth=LE32(&data[PTP_oi_ImagePixWidth]);
00617   object_info->ImagePixHeight=LE32(&data[PTP_oi_ImagePixHeight]);
00618   object_info->ImageBitDepth=LE32(&data[PTP_oi_ImageBitDepth]);
00619   object_info->ParentObject=LE32(&data[PTP_oi_ParentObject]);
00620   object_info->AssociationType=LE16(&data[PTP_oi_AssociationType]);
00621   object_info->AssociationDesc=LE32(&data[PTP_oi_AssociationDesc]);
00622   object_info->SequenceNumber=LE32(&data[PTP_oi_SequenceNumber]);
00623   PTP_GetString(object_info->Filename, &data[PTP_oi_filenamelen], &filenamelen);
00624 }
00625 
00626                  
00627 /**
00628   * @brief  PTP_GetObjectPropDesc
00629   *         Gets objectInfo and fills object_info structure.
00630   * @param  phost: Host handle
00631   * @param  opd: object prop descriptor structure
00632   * @retval None
00633   */
00634 static void PTP_GetObjectPropDesc (USBH_HandleTypeDef *phost, PTP_ObjectPropDescTypeDef *opd, uint32_t opdlen)
00635 {
00636   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData;   
00637   uint8_t *data = MTP_Handle->ptp.data_container.payload.data;
00638   uint32_t offset = 0, i;
00639   
00640   opd->ObjectPropertyCode=LE16(&data[PTP_opd_ObjectPropertyCode]);
00641   opd->DataType=LE16(&data[PTP_opd_DataType]);
00642   opd->GetSet=*(uint8_t *)(&data[PTP_opd_GetSet]);
00643   
00644   offset = PTP_opd_FactoryDefaultValue;
00645   PTP_GetDevicePropValue (phost, &offset, opdlen, &opd->FactoryDefaultValue, opd->DataType);
00646   
00647   opd->GroupCode=LE32(&data[offset]);
00648   offset+=sizeof(uint32_t);
00649   
00650   opd->FormFlag=*(uint8_t *)(&data[offset]);
00651   offset+=sizeof(uint8_t);
00652   
00653   switch (opd->FormFlag) 
00654   {
00655   case PTP_OPFF_Range:
00656     PTP_GetDevicePropValue(phost, &offset, opdlen, &opd->FORM.Range.MinimumValue, opd->DataType);
00657     PTP_GetDevicePropValue(phost, &offset, opdlen, &opd->FORM.Range.MaximumValue, opd->DataType);
00658     PTP_GetDevicePropValue(phost, &offset, opdlen, &opd->FORM.Range.StepSize, opd->DataType);
00659     break;
00660     
00661   case PTP_OPFF_Enumeration:
00662     
00663     opd->FORM.Enum.NumberOfValues = LE16(&data[offset]);
00664     offset+=sizeof(uint16_t);
00665     
00666     for (i=0 ; i < opd->FORM.Enum.NumberOfValues ; i++) 
00667     {
00668       PTP_GetDevicePropValue(phost, &offset, opdlen, &opd->FORM.Enum.SupportedValue[i], opd->DataType);
00669     }
00670     break;
00671   default:
00672     break;
00673   }
00674 }
00675                  
00676 /**
00677   * @brief  PTP_GetDevicePropValue
00678   *         Gets objectInfo and fills object_info structure.
00679   * @param  phost: Host handle
00680   * @param  opd: object prop descriptor structure
00681   * @retval None
00682   */             
00683 static void PTP_GetDevicePropValue(USBH_HandleTypeDef *phost, 
00684                                    uint32_t *offset, 
00685                                    uint32_t total, 
00686                                    PTP_PropertyValueTypedef* value, 
00687                                    uint16_t datatype)
00688 {
00689   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData;   
00690   uint8_t *data = MTP_Handle->ptp.data_container.payload.data;
00691   uint16_t len;
00692   switch (datatype) 
00693   {
00694   case PTP_DTC_INT8:
00695     value->i8 = *(uint8_t *)&(data[*offset]);
00696     *offset += 1;
00697     break;
00698   case PTP_DTC_UINT8:
00699     value->u8 = *(uint8_t *)&(data[*offset]);
00700     *offset += 1;                
00701     break;
00702   case PTP_DTC_INT16:
00703     
00704     value->i16 = LE16(&(data[*offset]));
00705     *offset += 2;                
00706     break;
00707   case PTP_DTC_UINT16:
00708     value->u16 = LE16(&(data[*offset]));                
00709     *offset += 2;                
00710     break;
00711   case PTP_DTC_INT32:
00712     value->i32 = LE32(&(data[*offset]));              
00713     *offset += 4;                
00714     break;
00715   case PTP_DTC_UINT32:
00716     value->u32 = LE32(&(data[*offset]));             
00717     *offset += 4;                
00718     break;
00719   case PTP_DTC_INT64:
00720     value->i64 = LE64(&(data[*offset]));            
00721     *offset += 8;                
00722     break;
00723   case PTP_DTC_UINT64:
00724     value->u64 = LE64(&(data[*offset]));              
00725     *offset += 8;                
00726     break;
00727     
00728   case PTP_DTC_UINT128:
00729     *offset += 16;
00730     break;
00731   case PTP_DTC_INT128:
00732     *offset += 16;
00733     break;
00734  
00735   case PTP_DTC_STR:
00736     
00737     PTP_GetString((uint8_t *)value->str, (uint8_t *)&(data[*offset]), &len);
00738     *offset += len*2+1;
00739     break;
00740   default:
00741     break;
00742   }
00743 }
00744 
00745                  
00746 /**
00747   * @brief  PTP_GetDevicePropValue
00748   *         Gets objectInfo and fills object_info structure.
00749   * @param  phost: Host handle
00750   * @param  opd: object prop descriptor structure
00751   * @retval None
00752   */             
00753 static uint32_t PTP_GetObjectPropList (USBH_HandleTypeDef *phost, 
00754                                    MTP_PropertiesTypedef *props, 
00755                                    uint32_t len)
00756 { 
00757   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData;   
00758   uint8_t *data = MTP_Handle->ptp.data_container.payload.data;
00759   uint32_t prop_count;
00760   uint32_t offset = 0, i;
00761   
00762  prop_count = LE32(data);
00763 
00764  
00765  if (prop_count == 0) 
00766  {
00767    return 0;
00768  }
00769 
00770  data += sizeof(uint32_t);
00771  len -= sizeof(uint32_t);
00772  
00773  for (i = 0; i < prop_count; i++) 
00774  {
00775    if (len <= 0) 
00776    {
00777      return 0;
00778    }
00779    
00780    props[i].ObjectHandle = LE32(data);
00781    data += sizeof(uint32_t);
00782    len -= sizeof(uint32_t);
00783    
00784    props[i].property = LE16(data);
00785    data += sizeof(uint16_t);
00786    len -= sizeof(uint16_t);
00787    
00788    props[i].datatype = LE16(data);
00789    data += sizeof(uint16_t);
00790    len -= sizeof(uint16_t);
00791    
00792    offset = 0;
00793    
00794    PTP_GetDevicePropValue(phost, &offset, len, &props[i].propval, props[i].datatype);
00795    
00796    data += offset;
00797    len -= offset;
00798  }
00799  
00800  return prop_count;
00801 }
00802                  
00803 /**
00804   * @brief  PTP_GetString
00805   *         Gets SCII String from.
00806   * @param  str: ascii string
00807   * @param  data: Device info structure
00808   * @retval None
00809   */
00810 static void PTP_GetString (uint8_t *str, uint8_t* data, uint16_t *len)
00811 {
00812   uint16_t strlength;
00813   uint16_t idx;
00814   
00815   *len = data[0];
00816   strlength = 2 * data[0]; 
00817   data ++; /* Adjust the offset ignoring the String Len */
00818   
00819   for (idx = 0; idx < strlength; idx+=2 )
00820   {
00821     /* Copy Only the string and ignore the UNICODE ID, hence add the src */
00822     *str =  data[idx];
00823     str++;
00824   }  
00825   *str = 0; /* mark end of string */  
00826 }
00827   
00828 /**
00829   * @brief  PTP_GetString
00830   *         Gets SCII String from.
00831   * @param  str: ascii string
00832   * @param  data: Device info structure
00833   * @retval None
00834   */              
00835 
00836 static uint32_t PTP_GetArray16 (uint16_t *array, uint8_t *data, uint32_t offset)
00837 {
00838   uint32_t size, idx = 0;
00839   
00840   size=LE32(&data[offset]);
00841   while (size > idx) 
00842   {
00843     array[idx] = LE16(&data[offset+(sizeof(uint16_t)*(idx+2))]);
00844     idx++;
00845   }
00846   return size;
00847 }
00848 
00849 /**
00850   * @brief  PTP_GetString
00851   *         Gets SCII String from.
00852   * @param  str: ascii string
00853   * @param  data: Device info structure
00854   * @retval None
00855   */              
00856 
00857 static uint32_t PTP_GetArray32 (uint32_t *array, uint8_t *data, uint32_t offset)
00858 {
00859   uint32_t size, idx = 0;
00860   
00861   size=LE32(&data[offset]);
00862   while (size > idx) 
00863   {
00864     array[idx] = LE32(&data[offset+(sizeof(uint32_t)*(idx+1))]);
00865     idx++;
00866   }
00867   return size;
00868 }
00869 
00870 /*******************************************************************************
00871                              
00872                           PTP Requests
00873 
00874 *******************************************************************************/
00875 /**
00876   * @brief  USBH_PTP_OpenSession
00877   *         Open a new session
00878   * @param  phost: Host handle
00879   * @param  session: Session ID (MUST BE > 0)
00880   * @retval USBH Status
00881   */
00882 USBH_StatusTypeDef USBH_PTP_OpenSession (USBH_HandleTypeDef *phost, uint32_t session)
00883 {
00884   USBH_StatusTypeDef   status = USBH_BUSY; 
00885   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
00886   PTP_ContainerTypedef  ptp_container;
00887   
00888   switch(MTP_Handle->ptp.req_state)
00889   {
00890   case PTP_REQ_SEND:
00891 
00892     /* Init session params */
00893     MTP_Handle->ptp.transaction_id = 0x00000000;
00894     MTP_Handle->ptp.session_id = session;
00895     MTP_Handle->ptp.flags = PTP_DP_NODATA;
00896     
00897     /* Fill operation request params */      
00898     ptp_container.Code = PTP_OC_OpenSession;
00899     ptp_container.SessionID = session;
00900     ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
00901     ptp_container.Param1 = session;
00902     ptp_container.Nparam = 1;
00903     
00904     /* convert request packet inti USB raw packet*/
00905     USBH_PTP_SendRequest (phost, &ptp_container); 
00906         
00907     /* Setup State machine and start transfer */
00908     MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
00909     MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
00910     status = USBH_BUSY;
00911 #if (USBH_USE_OS == 1)
00912     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
00913 #endif      
00914     break;
00915     
00916   case PTP_REQ_WAIT:
00917     status = USBH_PTP_Process(phost);
00918     break;
00919     
00920   default:
00921     break;
00922   }
00923   return status;
00924 }
00925 
00926 /**
00927   * @brief  USBH_PTP_GetDevicePropDesc
00928   *         Gets object partially
00929   * @param  phost: Host handle
00930   * @param  dev_info: Device info structure
00931   * @retval USBH Status
00932   */
00933 USBH_StatusTypeDef USBH_PTP_GetDevicePropDesc (USBH_HandleTypeDef *phost,
00934                                                 uint16_t propcode, 
00935             PTP_DevicePropDescTypdef* devicepropertydesc)
00936 {
00937   USBH_StatusTypeDef   status = USBH_BUSY; 
00938   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
00939   PTP_ContainerTypedef  ptp_container;
00940   uint8_t               *data = MTP_Handle->ptp.data_container.payload.data;
00941   switch(MTP_Handle->ptp.req_state)
00942   {
00943   case PTP_REQ_SEND:
00944 
00945     /* Set operation request type */
00946     MTP_Handle->ptp.flags = PTP_DP_GETDATA;
00947     MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
00948     MTP_Handle->ptp.data_length = 0;
00949     MTP_Handle->ptp.data_packet_counter = 0;
00950     MTP_Handle->ptp.data_packet = 0;
00951    
00952     /* Fill operation request params */      
00953     ptp_container.Code = PTP_OC_GetDevicePropDesc;
00954     ptp_container.SessionID = MTP_Handle->ptp.session_id;
00955     ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
00956     ptp_container.Param1 = propcode;     
00957     ptp_container.Nparam = 1;
00958     
00959     /* convert request packet into USB raw packet*/
00960     USBH_PTP_SendRequest (phost, &ptp_container); 
00961         
00962     /* Setup State machine and start transfer */
00963     MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
00964     MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
00965     status = USBH_BUSY;
00966 #if (USBH_USE_OS == 1)
00967     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
00968 #endif      
00969     break;
00970     
00971   case PTP_REQ_WAIT:
00972     status = USBH_PTP_Process(phost);
00973     
00974     if(status == USBH_OK)
00975     {
00976     devicepropertydesc->DevicePropertyCode = LE16(&data[PTP_dpd_DevicePropertyCode]);
00977     devicepropertydesc->DataType = LE16(&data[PTP_dpd_DataType]);
00978     devicepropertydesc->GetSet = *(uint8_t *)(&data[PTP_dpd_GetSet]);
00979     devicepropertydesc->FormFlag =  PTP_DPFF_None;
00980     }
00981     break;
00982     
00983   default:
00984     break;
00985   }
00986   return status;
00987 }
00988 /**
00989   * @brief  USBH_PTP_GetDeviceInfo
00990   *         Gets device info dataset and fills deviceinfo structure.
00991   * @param  phost: Host handle
00992   * @param  dev_info: Device info structure
00993   * @retval USBH Status
00994   */
00995 USBH_StatusTypeDef USBH_PTP_GetDeviceInfo (USBH_HandleTypeDef *phost, PTP_DeviceInfoTypedef *dev_info)
00996 {
00997   USBH_StatusTypeDef   status = USBH_BUSY; 
00998   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
00999   PTP_ContainerTypedef  ptp_container;
01000   
01001   switch(MTP_Handle->ptp.req_state)
01002   {
01003   case PTP_REQ_SEND:
01004 
01005     /* Set operation request type */
01006     MTP_Handle->ptp.flags = PTP_DP_GETDATA;
01007     MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
01008     MTP_Handle->ptp.data_length = 0;
01009     MTP_Handle->ptp.data_packet_counter = 0;
01010     MTP_Handle->ptp.data_packet = 0;
01011    
01012     /* Fill operation request params */      
01013     ptp_container.Code = PTP_OC_GetDeviceInfo;
01014     ptp_container.SessionID = MTP_Handle->ptp.session_id;
01015     ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
01016     ptp_container.Nparam = 0;
01017     
01018     /* convert request packet inti USB raw packet*/
01019     USBH_PTP_SendRequest (phost, &ptp_container); 
01020         
01021     /* Setup State machine and start transfer */
01022     MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
01023     MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
01024     status = USBH_BUSY; 
01025 #if (USBH_USE_OS == 1)
01026     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
01027 #endif     
01028     break;
01029     
01030   case PTP_REQ_WAIT:
01031     status = USBH_PTP_Process(phost);
01032     
01033     if(status == USBH_OK)
01034     {
01035        PTP_DecodeDeviceInfo (phost, dev_info);
01036     }
01037     break;
01038     
01039   default:
01040     break;
01041   }
01042   return status;
01043 }
01044 
01045 /**
01046   * @brief  USBH_PTP_GetStorageIds
01047   *         Gets device info dataset and fills deviceinfo structure.
01048   * @param  phost: Host handle
01049   * @param  dev_info: Device info structure
01050   * @retval USBH Status
01051   */
01052 USBH_StatusTypeDef USBH_PTP_GetStorageIds (USBH_HandleTypeDef *phost, PTP_StorageIDsTypedef *storage_ids)
01053 {
01054   USBH_StatusTypeDef   status = USBH_BUSY; 
01055   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
01056   PTP_ContainerTypedef  ptp_container;
01057   
01058   switch(MTP_Handle->ptp.req_state)
01059   {
01060   case PTP_REQ_SEND:
01061 
01062     /* Set operation request type */
01063     MTP_Handle->ptp.flags = PTP_DP_GETDATA;
01064     MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
01065     MTP_Handle->ptp.data_length = 0;
01066     MTP_Handle->ptp.data_packet_counter = 0;
01067     MTP_Handle->ptp.data_packet = 0;
01068    
01069     /* Fill operation request params */      
01070     ptp_container.Code = PTP_OC_GetStorageIDs;
01071     ptp_container.SessionID = MTP_Handle->ptp.session_id;
01072     ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
01073     ptp_container.Nparam = 0;
01074     
01075     /* convert request packet inti USB raw packet*/
01076     USBH_PTP_SendRequest (phost, &ptp_container); 
01077         
01078     /* Setup State machine and start transfer */
01079     MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
01080     MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
01081     status = USBH_BUSY;
01082 #if (USBH_USE_OS == 1)
01083     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
01084 #endif      
01085     break;
01086     
01087   case PTP_REQ_WAIT:
01088     status = USBH_PTP_Process(phost);
01089     
01090     if(status == USBH_OK)
01091     {
01092       PTP_GetStorageIDs (phost, storage_ids);
01093     }
01094     break;
01095     
01096   default:
01097     break;
01098   }
01099   return status;
01100 }
01101                  
01102 /**
01103   * @brief  USBH_PTP_GetDeviceInfo
01104   *         Gets device info dataset and fills deviceinfo structure.
01105   * @param  phost: Host handle
01106   * @param  dev_info: Device info structure
01107   * @retval USBH Status
01108   */
01109 USBH_StatusTypeDef USBH_PTP_GetStorageInfo (USBH_HandleTypeDef *phost, uint32_t storage_id, PTP_StorageInfoTypedef *storage_info)
01110 {
01111   USBH_StatusTypeDef   status = USBH_BUSY; 
01112   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
01113   PTP_ContainerTypedef  ptp_container;
01114   
01115   switch(MTP_Handle->ptp.req_state)
01116   {
01117   case PTP_REQ_SEND:
01118 
01119     /* Set operation request type */
01120     MTP_Handle->ptp.flags = PTP_DP_GETDATA;
01121     MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
01122     MTP_Handle->ptp.data_length = 0;
01123     MTP_Handle->ptp.data_packet_counter = 0;
01124     MTP_Handle->ptp.data_packet = 0;
01125    
01126     /* Fill operation request params */      
01127     ptp_container.Code = PTP_OC_GetStorageInfo;
01128     ptp_container.SessionID = MTP_Handle->ptp.session_id;
01129     ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
01130     ptp_container.Param1 = storage_id;    
01131     ptp_container.Nparam = 1;
01132     
01133     /* convert request packet inti USB raw packet*/
01134     USBH_PTP_SendRequest (phost, &ptp_container); 
01135         
01136     /* Setup State machine and start transfer */
01137     MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
01138     MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
01139     status = USBH_BUSY;
01140 #if (USBH_USE_OS == 1)
01141     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
01142 #endif      
01143     break;
01144     
01145   case PTP_REQ_WAIT:
01146     status = USBH_PTP_Process(phost);
01147     
01148     if(status == USBH_OK)
01149     {
01150       PTP_GetStorageInfo (phost, storage_id, storage_info);
01151     }
01152     break;
01153     
01154   default:
01155     break;
01156   }
01157   return status;
01158 }
01159                  
01160 /**
01161   * @brief  USBH_PTP_GetNumObjects
01162   *         Gets device info dataset and fills deviceinfo structure.
01163   * @param  phost: Host handle
01164   * @param  dev_info: Device info structure
01165   * @retval USBH Status
01166   */
01167 USBH_StatusTypeDef USBH_PTP_GetNumObjects (USBH_HandleTypeDef *phost, 
01168                                            uint32_t storage_id, 
01169                                            uint32_t objectformatcode, 
01170                                            uint32_t associationOH,
01171                                            uint32_t* numobs)
01172 {
01173   USBH_StatusTypeDef   status = USBH_BUSY; 
01174   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
01175   PTP_ContainerTypedef  ptp_container;
01176   
01177   switch(MTP_Handle->ptp.req_state)
01178   {
01179   case PTP_REQ_SEND:
01180 
01181     /* Set operation request type */
01182     MTP_Handle->ptp.flags = PTP_DP_NODATA;
01183    
01184     /* Fill operation request params */      
01185     ptp_container.Code = PTP_OC_GetNumObjects;
01186     ptp_container.SessionID = MTP_Handle->ptp.session_id;
01187     ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
01188     ptp_container.Param1 = storage_id;  
01189     ptp_container.Param2 = objectformatcode;
01190     ptp_container.Param3 = associationOH;    
01191     ptp_container.Nparam = 3;
01192     
01193     /* convert request packet into USB raw packet*/
01194     USBH_PTP_SendRequest (phost, &ptp_container); 
01195         
01196     /* Setup State machine and start transfer */
01197     MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
01198     MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
01199     status = USBH_BUSY;
01200 #if (USBH_USE_OS == 1)
01201     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
01202 #endif      
01203     break;
01204     
01205   case PTP_REQ_WAIT:
01206     status = USBH_PTP_Process(phost);
01207     
01208     if(status == USBH_OK)
01209     {
01210       *numobs = MTP_Handle->ptp.resp_container.param1;
01211     }
01212     break;
01213     
01214   default:
01215     break;
01216   }
01217   return status;
01218 }
01219 
01220 /**
01221   * @brief  USBH_PTP_GetObjectHandles
01222   *         Gets device info dataset and fills deviceinfo structure.
01223   * @param  phost: Host handle
01224   * @param  dev_info: Device info structure
01225   * @retval USBH Status
01226   */
01227 USBH_StatusTypeDef USBH_PTP_GetObjectHandles (USBH_HandleTypeDef *phost, 
01228                                            uint32_t storage_id, 
01229                                            uint32_t objectformatcode, 
01230                                            uint32_t associationOH,
01231                                            PTP_ObjectHandlesTypedef* objecthandles)
01232 {
01233   USBH_StatusTypeDef   status = USBH_BUSY; 
01234   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
01235   PTP_ContainerTypedef  ptp_container;
01236   
01237   switch(MTP_Handle->ptp.req_state)
01238   {
01239   case PTP_REQ_SEND:
01240 
01241     /* Set operation request type */
01242     MTP_Handle->ptp.flags = PTP_DP_GETDATA;
01243     MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
01244     MTP_Handle->ptp.data_length = 0;
01245     MTP_Handle->ptp.data_packet_counter = 0;
01246     MTP_Handle->ptp.data_packet = 0;
01247    
01248     /* Fill operation request params */      
01249     ptp_container.Code = PTP_OC_GetObjectHandles;
01250     ptp_container.SessionID = MTP_Handle->ptp.session_id;
01251     ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
01252     ptp_container.Param1 = storage_id;  
01253     ptp_container.Param2 = objectformatcode;
01254     ptp_container.Param3 = associationOH;    
01255     ptp_container.Nparam = 3;
01256     
01257     /* convert request packet into USB raw packet*/
01258     USBH_PTP_SendRequest (phost, &ptp_container); 
01259         
01260     /* Setup State machine and start transfer */
01261     MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
01262     MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
01263     status = USBH_BUSY;
01264 #if (USBH_USE_OS == 1)
01265     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
01266 #endif      
01267     break;
01268     
01269   case PTP_REQ_WAIT:
01270     status = USBH_PTP_Process(phost);
01271     
01272     if(status == USBH_OK)
01273     {
01274        objecthandles->n = PTP_GetArray32 (objecthandles->Handler, 
01275                                           MTP_Handle->ptp.data_container.payload.data, 
01276                                           0); 
01277     }
01278     break;
01279     
01280   default:
01281     break;
01282   }
01283   return status;
01284 }
01285                  
01286 /**
01287   * @brief  USBH_PTP_GetObjectInfo
01288   *         Gets objert info
01289   * @param  phost: Host handle
01290   * @param  dev_info: Device info structure
01291   * @retval USBH Status
01292   */
01293 USBH_StatusTypeDef USBH_PTP_GetObjectInfo (USBH_HandleTypeDef *phost, 
01294                                            uint32_t handle, 
01295                                            PTP_ObjectInfoTypedef* object_info)
01296 {
01297   USBH_StatusTypeDef   status = USBH_BUSY; 
01298   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
01299   PTP_ContainerTypedef  ptp_container;
01300   
01301   switch(MTP_Handle->ptp.req_state)
01302   {
01303   case PTP_REQ_SEND:
01304 
01305     /* Set operation request type */
01306     MTP_Handle->ptp.flags = PTP_DP_GETDATA;
01307     MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
01308     MTP_Handle->ptp.data_length = 0;
01309     MTP_Handle->ptp.data_packet_counter = 0;
01310     MTP_Handle->ptp.data_packet = 0;
01311    
01312     /* Fill operation request params */      
01313     ptp_container.Code = PTP_OC_GetObjectInfo;
01314     ptp_container.SessionID = MTP_Handle->ptp.session_id;
01315     ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
01316     ptp_container.Param1 = handle;  
01317     ptp_container.Nparam = 1;
01318     
01319     /* convert request packet into USB raw packet*/
01320     USBH_PTP_SendRequest (phost, &ptp_container); 
01321         
01322     /* Setup State machine and start transfer */
01323     MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
01324     MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
01325     status = USBH_BUSY;
01326 #if (USBH_USE_OS == 1)
01327     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
01328 #endif      
01329     break;
01330     
01331   case PTP_REQ_WAIT:
01332     status = USBH_PTP_Process(phost);
01333     
01334     if(status == USBH_OK)
01335     {
01336        PTP_GetObjectInfo (phost, object_info);
01337     }
01338     break;
01339     
01340   default:
01341     break;
01342   }
01343   return status;
01344 }
01345                  
01346 /**
01347   * @brief  USBH_PTP_DeleteObject
01348   *         Delete an object.
01349   * @param  phost: Host handle
01350   * @param  handle : Object Handle
01351   * @retval USBH Status
01352   */
01353 USBH_StatusTypeDef USBH_PTP_DeleteObject (USBH_HandleTypeDef *phost,
01354                                           uint32_t handle,
01355                                           uint32_t objectformatcode)
01356 {
01357   USBH_StatusTypeDef   status = USBH_BUSY; 
01358   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
01359   PTP_ContainerTypedef  ptp_container;
01360   
01361   switch(MTP_Handle->ptp.req_state)
01362   {
01363   case PTP_REQ_SEND:
01364 
01365     /* Set operation request type */
01366     MTP_Handle->ptp.flags = PTP_DP_NODATA;
01367    
01368     /* Fill operation request params */      
01369     ptp_container.Code = PTP_OC_DeleteObject;
01370     ptp_container.SessionID = MTP_Handle->ptp.session_id;
01371     ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
01372     ptp_container.Param1 = handle;  
01373     ptp_container.Param2 = objectformatcode;
01374     ptp_container.Nparam = 2;
01375     
01376     /* convert request packet into USB raw packet*/
01377     USBH_PTP_SendRequest (phost, &ptp_container); 
01378         
01379     /* Setup State machine and start transfer */
01380     MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
01381     MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
01382     status = USBH_BUSY;
01383 #if (USBH_USE_OS == 1)
01384     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
01385 #endif      
01386     break;
01387     
01388   case PTP_REQ_WAIT:
01389     status = USBH_PTP_Process(phost);
01390     break;
01391     
01392   default:
01393     break;
01394   }
01395   return status;
01396 }
01397                  
01398 /**
01399   * @brief  USBH_PTP_GetObject
01400   *         Gets object
01401   * @param  phost: Host handle
01402   * @param  dev_info: Device info structure
01403   * @retval USBH Status
01404   */
01405 USBH_StatusTypeDef USBH_PTP_GetObject (USBH_HandleTypeDef *phost, 
01406                                            uint32_t handle, 
01407                                            uint8_t *object)
01408 {
01409   USBH_StatusTypeDef   status = USBH_BUSY; 
01410   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
01411   PTP_ContainerTypedef  ptp_container;
01412   
01413   switch(MTP_Handle->ptp.req_state)
01414   {
01415   case PTP_REQ_SEND:
01416 
01417     /* Set operation request type */
01418     MTP_Handle->ptp.flags = PTP_DP_GETDATA;
01419     MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
01420     MTP_Handle->ptp.data_length = 0;
01421     MTP_Handle->ptp.data_packet_counter = 0;
01422     MTP_Handle->ptp.data_packet = 0;
01423     
01424     /* set object control params */
01425     MTP_Handle->ptp.object_ptr = object;
01426     
01427     /* Fill operation request params */      
01428     ptp_container.Code = PTP_OC_GetObject;
01429     ptp_container.SessionID = MTP_Handle->ptp.session_id;
01430     ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
01431     ptp_container.Param1 = handle;  
01432     ptp_container.Nparam = 1;
01433 
01434     
01435     /* convert request packet into USB raw packet*/
01436     USBH_PTP_SendRequest (phost, &ptp_container); 
01437         
01438     /* Setup State machine and start transfer */
01439     MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
01440     MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
01441     status = USBH_BUSY;
01442 #if (USBH_USE_OS == 1)
01443     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
01444 #endif      
01445     break;
01446     
01447   case PTP_REQ_WAIT:
01448     status = USBH_PTP_Process(phost);
01449     
01450     if(status == USBH_OK)
01451     {
01452       /* first packet is in the PTP data payload buffer */
01453       if(MTP_Handle->ptp.iteration == 0)
01454       {
01455         /* copy it to object */
01456         USBH_memcpy(MTP_Handle->ptp.object_ptr, MTP_Handle->ptp.data_container.payload.data, PTP_USB_BULK_PAYLOAD_LEN_READ);
01457       }
01458     }
01459     break;
01460     
01461   default:
01462     break;
01463   }
01464   return status;
01465 }
01466                  
01467 /**
01468   * @brief  USBH_PTP_GetPartialObject
01469   *         Gets object partially
01470   * @param  phost: Host handle
01471   * @param  dev_info: Device info structure
01472   * @retval USBH Status
01473   */
01474 USBH_StatusTypeDef USBH_PTP_GetPartialObject(USBH_HandleTypeDef *phost, 
01475                                            uint32_t handle, 
01476                                            uint32_t offset,
01477                                            uint32_t maxbytes, 
01478                                            uint8_t *object,
01479                                            uint32_t *len)
01480 {
01481   USBH_StatusTypeDef   status = USBH_BUSY; 
01482   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
01483   PTP_ContainerTypedef  ptp_container;
01484   
01485   switch(MTP_Handle->ptp.req_state)
01486   {
01487   case PTP_REQ_SEND:
01488 
01489     /* Set operation request type */
01490     MTP_Handle->ptp.flags = PTP_DP_GETDATA;
01491     MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
01492     MTP_Handle->ptp.data_length = 0;
01493     MTP_Handle->ptp.data_packet_counter = 0;
01494     MTP_Handle->ptp.data_packet = 0;
01495 
01496     /* set object control params */
01497     MTP_Handle->ptp.object_ptr = object;
01498     
01499     /* Fill operation request params */      
01500     ptp_container.Code = PTP_OC_GetPartialObject;
01501     ptp_container.SessionID = MTP_Handle->ptp.session_id;
01502     ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
01503     ptp_container.Param1 = handle;  
01504     ptp_container.Param2 = offset;
01505     ptp_container.Param3 = maxbytes;   
01506     ptp_container.Nparam = 3;
01507     
01508     /* convert request packet into USB raw packet*/
01509     USBH_PTP_SendRequest (phost, &ptp_container); 
01510         
01511     /* Setup State machine and start transfer */
01512     MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
01513     MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
01514     status = USBH_BUSY;
01515 #if (USBH_USE_OS == 1)
01516     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
01517 #endif      
01518     break;
01519     
01520   case PTP_REQ_WAIT:
01521     status = USBH_PTP_Process(phost);
01522     
01523     if(status == USBH_OK)
01524     {
01525       *len = MTP_Handle->ptp.resp_container.param1;
01526       /* first packet is in the PTP data payload buffer */
01527       if(MTP_Handle->ptp.iteration == 0)
01528       {
01529         /* copy it to object */
01530         USBH_memcpy(MTP_Handle->ptp.object_ptr, MTP_Handle->ptp.data_container.payload.data, *len);
01531       }      
01532     }
01533     break;
01534     
01535   default:
01536     break;
01537   }
01538   return status;
01539 }
01540                  
01541 /**
01542   * @brief  USBH_PTP_GetObjectPropsSupported
01543   *         Gets object partially
01544   * @param  phost: Host handle
01545   * @param  dev_info: Device info structure
01546   * @retval USBH Status
01547   */
01548 USBH_StatusTypeDef USBH_PTP_GetObjectPropsSupported (USBH_HandleTypeDef *phost,
01549                                                      uint16_t ofc,
01550                                                      uint32_t *propnum, 
01551                                                      uint16_t *props)
01552 {
01553   USBH_StatusTypeDef   status = USBH_BUSY; 
01554   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
01555   PTP_ContainerTypedef  ptp_container;
01556   
01557   switch(MTP_Handle->ptp.req_state)
01558   {
01559   case PTP_REQ_SEND:
01560 
01561     /* Set operation request type */
01562     MTP_Handle->ptp.flags = PTP_DP_GETDATA;
01563     MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
01564     MTP_Handle->ptp.data_length = 0;
01565     MTP_Handle->ptp.data_packet_counter = 0;
01566     MTP_Handle->ptp.data_packet = 0;
01567    
01568     /* Fill operation request params */      
01569     ptp_container.Code = PTP_OC_GetObjectPropsSupported;
01570     ptp_container.SessionID = MTP_Handle->ptp.session_id;
01571     ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
01572     ptp_container.Param1 = ofc;  
01573     ptp_container.Nparam = 1;
01574     
01575     /* convert request packet into USB raw packet*/
01576     USBH_PTP_SendRequest (phost, &ptp_container); 
01577         
01578     /* Setup State machine and start transfer */
01579     MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
01580     MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
01581     status = USBH_BUSY;
01582 #if (USBH_USE_OS == 1)
01583     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
01584 #endif      
01585     break;
01586     
01587   case PTP_REQ_WAIT:
01588     status = USBH_PTP_Process(phost);
01589     
01590     if(status == USBH_OK)
01591     {
01592       *propnum = PTP_GetArray16 (props, MTP_Handle->ptp.data_container.payload.data, 0);      
01593     }
01594     break;
01595     
01596   default:
01597     break;
01598   }
01599   return status;
01600 }
01601                  
01602 /**
01603   * @brief  USBH_PTP_GetObjectPropDesc
01604   *         Gets object partially
01605   * @param  phost: Host handle
01606   * @param  dev_info: Device info structure
01607   * @retval USBH Status
01608   */
01609 USBH_StatusTypeDef USBH_PTP_GetObjectPropDesc (USBH_HandleTypeDef *phost,
01610                                                 uint16_t opc, 
01611                                                 uint16_t ofc, 
01612                                                 PTP_ObjectPropDescTypeDef *opd)
01613 {
01614   USBH_StatusTypeDef   status = USBH_BUSY; 
01615   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
01616   PTP_ContainerTypedef  ptp_container;
01617   
01618   switch(MTP_Handle->ptp.req_state)
01619   {
01620   case PTP_REQ_SEND:
01621 
01622     /* Set operation request type */
01623     MTP_Handle->ptp.flags = PTP_DP_GETDATA;
01624     MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
01625     MTP_Handle->ptp.data_length = 0;
01626     MTP_Handle->ptp.data_packet_counter = 0;
01627     MTP_Handle->ptp.data_packet = 0;
01628    
01629     /* Fill operation request params */      
01630     ptp_container.Code = PTP_OC_GetObjectPropDesc;
01631     ptp_container.SessionID = MTP_Handle->ptp.session_id;
01632     ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
01633     ptp_container.Param1 = opc;  
01634     ptp_container.Param2 = ofc;      
01635     ptp_container.Nparam = 2;
01636     
01637     /* convert request packet into USB raw packet*/
01638     USBH_PTP_SendRequest (phost, &ptp_container); 
01639         
01640     /* Setup State machine and start transfer */
01641     MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
01642     MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
01643     status = USBH_BUSY;
01644 #if (USBH_USE_OS == 1)
01645     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
01646 #endif      
01647     break;
01648     
01649   case PTP_REQ_WAIT:
01650     status = USBH_PTP_Process(phost);
01651     
01652     if(status == USBH_OK)
01653     {
01654      PTP_GetObjectPropDesc(phost, opd, MTP_Handle->ptp.data_length);
01655     }
01656     break;
01657     
01658   default:
01659     break;
01660   }
01661   return status;
01662 }
01663                  
01664 /**
01665   * @brief  USBH_PTP_GetObjectPropList
01666   *         Gets object partially
01667   * @param  phost: Host handle
01668   * @param  dev_info: Device info structure
01669   * @retval USBH Status
01670   */
01671 USBH_StatusTypeDef USBH_PTP_GetObjectPropList (USBH_HandleTypeDef *phost,
01672                                                 uint32_t handle, 
01673                                                 MTP_PropertiesTypedef *pprops, 
01674                                                 uint32_t *nrofprops)
01675 {
01676   USBH_StatusTypeDef   status = USBH_BUSY; 
01677   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
01678   PTP_ContainerTypedef  ptp_container;
01679   
01680   switch(MTP_Handle->ptp.req_state)
01681   {
01682   case PTP_REQ_SEND:
01683 
01684     /* Set operation request type */
01685     MTP_Handle->ptp.flags = PTP_DP_GETDATA;
01686     MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
01687     MTP_Handle->ptp.data_length = 0;
01688     MTP_Handle->ptp.data_packet_counter = 0;
01689     MTP_Handle->ptp.data_packet = 0;
01690    
01691     /* copy first packet of the object into data container */
01692     USBH_memcpy(MTP_Handle->ptp.data_container.payload.data, MTP_Handle->ptp.object_ptr, PTP_USB_BULK_PAYLOAD_LEN_READ);
01693        
01694     /* Fill operation request params */      
01695     ptp_container.Code = PTP_OC_GetObjPropList;
01696     ptp_container.SessionID = MTP_Handle->ptp.session_id;
01697     ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
01698     ptp_container.Param1 = handle;  
01699     ptp_container.Param2 = 0x00000000U;  /* 0x00000000U should be "all formats" */
01700     ptp_container.Param3 = 0xFFFFFFFFU;  /* 0xFFFFFFFFU should be "all properties" */
01701     ptp_container.Param4 = 0x00000000U;
01702     ptp_container.Param5 = 0xFFFFFFFFU;  /* Return full tree below the Param1 handle */
01703     ptp_container.Nparam = 5;  
01704     
01705     /* convert request packet into USB raw packet*/
01706     USBH_PTP_SendRequest (phost, &ptp_container); 
01707         
01708     /* Setup State machine and start transfer */
01709     MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
01710     MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
01711     status = USBH_BUSY;
01712 #if (USBH_USE_OS == 1)
01713     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
01714 #endif      
01715     break;
01716     
01717   case PTP_REQ_WAIT:
01718     status = USBH_PTP_Process(phost);
01719     
01720     if(status == USBH_OK)
01721     {
01722       PTP_GetObjectPropList (phost, pprops,  MTP_Handle->ptp.data_length);
01723     }
01724     break;
01725     
01726   default:
01727     break;
01728   }
01729   return status;
01730 }
01731                
01732 /**
01733   * @brief  USBH_PTP_SendObject
01734   *         Send an object
01735   * @param  phost: Host handle
01736   * @param  dev_info: Device info structure
01737   * @retval USBH Status
01738   */
01739 USBH_StatusTypeDef USBH_PTP_SendObject (USBH_HandleTypeDef *phost, 
01740                                            uint32_t handle, 
01741                                            uint8_t *object,
01742                                            uint32_t size)
01743 {
01744   USBH_StatusTypeDef   status = USBH_BUSY; 
01745   MTP_HandleTypeDef    *MTP_Handle =  (MTP_HandleTypeDef *)phost->pActiveClass->pData; 
01746   PTP_ContainerTypedef  ptp_container;
01747   
01748   switch(MTP_Handle->ptp.req_state)
01749   {
01750   case PTP_REQ_SEND:
01751 
01752     /* Set operation request type */
01753     MTP_Handle->ptp.flags = PTP_DP_SENDDATA;
01754     MTP_Handle->ptp.data_ptr = (uint8_t *)&(MTP_Handle->ptp.data_container);
01755     MTP_Handle->ptp.data_packet_counter = 0;
01756     MTP_Handle->ptp.data_packet = 0;
01757     MTP_Handle->ptp.iteration = 0;
01758     
01759     /* set object control params */
01760     MTP_Handle->ptp.object_ptr = object;
01761     MTP_Handle->ptp.data_length = size;    
01762     
01763     /* Fill operation request params */      
01764     ptp_container.Code = PTP_OC_SendObject;
01765     ptp_container.SessionID = MTP_Handle->ptp.session_id;
01766     ptp_container.Transaction_ID = MTP_Handle->ptp.transaction_id ++;
01767     ptp_container.Nparam = 0;
01768 
01769     
01770     /* convert request packet into USB raw packet*/
01771     USBH_PTP_SendRequest (phost, &ptp_container); 
01772         
01773     /* Setup State machine and start transfer */
01774     MTP_Handle->ptp.state = PTP_OP_REQUEST_STATE;
01775     MTP_Handle->ptp.req_state = PTP_REQ_WAIT;
01776     status = USBH_BUSY; 
01777 #if (USBH_USE_OS == 1)
01778     osMessagePut ( phost->os_event, USBH_STATE_CHANGED_EVENT, 0);
01779 #endif      
01780     break;
01781     
01782   case PTP_REQ_WAIT:
01783     status = USBH_PTP_Process(phost);
01784     break;
01785     
01786   default:
01787     break;
01788   }
01789   return status;
01790 }               
01791 /**
01792 * @}
01793 */ 
01794 
01795 /**
01796 * @}
01797 */ 
01798 
01799 /**
01800 * @}
01801 */
01802 
01803 /**
01804 * @}
01805 */ 
01806 
01807 /**
01808 * @}
01809 */
01810 
01811 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
01812 
01813 
01814