@@ -480,6 +480,10 @@ void iecFuji::process_basic_commands()
480480 fujicmd_generate_guid ();
481481 response = mstr::toPETSCII2 (response);
482482 }
483+ else if (payload.find (" copy" ) != std::string::npos)
484+ copy_file_basic ();
485+ else if (payload.find (" update" ) != std::string::npos)
486+ update_firmware ();
483487 else if (payload.find (" bptiming" ) != std::string::npos)
484488 {
485489 if ( pt.size () < 3 )
@@ -535,6 +539,8 @@ bool iecFuji::is_supported(uint8_t cmd)
535539 case FUJICMD_WRITE_APPKEY:
536540 case FUJICMD_WRITE_DEVICE_SLOTS:
537541 case FUJICMD_WRITE_HOST_SLOTS:
542+ case FUJICMD_COPY_FILE:
543+ case FUJICMD_UPDATE_FIRMWARE:
538544 result = true ;
539545 break ;
540546 }
@@ -694,6 +700,9 @@ void iecFuji::process_immediate_raw_cmds()
694700 fujicmd_generate_guid ();
695701 response = mstr::toPETSCII2 (response);
696702 break ;
703+ case FUJICMD_UPDATE_FIRMWARE:
704+ update_firmware ();
705+ break ;
697706 default :
698707 // not an immediate command, so exit without changing current_fuji_cmd, as we need to be sent data
699708 was_immediate_cmd = false ;
@@ -817,36 +826,78 @@ void iecFuji::net_set_ssid_basic(bool store)
817826 fujicmd_net_set_ssid_success (net_config.ssid , net_config.password , store);
818827}
819828
820- void iecFuji::enable_device_basic ()
829+ void iecFuji::enable_device_basic (std::string ids )
821830{
831+ if (ids.empty ()) {
822832 // Strip off the ENABLE: part of the command
823- pt[0 ] = pt[0 ].substr (7 , std::string::npos);
833+ pt[0 ] = pt[0 ].substr (7 , std::string::npos);
834+ } else {
835+ pt = util_tokenize (ids, ' ,' );
836+ }
824837
825838 // Enable devices
826839 for (int i = 0 ; i < pt.size (); i++) {
827840 uint8_t device = atoi (pt[i].c_str ());
828- auto d = SYSTEM_BUS.findDevice (device, true );
829- if (d) {
830- d->setActive (true );
831- Debug_printv (" Enable Device #%d [%d]" , device, d->isActive ());
841+ if (device == 0 ) {
842+ // special case for device 0, we want to enable all drives if that is the case
843+ for (int dnum = 1 ; dnum <= MAX_DISK_DEVICES; dnum++) {
844+ auto d = SYSTEM_BUS.m_devices [dnum];
845+ if (d) {
846+ d->setActive (true );
847+ Config.store_device_slot_enable (dnum, true );
848+ Debug_printv (" Enable Device #%d [%d]" , (dnum + 7 ), d->isActive ());
849+ }
850+ }
851+ break ;
852+ }
853+ else
854+ {
855+ auto d = SYSTEM_BUS.findDevice (device, true );
856+ if (d) {
857+ d->setActive (true );
858+ Config.store_device_slot_enable ((device - 7 ), true );
859+ Debug_printv (" Enable Device #%d [%d]" , device, d->isActive ());
860+ }
832861 }
833862 }
863+ Config.save ();
834864}
835865
836- void iecFuji::disable_device_basic ()
866+ void iecFuji::disable_device_basic (std::string ids )
837867{
868+ if (ids.empty ()) {
838869 // Strip off the DISABLE: part of the command
839- pt[0 ] = pt[0 ].substr (8 , std::string::npos);
870+ pt[0 ] = pt[0 ].substr (8 , std::string::npos);
871+ } else {
872+ pt = util_tokenize (ids, ' ,' );
873+ }
840874
841875 // Disable devices
842876 for (int i = 0 ; i < pt.size (); i++) {
843877 uint8_t device = atoi (pt[i].c_str ());
844- auto d = SYSTEM_BUS.findDevice (device, true );
845- if (d) {
846- d->setActive (false );
847- Debug_printv (" Disable Device #%d [%d]" , device, d->isActive ());
878+ if (device == 0 ) {
879+ // special case for device 0, we want to disable all drives if that is the case
880+ for (int dnum = 1 ; dnum <= MAX_DISK_DEVICES; dnum++) {
881+ auto d = SYSTEM_BUS.m_devices [dnum];
882+ if (d) {
883+ d->setActive (false );
884+ Config.store_device_slot_enable (dnum, false );
885+ Debug_printv (" Disable Device #%d [%d]" , (dnum + 7 ), d->isActive ());
886+ }
887+ }
888+ break ;
889+ }
890+ else
891+ {
892+ auto d = SYSTEM_BUS.findDevice (device, true );
893+ if (d) {
894+ d->setActive (false );
895+ Config.store_device_slot_enable ((device - 7 ), false );
896+ Debug_printv (" Disable Device #%d [%d]" , device, d->isActive ());
897+ }
848898 }
849899 }
900+ Config.save ();
850901}
851902
852903void iecFuji::net_set_ssid_raw (bool store)
@@ -1971,4 +2022,101 @@ void iecFuji::hash_clear()
19712022 hasher.clear ();
19722023}
19732024
2025+ void iecFuji::copy_file_basic ()
2026+ {
2027+ if (pt.size () != 2 )
2028+ {
2029+ Debug_printv (" error: bad args" );
2030+ response = " BAD COPY ARGS" ;
2031+ return ;
2032+ }
2033+
2034+ // Strip off the COPY: part of the command
2035+ pt[0 ] = pt[0 ].substr (5 , std::string::npos);
2036+ if (mstr::isNumeric (pt[0 ])) {
2037+ // Find SSID by CRC8 Number
2038+ pt[0 ] = fnWiFi.get_network_name_by_crc8 (std::stoi (pt[0 ]));
2039+ }
2040+
2041+ copy_file (pt[0 ], pt[1 ]);
2042+ }
2043+
2044+ void iecFuji::copy_file_raw ()
2045+ {
2046+ copy_file (pt[0 ], pt[1 ]);
2047+ }
2048+
2049+ void iecFuji::copy_file (std::string source, std::string destination)
2050+ {
2051+ std::unique_ptr<MFile> in_file (MFSOwner::File (source));
2052+ std::unique_ptr<MFile> out_file (MFSOwner::File (destination));
2053+
2054+ // If destination is a directory then save with source filename
2055+ if ( out_file->isDirectory () )
2056+ {
2057+ destination += " /" + in_file->name ;
2058+ out_file.reset (MFSOwner::File (destination));
2059+ }
2060+
2061+ // Create streams and copy file
2062+ {
2063+ auto in_stream = in_file->getSourceStream (std::ios_base::in);
2064+ if (in_stream == nullptr )
2065+ {
2066+ Serial.printf (" 2 Error: Can't open source!\r\n " );
2067+ set_fuji_iec_status (62 , " can't open source stream" );
2068+ return ;
2069+ }
2070+
2071+ auto out_stream = out_file->getSourceStream (std::ios_base::out);
2072+ if (out_stream == nullptr )
2073+ {
2074+ Serial.printf (" 2 Error: Can't open destination!\r\n " );
2075+ set_fuji_iec_status (62 , " can't open destination stream" );
2076+ return ;
2077+ }
2078+
2079+ Debug_printv (" size[%lu] name[%s] url[%s] destination[%s]" , in_file->size , in_file->name .c_str (), in_stream->url .c_str (), destination.c_str ());
2080+
2081+ // Receive File
2082+ int count = 0 ;
2083+ uint8_t bytes[255 ];
2084+ while (true )
2085+ {
2086+ int bytes_read = in_stream->read (bytes, 255 );
2087+ if (bytes_read < 1 )
2088+ {
2089+ if (in_stream->available ())
2090+ Serial.printf (" \n Error reading '%s'\r " , in_file->name .c_str ());
2091+ break ;
2092+ }
2093+
2094+ int bytes_written = out_stream->write (bytes, bytes_read);
2095+ if (bytes_written != bytes_read)
2096+ {
2097+ Serial.printf (" \n Error writing '%s'\r " , out_file->name .c_str ());
2098+ break ;
2099+ }
2100+
2101+ // Show percentage complete in stdout
2102+ uint8_t percent = (in_stream->position () * 100 ) / in_stream->size ();
2103+ #ifdef ENABLE_DISPLAY
2104+ LEDS.progress = percent;
2105+ #endif
2106+ Serial.printf (" Downloading '%s' %d%% [%lu]\r " , in_file->name .c_str (), percent, in_stream->position ());
2107+ count++;
2108+ }
2109+ Serial.printf (" \n " );
2110+ }
2111+
2112+ set_fuji_iec_status (0 , " " );
2113+ }
2114+
2115+ void iecFuji::update_firmware ()
2116+ {
2117+ fnSystem.update_firmware ();
2118+ set_fuji_iec_status (0 , " " );
2119+ }
2120+
2121+
19742122#endif /* BUILD_IEC */
0 commit comments