diff options
author | Koushik Dutta <koushd@gmail.com> | 2013-08-14 10:01:22 -0700 |
---|---|---|
committer | Koushik Dutta <koushd@gmail.com> | 2013-08-14 10:01:22 -0700 |
commit | 49a02b8c916e8ef011d9f56901d208eca626b85b (patch) | |
tree | 1148a42ede0e6661854b8f92d4bbe52a4290d02b /heimdall/source/BridgeManager.cpp | |
parent | c82df274ecea32cd6528f070a21528bf80a2f466 (diff) | |
parent | f95619028fa5c80284e6ade2ced7772e41040424 (diff) | |
download | external_heimdall-49a02b8c916e8ef011d9f56901d208eca626b85b.zip external_heimdall-49a02b8c916e8ef011d9f56901d208eca626b85b.tar.gz external_heimdall-49a02b8c916e8ef011d9f56901d208eca626b85b.tar.bz2 |
Merge remote-tracking branch 'bd/master' into cm-10.2
Conflicts:
Linux/README
OSX/README.txt
heimdall-frontend/doc-pak/README
heimdall/doc-pak/README
Change-Id: Ib5867d7a2be030290a3896ab82fe48a7f0a97e63
Diffstat (limited to 'heimdall/source/BridgeManager.cpp')
-rw-r--r-- | heimdall/source/BridgeManager.cpp | 257 |
1 files changed, 103 insertions, 154 deletions
diff --git a/heimdall/source/BridgeManager.cpp b/heimdall/source/BridgeManager.cpp index 805029a..5150788 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 @@ -57,18 +57,18 @@ #define USB_CLASS_CDC_DATA 0x0A +using namespace libpit; 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 { - kDumpBufferSize = 4096 + kDumpBufferSize = 4096, }; enum @@ -84,6 +84,11 @@ enum kReceivePacketMaxAttempts = 5 }; +enum +{ + kPitSizeMultiplicand = 4096 +}; + int BridgeManager::FindDeviceInterface(void) { Interface::Print("Detecting device...\n"); @@ -302,34 +307,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 +466,8 @@ BridgeManager::BridgeManager(bool verbose, int communicationDelay) fileTransferSequenceMaxLength = kFileTransferSequenceMaxLengthDefault; fileTransferPacketSize = kFileTransferPacketSizeDefault; fileTransferSequenceTimeout = kFileTransferSequenceTimeoutDefault; + + usbLogLevel = UsbLogLevel::Default; } BridgeManager::~BridgeManager() @@ -507,14 +487,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); @@ -566,11 +571,11 @@ bool BridgeManager::DetectDevice(void) return (detected); } -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) @@ -579,6 +584,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(); @@ -591,7 +620,7 @@ int BridgeManager::Initialise() if (!SetupDeviceInterface()) return (BridgeManager::kInitialiseFailed); - if (!CheckProtocol()) + if (!resume) { if (!InitialiseProtocol()) return (BridgeManager::kInitialiseFailed); @@ -618,14 +647,14 @@ 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. + fileTransferSequenceMaxLength = 30; // Therefore, fileTransferPacketSize * fileTransferSequenceMaxLength == 30 MiB per sequence. FilePartSizePacket filePartSizePacket(fileTransferPacketSize); @@ -889,11 +918,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); @@ -917,7 +944,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; @@ -937,11 +964,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"); @@ -959,7 +995,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; @@ -1205,13 +1241,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) @@ -1241,13 +1270,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) @@ -1344,106 +1366,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; - - 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); - } + this->usbLogLevel = usbLogLevel; - 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) + switch (usbLogLevel) { - Interface::PrintError("Failed to receive dump part #%d!\n", i); - continue; - delete receiveFilePartPacket; - delete [] buffer; - return (true); - } - - if (bufferOffset + receiveFilePartPacket->GetReceivedSize() > kDumpBufferSize * ReceiveFilePartPacket::kDataSize) - { - // 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); } |