4747#include "supervisor/usb.h"
4848
4949#include "py/mpstate.h"
50+ #include "py/stackctrl.h"
5051
5152STATIC bleio_service_obj_t supervisor_ble_service ;
5253STATIC bleio_uuid_obj_t supervisor_ble_service_uuid ;
@@ -97,7 +98,7 @@ void supervisor_start_bluetooth_file_transfer(void) {
9798 NULL , // no initial value
9899 NULL ); // no description
99100
100- uint32_t version = 1 ;
101+ uint32_t version = 2 ;
101102 mp_buffer_info_t bufinfo ;
102103 bufinfo .buf = & version ;
103104 bufinfo .len = sizeof (version );
@@ -291,7 +292,7 @@ STATIC uint8_t _process_write(const uint8_t *raw_buf, size_t command_len) {
291292 // Don't reload until everything is written out of the packet buffer.
292293 common_hal_bleio_packet_buffer_flush (& _transfer_packet_buffer );
293294 // Trigger an autoreload
294- autoreload_now ();
295+ autoreload_start ();
295296 return ANY_COMMAND ;
296297 }
297298
@@ -345,12 +346,45 @@ STATIC uint8_t _process_write_data(const uint8_t *raw_buf, size_t command_len) {
345346 // Don't reload until everything is written out of the packet buffer.
346347 common_hal_bleio_packet_buffer_flush (& _transfer_packet_buffer );
347348 // Trigger an autoreload
348- autoreload_now ();
349+ autoreload_start ();
349350 return ANY_COMMAND ;
350351 }
351352 return WRITE_DATA ;
352353}
353354
355+ STATIC FRESULT _delete_directory_contents (FATFS * fs , const TCHAR * path ) {
356+ FF_DIR dir ;
357+ FRESULT res = f_opendir (fs , & dir , path );
358+ FILINFO file_info ;
359+ // Check the stack since we're putting paths on it.
360+ if (mp_stack_usage () >= MP_STATE_THREAD (stack_limit )) {
361+ return FR_INT_ERR ;
362+ }
363+ while (res == FR_OK ) {
364+ res = f_readdir (& dir , & file_info );
365+ if (res != FR_OK || file_info .fname [0 ] == '\0' ) {
366+ break ;
367+ }
368+ size_t pathlen = strlen (path );
369+ size_t fnlen = strlen (file_info .fname );
370+ TCHAR full_path [pathlen + 1 + fnlen ];
371+ memcpy (full_path , path , pathlen );
372+ full_path [pathlen ] = '/' ;
373+ size_t full_pathlen = pathlen + 1 + fnlen ;
374+ memcpy (full_path + pathlen + 1 , file_info .fname , fnlen );
375+ full_path [full_pathlen ] = '\0' ;
376+ if ((file_info .fattrib & AM_DIR ) != 0 ) {
377+ res = _delete_directory_contents (fs , full_path );
378+ }
379+ if (res != FR_OK ) {
380+ break ;
381+ }
382+ res = f_unlink (fs , full_path );
383+ }
384+ f_closedir (& dir );
385+ return res ;
386+ }
387+
354388STATIC uint8_t _process_delete (const uint8_t * raw_buf , size_t command_len ) {
355389 const struct delete_command * command = (struct delete_command * )raw_buf ;
356390 size_t header_size = 4 ;
@@ -370,7 +404,16 @@ STATIC uint8_t _process_delete(const uint8_t *raw_buf, size_t command_len) {
370404 FATFS * fs = & ((fs_user_mount_t * )MP_STATE_VM (vfs_mount_table )-> obj )-> fatfs ;
371405 char * path = (char * )((uint8_t * )command ) + header_size ;
372406 path [command -> path_length ] = '\0' ;
373- FRESULT result = f_unlink (fs , path );
407+ FRESULT result ;
408+ FILINFO file ;
409+ if (f_stat (fs , path , & file ) == FR_OK ) {
410+ if ((file .fattrib & AM_DIR ) != 0 ) {
411+ result = _delete_directory_contents (fs , path );
412+ }
413+ if (result == FR_OK ) {
414+ result = f_unlink (fs , path );
415+ }
416+ }
374417 if (result != FR_OK ) {
375418 response .status = STATUS_ERROR ;
376419 }
@@ -504,6 +547,7 @@ void supervisor_bluetooth_file_transfer_background(void) {
504547 if (size == 0 ) {
505548 break ;
506549 }
550+ autoreload_suspend (AUTORELOAD_LOCK_BLE );
507551 // TODO: If size < 0 return an error.
508552 current_offset += size ;
509553 #if CIRCUITPY_VERBOSE_BLE
@@ -521,6 +565,7 @@ void supervisor_bluetooth_file_transfer_background(void) {
521565 response [0 ] = next_command ;
522566 response [1 ] = STATUS_ERROR_PROTOCOL ;
523567 common_hal_bleio_packet_buffer_write (& _transfer_packet_buffer , response , 2 , NULL , 0 );
568+ autoreload_resume (AUTORELOAD_LOCK_BLE );
524569 break ;
525570 }
526571 switch (current_state ) {
@@ -550,6 +595,9 @@ void supervisor_bluetooth_file_transfer_background(void) {
550595 if (next_command != THIS_COMMAND ) {
551596 current_offset = 0 ;
552597 }
598+ if (next_command == ANY_COMMAND ) {
599+ autoreload_resume (AUTORELOAD_LOCK_BLE );
600+ }
553601 }
554602 running = false;
555603}
@@ -558,4 +606,5 @@ void supervisor_bluetooth_file_transfer_disconnected(void) {
558606 next_command = ANY_COMMAND ;
559607 current_offset = 0 ;
560608 f_close (& active_file );
609+ autoreload_resume (AUTORELOAD_LOCK_BLE );
561610}
0 commit comments