From ebbc3e7cd2086a9f62a857dffe9ab0bd1f5da768 Mon Sep 17 00:00:00 2001 From: Benjamin Dobell Date: Fri, 8 Mar 2013 00:00:52 +1100 Subject: - Removed legacy command line hard-coded partition name parameters. - As a result of the above two points, there are no "known boot partitions", and hence boot partitions are not automatically flashed last. - Made partitions flash in the order in order in which partition arguments are specified. Hence, it's recommended that you specify boot partitions last. - Added --usb-level argument that can be used for debugging libusbx, or flashing issues in general. - Removed generally non-functional firmware dumping behaviour. - Removed auto-resume functionality - Although this feature was definitely nice to have; I believe it may be responsible for flashing compatibility issues for a variety of devices. - As a result of the above. In order perform another action after a --no-reboot action, you must provide the --resume flag. - Heimdall Frontend also has support for specifying the --resume flag via a GUI. Heimdall Frontend also tries to keep track of your actions and enable "Resume" automatically after a "No Reboot" action. - Refactored quite a few of the actions, and code responsible for flashing (particularly PIT file flashing). - Bumped version to 1.4RC3 *however* this commit is not yet an official release candidate. It's still a WIP. In particular build files still have not been updated for Linux and OS X. --- heimdall/source/BridgeManager.cpp | 230 ++++++++++++++++---------------------- 1 file changed, 97 insertions(+), 133 deletions(-) (limited to 'heimdall/source/BridgeManager.cpp') diff --git a/heimdall/source/BridgeManager.cpp b/heimdall/source/BridgeManager.cpp index aa7b969..8f1b32e 100644 --- a/heimdall/source/BridgeManager.cpp +++ b/heimdall/source/BridgeManager.cpp @@ -57,6 +57,7 @@ #define USB_CLASS_CDC_DATA 0x0A +using namespace libpit; using namespace Heimdall; const DeviceIdentifier BridgeManager::supportedDevices[BridgeManager::kSupportedDeviceCount] = { @@ -68,7 +69,7 @@ const DeviceIdentifier BridgeManager::supportedDevices[BridgeManager::kSupported enum { - kDumpBufferSize = 4096 + kDumpBufferSize = 4096, }; enum @@ -84,6 +85,11 @@ enum kReceivePacketMaxAttempts = 5 }; +enum +{ + kPitSizeMultiplicand = 4096 +}; + int BridgeManager::FindDeviceInterface(void) { Interface::Print("Detecting device...\n"); @@ -302,34 +308,7 @@ void BridgeManager::ReleaseDeviceInterface(void) Interface::Print("\n"); } -bool BridgeManager::CheckProtocol(void) const -{ - Interface::Print("Checking if protocol is initialised...\n"); - - DeviceTypePacket deviceTypePacket; - - if (!SendPacket(&deviceTypePacket, 150, false)) - { - Interface::Print("Protocol is not initialised.\n"); - return (false); - } - - unsigned char buffer[1024]; - memset(buffer, 0, sizeof(buffer)); - - SessionSetupResponse deviceTypeResponse; - - if (!ReceivePacket(&deviceTypeResponse, 150, false, buffer, sizeof(buffer))) - { - Interface::Print("Protocol is not initialised.\n\n"); - return (false); - } - - Interface::Print("Protocol is initialised.\n\n"); - return (true); -} - -bool BridgeManager::InitialiseProtocol(void) const +bool BridgeManager::InitialiseProtocol(void) { Interface::Print("Initialising protocol...\n"); @@ -488,6 +467,8 @@ BridgeManager::BridgeManager(bool verbose, int communicationDelay) fileTransferSequenceMaxLength = kFileTransferSequenceMaxLengthDefault; fileTransferPacketSize = kFileTransferPacketSizeDefault; fileTransferSequenceTimeout = kFileTransferSequenceTimeoutDefault; + + usbLogLevel = UsbLogLevel::Default; } BridgeManager::~BridgeManager() @@ -507,14 +488,39 @@ BridgeManager::~BridgeManager() bool BridgeManager::DetectDevice(void) { - // Initialise libusb-1.0 + // Initialise libusb int result = libusb_init(&libusbContext); + if (result != LIBUSB_SUCCESS) { Interface::PrintError("Failed to initialise libusb. libusb error: %d\n", result); return (false); } + // Setup libusb log level. + switch (usbLogLevel) + { + case UsbLogLevel::None: + libusb_set_debug(libusbContext, LIBUSB_LOG_LEVEL_NONE); + break; + + case UsbLogLevel::Error: + libusb_set_debug(libusbContext, LIBUSB_LOG_LEVEL_ERROR); + break; + + case UsbLogLevel::Warning: + libusb_set_debug(libusbContext, LIBUSB_LOG_LEVEL_WARNING); + break; + + case UsbLogLevel::Info: + libusb_set_debug(libusbContext, LIBUSB_LOG_LEVEL_INFO); + break; + + case UsbLogLevel::Debug: + libusb_set_debug(libusbContext, LIBUSB_LOG_LEVEL_DEBUG); + break; + } + // Get handle to Galaxy S device struct libusb_device **devices; int deviceCount = libusb_get_device_list(libusbContext, &devices); @@ -542,11 +548,11 @@ bool BridgeManager::DetectDevice(void) return (false); } -int BridgeManager::Initialise() +int BridgeManager::Initialise(bool resume) { Interface::Print("Initialising connection...\n"); - // Initialise libusb-1.0 + // Initialise libusb int result = libusb_init(&libusbContext); if (result != LIBUSB_SUCCESS) @@ -555,6 +561,30 @@ int BridgeManager::Initialise() Interface::Print("Failed to connect to device!"); return (BridgeManager::kInitialiseFailed); } + + // Setup libusb log level. + switch (usbLogLevel) + { + case UsbLogLevel::None: + libusb_set_debug(libusbContext, LIBUSB_LOG_LEVEL_NONE); + break; + + case UsbLogLevel::Error: + libusb_set_debug(libusbContext, LIBUSB_LOG_LEVEL_ERROR); + break; + + case UsbLogLevel::Warning: + libusb_set_debug(libusbContext, LIBUSB_LOG_LEVEL_WARNING); + break; + + case UsbLogLevel::Info: + libusb_set_debug(libusbContext, LIBUSB_LOG_LEVEL_INFO); + break; + + case UsbLogLevel::Debug: + libusb_set_debug(libusbContext, LIBUSB_LOG_LEVEL_DEBUG); + break; + } result = FindDeviceInterface(); @@ -567,7 +597,7 @@ int BridgeManager::Initialise() if (!SetupDeviceInterface()) return (BridgeManager::kInitialiseFailed); - if (!CheckProtocol()) + if (!resume) { if (!InitialiseProtocol()) return (BridgeManager::kInitialiseFailed); @@ -865,11 +895,9 @@ bool BridgeManager::RequestDeviceType(unsigned int request, int *result) const return (true); } -bool BridgeManager::SendPitFile(FILE *file) const +bool BridgeManager::SendPitData(const PitData *pitData) const { - fseek(file, 0, SEEK_END); - long fileSize = ftell(file); - rewind(file); + unsigned int pitBufferSize = pitData->GetPaddedSize(); // Start file transfer PitFilePacket *pitFilePacket = new PitFilePacket(PitFilePacket::kRequestFlash); @@ -893,7 +921,7 @@ bool BridgeManager::SendPitFile(FILE *file) const } // Transfer file size - FlashPartPitFilePacket *flashPartPitFilePacket = new FlashPartPitFilePacket(fileSize); + FlashPartPitFilePacket *flashPartPitFilePacket = new FlashPartPitFilePacket(pitBufferSize); success = SendPacket(flashPartPitFilePacket); delete flashPartPitFilePacket; @@ -913,11 +941,20 @@ bool BridgeManager::SendPitFile(FILE *file) const return (false); } + // Create packed in-memory PIT file + + unsigned char *pitBuffer = new unsigned char[pitBufferSize]; + memset(pitBuffer, 0, pitBufferSize); + + pitData->Pack(pitBuffer); + // Flash pit file - SendFilePartPacket *sendFilePartPacket = new SendFilePartPacket(file, fileSize); + SendFilePartPacket *sendFilePartPacket = new SendFilePartPacket(pitBuffer, pitBufferSize); success = SendPacket(sendFilePartPacket); delete sendFilePartPacket; + delete [] pitBuffer; + if (!success) { Interface::PrintError("Failed to send file part packet!\n"); @@ -935,7 +972,7 @@ bool BridgeManager::SendPitFile(FILE *file) const } // End pit file transfer - EndPitFileTransferPacket *endPitFileTransferPacket = new EndPitFileTransferPacket(fileSize); + EndPitFileTransferPacket *endPitFileTransferPacket = new EndPitFileTransferPacket(pitBufferSize); success = SendPacket(endPitFileTransferPacket); delete endPitFileTransferPacket; @@ -1320,106 +1357,33 @@ bool BridgeManager::SendFile(FILE *file, unsigned int destination, unsigned int return (true); } -bool BridgeManager::ReceiveDump(unsigned int chipType, unsigned int chipId, FILE *file) const +void BridgeManager::SetUsbLogLevel(UsbLogLevel usbLogLevel) { - bool success; - - // Start file transfer - BeginDumpPacket *beginDumpPacket = new BeginDumpPacket(chipType, chipId); - success = SendPacket(beginDumpPacket); - delete beginDumpPacket; + this->usbLogLevel = usbLogLevel; - if (!success) - { - Interface::PrintError("Failed to request dump!\n"); - return (false); - } - - DumpResponse *dumpResponse = new DumpResponse(); - success = ReceivePacket(dumpResponse); - unsigned int dumpSize = dumpResponse->GetDumpSize(); - delete dumpResponse; - - if (!success) - { - Interface::PrintError("Failed to receive dump size!\n"); - return (false); - } - - unsigned int transferCount = dumpSize / ReceiveFilePartPacket::kDataSize; - if (transferCount % ReceiveFilePartPacket::kDataSize != 0) - transferCount++; - - char *buffer = new char[kDumpBufferSize * ReceiveFilePartPacket::kDataSize]; - unsigned int bufferOffset = 0; - - for (unsigned int i = 0; i < transferCount; i++) + if (libusbContext) { - DumpPartFileTransferPacket *dumpPartPacket = new DumpPartFileTransferPacket(i); - success = SendPacket(dumpPartPacket); - delete dumpPartPacket; - - if (!success) - { - Interface::PrintError("Failed to request dump part #%d!\n", i); - delete [] buffer; - return (false); - } - - ReceiveFilePartPacket *receiveFilePartPacket = new ReceiveFilePartPacket(); - success = ReceivePacket(receiveFilePartPacket); - - if (!success) - { - Interface::PrintError("Failed to receive dump part #%d!\n", i); - continue; - delete receiveFilePartPacket; - delete [] buffer; - return (true); - } - - if (bufferOffset + receiveFilePartPacket->GetReceivedSize() > kDumpBufferSize * ReceiveFilePartPacket::kDataSize) + switch (usbLogLevel) { - // Write the buffer to the output file - fwrite(buffer, 1, bufferOffset, file); - bufferOffset = 0; - } - - // Copy the packet data into pitFile. - memcpy(buffer + bufferOffset, receiveFilePartPacket->GetData(), receiveFilePartPacket->GetReceivedSize()); - bufferOffset += receiveFilePartPacket->GetReceivedSize(); - - delete receiveFilePartPacket; - } - - if (bufferOffset != 0) - { - // Write the buffer to the output file - fwrite(buffer, 1, bufferOffset, file); - } - - delete [] buffer; + case UsbLogLevel::None: + libusb_set_debug(libusbContext, LIBUSB_LOG_LEVEL_NONE); + break; - // End file transfer - FileTransferPacket *fileTransferPacket = new FileTransferPacket(FileTransferPacket::kRequestEnd); - success = SendPacket(fileTransferPacket); - delete fileTransferPacket; + case UsbLogLevel::Error: + libusb_set_debug(libusbContext, LIBUSB_LOG_LEVEL_ERROR); + break; - if (!success) - { - Interface::PrintError("Failed to send request to end dump transfer!\n"); - return (false); - } + case UsbLogLevel::Warning: + libusb_set_debug(libusbContext, LIBUSB_LOG_LEVEL_WARNING); + break; - ResponsePacket *responsePacket = new ResponsePacket(ResponsePacket::kResponseTypeFileTransfer); - success = ReceivePacket(responsePacket); - delete responsePacket; + case UsbLogLevel::Info: + libusb_set_debug(libusbContext, LIBUSB_LOG_LEVEL_INFO); + break; - if (!success) - { - Interface::PrintError("Failed to receive end dump transfer verification!\n"); - return (false); + case UsbLogLevel::Debug: + libusb_set_debug(libusbContext, LIBUSB_LOG_LEVEL_DEBUG); + break; + } } - - return (true); } -- cgit v1.1 From 8301663c99ee5cabeb26e20b176fe96fe8c6683e Mon Sep 17 00:00:00 2001 From: Benjamin Dobell Date: Sun, 5 May 2013 20:57:50 +1000 Subject: Minor command line output changes - No functional changes. --- heimdall/source/BridgeManager.cpp | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) (limited to 'heimdall/source/BridgeManager.cpp') diff --git a/heimdall/source/BridgeManager.cpp b/heimdall/source/BridgeManager.cpp index 8f1b32e..1ab46ae 100644 --- a/heimdall/source/BridgeManager.cpp +++ b/heimdall/source/BridgeManager.cpp @@ -624,11 +624,11 @@ bool BridgeManager::BeginSession(void) unsigned int deviceDefaultPacketSize = beginSessionResponse.GetResult(); + Interface::Print("\nSome devices may take up to 2 minutes to respond.\nPlease be patient!\n\n"); + Sleep(3000); // Give the user time to read the message. + if (deviceDefaultPacketSize != 0) // 0 means changing the packet size is not supported. { - Interface::Print("\nThis device may take up to 2 minutes to respond.\nPlease be patient!\n\n"); - Sleep(2000); // Give the user time to read the message. - fileTransferSequenceTimeout = 120000; // 2 minutes! fileTransferPacketSize = 1048576; // 1 MiB fileTransferSequenceMaxLength = 100; // 100 MiB per sequence. Which is the same as the default of 800 * 131072. @@ -1218,13 +1218,6 @@ bool BridgeManager::SendFile(FILE *file, unsigned int destination, unsigned int success = ReceivePacket(sendFilePartResponse); int receivedPartIndex = sendFilePartResponse->GetPartIndex(); - if (verbose) - { - const unsigned char *data = sendFilePartResponse->GetData(); - Interface::Print("File Part #%d... Response: %X %X %X %X %X %X %X %X \n", filePartIndex, - data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); - } - delete sendFilePartResponse; if (!success) @@ -1254,13 +1247,6 @@ bool BridgeManager::SendFile(FILE *file, unsigned int destination, unsigned int success = ReceivePacket(sendFilePartResponse); unsigned int receivedPartIndex = sendFilePartResponse->GetPartIndex(); - if (verbose) - { - const unsigned char *data = sendFilePartResponse->GetData(); - Interface::Print("File Part #%d... Response: %X %X %X %X %X %X %X %X \n", filePartIndex, - data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); - } - delete sendFilePartResponse; if (receivedPartIndex != filePartIndex) -- cgit v1.1 From f46ef9d47a2b22ca37d763ac98c70afe26929ef3 Mon Sep 17 00:00:00 2001 From: Benjamin Dobell Date: Sun, 5 May 2013 23:59:47 +1000 Subject: For devices that support variable packet size - decreased sequence size from 100 MiB to 30 MiB. --- heimdall/source/BridgeManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'heimdall/source/BridgeManager.cpp') diff --git a/heimdall/source/BridgeManager.cpp b/heimdall/source/BridgeManager.cpp index 1ab46ae..35be1fd 100644 --- a/heimdall/source/BridgeManager.cpp +++ b/heimdall/source/BridgeManager.cpp @@ -631,7 +631,7 @@ bool BridgeManager::BeginSession(void) { fileTransferSequenceTimeout = 120000; // 2 minutes! fileTransferPacketSize = 1048576; // 1 MiB - fileTransferSequenceMaxLength = 100; // 100 MiB per sequence. Which is the same as the default of 800 * 131072. + fileTransferSequenceMaxLength = 30; // Therefore, fileTransferPacketSize * fileTransferSequenceMaxLength == 30 MiB per sequence. FilePartSizePacket filePartSizePacket(fileTransferPacketSize); -- cgit v1.1 From c9e4f764c2cc81f3ab223116e73340ea33e1abcb Mon Sep 17 00:00:00 2001 From: Benjamin Dobell Date: Sat, 11 May 2013 13:36:05 +1000 Subject: Removed bad Galaxy Camera device identifier, as it was the PID for regular boot, not download mode. --- heimdall/source/BridgeManager.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'heimdall/source/BridgeManager.cpp') diff --git a/heimdall/source/BridgeManager.cpp b/heimdall/source/BridgeManager.cpp index 35be1fd..5e23560 100644 --- a/heimdall/source/BridgeManager.cpp +++ b/heimdall/source/BridgeManager.cpp @@ -63,8 +63,7 @@ using namespace Heimdall; const DeviceIdentifier BridgeManager::supportedDevices[BridgeManager::kSupportedDeviceCount] = { DeviceIdentifier(BridgeManager::kVidSamsung, BridgeManager::kPidGalaxyS), DeviceIdentifier(BridgeManager::kVidSamsung, BridgeManager::kPidGalaxyS2), - DeviceIdentifier(BridgeManager::kVidSamsung, BridgeManager::kPidDroidCharge), - DeviceIdentifier(BridgeManager::kVidSamsung, BridgeManager::kPidGalaxyCamera) + DeviceIdentifier(BridgeManager::kVidSamsung, BridgeManager::kPidDroidCharge) }; enum -- cgit v1.1 From 07dcba54fc8cc5b7c6515305aa233e24a58adc94 Mon Sep 17 00:00:00 2001 From: Benjamin Dobell Date: Mon, 13 May 2013 00:08:30 +1000 Subject: Update copyright notices, version identifier and documentation for 1.4.0 release. --- heimdall/source/BridgeManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'heimdall/source/BridgeManager.cpp') diff --git a/heimdall/source/BridgeManager.cpp b/heimdall/source/BridgeManager.cpp index 5e23560..ed12b87 100644 --- a/heimdall/source/BridgeManager.cpp +++ b/heimdall/source/BridgeManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2010-2012 Benjamin Dobell, Glass Echidna +/* Copyright (c) 2010-2013 Benjamin Dobell, Glass Echidna Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal -- cgit v1.1