aboutsummaryrefslogtreecommitdiffstats
path: root/heimdall/source/BridgeManager.cpp
diff options
context:
space:
mode:
authorKoushik Dutta <koushd@gmail.com>2013-08-14 10:01:22 -0700
committerKoushik Dutta <koushd@gmail.com>2013-08-14 10:01:22 -0700
commit49a02b8c916e8ef011d9f56901d208eca626b85b (patch)
tree1148a42ede0e6661854b8f92d4bbe52a4290d02b /heimdall/source/BridgeManager.cpp
parentc82df274ecea32cd6528f070a21528bf80a2f466 (diff)
parentf95619028fa5c80284e6ade2ced7772e41040424 (diff)
downloadexternal_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.cpp257
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);
}