diff --git a/embedded/DFUHelperDeviceInfo.json b/embedded/DFUHelperDeviceInfo.json index fff8bba..848dacd 100644 --- a/embedded/DFUHelperDeviceInfo.json +++ b/embedded/DFUHelperDeviceInfo.json @@ -259,6 +259,7 @@ "sequence":"appletv4" }, "appletv4k":{ + "is_supported": false, "image_name":"atv_std_brd", "image_width":300, "image_height":240, diff --git a/src/events/event.cpp b/src/events/event.cpp index 755b9b7..8fcc9d8 100644 --- a/src/events/event.cpp +++ b/src/events/event.cpp @@ -241,11 +241,14 @@ bool build_normal_state(const IdeviceFFI::UsbmuxdDevice& device, DeviceState& ou } } - out.isSupported = SequenceIsSupported(out.productType); + DfuSequence seq = ParseSequence(out.productType); + out.isSupported = SequenceIsSupported(&seq); + out.requiresCLI = SequenceRequiresCLI(&seq); + return true; } -static void handle_other_add(hotplug_handle_t handle, DeviceMode mode, bool supported) { +static void handle_other_add(hotplug_handle_t handle, DeviceMode mode) { char serial[256] = {}; if (!get_usb_device_serial(handle, serial, sizeof(serial))) return; @@ -269,7 +272,10 @@ static void handle_other_add(hotplug_handle_t handle, DeviceMode mode, bool supp m.state.productType = product_model ? product_model : ""; m.state.productVersion.clear(); m.state.displayName = product_name ? product_name : ""; - m.state.isSupported = supported; + + DfuSequence seq = ParseSequence(m.state.productType); + m.state.isSupported = SequenceIsSupported(&seq); + m.state.requiresCLI = SequenceRequiresCLI(&seq); m.recoveryPresent = (mode == DeviceMode::Recovery); m.dfuPresent = (mode == DeviceMode::DFU); @@ -409,9 +415,9 @@ static void hotplug_callback(hotplug_event_t event, hotplug_handle_t handle) { #endif switch (event) { - case HOTPLUG_EVENT_DFU_ADD: handle_other_add(handle, DeviceMode::DFU, false); break; + case HOTPLUG_EVENT_DFU_ADD: handle_other_add(handle, DeviceMode::DFU); break; case HOTPLUG_EVENT_DFU_REMOVE: remove_device(srv, DeviceMode::DFU); break; - case HOTPLUG_EVENT_RECOVERY_ADD: handle_other_add(handle, DeviceMode::Recovery, true); break; + case HOTPLUG_EVENT_RECOVERY_ADD: handle_other_add(handle, DeviceMode::Recovery); break; case HOTPLUG_EVENT_RECOVERY_REMOVE: remove_device(srv, DeviceMode::Recovery); break; } } diff --git a/src/events/event.hpp b/src/events/event.hpp index 158d1a5..6abdc1a 100644 --- a/src/events/event.hpp +++ b/src/events/event.hpp @@ -50,6 +50,7 @@ struct DeviceState { bool connected = false; bool isSupported = false; + bool requiresCLI = false; bool multipleDevices = false; DeviceMode mode = DeviceMode::None; std::string productVersion; diff --git a/src/sequence.cpp b/src/sequence.cpp index ae5d50d..4292c8d 100644 --- a/src/sequence.cpp +++ b/src/sequence.cpp @@ -53,6 +53,8 @@ DfuSequence ParseSequence(const std::string& deviceKey) const auto& layout = itLayout.value(); + // assume supported if not specified + seq.isSupported = layout.value("is_supported", true); seq.imageName = layout.value("image_name", ""); seq.imageWidth = layout.value("image_width", 0); seq.imageHeight = layout.value("image_height", 0); @@ -106,10 +108,14 @@ DfuSequence ParseSequence(const std::string& deviceKey) return seq; } -bool SequenceIsSupported(const std::string& deviceKey) +bool SequenceIsSupported(const DfuSequence* seq) { - DfuSequence seq = ParseSequence(deviceKey); - return !seq.steps.empty(); + return seq && !seq->steps.empty(); +} + +bool SequenceRequiresCLI(const DfuSequence* seq) +{ + return seq && !seq->isSupported; } #endif // WITH_GUI || WITH_TUI diff --git a/src/sequence.hpp b/src/sequence.hpp index 722265b..ff6216d 100644 --- a/src/sequence.hpp +++ b/src/sequence.hpp @@ -51,6 +51,7 @@ struct DfuStep struct DfuSequence { + bool isSupported = true; std::string imageName; int imageWidth = 0; int imageHeight = 0; @@ -60,7 +61,8 @@ struct DfuSequence }; DfuSequence ParseSequence(const std::string& deviceKey); -bool SequenceIsSupported(const std::string& deviceKey); +bool SequenceIsSupported(const DfuSequence* seq); +bool SequenceRequiresCLI(const DfuSequence* seq); #endif // SEQUENCE_H diff --git a/src/tui/TuiMainPanel.cpp b/src/tui/TuiMainPanel.cpp index c229f8c..794bd19 100644 --- a/src/tui/TuiMainPanel.cpp +++ b/src/tui/TuiMainPanel.cpp @@ -73,17 +73,23 @@ static std::string get_device_subtitle(const DeviceState& state) { switch (state.mode) { case DeviceMode::Normal: - if (state.isSupported) { + if (state.requiresCLI) { + return "Sorry, jailbreaking is only available via CLI mode * iOS " + version + "\n" + ecid; + } else if (state.isSupported) { return "Connected in normal mode * iOS " + version + "\n" + ecid; + } else { + return "Sorry, this normal device is not supported * iOS " + version + "\n" + ecid; } - return "Not supported * iOS " + version + "\n" + ecid; case DeviceMode::Recovery: - if (state.isSupported) { - return "Connected in recovery mode\n" + ecid; + if (state.requiresCLI) { + return "Sorry, jailbreaking is only available via CLI mode.\n" + ecid; + } else if (state.isSupported) { + return "Connected in recovery mode.\n" + ecid; + } else { + return "Sorry, this recovery device is not supported.\n" + ecid; } - return "Not supported\n" + ecid; case DeviceMode::DFU: - return "Sorry, jailbreaking in DFU mode is not supported.\n"; + return "Sorry, jailbreaking in DFU is not supported.\n"; case DeviceMode::None: return "Please connect a device to get started. Ensure version range is 15.0+"; } @@ -221,7 +227,7 @@ void TuiMainPanel::handle_enter(int selected, int sy, int sx) { case 2: { if (block_start) break; - bool can_start = (state.connected && state.isSupported && state.mode != DeviceMode::DFU); + bool can_start = (state.connected && state.isSupported && !state.requiresCLI && state.mode != DeviceMode::DFU); if (can_start) { if (state.mode == DeviceMode::Recovery) { GetFrame()->ShowDfu(1); @@ -255,7 +261,7 @@ bool TuiMainPanel::is_button_enabled(int btn_idx) const { switch(btn_idx) { case 0: return true; case 1: return true; - case 2: return (state.connected && state.isSupported && state.mode != DeviceMode::DFU); + case 2: return (state.connected && state.isSupported && !state.requiresCLI && state.mode != DeviceMode::DFU); case 3: return true; } diff --git a/src/wx/MainPanel.cpp b/src/wx/MainPanel.cpp index 625b74d..79d4033 100644 --- a/src/wx/MainPanel.cpp +++ b/src/wx/MainPanel.cpp @@ -216,7 +216,7 @@ void MainPanel::SetDeviceState(const DeviceState& state) m_deviceTitle->SetLabel("Multiple devices detected"); m_deviceSubtitle->SetLabel( wxString::Format( - "%u devices connected. Please only connect one device.\n", + "%u USB devices connected. Disconnect extras and keep only one device attached.\n", state.connectedDeviceCount ) ); @@ -239,30 +239,38 @@ void MainPanel::SetDeviceState(const DeviceState& state) switch (state.mode) { case DeviceMode::Normal: - if (state.isSupported) { + if (state.requiresCLI) { m_deviceTitle->SetLabel(productString); - m_deviceSubtitle->SetLabel("Connected in normal mode - iOS " + versionString + "\n" + ecidString); + m_deviceSubtitle->SetLabel("Sorry, jailbreaking is only available via CLI mode - OS " + versionString + "\n" + ecidString); + m_startButton->Enable(false); + } else if (state.isSupported) { + m_deviceTitle->SetLabel(productString); + m_deviceSubtitle->SetLabel("Connected in normal mode - OS " + versionString + "\n" + ecidString); m_startButton->Enable(); } else { m_deviceTitle->SetLabel(productString); - m_deviceSubtitle->SetLabel("Not supported - iOS " + versionString + "\n" + ecidString); + m_deviceSubtitle->SetLabel("Sorry, this normal device is not supported - OS " + versionString + "\n" + ecidString); m_startButton->Enable(false); } break; case DeviceMode::Recovery: - if (state.isSupported) { + if (state.requiresCLI) { m_deviceTitle->SetLabel(productString); - m_deviceSubtitle->SetLabel("Connected in recovery mode\n" + ecidString); + m_deviceSubtitle->SetLabel("Sorry, jailbreaking is only available via CLI mode.\n" + ecidString); + m_startButton->Enable(false); + } else if (state.isSupported) { + m_deviceTitle->SetLabel(productString); + m_deviceSubtitle->SetLabel("Connected in recovery mode.\n" + ecidString); m_startButton->Enable(); } else { m_deviceTitle->SetLabel(productString); - m_deviceSubtitle->SetLabel("Not supported\n" + ecidString); + m_deviceSubtitle->SetLabel("Sorry, this recovery device is not supported.\n" + ecidString); m_startButton->Enable(false); } break; case DeviceMode::DFU: m_deviceTitle->SetLabel("DFU Mode device"); - m_deviceSubtitle->SetLabel("Sorry, jailbreaking in DFU mode is not supported.\n"); + m_deviceSubtitle->SetLabel("Sorry, jailbreaking in DFU is not supported.\n"); m_startButton->Enable(false); break; case DeviceMode::None: