aboutsummaryrefslogtreecommitdiffstats
path: root/heimdall/source/BridgeManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'heimdall/source/BridgeManager.cpp')
-rw-r--r--heimdall/source/BridgeManager.cpp288
1 files changed, 126 insertions, 162 deletions
diff --git a/heimdall/source/BridgeManager.cpp b/heimdall/source/BridgeManager.cpp
index d21ea60..6546541 100644
--- a/heimdall/source/BridgeManager.cpp
+++ b/heimdall/source/BridgeManager.cpp
@@ -80,7 +80,6 @@ enum
enum
{
- kHandshakeMaxAttempts = 5,
kReceivePacketMaxAttempts = 5
};
@@ -307,144 +306,150 @@ void BridgeManager::ReleaseDeviceInterface(void)
Interface::Print("\n");
}
-bool BridgeManager::InitialiseProtocol(void)
+enum
{
- Interface::Print("Initialising protocol...\n");
-
- unsigned char dataBuffer[7];
-
- int result = libusb_control_transfer(deviceHandle, LIBUSB_REQUEST_TYPE_CLASS, 0x22, 0x3, 0, nullptr, 0, 1000);
-
- if (result < 0 && verbose)
- Interface::PrintWarning("Control transfer #1 failed. Result: %d\n", result);
+ kControlRequestSetLineCoding = 0x20,
+ kControlRequestSetControlLineState = 0x22
+};
- memset(dataBuffer, 0, 7);
- dataBuffer[1] = 0xC2;
- dataBuffer[2] = 0x01;
- dataBuffer[6] = 0x07;
- result = libusb_control_transfer(deviceHandle, LIBUSB_REQUEST_TYPE_CLASS, 0x20, 0x0, 0, dataBuffer, 7, 1000);
+enum
+{
+ kLineCodingCharFormatZeroToOneStopBit = 0,
+ kLineCodingCharFormatOneToOneAndAHalfStopBits = 1,
+ kLineCodingCharFormatTwoToTwoAndAHalfStopBits = 2
+};
- if (result < 0 && verbose)
- Interface::PrintWarning("Control transfer #2 failed. Result: %d\n", result);
+enum
+{
+ kParityTypeNone = 0,
+ kParityTypeOdd = 1,
+ kParityTypeEven = 2,
+ kParityTypeMark = 3,
+ kParityTypeSpace = 4
+};
- result = libusb_control_transfer(deviceHandle, LIBUSB_REQUEST_TYPE_CLASS, 0x22, 0x3, 0, nullptr, 0, 1000);
+bool BridgeManager::SetControlLineState(unsigned short controlSignalFlags)
+{
+ int result = libusb_control_transfer(deviceHandle, LIBUSB_REQUEST_TYPE_CLASS, kControlRequestSetControlLineState, controlSignalFlags, 0, nullptr, 0, 1000);
- if (result < 0 && verbose)
- Interface::PrintWarning("Control transfer #3 failed. Result: %d\n", result);
+ if (result != LIBUSB_SUCCESS)
+ {
+ if (verbose)
+ Interface::PrintWarning("Control line state (signal flags: 0x%x) transfer failed. Result: %d\n", controlSignalFlags, result);
- result = libusb_control_transfer(deviceHandle, LIBUSB_REQUEST_TYPE_CLASS, 0x22, 0x2, 0, nullptr, 0, 1000);
+ return (false);
+ }
+ else
+ {
+ return (true);
+ }
+}
- if (result < 0 && verbose)
- Interface::PrintWarning("Control transfer #4 failed. Result: %d\n", result);
+bool BridgeManager::SetControlLineCoding(LineCoding lineCoding)
+{
+ unsigned char dataBuffer[7];
- memset(dataBuffer, 0, 7);
- dataBuffer[1] = 0xC2;
- dataBuffer[2] = 0x01;
- dataBuffer[6] = 0x08;
+ dataBuffer[0] = lineCoding.dteRate & 0xFF;
+ dataBuffer[1] = (lineCoding.dteRate >> 8) & 0xFF;
+ dataBuffer[2] = (lineCoding.dteRate >> 16) & 0xFF;
+ dataBuffer[3] = (lineCoding.dteRate >> 24) & 0xFF;
+ dataBuffer[4] = lineCoding.charFormat;
+ dataBuffer[5] = lineCoding.parityType;
+ dataBuffer[6] = lineCoding.dataBits;
- result = libusb_control_transfer(deviceHandle, LIBUSB_REQUEST_TYPE_CLASS, 0x20, 0x0, 0, dataBuffer, 7, 1000);
+ int result = libusb_control_transfer(deviceHandle, LIBUSB_REQUEST_TYPE_CLASS, kControlRequestSetLineCoding, 0x0, 0, dataBuffer, 7, 1000);
- if (result < 0 && verbose)
- Interface::PrintWarning("Control transfer #5 failed. Result: %d\n", result);
+ if (result != LIBUSB_SUCCESS)
+ {
+ if (verbose)
+ Interface::PrintWarning("Setting control line coding failed. Result: %d\n", result);
- result = libusb_control_transfer(deviceHandle, LIBUSB_REQUEST_TYPE_CLASS, 0x22, 0x2, 0, nullptr, 0, 1000);
+ return (false);
+ }
+ else
+ {
+ return (true);
+ }
+}
- if (result < 0 && verbose)
- Interface::PrintWarning("Control transfer #6 failed. Result: %d\n", result);
+enum
+{
+ kLineStateControlSignalDtePresent = 1,
+ kLineStateControlSignalCarrierControl = 1 << 1
+};
- unsigned int attempt = 0;
+bool BridgeManager::InitialiseProtocol(void)
+{
+ Interface::Print("Initialising protocol...\n");
- // max(250, communicationDelay)
- int retryDelay = (communicationDelay > 250) ? communicationDelay : 250;
+ /*LineCoding lineCoding;
- for (; attempt < kHandshakeMaxAttempts; attempt++)
- {
- if (attempt > 0)
- {
- if (verbose)
- Interface::PrintErrorSameLine(" Retrying...\n");
-
- // Wait longer each retry
- Sleep(retryDelay * (attempt + 1));
- }
+ lineCoding.dteRate = 115200;
+ lineCoding.charFormat = kLineCodingCharFormatZeroToOneStopBit;
+ lineCoding.parityType = kParityTypeNone;
+ lineCoding.dataBits = 7;
- int dataTransferred = 0;
+ SetControlLineState(kLineStateControlSignalDtePresent | kLineStateControlSignalCarrierControl);
+ SetControlLineCoding(lineCoding);
+ SetControlLineState(kLineStateControlSignalDtePresent | kLineStateControlSignalCarrierControl);
+ SetControlLineState(kLineStateControlSignalCarrierControl);
+
+ lineCoding.dataBits = 8;
+ SetControlLineCoding(lineCoding);
- // Send "ODIN"
- memcpy(dataBuffer, "ODIN", 4);
- memset(dataBuffer + 4, 0, 1);
+ SetControlLineState(kLineStateControlSignalCarrierControl);*/
- result = libusb_bulk_transfer(deviceHandle, outEndpoint, dataBuffer, 4, &dataTransferred, 1000);
- if (result < 0)
- {
- if (verbose)
- Interface::PrintError("Failed to send data: \"%s\"\n", dataBuffer);
- else
- Interface::PrintError("Failed to send data!");
+ int dataTransferred = 0;
- return (false);
- }
+ unsigned char dataBuffer[7];
- if (dataTransferred != 4)
- {
- if (verbose)
- Interface::PrintError("Failed to complete sending of data: \"%s\"\n", dataBuffer);
- else
- Interface::PrintError("Failed to complete sending of data!");
+ // Send "ODIN"
+ memcpy(dataBuffer, "ODIN", 4);
+ memset(dataBuffer + 4, 0, 1);
- return (false);
- }
+ if (!SendBulkTransfer(dataBuffer, 4, 1000))
+ {
+ Interface::PrintError("Failed to send handshake!");
+ }
- // Expect "LOKE"
- memset(dataBuffer, 0, 7);
+ // Expect "LOKE"
+ memset(dataBuffer, 0, 7);
- int retry = 0;
- dataTransferred = 0;
+ int retry = 0;
+ dataTransferred = 0;
- result = libusb_bulk_transfer(deviceHandle, inEndpoint, dataBuffer, 7, &dataTransferred, 1000);
+ int result = libusb_bulk_transfer(deviceHandle, inEndpoint, dataBuffer, 7, &dataTransferred, 1000);
- if (result < 0)
+ if (result != LIBUSB_SUCCESS)
+ {
+ if (verbose)
+ Interface::PrintError("Failed to receive handshake response. Result: %d\n", result);
+ }
+ else
+ {
+ if (dataTransferred == 4 && memcmp(dataBuffer, "LOKE", 4) == 0)
{
- if (verbose)
- Interface::PrintError("Failed to receive handshake response.");
+ // Successfully received "LOKE"
+ Interface::Print("Protocol initialisation successful.\n\n");
+ return (true);
}
else
{
- if (dataTransferred == 4 && memcmp(dataBuffer, "LOKE", 4) == 0)
- {
- // Successfully received "LOKE"
- break;
- }
- else
- {
- if (verbose)
- Interface::PrintError("Expected: \"%s\"\nReceived: \"%s\"\n", "LOKE", dataBuffer);
+ if (verbose)
+ Interface::PrintError("Expected: \"LOKE\"\nReceived: \"%s\"\n", dataBuffer);
- Interface::PrintError("Unexpected handshake response!");
- }
+ Interface::PrintError("Unexpected handshake response!\n");
}
}
- if (attempt == kHandshakeMaxAttempts)
- {
- if (verbose)
- Interface::PrintErrorSameLine("\n");
-
- Interface::PrintError("Protocol initialisation failed!\n\n");
- return (false);
- }
- else
- {
- Interface::Print("Protocol initialisation successful.\n\n");
- return (true);
- }
+ Interface::PrintError("Protocol initialisation failed!\n\n");
+ return (false);
}
-BridgeManager::BridgeManager(bool verbose, int communicationDelay)
+BridgeManager::BridgeManager(bool verbose)
{
this->verbose = verbose;
- this->communicationDelay = communicationDelay;
libusbContext = nullptr;
deviceHandle = nullptr;
@@ -652,46 +657,6 @@ bool BridgeManager::BeginSession(void)
}
}
- // -------------------- KIES DOESN'T DO THIS --------------------
-
- /*DeviceTypePacket deviceTypePacket;
-
- if (!SendPacket(&deviceTypePacket))
- {
- Interface::PrintError("Failed to request device type!\n");
- return (false);
- }
-
- SessionSetupResponse deviceTypeResponse;
-
- if (!ReceivePacket(&deviceTypeResponse))
- return (false);
-
- unsigned int deviceType = deviceTypeResponse.GetResult();
-
- switch (deviceType)
- {
- // NOTE: If you add a new device type don't forget to update the error message below!
-
- case 0: // Galaxy S etc.
- case 3: // Galaxy Tab
- case 30: // Galaxy S 2 Skyrocket
- case 180: // Galaxy S etc.
- case 190: // M110S Galaxy S
-
- if (verbose)
- Interface::Print("Session begun with device of type: %d.\n\n", deviceType);
- else
- Interface::Print("Session begun.\n\n");
-
- return (true);
-
- default:
-
- Interface::PrintError("Unexpected device info response!\nExpected: 0, 3, 30, 180 or 190\nReceived:%d\n", deviceType);
- return (false);
- }*/
-
Interface::Print("Session begun.\n\n");
return (true);
}
@@ -752,21 +717,17 @@ bool BridgeManager::EndSession(bool reboot) const
return (true);
}
-bool BridgeManager::SendPacket(OutboundPacket *packet, int timeout, bool retry) const
+bool BridgeManager::SendBulkTransfer(unsigned char *data, int length, int timeout, bool retry) const
{
- packet->Pack();
-
int dataTransferred;
- int result = libusb_bulk_transfer(deviceHandle, outEndpoint, packet->GetData(), packet->GetSize(),
- &dataTransferred, timeout);
+ int result = libusb_bulk_transfer(deviceHandle, outEndpoint, data, length, &dataTransferred, timeout);
- if (result < 0 && retry)
+ if (result != LIBUSB_SUCCESS && retry)
{
- // max(250, communicationDelay)
- int retryDelay = (communicationDelay > 250) ? communicationDelay : 250;
+ static const int retryDelay = 250;
if (verbose)
- Interface::PrintError("libusb error %d whilst sending packet.", result);
+ Interface::PrintError("libusb error %d whilst sending bulk transfer.", result);
// Retry
for (int i = 0; i < 5; i++)
@@ -777,24 +738,31 @@ bool BridgeManager::SendPacket(OutboundPacket *packet, int timeout, bool retry)
// Wait longer each retry
Sleep(retryDelay * (i + 1));
- result = libusb_bulk_transfer(deviceHandle, outEndpoint, packet->GetData(), packet->GetSize(),
- &dataTransferred, timeout);
+ result = libusb_bulk_transfer(deviceHandle, outEndpoint, data, length, &dataTransferred, timeout);
- if (result >= 0)
+ if (result == LIBUSB_SUCCESS)
break;
if (verbose)
- Interface::PrintError("libusb error %d whilst sending packet.", result);
+ Interface::PrintError("libusb error %d whilst sending bulk transfer.", result);
}
if (verbose)
Interface::PrintErrorSameLine("\n");
}
- if (communicationDelay != 0)
- Sleep(communicationDelay);
+ return (result == LIBUSB_SUCCESS && dataTransferred == length);
+}
- if (result < 0 || dataTransferred != packet->GetSize())
+bool BridgeManager::SendPacket(OutboundPacket *packet, int timeout, bool retry) const
+{
+ packet->Pack();
+
+ if (!SendBulkTransfer(packet->GetData(), packet->GetSize(), timeout, retry))
+ return (false);
+
+ // After each packet we send an empty bulk transfer... Hey! I'm just implementing the protocol, I didn't define it!
+ if (!SendBulkTransfer(nullptr, 0, timeout, retry))
return (false);
return (true);
@@ -816,8 +784,7 @@ bool BridgeManager::ReceivePacket(InboundPacket *packet, int timeout, bool retry
unsigned int attempt = 0;
unsigned int maxAttempts = (retry) ? kReceivePacketMaxAttempts : 1;
- // max(250, communicationDelay)
- int retryDelay = (communicationDelay > 250) ? communicationDelay : 250;
+ static const int retryDelay = 250;
for (; attempt < maxAttempts; attempt++)
{
@@ -845,9 +812,6 @@ bool BridgeManager::ReceivePacket(InboundPacket *packet, int timeout, bool retry
if (attempt == maxAttempts)
return (false);
- if (communicationDelay != 0)
- Sleep(communicationDelay);
-
if (dataTransferred != packet->GetSize() && !packet->IsSizeVariable())
{
if (verbose)