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 }