Пример #1
0
//! @brief This function mount a drive
//!
void ushell_cmd_mount( void )
{
   uint8_t u8_drive_lun;
   Fs_index sav_index;

   if( g_s_arg[0][0] == 0 )
      return;

   // Compute the logical unit number of drive
   u8_drive_lun=g_s_arg[0][0]-'a';
   // Check lun number
   if( u8_drive_lun >= nav_drive_nb() )
   {
      fputs(MSG_ER_DRIVE, stdout);
      return;
   }

   // Mount drive
   sav_index = nav_getindex();      // Save previous position
   if( nav_drive_set(u8_drive_lun))
   {
      if( nav_partition_mount() )
         return;                    // Here, drive mounted
   }
   fputs(MSG_ER_MOUNT, stdout);
   nav_gotoindex(&sav_index);       // Restore previous position
}
Пример #2
0
//! @brief This function delete a file or directory
//!
void ushell_cmd_rm( void )
{
   uint8_t u8_i = 0;
   Fs_index sav_index;

   if( g_s_arg[0][0] == 0 )
      return;

   // Save the position
   sav_index = nav_getindex();

   while( 1 )
   {
      // Restore the position
      nav_gotoindex(&sav_index);
      // Select file or directory
      if( !nav_setcwd( (FS_STRING)g_s_arg[0], true, false ) )
         break;
      // Delete file or directory
      if( !nav_file_del( false ) )
      {
         fputs(MSG_KO, stdout);
         break;
      }
      u8_i++;
   }
   printf( "%u file(s) deleted\n\r", u8_i );
}
Пример #3
0
//! @brief This function displays the free space of each drive present
//!
void ushell_cmd_free_space( void )
{
   uint8_t u8_tmp;
   Fs_index sav_index = nav_getindex();      // Save current position
   for( u8_tmp=0; u8_tmp<nav_drive_nb(); u8_tmp++ )
   {
      nav_drive_set( u8_tmp );      // Select drive
      if( !nav_partition_mount() )  // Mount drive
         continue;

      // Display drive letter name (a, b...)
      printf("%c: %s\r\n", 'a'+u8_tmp, mem_name(u8_tmp) );
      if( g_s_arg[0][0]=='l' )        // Choose command option
      {
         // Long and exact function
         printf("Free space: %llu Bytes / %llu Bytes\n\r",
                   (uint64_t)(nav_partition_freespace() << FS_SHIFT_B_TO_SECTOR),
                   (uint64_t)(nav_partition_space() << FS_SHIFT_B_TO_SECTOR));
      }
      else
      {
         // Otherwise use fast command
         printf("Free space: %u %%\n\r", nav_partition_freespace_percent() );
      }
   }
   nav_gotoindex(&sav_index);       // Restore position
}
Пример #4
0
bool   pl_main_save( void )
{
   _MEM_TYPE_SLOW_ Fs_index index;
   uint8_t nav_id_save;
   uint16_t u16_pos;

   // Check if the play list file is opened and modified
   if( !pl_main_isopen() )
      return false;
   if( !pl_g_list_is_modify )
      return true;
   pl_g_list_is_modify = false;

   // Check if a undo file exists
   if( !pl_g_list_undo )
      return true;

   // Remove original copy of play list file
   nav_id_save = nav_get();
   nav_select( FS_NAV_ID_PLAYLIST );
   u16_pos = pl_g_u16_list_sel;           // Save position in play list
   file_close();                          // Close list
   index = nav_getindex();                // Save the pointer on play list file
   pl_g_list_is_open = false;
   if( nav_gotoindex( &copyfile_index ) ) // Go to the copy of file
      nav_file_del( true );               // Remove the copy
   nav_gotoindex( &index );               // Re select play list file
   pl_main_open( true );                  // Re open play list file
   pl_nav_setpos(u16_pos);                // Restore position in play list
   nav_select( nav_id_save );

   return true;
}
Пример #5
0
//! This function closes the play list and selects this one in current navigator
//!
//! @return    false in case of error, see global value "fs_g_status" for more detail
//! @return    true otherwise
//!
bool   pl_main_close( void )
{
   _MEM_TYPE_SLOW_ Fs_index index;
   uint8_t nav_id_save;

   if( !pl_main_isopen() )
      return false;

   // Close play list
   nav_id_save = nav_get();
   nav_select( FS_NAV_ID_PLAYLIST );
   file_close();

#if( PL_READONLY == false )
   if( pl_g_list_is_modify )
   {
      if( pl_g_list_undo )
      {
         uint16_t size_name;
         FS_STRING sz_name;

         //** Play list modified but not saved, then restore previous list
         // Get name of play list
         nav_string_length_enable();
         nav_file_name( (FS_STRING)&size_name, 1, FS_NAME_GET, false );
         nav_string_length_disable();
         sz_name = PLAYLIST_BUF_ALLOC( size_name* (Is_unicode? 2 : 1 ) );
         if( NULL != sz_name )
         {
            if( nav_file_name( sz_name, size_name, FS_NAME_GET, false ) )
            {
               // Delete current play list
               if( nav_file_del( true ) )             // Remove copy file
               {
                  nav_gotoindex( &copyfile_index );   // Select copy play list
                  nav_file_rename( sz_name );         // rename copy play list
               }
            }
            PLAYLIST_BUF_FREE( sz_name );
         }
      }
   }
#endif

   // Select the play list file in current navigator
   index = nav_getindex();       // Save a pointer on play list file
   nav_select( nav_id_save );
   nav_gotoindex( &index );
   pl_g_list_is_open = false;
   return true;
}
Пример #6
0
//! This function goes to the parent directory
//!
//! @return  false in case of error, see global value "fs_g_status" for more detail
//! @return  true otherwise
//!
//! @verbatim
//! After the selected file is the first entry of the new file list FLAT
//! @endverbatim
//!
bool  nav_flat_gotoparent( void )
{
   _MEM_TYPE_SLOW_ Fs_index index;
   index = nav_getindex();
   while( 0 != fs_g_nav.u8_flat_dir_level )
   {
      fs_g_nav.u8_flat_dir_level--;
      nav_dir_gotoparent();
   }
   if( !nav_dir_gotoparent() )
   {
      nav_gotoindex( &index );
      return false;
   }
   // Go to at the beginning of FLAT list
   fs_g_nav.u8_flat_dir_level   = 0;
   fs_g_nav.u16_flat_pos_offset = 0;
   nav_filelist_reset();
   nav_flat_next();
   return true;
}
Пример #7
0
//!
//! @brief Synchronize the contents of two drives (limited to files).
//!
//! @param sync_direction   uint8_t: DEVICE_TO_HOST, HOST_TO_DEVICE or FULL_SYNC
//!
//! @return bool: true on success
//!
//! @todo Do recursive directory copy...
//!
bool host_mass_storage_task_sync_drives(uint8_t sync_direction)
{
  Fs_index local_index;
  Fs_index sav_local_index;
  Fs_index usb_index;
  Fs_index sav_usb_index;

  // First, check the host controller is in full operating mode with the
  // B-device attached and enumerated
  if (!Is_host_ready()) return false;

  nav_reset();

  // Try to mount local drive
  nav_drive_set(LUN_ID_AT45DBX_MEM);
  if (!nav_partition_mount()) return false;
  local_index = nav_getindex();
  sav_local_index = nav_getindex();

  // Try to mount first USB device drive
  nav_drive_set(LUN_ID_MEM_USB);
  if (!nav_partition_mount()) return false;
  usb_index = nav_getindex();
  sav_usb_index = nav_getindex();

  // First synchronization: USB/OUT -> Local/IN
  if (sync_direction & DEVICE_TO_HOST)
  {
    if (!host_mass_storage_task_sync_dir(&local_index, DIR_LOCAL_IN_NAME, &usb_index, DIR_USB_OUT_NAME))
      return false;
  }

  // Restore positions
  nav_gotoindex(&sav_local_index);
  local_index = nav_getindex();
  nav_gotoindex(&sav_usb_index);
  usb_index = nav_getindex();
  nav_gotoindex(&local_index);

  // Second synchronization: Local/OUT -> USB/IN
  if (sync_direction & HOST_TO_DEVICE)
  {
    if (!host_mass_storage_task_sync_dir(&usb_index, DIR_USB_IN_NAME, &local_index, DIR_LOCAL_OUT_NAME))
      return false;
  }

  return true;
}
Пример #8
0
//! @brief This function initializes the hardware/software resources required for ushell task.
//!
void ushell_task_init(uint32_t pba_hz)
{
  uint8_t u8_i;

  //** Initialize the USART used by uShell with the configured parameters
  static const gpio_map_t SHL_USART_GPIO_MAP =
  {
    {SHL_USART_RX_PIN, SHL_USART_RX_FUNCTION},
    {SHL_USART_TX_PIN, SHL_USART_TX_FUNCTION}
  };
#if (defined __GNUC__)
  set_usart_base((void *)SHL_USART);
  gpio_enable_module(SHL_USART_GPIO_MAP,
                     sizeof(SHL_USART_GPIO_MAP) / sizeof(SHL_USART_GPIO_MAP[0]));
  usart_init(SHL_USART_BAUDRATE);
#elif (defined __ICCAVR32__)
  static const usart_options_t SHL_USART_OPTIONS =
  {
    .baudrate = SHL_USART_BAUDRATE,
    .charlength = 8,
    .paritytype = USART_NO_PARITY,
    .stopbits = USART_1_STOPBIT,
    .channelmode = USART_NORMAL_CHMODE
  };

  extern volatile avr32_usart_t *volatile stdio_usart_base;
  stdio_usart_base = SHL_USART;
  gpio_enable_module(SHL_USART_GPIO_MAP,
                     sizeof(SHL_USART_GPIO_MAP) / sizeof(SHL_USART_GPIO_MAP[0]));
  usart_init_rs232(SHL_USART, &SHL_USART_OPTIONS, pba_hz);
#endif


  //** Configure standard I/O streams as unbuffered.
#if (defined __GNUC__)
  setbuf(stdin, NULL);
#endif
  setbuf(stdout, NULL);

  // Set default state of ushell
  g_b_ushell_task_run = false;
  for( u8_i=0; u8_i<USHELL_HISTORY; u8_i++ ) {
     g_s_cmd_his[u8_i][0] = 0;  // Set end of line for all cmd line history
  }

  fputs(MSG_EXIT, stdout );

  g_u32_ushell_pba_hz = pba_hz;  // Save value to manage a time counter during perform command

#ifdef FREERTOS_USED
  xTaskCreate(ushell_task,
              configTSK_USHELL_NAME,
              configTSK_USHELL_STACK_SIZE,
              NULL,
              configTSK_USHELL_PRIORITY,
              NULL);
#endif  // FREERTOS_USED
}


#ifdef FREERTOS_USED
/*! \brief Entry point of the explorer task management.
 *
 * This function performs uShell decoding to access file-system functions.
 *
 * \param pvParameters Unused.
 */
void ushell_task(void *pvParameters)
#else
/*! \brief Entry point of the explorer task management.
 *
 * This function performs uShell decoding to access file-system functions.
 */
void ushell_task(void)
#endif
{

#ifdef FREERTOS_USED
   //** Inifinite loop for RTOS because it is a RTOS task
   portTickType xLastWakeTime;

   xLastWakeTime = xTaskGetTickCount();
   while (true)
   {
      vTaskDelayUntil(&xLastWakeTime, configTSK_USHELL_PERIOD);
#else
   //** No loop with the basic scheduler
   {
#endif  // FREERTOS_USED


   //** Check the USB mode and authorize/unauthorize ushell
   if(!g_b_ushell_task_run)
   {
      if( Is_usb_id_device() )
#ifdef FREERTOS_USED
         continue;   // Continue in the RTOS task
#else
         return;     // Exit of the task scheduled
#endif
      g_b_ushell_task_run = true;
      // Display shell startup
      fputs(MSG_WELCOME, stdout);
      ushell_cmd_nb_drive();
      fputs(MSG_PROMPT, stdout);

      // Reset the embedded FS on ushell navigator and on first drive
      nav_reset();
      nav_select( FS_NAV_ID_USHELL_CMD );
      nav_drive_set( 0 );
   }else{
      if( Is_usb_id_device() )
      {
         g_b_ushell_task_run = false;
         fputs(MSG_EXIT, stdout );
         nav_exit();
#ifdef FREERTOS_USED
         continue;   // Continue in the RTOS task
#else
         return;     // Exit of the task scheduled
#endif
      }
   }

   //** Scan shell command
   if( !ushell_cmd_scan() )
#ifdef FREERTOS_USED
      continue;   // Continue in the RTOS task
#else
      return;     // Exit of the task scheduled
#endif

   //** Command ready then decode and execute this one
   switch( ushell_cmd_decode() )
   {
      // Displays number of  drives
      case CMD_NB_DRIVE:
      ushell_cmd_nb_drive();
      break;

      // Displays free space information for all connected drives
      case CMD_DF:
      ushell_cmd_free_space();
      break;

      // Formats disk
      case CMD_FORMAT:
      ushell_cmd_format();
      break;

      // Mounts a drive (e.g. "b:")
      case CMD_MOUNT:
      ushell_cmd_mount();
      break;

      // Displays the space information for current drive
      case CMD_SPACE:
      ushell_cmd_space();
      break;

      // Lists the files present in current directory (e.g. "ls")
      case CMD_LS:
      ushell_cmd_ls(false);
      break;
      case CMD_LS_MORE:
      ushell_cmd_ls(true);
      break;

      // Enters in a directory (e.g. "cd folder_toto")
      case CMD_CD:
      ushell_cmd_cd();
      break;

      // Enters in parent directory ("cd..")
      case CMD_UP:
      ushell_cmd_gotoparent();
      break;

      // Displays a text file
      case CMD_CAT:
      ushell_cmd_cat(false);
      break;
      case CMD_CAT_MORE:
      ushell_cmd_cat(true);
      break;

      // Displays the help
      case CMD_HELP:
      ushell_cmd_help();
      break;

      // Creates directory
      case CMD_MKDIR:
      ushell_cmd_mkdir();
      break;

      // Creates file
      case CMD_TOUCH:
      ushell_cmd_touch();
      break;

      // Deletes files or directories
      case CMD_RM:
      ushell_cmd_rm();
      break;

      // Appends char to selected file
      case CMD_APPEND:
      ushell_cmd_append_file();
      break;

      // Index routines (= specific shortcut from ATMEL FileSystem)
      case CMD_SET_ID:
      g_mark_index = nav_getindex();
      break;
      case CMD_GOTO_ID:
      nav_gotoindex( &g_mark_index );
      break;

      // Copies file to other location
      case CMD_CP:
      ushell_cmd_copy();
      break;

      // Renames file
      case CMD_MV:
      ushell_cmd_rename();
      break;

      // Synchronize folders
      case CMD_SYNC:
      ushell_cmd_sync();
      break;

      case CMD_PERFORM:
      ushell_cmd_perform();
      break;

      // USB commands
#if USB_HOST_FEATURE == true
      case CMD_LS_USB:
      ushell_cmdusb_ls();
      break;
      case CMD_USB_SUSPEND:
      ushell_cmdusb_suspend();
      break;
      case CMD_USB_RESUME:
      ushell_cmdusb_resume();
      break;
#endif

      case CMD_NONE:
      break;

      // Unknown command
      default:
      fputs(MSG_ER_CMD_NOT_FOUND, stdout);
      break;
   }

   fputs(MSG_PROMPT, stdout);

   }
}


//! @brief Get the full command line to be interpreted.
//!
//! @return true, if a command is ready
//!
bool ushell_cmd_scan(void)
{
   int c_key;

   // Something new of the UART ?
   if (usart_read_char(SHL_USART, &c_key) != USART_SUCCESS)
   {
      usart_reset_status(SHL_USART);
      return false;
   }

   if( 0 != g_u8_escape_sequence )
   {
      //** Decode escape sequence
      if( 1 == g_u8_escape_sequence )
      {
         if( 0x5B != c_key )
         {
            g_u8_escape_sequence=0;
            return false;  // Escape sequence cancel
         }
         g_u8_escape_sequence=2;
      }
      else
      {
         // Decode value of the sequence
         switch (c_key)
         {
/*
Note: OVERRUN error on USART with an RTOS and USART without interrupt management
If you want support "Escape sequence", then you have to implement USART interrupt management
            case 0x41:     // UP command
            ushell_clean_cmd_line();
            ushell_history_up();
            ushell_history_display();
            break;
            case 0x42:     // DOWN command
            ushell_clean_cmd_line();
            ushell_history_down();
            ushell_history_display();
            break;
*/
            default:       // Ignore other command
            break;
         }
         g_u8_escape_sequence=0; // End of Escape sequence
      }
      return false;
   }

   //** Normal sequence
   switch (c_key)
   {
      //** Command validation
      case ASCII_CR:
      putchar(ASCII_CR);         // Echo
      putchar(ASCII_LF);         // Add new line flag
      g_s_cmd_his[g_u8_history_pos][g_u8_cmd_size]=0;  // Add NULL terminator at the end of command line
      return true;

      //** Enter in escape sequence
      case ASCII_ESCAPE:
      g_u8_escape_sequence=1;
      break;

      //** backspace
      case ASCII_BKSPACE:
      if(g_u8_cmd_size>0)        // Beginning of line ?
      {
         // Remove the last character on terminal
         putchar(ASCII_BKSPACE); // Send a backspace to go in previous character
         putchar(' ');           // Send a space to erase previous character
         putchar(ASCII_BKSPACE); // Send a backspace to go in new end position (=previous character position)
         // Remove the last character on cmd line buffer
         g_u8_cmd_size--;
      }
      break;

      // History management
      case '!':
      ushell_clean_cmd_line();
      ushell_history_up();
      ushell_history_display();
      break;
      case '$':
      ushell_clean_cmd_line();
      ushell_history_down();
      ushell_history_display();
      break;

      //** Other char
      default:
      if( (0x1F<c_key) && (c_key<0x7F) && (USHELL_SIZE_CMD_LINE!=g_u8_cmd_size) )
      {
         // Accept char
         putchar(c_key);                                          // Echo
         g_s_cmd_his[g_u8_history_pos][g_u8_cmd_size++] = c_key;  // append to cmd line
      }
      break;
   }
   return false;
}
Пример #9
0
//! @brief Perform transfer between two devices
//!
void ushell_cmd_perform( void )
{
   Fs_index sav_index;
   Fs_file_segment seg1, seg2;

   if( g_s_arg[0][0] == 0 )
      return;

   sav_index = nav_getindex();   // Save the position

   // Alloc a file on each devices
   printf("Alloc a file on each devices\n\r");
   seg1 = ushell_cmd_perform_alloc( (g_s_arg[0][0]-'a') , FILE_ALLOC_SIZE );
   if( seg1.u16_size == 0 )
   {
      printf("!!!Error allocation on device 1\n\r");
      // Restore the position
      nav_gotoindex(&sav_index);
      return;
   }
   if( g_s_arg[1][0] != 0 )
   {
      nav_select( FS_NAV_ID_COPYFILE );
      seg2 = ushell_cmd_perform_alloc( (g_s_arg[1][0]-'a') , FILE_ALLOC_SIZE );
      if( seg2.u16_size == 0 )
      {
         nav_select( FS_NAV_ID_USHELL_CMD );
         file_close();
         nav_file_del(false);
         printf("!!!Error allocation on device 2\n\r");
         // Restore the position
         nav_gotoindex(&sav_index);
         return;
      }

      // Transfer data from device 1 to device 2
      printf("Transfer data from device 1 to device 2\r\n");
      ushell_cmd_perform_transfer(seg1,seg2);
      printf("Transfer data from device 2 to device 1\r\n");
      ushell_cmd_perform_transfer(seg2,seg1);
      // Delete files allocated
      nav_select( FS_NAV_ID_COPYFILE );
      file_close();
      nav_file_del(false);
      nav_select( FS_NAV_ID_USHELL_CMD );
   }
   else
   {
      ushell_cmd_perform_access( false, seg1 );
      ushell_cmd_perform_access( true, seg1 );
      if( LUN_ID_USB <= nav_drive_get() )
      {
         printf("Transfer large buffer on USB\r\n");
         ushell_cmd_perform_extaccess( false, seg1 );
         ushell_cmd_perform_extaccess( true, seg1 );
      }

   }

   file_close();
   nav_file_del(false);
   // Restore the position
   nav_gotoindex(&sav_index);
   printf("End of test\n\r");
   return;
}
Пример #10
0
//! @brief Synchronize a path with an other path
//!
//! @return true if success
//!
bool ushell_cmd_sync( void )
{
   Fs_index sav_index;
   uint8_t u8_folder_level = 0;

   if( g_s_arg[0][0] == 0 )
      return false;
   if( g_s_arg[1][0] == 0 )
      return false;
   // Add '\' at the end of path, else the nav_setcwd select the directory but don't enter into.
   ushell_path_valid_syntac( g_s_arg[0] );
   ushell_path_valid_syntac( g_s_arg[1] );

   printf("Synchronize folders:\n\r");
   sav_index = nav_getindex();   // Save the position

   // Select source directory in COPYFILE navigator handle
   nav_select( FS_NAV_ID_COPYFILE );
   printf("Select source directory\n\r");
   if( !nav_setcwd( (FS_STRING)g_s_arg[0], true, false ) )
      goto ushell_cmd_sync_error;
   nav_filelist_reset();

   // Select destination directory in USHELL navigator handle
   nav_select( FS_NAV_ID_USHELL_CMD );
   printf("Select destination directory\n\r");
   if( !nav_setcwd( (FS_STRING)g_s_arg[1], true, true ) )
      goto ushell_cmd_sync_error;
   nav_filelist_reset();

   // loop to scan and create ALL folders and files
   while(1)
   {
      while(1)
      {
         // Loop to Search files or directories
         // Reselect Source
         nav_select( FS_NAV_ID_COPYFILE );
         if( nav_filelist_set( 0 , FS_FIND_NEXT ) )
            break;   // a next file and directory is found

         // No other dir or file in current dir then go to parent dir on Source and Destination disk
         if( 0 == u8_folder_level )
         {
            // end of update folder
            //********* END OF COPY **************
            goto ushell_cmd_sync_finish;
         }

         printf("Go to parent\n\r");
         // Remark, nav_dir_gotoparent() routine go to in parent dir and select the children dir in list
         u8_folder_level--;
         if( !nav_dir_gotoparent() )
            goto ushell_cmd_sync_error;
         // Select Destination navigator and go to the same dir of Source
         nav_select( FS_NAV_ID_USHELL_CMD );
         if( !nav_dir_gotoparent() )
            goto ushell_cmd_sync_error;
      } // end of while (1)

      if( nav_file_isdir())
      {
         printf("Dir found - create dir: ");
         //** here, a new directory is found and is selected
         // Get name of current selection (= dir name on Source)
         if( !nav_file_name( (FS_STRING)g_s_arg[0], USHELL_SIZE_CMD_LINE, FS_NAME_GET, false ))
            goto ushell_cmd_sync_error;
         // Enter in dir (on Source)
         if( !nav_dir_cd())
            goto ushell_cmd_sync_error;
         u8_folder_level++;
         // Select Destination disk
         nav_select( FS_NAV_ID_USHELL_CMD );
         // Create folder in Destination disk
         printf((char*)g_s_arg[0]);
         printf("\n\r");
         if( !nav_dir_make( (FS_STRING )g_s_arg[0] ))
         {
            if( FS_ERR_FILE_EXIST != fs_g_status )
               goto ushell_cmd_sync_error;
            // here, error the name exist
         }
         // Here the navigator have selected the folder on Destination
         if( !nav_dir_cd())
         {
            if( FS_ERR_NO_DIR == fs_g_status )
            {
               // FYC -> Copy impossible, because a file have the same name of folder
            }
            goto ushell_cmd_sync_error;
         }
         // here, the folder is created and the navigator is entered in this dir
      }
      else
      {
         printf("File found - copy file: ");
         //** here, a new file is found and is selected
         // Get name of current selection (= file name on Source)
         if( !nav_file_name( (FS_STRING)g_s_arg[0], USHELL_SIZE_CMD_LINE, FS_NAME_GET, false ))
            goto ushell_cmd_sync_error;
         printf((char*)g_s_arg[0]);
         printf("\n\r");
         if( !nav_file_copy())
            goto ushell_cmd_sync_error;

         // Paste file in current dir of Destination disk
         nav_select( FS_NAV_ID_USHELL_CMD );
         while( !nav_file_paste_start( (FS_STRING)g_s_arg[0] ) )
         {
            // Error
            if( fs_g_status != FS_ERR_FILE_EXIST )
               goto ushell_cmd_sync_error;
            // File exists then deletes this one
            printf("File exists then deletes this one.\n\r");
            if( !nav_file_del( true ) )
               goto ushell_cmd_sync_error;
            // here, retry PASTE
         }
         // Copy running
         {
         uint8_t status;
         do{
            status = nav_file_paste_state(false);
         }while( COPY_BUSY == status );

         if( COPY_FINISH != status )
            goto ushell_cmd_sync_error;
         }
      } // if dir OR file
   } // end of first while(1)

ushell_cmd_sync_error:
   // Restore the position
   nav_select( FS_NAV_ID_USHELL_CMD );
   nav_gotoindex(&sav_index);
   printf("!!!Copy fail\n\r");
   return false;

ushell_cmd_sync_finish:
   // Restore the position
   nav_select( FS_NAV_ID_USHELL_CMD );
   nav_gotoindex(&sav_index);
   printf("End of copy\n\r");
   return true;
}
Пример #11
0
//! @brief This function copies a file to other location
//!
void ushell_cmd_copy( void )
{
   Fs_index sav_index;
   uint8_t u8_status_copy;

   if( g_s_arg[0][0] == 0 )
      return;

   // Save the position
   sav_index = nav_getindex();

   // Select source file
   if( !nav_setcwd( (FS_STRING)g_s_arg[0], true, false ) )
   {
      fputs(MSG_ER_UNKNOWN_FILE, stdout);
      return;
   }
   // Get name of source to be used as same destination name
   nav_file_name( (FS_STRING)g_s_arg[0], MAX_FILE_PATH_LENGTH, FS_NAME_GET, true );
   // Mark this selected file like source file
   if( !nav_file_copy())
   {
      fputs(MSG_KO, stdout);
      goto cp_end;
   }

   // Select destination
   if( g_s_arg[1][0]==0 )
   {
      // g_s_arg[1] is NULL, using mark
      if( !nav_gotoindex(&g_mark_index) )
         goto cp_end;
   }
   else
   {
      // g_s_arg[1] exists, then go to this destination
      if( !nav_setcwd( (FS_STRING)g_s_arg[1], true, false ) )
      {
         fputs(MSG_ER_UNKNOWN_FILE, stdout);
         goto cp_end;
      }
   }

   // Set the name destination and start paste
   if( !nav_file_paste_start((FS_STRING)g_s_arg[0]) )
   {
      fputs(MSG_ER_PASTE, stdout);
      goto cp_end;
   }

   // Performs copy
   do
   {
      u8_status_copy = nav_file_paste_state( false );
   }while( u8_status_copy == COPY_BUSY );

   // Check status of copy action
   if( u8_status_copy == COPY_FAIL )
   {
      fputs(MSG_ER_PASTE, stdout);
      goto cp_end;
   }

cp_end:
   // Restore the position
   nav_gotoindex(&sav_index);
}
//! This function opens a file list at the current position in navigator
//!
//! @param b_playlist   if true then the current selected file is a play list file to open
//!                     else create a file list with files included in a disk part
//! @param pos          If b_playlist true, then position in the play list to start
//!                     else folder level of the current position
//!
//! @return             false, in case of error or file list empty
//!
bool  navauto_open( bool b_playlist , uint16_t pos )
{
   Navauto_mov_state state;

   g_navauto_b_playlist     = b_playlist;
   g_navauto_u16_dir_level_root = 0;
   g_navauto_u16_nb = 0;

   if( b_playlist )
   {
      g_navauto_u16_pos        = pos;
      if( !pl_main_open(false) )
         return false;
      g_navauto_u16_nb = pl_nav_getnbfile();
      if( 0 == g_navauto_u16_nb )
         return false;
      if( NAVAUTO_RAND_OFF == navauto_getrand() )
      {
         if( pl_nav_setpos( g_navauto_u16_pos ))
         {
            if( nav_filelist_validpos() )
               return true;
         }
      }else{
         navauto_rand_init();
      }
      // Error position then restart at the beginning
      g_navauto_u16_pos = 0;
   }
   else
   {
#if( FS_NAV_AUTOMATIC_NBFILE == ENABLE )
      Fs_index       index;
      Fs_index       index2;
      Navauto_rand   rand_mode;
      uint16_t            u16_current_pos=0;

      index.u8_lun = 0xFF;    // Reset index (by default no valid selected file)
      g_navauto_u16_dir_level  = pos;

      rand_mode = navauto_getrand();               // Save random mode
      navauto_setrand( NAVAUTO_RAND_OFF );

      // If no valid file then found the first valid file
      if( !nav_file_checkext( g_navauto_filter ))
      {
         // Go to previous position because "navauto_mov_explorer()" execute a next before search valid file
         if( !nav_filelist_set( 0 , FS_FIND_PREV ) )
           nav_filelist_reset();
         state = navauto_mov_explorer(FS_FIND_NEXT, NAVAUTO_MOV_OPTS_NONE);
         if((NAVAUTO_MOV_OK_LOOP != state.status)
         && (NAVAUTO_MOV_OK      != state.status) )
         {
           navauto_setrand(rand_mode);
           return false;  // List empty
         }
      }
      index = nav_getindex();

      // Compute the size of file list and search the position of selected file
      navauto_mov_explorer_reset();                // Go to beginning of loop
      // Note: the number of file is updated in navauto_mov_explorer() routine when the end of list is detected

      while( navauto_mov_explorer( FS_FIND_NEXT, NAVAUTO_MOV_OPTS_NONE ).status == NAVAUTO_MOV_OK )
      {
         index2 = nav_getindex();
         // Check the current position with the selected file
         if( (index.u8_lun == index2.u8_lun)
         &&  (index.u32_cluster_sel_dir == index2.u32_cluster_sel_dir)
         &&  (index.u16_entry_pos_sel_file == index2.u16_entry_pos_sel_file) )
         {
            u16_current_pos = g_navauto_u16_pos;   // Save the position number found
            g_navauto_u16_dir_level_root = g_navauto_u16_dir_level;
         }
      }

      navauto_setrand(rand_mode);                  // Restore random mode
      if( 0 == g_navauto_u16_nb )
         return false;  // loop empty

      // Go to a file from file list
      if( NAVAUTO_RAND_OFF == navauto_getrand() )
      {
         if( 0xFF != index.u8_lun )
         {
            // Reselect the file selected at startup
            nav_gotoindex( &index );               // Go to this one
            g_navauto_u16_dir_level  = g_navauto_u16_dir_level_root;        // Update position file
            g_navauto_u16_pos = u16_current_pos;   // Update folder level corresponding at file
         }
         // Else, the first file is already selected at the end of "compute file list size" loop
         return true;
      }else{
         navauto_rand_init();
      }
#else
      Fs_index       index;
      Navauto_rand   rand_mode;

      rand_mode = navauto_getrand();
      navauto_setrand(NAVAUTO_RAND_OFF);

      // If no valid file then find the first valid file
      if( !nav_file_checkext( g_navauto_filter ))
      {
         // Go to previous position because "navauto_mov_explorer()" execute a next before search valid file
         if( !nav_filelist_set( 0 , FS_FIND_PREV ) )
           nav_filelist_reset();
         state = navauto_mov_explorer(FS_FIND_NEXT, NAVAUTO_MOV_OPTS_NONE);
         if((NAVAUTO_MOV_OK_LOOP != state.status)
         && (NAVAUTO_MOV_OK      != state.status) )
         {
           navauto_setrand(rand_mode);
           return false;  // List empty
         }
      }
      index = nav_getindex();

      navauto_setrand(rand_mode);

      navauto_mov_explorer_reset();
      // Compute directory level
      g_navauto_u16_dir_level = 0;
      while(nav_dir_gotoparent())
        g_navauto_u16_dir_level++;
      g_navauto_u16_dir_level_root = g_navauto_u16_dir_level;
      //g_navauto_u16_dir_level  = pos;
      // Restore index
      nav_gotoindex(&index);

      g_navauto_u16_nb = 0xFFFF;

      if( NAVAUTO_RAND_OFF == navauto_getrand() )
        navauto_rand_init();

      if( nav_file_checkext( g_navauto_filter ))
      {
        // Valid file then update position with the first position but it is not the first !
        g_navauto_u16_pos = 1;
        return true;
      }
#endif
   }
   // Find first file or use the random feature
   state = navauto_mov(FS_FIND_NEXT, NAVAUTO_MOV_OPTS_NONE);
   if((NAVAUTO_MOV_OK_LOOP != state.status)
   && (NAVAUTO_MOV_OK      != state.status) )
      return false;  // List empty
   return true;
}
Пример #13
0
//! This function creates a copy of the play list in case of a restore action
//!
//! @return    false in case of error, see global value "fs_g_status" for more detail
//! @return    true otherwise
//!
bool   pl_main_modify( void )
{
   _MEM_TYPE_SLOW_ uint8_t name_copyfile[]="~copy.m3u";
   _MEM_TYPE_SLOW_ Fs_index index;
   uint8_t nav_id_save;
   uint16_t u16_pos;
   uint8_t status;
   bool b_copy_finish = false;

   if( !pl_main_isopen() )
      return false;
   if( pl_g_list_is_modify )
      return true;
   // If an error occurs during copy process then the play list file is set in read only mode
   fs_g_status = FS_ERR_PL_READ_ONLY;
   if( pl_g_list_is_readonly )
      return false;
   if( !pl_g_list_undo )
   {
      pl_g_list_is_modify = true;
      return true;
   }

   // Save information about current play list file
   nav_id_save = nav_get();
   nav_select( FS_NAV_ID_PLAYLIST );
   u16_pos = pl_g_u16_list_sel;           // Save position in play list
   file_close();                          // Close list
   pl_g_list_is_open = false;
   index = nav_getindex();                // Get pointer on play list

   // Copy play list file in a temporary file
#if( (FS_ASCII == true) && (FS_UNICODE == true) )
   nav_string_ascii();                    // copy file name stored in ASCII
#endif
   if( !nav_file_copy())
      goto pl_main_modify_end;
   if( !nav_file_paste_start( name_copyfile ) )
   {
      if( FS_ERR_FILE_EXIST != fs_g_status)
         goto pl_main_modify_end;
      // File exist then delete
      if( !nav_file_del(true) )
         goto pl_main_modify_end;
      // Retry paste
      if( !nav_file_paste_start( name_copyfile ) )
         goto pl_main_modify_end;
   }
   // Run paste
   do{
      status = nav_file_paste_state(false);  // Copy running
   }while( COPY_BUSY == status );
   if( COPY_FINISH != status )
      goto pl_main_modify_end;
   // Save pointer on copy file
   copyfile_index = nav_getindex();
   b_copy_finish = true;

pl_main_modify_end:
   // Restore the play list file
#if( (FS_ASCII == true) && (FS_UNICODE == true) )
   nav_string_unicode();
#endif
   nav_gotoindex( &index );               // Go to original play list file
   pl_main_open( true );                  // Re open play list file
   pl_g_list_is_modify = b_copy_finish;
   nav_select( nav_id_save );
   pl_nav_setpos(u16_pos);                // Restore position in play list
   return pl_g_list_is_modify;
}
Пример #14
0
//!
//! @brief Synchronize the contents of two directories (limited to files).
//!
//! @param dst_fs_idx   Fs_index *:   File system index for destination navigation path
//! @param dst_dir      const char *: Pointer to destination directory name
//! @param src_fs_idx   Fs_index *:   File system index for source navigation path
//! @param src_dir      const char *: Pointer to source directory name
//!
//! @return bool: true on success
//!
//! @todo Do recursive directory copy...
//!
bool host_mass_storage_task_sync_dir(Fs_index *dst_fs_idx, const char *dst_dir, Fs_index *src_fs_idx, const char *src_dir)
{
  uint8_t nb_file;
  uint8_t i;
  uint32_t free_space;
  uint16_t file_size;

  // First, check the host controller is in full operating mode with the
  // B-device attached and enumerated
  if (!Is_host_ready()) return false;

  // Go to source navigation
  nav_gotoindex(src_fs_idx);
  if (!goto_code_name(src_dir)) return false;   // Check that source directory exists
  nav_dir_cd();                                 // Source directory exists, so go to it
  *src_fs_idx = nav_getindex();                 // Save navigation position
  nav_filelist_first(FS_FILE);                  // Go to first file
  nb_file = nav_filelist_nb(FS_FILE);           // Get the number of files in this directory

  // Go to destination navigation
  nav_gotoindex(dst_fs_idx);
  if (!goto_code_name(dst_dir))                 // Destination directory does not exist, so create it
  {
    str_code_to_unicode_ram(dst_dir, ms_str_unicode);
    nav_dir_make(ms_str_unicode);
    if (!goto_code_name(dst_dir)) return false; // Check that destination directory has been created
  }
  nav_dir_cd();
  *dst_fs_idx = nav_getindex();

  // Get available free space
  free_space = nav_partition_space();
  nav_gotoindex(src_fs_idx);
  nav_filelist_first(FS_FILE);

  // For all files in directory
  for (i = 0; i < nb_file; i++)
  {
    // Get source name to be used as destination name
    nav_file_name(ms_str_unicode, MAX_FILE_PATH_LENGTH, FS_NAME_GET);
    file_size = nav_file_lgtsector();           // Get file size
    if (file_size > free_space) return false;   // Check that there is enough free space left
    // Update free space (to save time, do no call nav_partition_space() again)
    free_space -= file_size;
    // Mark source
    nav_file_copy();
    // Save current source position
    *src_fs_idx = nav_getindex();

    // Go to destination navigation
    nav_gotoindex(dst_fs_idx);
    if (goto_unicode_name(ms_str_unicode))      // If file already exists
    {
      nav_file_del();                           // Delete it
    }

    // Paste
    nav_file_paste_start(ms_str_unicode);
    // Restore previous navigation position
    nav_gotoindex(src_fs_idx);
    // Copy
    while (nav_file_paste_state(false) == COPY_BUSY);

    // Restore previous navigation position
    nav_gotoindex(src_fs_idx);
    nav_filelist_set(0, FS_FIND_NEXT);
  }

  return true;
}