• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022, sakumisu
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #include "usbd_core.h"
7 #include "usbd_mtp.h"
8 #include "usbd_mtp_config.h"
9 
10 /* MTP Stage */
11 enum Stage {
12     MTP_READ_COMMAND = 0,
13     MTP_DATA_OUT = 1,
14     MTP_DATA_IN = 2,
15     MTP_SEND_RESPONSE = 3,
16     MTP_WAIT_RESPONSE = 4,
17 };
18 
19 USB_NOCACHE_RAM_SECTION struct usbd_mtp_priv {
20     USB_MEM_ALIGNX struct mtp_container_command con_command;
21     USB_MEM_ALIGNX struct mtp_container_data con_data;
22     USB_MEM_ALIGNX struct mtp_container_response con_response;
23     enum Stage stage;
24     uint8_t session_state;
25     uint32_t response_code;
26 } g_usbd_mtp;
27 
28 /* Max USB packet size */
29 #ifndef CONFIG_USB_HS
30 #define MTP_BULK_EP_MPS 64
31 #else
32 #define MTP_BULK_EP_MPS 512
33 #endif
34 
35 #define MTP_OUT_EP_IDX 0
36 #define MTP_IN_EP_IDX  1
37 #define MTP_INT_EP_IDX 2
38 
39 /* Describe EndPoints configuration */
40 static struct usbd_endpoint mtp_ep_data[3];
41 
mtp_class_interface_request_handler(struct usb_setup_packet * setup,uint8_t ** data,uint32_t * len)42 static int mtp_class_interface_request_handler(struct usb_setup_packet *setup, uint8_t **data, uint32_t *len)
43 {
44     USB_LOG_DBG("MTP Class request: "
45                 "bRequest 0x%02x\r\n",
46                 setup->bRequest);
47 
48     switch (setup->bRequest) {
49         case MTP_REQUEST_CANCEL:
50 
51             break;
52         case MTP_REQUEST_GET_EXT_EVENT_DATA:
53 
54             break;
55         case MTP_REQUEST_RESET:
56 
57             break;
58         case MTP_REQUEST_GET_DEVICE_STATUS:
59 
60             break;
61 
62         default:
63             USB_LOG_WRN("Unhandled MTP Class bRequest 0x%02x\r\n", setup->bRequest);
64             return -1;
65     }
66 
67     return 0;
68 }
69 
usbd_mtp_send_response(uint32_t code)70 static void usbd_mtp_send_response(uint32_t code)
71 {
72     USB_LOG_DBG("Send response\r\n");
73 
74     g_usbd_mtp.stage = MTP_WAIT_RESPONSE;
75 
76     g_usbd_mtp.con_response.conlen = 12;
77     g_usbd_mtp.con_response.contype = MTP_CONTAINER_TYPE_RESPONSE;
78     g_usbd_mtp.con_response.code = code;
79     g_usbd_mtp.con_response.trans_id = g_usbd_mtp.con_command.trans_id;
80 
81     usbd_ep_start_write(mtp_ep_data[MTP_IN_EP_IDX].ep_addr, (uint8_t *)&g_usbd_mtp.con_response, 12);
82 }
83 
usbd_mtp_send_info(uint8_t * data,uint32_t len)84 static void usbd_mtp_send_info(uint8_t *data, uint32_t len)
85 {
86     USB_LOG_DBG("Send info\r\n");
87 
88     g_usbd_mtp.stage = MTP_SEND_RESPONSE;
89 
90     g_usbd_mtp.con_data.conlen = 12 + len;
91     g_usbd_mtp.con_data.contype = MTP_CONTAINER_TYPE_DATA;
92     g_usbd_mtp.con_data.code = MTP_RESPONSE_OK;
93     g_usbd_mtp.con_data.trans_id = g_usbd_mtp.con_command.trans_id;
94 
95     memcpy(g_usbd_mtp.con_data.data, data, len);
96     usbd_ep_start_write(mtp_ep_data[MTP_IN_EP_IDX].ep_addr, (uint8_t *)&g_usbd_mtp.con_data, 12 + len);
97 }
98 
usbd_mtp_get_device_info(void)99 static void usbd_mtp_get_device_info(void)
100 {
101     struct mtp_device_info device_info;
102     uint16_t i;
103 
104     device_info.StandardVersion = 100;
105     device_info.VendorExtensionID = 0x06;
106     device_info.VendorExtensionVersion = 100;
107     device_info.VendorExtensionDesc_len = (uint8_t)CONFIG_MTP_VEND_EXT_DESC_LEN;
108 
109     for (i = 0; i < CONFIG_MTP_VEND_EXT_DESC_LEN; i++) {
110         device_info.VendorExtensionDesc[i] = VendExtDesc[i];
111     }
112 
113     /* device supports one mode , standard mode */
114     device_info.FunctionalMode = 0x0000;
115 
116     /* All supported operation */
117     device_info.OperationsSupported_len = CONFIG_MTP_SUPP_OP_LEN;
118     for (i = 0U; i < CONFIG_MTP_SUPP_OP_LEN; i++) {
119         device_info.OperationsSupported[i] = SuppOP[i];
120     }
121 
122     /* event that are currently generated by the device*/
123     device_info.EventsSupported_len = CONFIG_MTP_SUPP_EVENTS_LEN;
124 
125     for (i = 0U; i < CONFIG_MTP_SUPP_EVENTS_LEN; i++) {
126         device_info.EventsSupported[i] = SuppEvents[i];
127     }
128 
129     device_info.DevicePropertiesSupported_len = CONFIG_MTP_SUPP_DEVICE_PROP_LEN;
130 
131     for (i = 0U; i < CONFIG_MTP_SUPP_DEVICE_PROP_LEN; i++) {
132         device_info.DevicePropertiesSupported[i] = DevicePropSupp[i];
133     }
134 
135     device_info.CaptureFormats_len = CONFIG_MTP_SUPP_CAPT_FORMAT_LEN;
136 
137     for (i = 0U; i < CONFIG_MTP_SUPP_CAPT_FORMAT_LEN; i++) {
138         device_info.CaptureFormats[i] = SuppCaptFormat[i];
139     }
140 
141     device_info.ImageFormats_len = CONFIG_MTP_SUPP_IMG_FORMAT_LEN; /* number of image formats that are supported by the device*/
142     for (i = 0U; i < CONFIG_MTP_SUPP_IMG_FORMAT_LEN; i++) {
143         device_info.ImageFormats[i] = SuppImgFormat[i];
144     }
145 
146     device_info.Manufacturer_len = (uint8_t)CONFIG_MTP_MANUF_LEN;
147     for (i = 0U; i < CONFIG_MTP_MANUF_LEN; i++) {
148         device_info.Manufacturer[i] = Manuf[i];
149     }
150 
151     device_info.Model_len = (uint8_t)CONFIG_MTP_MODEL_LEN;
152     for (i = 0U; i < CONFIG_MTP_MODEL_LEN; i++) {
153         device_info.Model[i] = Model[i];
154     }
155 
156     device_info.DeviceVersion_len = (uint8_t)CONFIG_MTP_DEVICE_VERSION_LEN;
157     for (i = 0U; i < CONFIG_MTP_DEVICE_VERSION_LEN; i++) {
158         device_info.DeviceVersion[i] = DeviceVers[i];
159     }
160 
161     device_info.SerialNumber_len = (uint8_t)CONFIG_MTP_SERIAL_NBR_LEN;
162     for (i = 0U; i < CONFIG_MTP_SERIAL_NBR_LEN; i++) {
163         device_info.SerialNumber[i] = SerialNbr[i];
164     }
165 
166     usbd_mtp_send_info((uint8_t *)&device_info, sizeof(struct mtp_device_info));
167 }
168 
usbd_mtp_open_session(void)169 static void usbd_mtp_open_session(void)
170 {
171     usbd_mtp_send_response(MTP_RESPONSE_OK);
172 }
173 
usbd_mtp_get_storage_ids(void)174 static void usbd_mtp_get_storage_ids(void)
175 {
176     struct mtp_storage_id storage_id;
177 
178     storage_id.StorageIDS_len = CONFIG_MTP_STORAGE_ID_LEN;
179     storage_id.StorageIDS[0] = MTP_STORAGE_ID;
180 
181     usbd_mtp_send_info((uint8_t *)&storage_id, sizeof(struct mtp_storage_id));
182 }
183 
usbd_mtp_get_storage_info(void)184 static void usbd_mtp_get_storage_info(void)
185 {
186     struct mtp_storage_info storage_info;
187 
188     storage_info.StorageType = MTP_STORAGE_REMOVABLE_RAM;
189     storage_info.FilesystemType = MTP_FILESYSTEM_GENERIC_FLAT;
190     storage_info.AccessCapability = MTP_ACCESS_CAP_RW;
191     storage_info.MaxCapability = 0x0080DFA81A000000;    // todo
192     storage_info.FreeSpaceInBytes = 0x00007EEB0D000000; // todo
193     storage_info.FreeSpaceInObjects = 0xFFFFFFFFU;      /* not used */
194     storage_info.StorageDescription = 0U;
195     storage_info.VolumeLabel = 0U;
196 
197     usbd_mtp_send_info((uint8_t *)&storage_info, sizeof(struct mtp_storage_info));
198 }
199 
usbd_mtp_get_object_handles(void)200 static void usbd_mtp_get_object_handles(void)
201 {
202     struct mtp_object_handle object_handle;
203 
204     // todo
205 
206     usbd_mtp_send_info((uint8_t *)&object_handle, sizeof(struct mtp_object_handle));
207 }
208 
usbd_mtp_get_object_info(void)209 static void usbd_mtp_get_object_info(void)
210 {
211     struct mtp_object_info object_info;
212 
213     object_info.Storage_id = MTP_STORAGE_ID;
214     object_info.ObjectFormat = 0;         // todo
215     object_info.ObjectCompressedSize = 0; //todo
216     object_info.ProtectionStatus = 0U;
217     object_info.ThumbFormat = MTP_OBJ_FORMAT_UNDEFINED;
218     object_info.ThumbCompressedSize = 0U;
219     object_info.ThumbPixWidth = 0U; /* not supported or not an image */
220     object_info.ThumbPixHeight = 0U;
221     object_info.ImagePixWidth = 0U;
222     object_info.ImagePixHeight = 0U;
223     object_info.ImageBitDepth = 0U;
224     object_info.ParentObject = 0; // todo
225     object_info.AssociationType = 0U;
226     object_info.AssociationDesc = 0U;
227     object_info.SequenceNumber = 0U;
228 
229     /* we have to get this value before object_info.Filename */
230     object_info.Filename_len = sizeof(DefaultFileName);
231     memcpy(object_info.Filename, DefaultFileName, (uint32_t)object_info.Filename_len + 1U);
232 
233     object_info.CaptureDate = 0U;
234     object_info.ModificationDate = 0U;
235     object_info.Keywords = 0U;
236 
237     usbd_mtp_send_info((uint8_t *)&object_info, sizeof(struct mtp_object_info));
238 }
239 
usbd_mtp_get_object_prop_desc(void)240 static void usbd_mtp_get_object_prop_desc(void)
241 {
242     struct mtp_object_prop_desc object_prop_desc;
243 
244     uint16_t undef_format = MTP_OBJ_FORMAT_UNDEFINED;
245     uint32_t storageid = MTP_STORAGE_ID;
246 
247     switch (g_usbd_mtp.con_command.param1) /* switch obj prop code */
248     {
249         case MTP_OB_PROP_OBJECT_FORMAT:
250             object_prop_desc.ObjectPropertyCode = (uint16_t)(g_usbd_mtp.con_command.param1);
251             object_prop_desc.DataType = MTP_DATATYPE_UINT16;
252             object_prop_desc.GetSet = MTP_PROP_GET;
253             object_prop_desc.DefValue = (uint8_t *)&undef_format;
254             object_prop_desc.GroupCode = 0U;
255             object_prop_desc.FormFlag = 0U;
256             break;
257 
258         case MTP_OB_PROP_STORAGE_ID:
259             object_prop_desc.ObjectPropertyCode = (uint16_t)(g_usbd_mtp.con_command.param1);
260             object_prop_desc.DataType = MTP_DATATYPE_UINT32;
261             object_prop_desc.GetSet = MTP_PROP_GET;
262             object_prop_desc.DefValue = (uint8_t *)&storageid;
263             object_prop_desc.GroupCode = 0U;
264             object_prop_desc.FormFlag = 0U;
265             break;
266 
267         case MTP_OB_PROP_OBJ_FILE_NAME:
268             object_prop_desc.ObjectPropertyCode = (uint16_t)(g_usbd_mtp.con_command.param1);
269             object_prop_desc.DataType = MTP_DATATYPE_STR;
270             object_prop_desc.GetSet = MTP_PROP_GET;
271             object_prop_desc.DefValue = 0U;
272             object_prop_desc.GroupCode = 0U;
273             object_prop_desc.FormFlag = 0U;
274             break;
275 
276         case MTP_OB_PROP_PARENT_OBJECT:
277             object_prop_desc.ObjectPropertyCode = (uint16_t)(g_usbd_mtp.con_command.param1);
278             object_prop_desc.DataType = MTP_DATATYPE_STR;
279             object_prop_desc.GetSet = MTP_PROP_GET;
280             object_prop_desc.DefValue = 0U;
281             object_prop_desc.GroupCode = 0U;
282             object_prop_desc.FormFlag = 0U;
283             break;
284 
285         case MTP_OB_PROP_OBJECT_SIZE:
286             object_prop_desc.ObjectPropertyCode = (uint16_t)(g_usbd_mtp.con_command.param1);
287             object_prop_desc.DataType = MTP_DATATYPE_UINT64;
288             object_prop_desc.GetSet = MTP_PROP_GET;
289             object_prop_desc.DefValue = 0U;
290             object_prop_desc.GroupCode = 0U;
291             object_prop_desc.FormFlag = 0U;
292             break;
293 
294         case MTP_OB_PROP_NAME:
295             object_prop_desc.ObjectPropertyCode = (uint16_t)(g_usbd_mtp.con_command.param1);
296             object_prop_desc.DataType = MTP_DATATYPE_STR;
297             object_prop_desc.GetSet = MTP_PROP_GET;
298             object_prop_desc.DefValue = NULL;
299             object_prop_desc.GroupCode = 0U;
300             object_prop_desc.FormFlag = 0U;
301             break;
302 
303         case MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN:
304             object_prop_desc.ObjectPropertyCode = (uint16_t)(g_usbd_mtp.con_command.param1);
305             object_prop_desc.DataType = MTP_DATATYPE_UINT128;
306             object_prop_desc.GetSet = MTP_PROP_GET;
307             object_prop_desc.DefValue = 0U;
308             object_prop_desc.GroupCode = 0U;
309             object_prop_desc.FormFlag = 0U;
310             break;
311 
312         case MTP_OB_PROP_PROTECTION_STATUS:
313             object_prop_desc.ObjectPropertyCode = (uint16_t)(g_usbd_mtp.con_command.param1);
314             object_prop_desc.DataType = MTP_DATATYPE_UINT16;
315             object_prop_desc.GetSet = MTP_PROP_GET_SET;
316             object_prop_desc.DefValue = 0U;
317             object_prop_desc.GroupCode = 0U;
318             object_prop_desc.FormFlag = 0U;
319             break;
320 
321         default:
322             break;
323     }
324     // todo
325     usbd_mtp_send_info((uint8_t *)&object_prop_desc, sizeof(struct mtp_object_prop_desc));
326 }
327 
usbd_mtp_get_object_props_supported(void)328 static void usbd_mtp_get_object_props_supported(void)
329 {
330     struct mtp_object_props_support object_props_support;
331     uint32_t i;
332 
333     object_props_support.ObjectPropCode_len = CONFIG_MTP_SUPP_OBJ_PROP_LEN;
334 
335     for (i = 0U; i < CONFIG_MTP_SUPP_OBJ_PROP_LEN; i++) {
336         object_props_support.ObjectPropCode[i] = ObjectPropCode[i];
337     }
338     usbd_mtp_send_info((uint8_t *)&object_props_support, sizeof(struct mtp_object_props_support));
339 }
340 
usbd_mtp_get_object_prop_list(void)341 static void usbd_mtp_get_object_prop_list(void)
342 {
343     struct mtp_object_prop_list object_prop_list;
344 
345     uint16_t filename[255];
346     uint32_t storageid = MTP_STORAGE_ID;
347     uint32_t default_val = 0U;
348     uint32_t i;
349     uint16_t format;
350     uint64_t objsize;
351     uint32_t parent_proval;
352 
353     object_prop_list.Properties_len = CONFIG_MTP_SUPP_OBJ_PROP_LEN;
354 
355     for (i = 0U; i < CONFIG_MTP_SUPP_OBJ_PROP_LEN; i++) {
356         object_prop_list.Properties[i].ObjectHandle = g_usbd_mtp.con_command.param1;
357 
358         switch (ObjectPropCode[i]) {
359             case MTP_OB_PROP_STORAGE_ID:
360                 object_prop_list.Properties[i].PropertyCode = MTP_OB_PROP_STORAGE_ID;
361                 object_prop_list.Properties[i].Datatype = MTP_DATATYPE_UINT32;
362                 object_prop_list.Properties[i].propval = (uint8_t *)&storageid;
363                 break;
364 
365             case MTP_OB_PROP_OBJECT_FORMAT:
366                 object_prop_list.Properties[i].PropertyCode = MTP_OB_PROP_OBJECT_FORMAT;
367                 object_prop_list.Properties[i].Datatype = MTP_DATATYPE_UINT16;
368                 object_prop_list.Properties[i].propval = (uint8_t *)&format;
369                 break;
370 
371             case MTP_OB_PROP_OBJ_FILE_NAME:
372                 object_prop_list.Properties[i].PropertyCode = MTP_OB_PROP_OBJ_FILE_NAME;
373                 object_prop_list.Properties[i].Datatype = MTP_DATATYPE_STR;
374                 object_prop_list.Properties[i].propval = NULL;
375                 break;
376 
377             case MTP_OB_PROP_PARENT_OBJECT:
378                 object_prop_list.Properties[i].PropertyCode = MTP_OB_PROP_PARENT_OBJECT;
379                 object_prop_list.Properties[i].Datatype = MTP_DATATYPE_UINT32;
380                 object_prop_list.Properties[i].propval = (uint8_t *)&parent_proval;
381                 break;
382 
383             case MTP_OB_PROP_OBJECT_SIZE:
384                 object_prop_list.Properties[i].PropertyCode = MTP_OB_PROP_OBJECT_SIZE;
385                 object_prop_list.Properties[i].Datatype = MTP_DATATYPE_UINT64;
386                 object_prop_list.Properties[i].propval = (uint8_t *)&objsize;
387                 break;
388 
389             case MTP_OB_PROP_NAME:
390                 object_prop_list.Properties[i].PropertyCode = MTP_OB_PROP_NAME;
391                 object_prop_list.Properties[i].Datatype = MTP_DATATYPE_STR;
392                 object_prop_list.Properties[i].propval = NULL;
393                 break;
394 
395             case MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN:
396                 object_prop_list.Properties[i].PropertyCode = MTP_OB_PROP_PERS_UNIQ_OBJ_IDEN;
397                 object_prop_list.Properties[i].Datatype = MTP_DATATYPE_UINT128;
398                 object_prop_list.Properties[i].propval = (uint8_t *)&g_usbd_mtp.con_command.param1;
399                 break;
400 
401             case MTP_OB_PROP_PROTECTION_STATUS:
402                 object_prop_list.Properties[i].PropertyCode = MTP_OB_PROP_PROTECTION_STATUS;
403                 object_prop_list.Properties[i].Datatype = MTP_DATATYPE_UINT16;
404                 object_prop_list.Properties[i].propval = (uint8_t *)&default_val;
405                 break;
406 
407             default:
408                 break;
409         }
410     }
411     // todo
412     usbd_mtp_send_info((uint8_t *)&object_prop_list, sizeof(struct mtp_object_prop_list));
413 }
414 
usbd_mtp_get_device_prop_desc(void)415 static void usbd_mtp_get_device_prop_desc(void)
416 {
417     struct mtp_device_prop_desc device_prop_desc;
418     uint32_t i;
419 
420     device_prop_desc.DevicePropertyCode = MTP_DEV_PROP_DEVICE_FRIENDLY_NAME;
421     device_prop_desc.DataType = MTP_DATATYPE_STR;
422     device_prop_desc.GetSet = MTP_PROP_GET_SET;
423     device_prop_desc.DefaultValue_len = CONFIG_MTP_DEVICE_PROP_DESC_DEF_LEN;
424 
425     for (i = 0U; i < (sizeof(DevicePropDefVal) / 2U); i++) {
426         device_prop_desc.DefaultValue[i] = DevicePropDefVal[i];
427     }
428 
429     device_prop_desc.CurrentValue_len = CONFIG_MTP_DEVICE_PROP_DESC_CUR_LEN;
430 
431     for (i = 0U; i < (sizeof(DevicePropCurDefVal) / 2U); i++) {
432         device_prop_desc.CurrentValue[i] = DevicePropCurDefVal[i];
433     }
434 
435     device_prop_desc.FormFlag = 0U;
436 
437     usbd_mtp_send_info((uint8_t *)&device_prop_desc, sizeof(struct mtp_device_prop_desc));
438 }
439 
usbd_mtp_decode_command(struct mtp_container_command * command)440 static int usbd_mtp_decode_command(struct mtp_container_command *command)
441 {
442     printf("code:%04x\r\n", command->code);
443     switch (command->code) {
444         case MTP_OP_GET_DEVICE_INFO:
445             usbd_mtp_get_device_info();
446             break;
447         case MTP_OP_OPEN_SESSION:
448             usbd_mtp_open_session();
449             break;
450         case MTP_OP_CLOSE_SESSION:
451             break;
452         case MTP_OP_GET_STORAGE_IDS:
453             usbd_mtp_get_storage_ids();
454             break;
455         case MTP_OP_GET_STORAGE_INFO:
456             usbd_mtp_get_storage_info();
457             break;
458         case MTP_OP_GET_OBJECT_HANDLES:
459             usbd_mtp_get_object_handles();
460             break;
461         case MTP_OP_GET_OBJECT_INFO:
462             usbd_mtp_get_object_info();
463             break;
464         case MTP_OP_GET_OBJECT_PROP_REFERENCES:
465             break;
466         case MTP_OP_GET_OBJECT_PROPS_SUPPORTED:
467             usbd_mtp_get_object_props_supported();
468             break;
469         case MTP_OP_GET_OBJECT_PROP_DESC:
470             usbd_mtp_get_object_prop_desc();
471             break;
472         case MTP_OP_GET_OBJECT_PROPLIST:
473             usbd_mtp_get_object_prop_list();
474             break;
475         case MTP_OP_GET_OBJECT_PROP_VALUE:
476             break;
477         case MTP_OP_GET_DEVICE_PROP_DESC:
478             usbd_mtp_get_device_prop_desc();
479             break;
480         case MTP_OP_GET_OBJECT:
481             break;
482         case MTP_OP_SEND_OBJECT_INFO:
483             break;
484         case MTP_OP_SEND_OBJECT:
485             break;
486         case MTP_OP_DELETE_OBJECT:
487             break;
488 
489         default:
490             break;
491     }
492     return 0;
493 }
494 
usbd_mtp_bulk_out(uint8_t ep,uint32_t nbytes)495 static void usbd_mtp_bulk_out(uint8_t ep, uint32_t nbytes)
496 {
497     switch (g_usbd_mtp.stage) {
498         case MTP_READ_COMMAND:
499             usbd_mtp_decode_command(&g_usbd_mtp.con_command);
500             break;
501         case MTP_DATA_OUT:
502             break;
503         default:
504             break;
505     }
506 }
507 
usbd_mtp_bulk_in(uint8_t ep,uint32_t nbytes)508 static void usbd_mtp_bulk_in(uint8_t ep, uint32_t nbytes)
509 {
510     printf("send:%d\r\n", nbytes);
511     switch (g_usbd_mtp.stage) {
512         case MTP_DATA_IN:
513             break;
514         case MTP_SEND_RESPONSE:
515             usbd_mtp_send_response(MTP_RESPONSE_OK);
516             break;
517         case MTP_WAIT_RESPONSE:
518             USB_LOG_DBG("Start reading command\r\n");
519             g_usbd_mtp.stage = MTP_READ_COMMAND;
520             usbd_ep_start_read(mtp_ep_data[MTP_OUT_EP_IDX].ep_addr, (uint8_t *)&g_usbd_mtp.con_command, MTP_BULK_EP_MPS);
521             break;
522 
523         default:
524             break;
525     }
526 }
527 
mtp_notify_handler(uint8_t event,void * arg)528 static void mtp_notify_handler(uint8_t event, void *arg)
529 {
530     switch (event) {
531         case USBD_EVENT_RESET:
532             break;
533         case USBD_EVENT_CONFIGURED:
534             USB_LOG_DBG("Start reading command\r\n");
535             g_usbd_mtp.stage = MTP_READ_COMMAND;
536             usbd_ep_start_read(mtp_ep_data[MTP_OUT_EP_IDX].ep_addr, (uint8_t *)&g_usbd_mtp.con_command, MTP_BULK_EP_MPS);
537             break;
538 
539         default:
540             break;
541     }
542 }
543 
usbd_mtp_init_intf(struct usbd_interface * intf,const uint8_t out_ep,const uint8_t in_ep,const uint8_t int_ep)544 struct usbd_interface *usbd_mtp_init_intf(struct usbd_interface *intf,
545                                           const uint8_t out_ep,
546                                           const uint8_t in_ep,
547                                           const uint8_t int_ep)
548 {
549     intf->class_interface_handler = mtp_class_interface_request_handler;
550     intf->class_endpoint_handler = NULL;
551     intf->vendor_handler = NULL;
552     intf->notify_handler = mtp_notify_handler;
553 
554     mtp_ep_data[MTP_OUT_EP_IDX].ep_addr = out_ep;
555     mtp_ep_data[MTP_OUT_EP_IDX].ep_cb = usbd_mtp_bulk_out;
556     mtp_ep_data[MTP_IN_EP_IDX].ep_addr = in_ep;
557     mtp_ep_data[MTP_IN_EP_IDX].ep_cb = usbd_mtp_bulk_in;
558     mtp_ep_data[MTP_INT_EP_IDX].ep_addr = int_ep;
559     mtp_ep_data[MTP_INT_EP_IDX].ep_cb = NULL;
560 
561     usbd_add_endpoint(&mtp_ep_data[MTP_OUT_EP_IDX]);
562     usbd_add_endpoint(&mtp_ep_data[MTP_IN_EP_IDX]);
563     usbd_add_endpoint(&mtp_ep_data[MTP_INT_EP_IDX]);
564 
565     return intf;
566 }