1 /******************************************************************************************************************************************
2 * 文件名称: usbh_mtp.c
3 * 功能说明: This file includes the PTP operations layer.
4 * 技术支持: http://www.synwit.com.cn/e/tool/gbook/?bid=1
5 * 注意事项:
6 * 版本日期: V1.1.0 2020年11月3日
7 * 升级记录:
8 *
9 *
10 *******************************************************************************************************************************************
11 * @attention
12 *
13 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS WITH CODING INFORMATION
14 * REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME. AS A RESULT, SYNWIT SHALL NOT BE HELD LIABLE
15 * FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
16 * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN IN CONN-
17 * -ECTION WITH THEIR PRODUCTS.
18 *
19 * COPYRIGHT 2012 Synwit Technology
20 *******************************************************************************************************************************************/
21 #include <string.h>
22 #include "SWM341.h"
23 #include "usbh_core.h"
24 #include "usbh_mtp.h"
25
26
27 /******************************************************************************************************************************************
28 * 函数名称: PTP_GetDevicePropValue()
29 * 功能说明:
30 * 输 入: 无
31 * 输 出: 无
32 * 注意事项: 无
33 ******************************************************************************************************************************************/
PTP_GetDevicePropValue(USBH_Info_t * phost,uint32_t * offset,uint32_t total,PTP_PropertyValue_t * value,uint16_t datatype)34 void PTP_GetDevicePropValue(USBH_Info_t *phost, uint32_t *offset, uint32_t total, PTP_PropertyValue_t *value, uint16_t datatype)
35 {
36 uint8_t *data = USBH_MTP_Info.data_container.payload;
37 uint16_t len;
38 switch(datatype)
39 {
40 case PTP_DTC_INT8:
41 value->i8 = *(int8_t *)(void *) & (data[*offset]);
42 *offset += 1U;
43 break;
44
45 case PTP_DTC_UINT8:
46 value->u8 = *(uint8_t *) & (data[*offset]);
47 *offset += 1U;
48 break;
49
50 case PTP_DTC_INT16:
51 value->i16 = *(int16_t *)(void *) & (data[*offset]);
52 *offset += 2U;
53 break;
54
55 case PTP_DTC_UINT16:
56 value->u16 = PTP_LE16(&(data[*offset]));
57 *offset += 2U;
58 break;
59
60 case PTP_DTC_INT32:
61 value->i32 = *(int32_t *)(void *)(&(data[*offset]));
62 *offset += 4U;
63 break;
64
65 case PTP_DTC_UINT32:
66 value->u32 = PTP_LE32(&(data[*offset]));
67 *offset += 4U;
68 break;
69
70 case PTP_DTC_INT64:
71 value->i64 = *(int64_t *)(void *)(&(data[*offset]));
72 *offset += 8U;
73 break;
74
75 case PTP_DTC_UINT64:
76 value->u64 = PTP_LE64(&(data[*offset]));
77 *offset += 8U;
78 break;
79
80 case PTP_DTC_UINT128:
81 *offset += 16U;
82 break;
83
84 case PTP_DTC_INT128:
85 *offset += 16U;
86 break;
87
88 case PTP_DTC_STR:
89 PTP_GetString((uint8_t *)(void *)value->str, (uint8_t *) & (data[*offset]), &len);
90 *offset += (uint32_t)(len * 2U) + 1U;
91 break;
92
93 default:
94 break;
95 }
96 }
97
98
99 /******************************************************************************************************************************************
100 * 函数名称: PTP_GetString()
101 * 功能说明:
102 * 输 入: 无
103 * 输 出: 无
104 * 注意事项: 无
105 ******************************************************************************************************************************************/
PTP_GetString(uint8_t * str,uint8_t * data,uint16_t * len)106 void PTP_GetString(uint8_t *str, uint8_t *data, uint16_t *len)
107 {
108 uint16_t strlength;
109 uint16_t idx;
110
111 *len = data[0];
112 strlength = (uint16_t)(2U * (uint32_t)data[0]);
113 data ++; /* Adjust the offset ignoring the String Len */
114
115 for (idx = 0U; idx < strlength; idx += 2U)
116 {
117 /* Copy Only the string and ignore the UNICODE ID, hence add the src */
118 *str = data[idx];
119 str++;
120 }
121 *str = 0U; /* mark end of string */
122 }
123
124
125 /******************************************************************************************************************************************
126 * 函数名称: PTP_GetArray16()
127 * 功能说明:
128 * 输 入: 无
129 * 输 出: 无
130 * 注意事项: 无
131 ******************************************************************************************************************************************/
PTP_GetArray16(uint16_t * array,uint8_t * data,uint32_t offset)132 uint32_t PTP_GetArray16(uint16_t *array, uint8_t *data, uint32_t offset)
133 {
134 uint32_t size, idx = 0U;
135
136 size = PTP_LE32(&data[offset]);
137 while(size > idx)
138 {
139 array[idx] = (uint16_t)data[offset + (sizeof(uint16_t) * (idx + 2U))];
140 idx++;
141 }
142 return size;
143 }
144
145
146 /******************************************************************************************************************************************
147 * 函数名称: PTP_GetArray32()
148 * 功能说明:
149 * 输 入: 无
150 * 输 出: 无
151 * 注意事项: 无
152 ******************************************************************************************************************************************/
PTP_GetArray32(uint32_t * array,uint8_t * data,uint32_t offset)153 uint32_t PTP_GetArray32(uint32_t *array, uint8_t *data, uint32_t offset)
154 {
155 uint32_t size, idx = 0U;
156
157 size = PTP_LE32(&data[offset]);
158 while(size > idx)
159 {
160 array[idx] = PTP_LE32(&data[offset + (sizeof(uint32_t) * (idx + 1U))]);
161 idx++;
162 }
163 return size;
164 }
165
166
167 /******************************************************************************************************************************************
168 * 函数名称: PTP_DecodeDeviceInfo()
169 * 功能说明:
170 * 输 入: 无
171 * 输 出: 无
172 * 注意事项: 无
173 ******************************************************************************************************************************************/
PTP_DecodeDeviceInfo(USBH_Info_t * phost,PTP_DeviceInfo_t * dev_info)174 void PTP_DecodeDeviceInfo(USBH_Info_t *phost, PTP_DeviceInfo_t *dev_info)
175 {
176 uint8_t *data = USBH_MTP_Info.data_container.payload;
177 uint32_t totallen;
178 uint16_t len;
179
180 dev_info->StandardVersion = PTP_LE16(&data[PTP_di_StandardVersion]);
181 dev_info->VendorExtensionID = PTP_LE32(&data[PTP_di_VendorExtensionID]);
182 dev_info->VendorExtensionVersion = PTP_LE16(&data[PTP_di_VendorExtensionVersion]);
183 PTP_GetString(dev_info->VendorExtensionDesc, &data[PTP_di_VendorExtensionDesc], &len);
184
185 totallen = (uint32_t)(len * 2U) + 1U;
186 dev_info->FunctionalMode = PTP_LE16(&data[PTP_di_FunctionalMode + totallen]);
187 dev_info->OperationsSupportedNbr = PTP_GetArray16((uint16_t *)(void *)&dev_info->OperationsSupported, data, PTP_di_OperationsSupported + totallen);
188
189 totallen = totallen + (dev_info->OperationsSupportedNbr * sizeof(uint16_t)) + sizeof(uint32_t);
190 dev_info->EventsSupportedNbr = PTP_GetArray16((uint16_t *)(void *)&dev_info->EventsSupported, data, PTP_di_OperationsSupported + totallen);
191
192 totallen = totallen + (dev_info->EventsSupportedNbr * sizeof(uint16_t)) + sizeof(uint32_t);
193 dev_info->DevicePropertiesSupportedNbr = PTP_GetArray16((uint16_t *)(void *)&dev_info->DevicePropertiesSupported, data, PTP_di_OperationsSupported + totallen);
194
195 totallen = totallen + (dev_info->DevicePropertiesSupportedNbr * sizeof(uint16_t)) + sizeof(uint32_t);
196
197 dev_info->CaptureFormatsNbr = PTP_GetArray16((uint16_t *)(void *)&dev_info->CaptureFormats, data, PTP_di_OperationsSupported + totallen);
198
199 totallen = totallen + (dev_info->CaptureFormatsNbr * sizeof(uint16_t)) + sizeof(uint32_t);
200 dev_info->ImageFormatsNbr = PTP_GetArray16((uint16_t *)(void *)&dev_info->ImageFormats, data, PTP_di_OperationsSupported + totallen);
201
202 totallen = totallen + (dev_info->ImageFormatsNbr * sizeof(uint16_t)) + sizeof(uint32_t);
203 PTP_GetString(dev_info->Manufacturer, &data[PTP_di_OperationsSupported + totallen], &len);
204
205 totallen += (uint32_t)(len * 2U) + 1U;
206 PTP_GetString(dev_info->Model, &data[PTP_di_OperationsSupported + totallen], &len);
207
208 totallen += (uint32_t)(len * 2U) + 1U;
209 PTP_GetString(dev_info->DeviceVersion, &data[PTP_di_OperationsSupported + totallen], &len);
210
211 totallen += (uint32_t)(len * 2U) + 1U;
212 PTP_GetString(dev_info->SerialNumber, &data[PTP_di_OperationsSupported + totallen], &len);
213 }
214
215
216 /******************************************************************************************************************************************
217 * 函数名称: PTP_DecodeStorageInfo()
218 * 功能说明:
219 * 输 入: 无
220 * 输 出: 无
221 * 注意事项: 无
222 ******************************************************************************************************************************************/
PTP_DecodeStorageInfo(USBH_Info_t * phost,PTP_StorageInfo_t * storage_info)223 void PTP_DecodeStorageInfo(USBH_Info_t *phost, PTP_StorageInfo_t *storage_info)
224 {
225 uint8_t *data = USBH_MTP_Info.data_container.payload;
226 uint16_t len;
227
228 storage_info->StorageType = PTP_LE16(&data[PTP_si_StorageType]);
229 storage_info->FilesystemType = PTP_LE16(&data[PTP_si_FilesystemType]);
230 storage_info->AccessCapability = PTP_LE16(&data[PTP_si_AccessCapability]);
231 storage_info->MaxCapability = PTP_LE64(&data[PTP_si_MaxCapability]);
232 storage_info->FreeSpaceInBytes = PTP_LE64(&data[PTP_si_FreeSpaceInBytes]);
233 storage_info->FreeSpaceInImages = PTP_LE32(&data[PTP_si_FreeSpaceInImages]);
234
235 PTP_GetString(storage_info->StorageDescription, &data[PTP_si_StorageDescription], &len);
236 PTP_GetString(storage_info->VolumeLabel, &data[PTP_si_StorageDescription + (len * 2U) + 1U], &len);
237 }
238
239
240 /******************************************************************************************************************************************
241 * 函数名称: PTP_DecodeObjectInfo()
242 * 功能说明:
243 * 输 入: 无
244 * 输 出: 无
245 * 注意事项: 无
246 ******************************************************************************************************************************************/
PTP_DecodeObjectInfo(USBH_Info_t * phost,PTP_ObjectInfo_t * object_info)247 void PTP_DecodeObjectInfo(USBH_Info_t *phost, PTP_ObjectInfo_t *object_info)
248 {
249 uint8_t *data = USBH_MTP_Info.data_container.payload;
250 uint16_t filenamelen;
251
252 object_info->StorageID = PTP_LE32(&data[PTP_oi_StorageID]);
253 object_info->ObjectFormat = PTP_LE16(&data[PTP_oi_ObjectFormat]);
254 object_info->ProtectionStatus = PTP_LE16(&data[PTP_oi_ProtectionStatus]);
255 object_info->ObjectCompressedSize = PTP_LE64(&data[PTP_oi_ObjectCompressedSize]);
256
257 /* For Samsung Galaxy */
258 if((data[PTP_oi_filenamelen] == 0U) && (data[PTP_oi_filenamelen + 4U] != 0U))
259 {
260 data += 4;
261 }
262 object_info->ThumbFormat = PTP_LE16(&data[PTP_oi_ThumbFormat]);
263 object_info->ThumbCompressedSize = PTP_LE32(&data[PTP_oi_ThumbCompressedSize]);
264 object_info->ThumbPixWidth = PTP_LE32(&data[PTP_oi_ThumbPixWidth]);
265 object_info->ThumbPixHeight = PTP_LE32(&data[PTP_oi_ThumbPixHeight]);
266 object_info->ImagePixWidth = PTP_LE32(&data[PTP_oi_ImagePixWidth]);
267 object_info->ImagePixHeight = PTP_LE32(&data[PTP_oi_ImagePixHeight]);
268 object_info->ImageBitDepth = PTP_LE32(&data[PTP_oi_ImageBitDepth]);
269 object_info->ParentObject = PTP_LE32(&data[PTP_oi_ParentObject]);
270 object_info->AssociationType = PTP_LE16(&data[PTP_oi_AssociationType]);
271 object_info->AssociationDesc = PTP_LE32(&data[PTP_oi_AssociationDesc]);
272 object_info->SequenceNumber = PTP_LE32(&data[PTP_oi_SequenceNumber]);
273 PTP_GetString(object_info->Filename, &data[PTP_oi_filenamelen], &filenamelen);
274 }
275
276
277 /******************************************************************************************************************************************
278 * 函数名称: PTP_DecodeObjectPropDesc()
279 * 功能说明:
280 * 输 入: 无
281 * 输 出: 无
282 * 注意事项: 无
283 ******************************************************************************************************************************************/
PTP_DecodeObjectPropDesc(USBH_Info_t * phost,PTP_ObjectPropDesc_t * opd,uint32_t opdlen)284 void PTP_DecodeObjectPropDesc(USBH_Info_t *phost, PTP_ObjectPropDesc_t *opd, uint32_t opdlen)
285 {
286 uint8_t *data = USBH_MTP_Info.data_container.payload;
287 uint32_t offset = 0U, i;
288
289 opd->ObjectPropertyCode = PTP_LE16(&data[PTP_opd_ObjectPropertyCode]);
290 opd->DataType = PTP_LE16(&data[PTP_opd_DataType]);
291 opd->GetSet = *(uint8_t *)(&data[PTP_opd_GetSet]);
292
293 offset = PTP_opd_FactoryDefaultValue;
294 PTP_GetDevicePropValue(phost, &offset, opdlen, &opd->FactoryDefaultValue, opd->DataType);
295
296 opd->GroupCode = PTP_LE32(&data[offset]);
297 offset += sizeof(uint32_t);
298
299 opd->FormFlag = *(uint8_t *)(&data[offset]);
300 offset += sizeof(uint8_t);
301
302 switch(opd->FormFlag)
303 {
304 case PTP_OPFF_Range:
305 PTP_GetDevicePropValue(phost, &offset, opdlen, &opd->FORM.Range.MinimumValue, opd->DataType);
306 PTP_GetDevicePropValue(phost, &offset, opdlen, &opd->FORM.Range.MaximumValue, opd->DataType);
307 PTP_GetDevicePropValue(phost, &offset, opdlen, &opd->FORM.Range.StepSize, opd->DataType);
308 break;
309
310 case PTP_OPFF_Enumeration:
311 opd->FORM.Enum.NumberOfValues = PTP_LE16(&data[offset]);
312 offset += sizeof(uint16_t);
313
314 for(i = 0U; i < opd->FORM.Enum.NumberOfValues ; i++)
315 {
316 PTP_GetDevicePropValue(phost, &offset, opdlen, &opd->FORM.Enum.SupportedValue[i], opd->DataType);
317 }
318 break;
319
320 default:
321 break;
322 }
323 }
324
325
326 /******************************************************************************************************************************************
327 * 函数名称: PTP_DecodeObjectPropList()
328 * 功能说明:
329 * 输 入: 无
330 * 输 出: 无
331 * 注意事项: 无
332 ******************************************************************************************************************************************/
PTP_DecodeObjectPropList(USBH_Info_t * phost,MTP_Properties_t * props,uint32_t len)333 uint32_t PTP_DecodeObjectPropList(USBH_Info_t *phost, MTP_Properties_t *props, uint32_t len)
334 {
335 uint8_t *data = USBH_MTP_Info.data_container.payload;
336 uint32_t prop_count;
337 uint32_t offset = 0U, i;
338
339 prop_count = PTP_LE32(data);
340 if(prop_count == 0U)
341 {
342 return 0;
343 }
344
345 data += sizeof(uint32_t);
346 len -= sizeof(uint32_t);
347
348 for(i = 0U; i < prop_count; i++)
349 {
350 if(len <= 0U)
351 {
352 return 0;
353 }
354
355 props[i].ObjectHandle = PTP_LE32(data);
356 data += sizeof(uint32_t);
357 len -= sizeof(uint32_t);
358
359 props[i].property = PTP_LE16(data);
360 data += sizeof(uint16_t);
361 len -= sizeof(uint16_t);
362
363 props[i].datatype = PTP_LE16(data);
364 data += sizeof(uint16_t);
365 len -= sizeof(uint16_t);
366
367 offset = 0U;
368
369 PTP_GetDevicePropValue(phost, &offset, len, &props[i].propval, props[i].datatype);
370
371 data += offset;
372 len -= offset;
373 }
374
375 return prop_count;
376 }
377