27
27
#include "tusb.h"
28
28
#include "tinyusb_logo_png.h"
29
29
30
- #define MTPD_STORAGE_DESCRIPTION "storage"
31
- #define MTPD_VOLUME_IDENTIFIER "volume"
32
-
33
30
//--------------------------------------------------------------------+
34
31
// Dataset
35
32
//--------------------------------------------------------------------+
@@ -118,29 +115,6 @@ enum {
118
115
119
116
static bool is_session_opened = false;
120
117
121
- //--------------------------------------------------------------------+
122
- // OPERATING STATUS
123
- //--------------------------------------------------------------------+
124
- typedef struct {
125
- // Session
126
- uint32_t session_id ;
127
- // Association traversal
128
- uint32_t traversal_parent ;
129
- uint32_t traversal_index ;
130
- // Object open for reading
131
- uint32_t read_handle ;
132
- uint32_t read_pos ;
133
- // Object open for writing
134
- uint32_t write_handle ;
135
- uint32_t write_pos ;
136
- // Unique identifier
137
- uint32_t last_handle ;
138
- } fs_operation_t ;
139
-
140
- static fs_operation_t _fs_operation = {
141
- .last_handle = 1
142
- };
143
-
144
118
//--------------------------------------------------------------------+
145
119
// INTERNAL FUNCTIONS
146
120
//--------------------------------------------------------------------+
@@ -166,7 +140,6 @@ uint32_t fs_get_object_count(void) {
166
140
167
141
int32_t tud_mtp_data_complete_cb (tud_mtp_cb_data_t * cb_data ) {
168
142
mtp_container_info_t * reply = & cb_data -> reply ;
169
- reply -> header -> len = sizeof (mtp_container_header_t );
170
143
reply -> header -> code = (cb_data -> xfer_result == XFER_RESULT_SUCCESS ) ? MTP_RESP_OK : MTP_RESP_GENERAL_ERROR ;
171
144
tud_mtp_response_send (reply );
172
145
return 0 ;
@@ -181,30 +154,42 @@ int32_t tud_mtp_data_more_cb(tud_mtp_cb_data_t* cb_data) {
181
154
// only a few command that need more data e.g GetObject and SendObject
182
155
const mtp_container_command_t * command = cb_data -> command ;
183
156
mtp_container_info_t * reply = & cb_data -> reply ;
184
- switch (command -> header .code ) {
157
+ uint32_t resp_code = 0 ;
158
+ switch (command -> code ) {
185
159
case MTP_OP_GET_OBJECT : {
186
160
const uint32_t obj_handle = command -> params [0 ];
187
161
fs_object_info_t * obj = fs_get_object (obj_handle );
188
162
if (obj == NULL ) {
189
- return MTP_RESP_INVALID_OBJECT_HANDLE ;
163
+ resp_code = MTP_RESP_INVALID_OBJECT_HANDLE ;
164
+ } else {
165
+ // file contents offset is xferred byte minus header size
166
+ const uint32_t offset = cb_data -> xferred_bytes - sizeof (mtp_container_header_t );
167
+ const uint32_t xact_len = tu_min32 (obj -> size - offset , reply -> payload_size );
168
+ memcpy (reply -> payload , obj -> data + offset , xact_len );
169
+ tud_mtp_data_send (& cb_data -> reply );
190
170
}
191
- // file contents offset is xferred byte minus header size
192
- const uint32_t offset = cb_data -> xferred_bytes - sizeof (mtp_container_header_t );
193
- const uint32_t xact_len = tu_min32 (obj -> size - offset , reply -> payload_size );
194
- memcpy (reply -> payload , obj -> data + offset , xact_len );
195
- tud_mtp_data_send (& cb_data -> reply );
171
+ break ;
196
172
}
197
173
198
- default : return MTP_RESP_OPERATION_NOT_SUPPORTED ;
174
+ default :
175
+ resp_code = MTP_RESP_OPERATION_NOT_SUPPORTED ;
176
+ break ;
199
177
}
200
178
201
- return MTP_RESP_OK ;
179
+ // send response if needed
180
+ if (resp_code != 0 ) {
181
+ reply -> header -> code = resp_code ;
182
+ tud_mtp_response_send (reply );
183
+ }
184
+
185
+ return 0 ; // 0 mean data/response is sent already
202
186
}
203
187
204
188
int32_t tud_mtp_command_received_cb (tud_mtp_cb_data_t * cb_data ) {
205
189
const mtp_container_command_t * command = cb_data -> command ;
206
190
mtp_container_info_t * reply = & cb_data -> reply ;
207
- switch (command -> header .code ) {
191
+ uint32_t resp_code = 0 ;
192
+ switch (command -> code ) {
208
193
case MTP_OP_GET_DEVICE_INFO : {
209
194
// Device info is already prepared up to playback formats. Application only need to add string fields
210
195
mtp_container_add_cstring (& cb_data -> reply , DEV_INFO_MANUFACTURER );
@@ -218,24 +203,20 @@ int32_t tud_mtp_command_received_cb(tud_mtp_cb_data_t* cb_data) {
218
203
219
204
case MTP_OP_OPEN_SESSION :
220
205
if (is_session_opened ) {
221
- //return MTP_RESP_SESSION_ALREADY_OPEN;
222
- reply -> header -> code = MTP_RESP_SESSION_ALREADY_OPEN ;
206
+ resp_code = MTP_RESP_SESSION_ALREADY_OPEN ;
223
207
}else {
224
- reply -> header -> code = MTP_RESP_OK ;
208
+ resp_code = MTP_RESP_OK ;
225
209
}
226
210
is_session_opened = true;
227
- tud_mtp_response_send (& cb_data -> reply );
228
211
break ;
229
212
230
213
case MTP_OP_CLOSE_SESSION :
231
214
if (!is_session_opened ) {
232
- // return MTP_RESP_SESSION_NOT_OPEN;
233
- reply -> header -> code = MTP_RESP_SESSION_NOT_OPEN ;
215
+ resp_code = MTP_RESP_SESSION_NOT_OPEN ;
234
216
} else {
235
- reply -> header -> code = MTP_RESP_OK ;
217
+ resp_code = MTP_RESP_OK ;
236
218
}
237
219
is_session_opened = false;
238
- tud_mtp_response_send (& cb_data -> reply );
239
220
break ;
240
221
241
222
case MTP_OP_GET_STORAGE_IDS : {
@@ -246,7 +227,7 @@ int32_t tud_mtp_command_received_cb(tud_mtp_cb_data_t* cb_data) {
246
227
}
247
228
248
229
case MTP_OP_GET_STORAGE_INFO : {
249
- uint32_t storage_id = command -> params [0 ];
230
+ const uint32_t storage_id = command -> params [0 ];
250
231
TU_VERIFY (SUPPORTED_STORAGE_ID == storage_id , -1 );
251
232
// update storage info with current free space
252
233
storage_info .free_space_in_objects = FS_MAX_FILE_COUNT - fs_get_object_count ();
@@ -271,7 +252,9 @@ int32_t tud_mtp_command_received_cb(tud_mtp_cb_data_t* cb_data) {
271
252
tud_mtp_data_send (& cb_data -> reply );
272
253
break ;
273
254
274
- default : return MTP_RESP_PARAMETER_NOT_SUPPORTED ;
255
+ default :
256
+ resp_code = MTP_RESP_PARAMETER_NOT_SUPPORTED ;
257
+ break ;
275
258
}
276
259
break ;
277
260
}
@@ -284,7 +267,9 @@ int32_t tud_mtp_command_received_cb(tud_mtp_cb_data_t* cb_data) {
284
267
tud_mtp_data_send (& cb_data -> reply );
285
268
break ;
286
269
287
- default : return MTP_RESP_PARAMETER_NOT_SUPPORTED ;
270
+ default :
271
+ resp_code = MTP_RESP_PARAMETER_NOT_SUPPORTED ;
272
+ break ;
288
273
}
289
274
break ;
290
275
}
@@ -295,74 +280,83 @@ int32_t tud_mtp_command_received_cb(tud_mtp_cb_data_t* cb_data) {
295
280
(void ) obj_format ;
296
281
const uint32_t parent_handle = command -> params [2 ]; // folder handle, 0xFFFFFFFF is root
297
282
if (storage_id != 0xFFFFFFFF && storage_id != SUPPORTED_STORAGE_ID ) {
298
- return MTP_RESP_INVALID_STORAGE_ID ;
299
- }
300
-
301
- uint32_t handles [ FS_MAX_FILE_COUNT ] = { 0 } ;
302
- uint32_t count = 0 ;
303
- for ( uint8_t i = 0 ; i < FS_MAX_FILE_COUNT ; i ++ ) {
304
- fs_object_info_t * obj = & fs_objects [ i ];
305
- if ( obj -> name [ 0 ] != 0 &&
306
- ( parent_handle == obj -> parent || ( parent_handle == 0xFFFFFFFF && obj -> parent == 0 ))) {
307
- handles [ count ++ ] = i + 1 ; // handle is index + 1
283
+ resp_code = MTP_RESP_INVALID_STORAGE_ID ;
284
+ } else {
285
+ uint32_t handles [ FS_MAX_FILE_COUNT ] = { 0 };
286
+ uint32_t count = 0 ;
287
+ for ( uint8_t i = 0 ; i < FS_MAX_FILE_COUNT ; i ++ ) {
288
+ fs_object_info_t * obj = & fs_objects [ i ];
289
+ if ( obj -> name [ 0 ] != 0 &&
290
+ ( parent_handle == obj -> parent || ( parent_handle == 0xFFFFFFFF && obj -> parent == 0 ))) {
291
+ handles [ count ++ ] = i + 1 ; // handle is index + 1
292
+ }
308
293
}
294
+ mtp_container_add_auint32 (& cb_data -> reply , count , handles );
295
+ tud_mtp_data_send (& cb_data -> reply );
309
296
}
310
- mtp_container_add_auint32 (& cb_data -> reply , count , handles );
311
- tud_mtp_data_send (& cb_data -> reply );
312
297
break ;
313
298
}
314
299
315
300
case MTP_OP_GET_OBJECT_INFO : {
316
301
const uint32_t obj_handle = command -> params [0 ];
317
302
fs_object_info_t * obj = fs_get_object (obj_handle );
318
303
if (obj == NULL ) {
319
- return MTP_RESP_INVALID_OBJECT_HANDLE ;
304
+ resp_code = MTP_RESP_INVALID_OBJECT_HANDLE ;
305
+ } else {
306
+ mtp_object_info_header_t obj_info_header = {
307
+ .storage_id = SUPPORTED_STORAGE_ID ,
308
+ .object_format = obj -> format ,
309
+ .protection_status = MTP_PROTECTION_STATUS_NO_PROTECTION ,
310
+ .object_compressed_size = obj -> size ,
311
+ .thumb_format = MTP_OBJ_FORMAT_UNDEFINED ,
312
+ .thumb_compressed_size = 0 ,
313
+ .thumb_pix_width = 0 ,
314
+ .thumb_pix_height = 0 ,
315
+ .image_pix_width = 128 ,
316
+ .image_pix_height = 64 ,
317
+ .image_bit_depth = 32 ,
318
+ .parent_object = obj -> parent ,
319
+ .association_type = MTP_ASSOCIATION_UNDEFINED ,
320
+ .association_desc = 0 ,
321
+ .sequence_number = 0
322
+ };
323
+ mtp_container_add_raw (& cb_data -> reply , & obj_info_header , sizeof (obj_info_header ));
324
+ mtp_container_add_cstring (& cb_data -> reply , obj -> name );
325
+ mtp_container_add_cstring (& cb_data -> reply , FS_FIXED_DATETIME );
326
+ mtp_container_add_cstring (& cb_data -> reply , FS_FIXED_DATETIME );
327
+ mtp_container_add_cstring (& cb_data -> reply , "" ); // keywords, not used
328
+
329
+ tud_mtp_data_send (& cb_data -> reply );
320
330
}
321
- mtp_object_info_header_t obj_info_header = {
322
- .storage_id = SUPPORTED_STORAGE_ID ,
323
- .object_format = obj -> format ,
324
- .protection_status = MTP_PROTECTION_STATUS_NO_PROTECTION ,
325
- .object_compressed_size = obj -> size ,
326
- .thumb_format = MTP_OBJ_FORMAT_UNDEFINED ,
327
- .thumb_compressed_size = 0 ,
328
- .thumb_pix_width = 0 ,
329
- .thumb_pix_height = 0 ,
330
- .image_pix_width = 128 ,
331
- .image_pix_height = 64 ,
332
- .image_bit_depth = 32 ,
333
- .parent_object = obj -> parent ,
334
- .association_type = MTP_ASSOCIATION_UNDEFINED ,
335
- .association_desc = 0 ,
336
- .sequence_number = 0
337
- };
338
- mtp_container_add_raw (& cb_data -> reply , & obj_info_header , sizeof (obj_info_header ));
339
- mtp_container_add_cstring (& cb_data -> reply , obj -> name );
340
- mtp_container_add_cstring (& cb_data -> reply , FS_FIXED_DATETIME );
341
- mtp_container_add_cstring (& cb_data -> reply , FS_FIXED_DATETIME );
342
- mtp_container_add_cstring (& cb_data -> reply , "" ); // keywords, not used
343
-
344
- tud_mtp_data_send (& cb_data -> reply );
345
331
break ;
346
332
}
347
333
348
334
case MTP_OP_GET_OBJECT : {
349
335
const uint32_t obj_handle = command -> params [0 ];
350
336
fs_object_info_t * obj = fs_get_object (obj_handle );
351
337
if (obj == NULL ) {
352
- return MTP_RESP_INVALID_OBJECT_HANDLE ;
338
+ resp_code = MTP_RESP_INVALID_OBJECT_HANDLE ;
339
+ } else {
340
+ // If file contents is larger than CFG_TUD_MTP_EP_BUFSIZE, only partial data is added here
341
+ // the rest will be sent in tud_mtp_data_more_cb
342
+ mtp_container_add_raw (& cb_data -> reply , obj -> data , obj -> size );
343
+ tud_mtp_data_send (& cb_data -> reply );
353
344
}
354
-
355
- // If file contents is larger than CFG_TUD_MTP_EP_BUFSIZE, only partial data is added here
356
- // the rest will be sent in tud_mtp_data_more_cb
357
- mtp_container_add_raw (& cb_data -> reply , obj -> data , obj -> size );
358
- tud_mtp_data_send (& cb_data -> reply );
359
345
break ;
360
346
}
361
347
362
- default : return MTP_RESP_OPERATION_NOT_SUPPORTED ;
348
+ default :
349
+ resp_code = MTP_RESP_OPERATION_NOT_SUPPORTED ;
350
+ break ;
363
351
}
364
352
365
- return MTP_RESP_OK ;
353
+ // send response if needed
354
+ if (resp_code != 0 ) {
355
+ reply -> header -> code = resp_code ;
356
+ tud_mtp_response_send (reply );
357
+ }
358
+
359
+ return 0 ;
366
360
}
367
361
368
362
//--------------------------------------------------------------------+
@@ -556,23 +550,7 @@ void tud_mtp_storage_object_done(void) {
556
550
#endif
557
551
558
552
void tud_mtp_storage_cancel (void ) {
559
- fs_object_info_t * obj ;
560
-
561
- _fs_operation .traversal_parent = 0 ;
562
- _fs_operation .traversal_index = 0 ;
563
- _fs_operation .read_handle = 0 ;
564
- _fs_operation .read_pos = 0 ;
565
- // If write operation is canceled, discard object
566
- if (_fs_operation .write_handle ) {
567
- obj = fs_get_object (_fs_operation .write_handle );
568
- // if (obj)
569
- // obj->allocated = false;
570
- }
571
- _fs_operation .write_handle = 0 ;
572
- _fs_operation .write_pos = 0 ;
573
553
}
574
554
575
555
void tud_mtp_storage_reset (void ) {
576
- tud_mtp_storage_cancel ();
577
- _fs_operation .session_id = 0 ;
578
556
}
0 commit comments