1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
|
/*
* SPDX-FileCopyrightText: Copyright (c) 2025 Ennebi Elettronica (https://ennebielettronica.com)
* SPDX-FileCopyrightText: Copyright (c) 2025 Ha Thach (tinyusb.org)
* SPDX-License-Identifier: MIT
*
* This file is part of the TinyUSB stack.
*/
#ifndef TUSB_MTP_DEVICE_H_
#define TUSB_MTP_DEVICE_H_
#include "common/tusb_common.h"
#include "mtp.h"
#if (CFG_TUD_ENABLED && CFG_TUD_MTP)
#ifdef __cplusplus
extern "C" {
#endif
// callback data for Bulk Only Transfer (BOT) protocol
typedef struct {
uint8_t idx; // mtp instance
uint8_t phase; // current phase
uint32_t session_id;
const mtp_container_command_t* command_container;
mtp_container_info_t io_container;
tusb_xfer_result_t xfer_result;
uint32_t total_xferred_bytes; // number of bytes transferred so far in this phase
} tud_mtp_cb_data_t;
// callback data for Control requests
typedef struct {
uint8_t idx;
uint8_t stage; // control stage
// buffer for data stage
uint16_t bufsize;
uint8_t* buf;
const tusb_control_request_t* request;
uint32_t session_id;
} tud_mtp_request_cb_data_t;
// Number of supported operations, events, device properties, capture formats, playback formats
// and max number of characters for strings manufacturer, model, device_version, serial_number
#define MTP_DEVICE_INFO_STRUCT(_extension_nchars, _op_count, _event_count, _devprop_count, _capture_count, _playback_count) \
struct TU_ATTR_PACKED { \
uint16_t standard_version; \
uint32_t mtp_vendor_extension_id; \
uint16_t mtp_version; \
mtp_string_t(_extension_nchars) mtp_extensions; \
uint16_t functional_mode; \
mtp_auint16_t(_op_count) supported_operations; \
mtp_auint16_t(_event_count) supported_events; \
mtp_auint16_t(_devprop_count) supported_device_properties; \
mtp_auint16_t(_capture_count) capture_formats; \
mtp_auint16_t(_playback_count) playback_formats; \
/* string fields will be added using append function */ \
/* mtp_string_t() Manufacturer */ \
/* mtp_string_t() Model */ \
/* mtp_string_t() Device Version */ \
/* mtp_string_t() Serial Number */ \
}
typedef MTP_DEVICE_INFO_STRUCT( //-V2586 [MISRA-C-18.7] Flexible array members should not be declared
sizeof(CFG_TUD_MTP_DEVICEINFO_EXTENSIONS), TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_SUPPORTED_OPERATIONS),
TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_SUPPORTED_EVENTS), TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_SUPPORTED_DEVICE_PROPERTIES),
TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_CAPTURE_FORMATS), TU_ARGS_NUM(CFG_TUD_MTP_DEVICEINFO_PLAYBACK_FORMATS)
) tud_mtp_device_info_t;
//--------------------------------------------------------------------+
// Application API
//--------------------------------------------------------------------+
// check if mtp interface is mounted
bool tud_mtp_mounted(void);
// send data phase
bool tud_mtp_data_send(mtp_container_info_t* p_container);
// receive data phase
bool tud_mtp_data_receive(mtp_container_info_t* p_container);
// send response
bool tud_mtp_response_send(mtp_container_info_t* p_container);
// send event notification on event endpoint
bool tud_mtp_event_send(mtp_event_t* event);
//--------------------------------------------------------------------+
// Control request Callbacks
//--------------------------------------------------------------------+
// Invoked when received Cancel request. Data is available in callback data's buffer
// return false to stall the request
bool tud_mtp_request_cancel_cb(tud_mtp_request_cb_data_t* cb_data);
// Invoked when received Device Reset request
// return false to stall the request
bool tud_mtp_request_device_reset_cb(tud_mtp_request_cb_data_t* cb_data);
// Invoked when received Get Extended Event request. Application fill callback data's buffer for response
// return negative to stall the request
int32_t tud_mtp_request_get_extended_event_cb(tud_mtp_request_cb_data_t* cb_data);
// Invoked when received Get DeviceStatus request. Application fill callback data's buffer for response
// return negative to stall the request
int32_t tud_mtp_request_get_device_status_cb(tud_mtp_request_cb_data_t* cb_data);
// Invoked when received vendor-specific request not in the above standard MTP requests
// return false to stall the request
bool tud_mtp_request_vendor_cb(tud_mtp_request_cb_data_t* cb_data);
//--------------------------------------------------------------------+
// Bulk only protocol Callbacks
//--------------------------------------------------------------------+
// Invoked when new command is received. Application fill the cb_data->io_container and call tud_mtp_data_send() or
// tud_mtp_response_send() for Data or Response phase.
// Return negative to stall the endpoints
int32_t tud_mtp_command_received_cb(tud_mtp_cb_data_t * cb_data);
// Invoked when a data packet is transferred. If data spans over multiple packets, application can use
// total_xferred_bytes and io_container's payload_bytes to determine the offset and remaining bytes to be transferred.
// Return negative to stall the endpoints
int32_t tud_mtp_data_xfer_cb(tud_mtp_cb_data_t* cb_data);
// Invoked when all bytes in DATA phase is complete. A response packet is expected
// Return negative to stall the endpoints
int32_t tud_mtp_data_complete_cb(tud_mtp_cb_data_t* cb_data);
// Invoked when response phase is complete
// Return negative to stall the endpoints
int32_t tud_mtp_response_complete_cb(tud_mtp_cb_data_t* cb_data);
//--------------------------------------------------------------------+
// Internal Class Driver API
//--------------------------------------------------------------------+
void mtpd_init (void);
bool mtpd_deinit (void);
void mtpd_reset (uint8_t rhport);
uint16_t mtpd_open (uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len);
bool mtpd_control_xfer_cb (uint8_t rhport, uint8_t stage, tusb_control_request_t const *p_request);
bool mtpd_xfer_cb (uint8_t rhport, uint8_t ep_addr, xfer_result_t event, uint32_t xferred_bytes);
#ifdef __cplusplus
}
#endif
#endif
#endif
|