~grimler/Heimdall

62368adc7d259ef43e5c1febca30b1f45420df31 — Henrik Grimler 2 years ago 0f1843c
BridgeManager: only libusb_reset_device on ubuntu

It seems that only ubuntu needs libusb_reset_device for successful
handshake. On most distros and device it works with or without, but
for some devices (like degaswifi/SM-T230 with a Marvell PXA 1088 SOC)
it causes handshake to fail.

Probably libusb_reset_device causes issues only for some devices, but
there seem to be no way to distinguish which ones from Heimdall (not
based on Odin protocol version or SOC at least).

Fixes commit 07a14d4aa8ad ("InitialiseProtocol: reset device before
handshake").
2 files changed, 41 insertions(+), 3 deletions(-)

M heimdall/source/BridgeManager.cpp
M heimdall/source/BridgeManager.h
M heimdall/source/BridgeManager.cpp => heimdall/source/BridgeManager.cpp +38 -2
@@ 20,6 20,7 @@

// C Standard Library
#include <cstdio>
#include <fstream>

// libusb
#include <libusb.h>


@@ 311,10 312,16 @@ bool BridgeManager::InitialiseProtocol(void)
	memcpy(dataBuffer, "ODIN", 4);
	memset(dataBuffer + 4, 0, 1);

	if (libusb_reset_device(deviceHandle))
#ifdef OS_LINUX
	if (IsUbuntu())
	{
		Interface::PrintError("Failed to reset device!\n");
		Interface::Print("Resetting device...\n");
		if (libusb_reset_device(deviceHandle))
		{
			Interface::PrintError("Failed to reset device!\n");
		}
	}
#endif

	if (!SendBulkTransfer(dataBuffer, 4, 1000))
	{


@@ 1237,3 1244,32 @@ void BridgeManager::SetUsbLogLevel(UsbLogLevel usbLogLevel)
		}
	}
}

#ifdef OS_LINUX
bool BridgeManager::IsUbuntu()
{
	std::ifstream os_release("/etc/os-release");
	std::string line, entry, os;
	int pos;
	while (std::getline(os_release, line))
	{
		pos = line.find("=");
		entry = line.substr(0, pos);
		if (entry == "ID")
		{
			os = line.substr(pos+1);
			if (verbose)
			{
				Interface::Print("Linux distro ID: %s\n",
						 os.c_str());
			}
			if (os == "ubuntu")
			{
				return true;
			}
			break;
		}
	}
	return false;
}
#endif

M heimdall/source/BridgeManager.h => heimdall/source/BridgeManager.h +3 -1
@@ 166,7 166,9 @@ namespace Heimdall
			bool SendFile(FILE *file, unsigned int destination, unsigned int deviceType, unsigned int fileIdentifier = 0xFFFFFFFF) const;

			void SetUsbLogLevel(UsbLogLevel usbLogLevel);

#ifdef OS_LINUX
			bool IsUbuntu(void);
#endif
			UsbLogLevel GetUsbLogLevel(void) const
			{
				return usbLogLevel;