Open iamtag opened 9 years ago
./Heimdall/heimdall/source/BridgeManager.cpp
line=932,50-64 74%
<-success = ReceivePacket(receiveFilePartPacket, receiveEmptyTransferFlags);
->success = ReceivePacket(receiveFilePartPacket, kDefaultTimeOutEmptyTransfer, receiveEmptyTransferFlags);
Thanks, this was actually already reported https://github.com/Benjamin-Dobell/Heimdall/issues/232 - I'll push a commit fixing it shortly.
./Heimdall/heimdall/source/BridgeManager.cpp
line=747,7-21 59%
<-if (ReceiveBulkTransfer(null, 0, kDefaultTimeoutEmptyTransfer, false) < 0 && verbose)
->
//in my side receivebulktransfer to a null buffer will get a error.
unsigned char szTempBuffer[16];
if (ReceiveBulkTransfer(szTempBuffer, 16, kDefaultTimeoutEmptyTransfer, false)<0 && verbose)
This does not seem correct. You've replaced an intentionally 0-length transfer with a 16-byte transfer.
in my hand, the SM-G7108 must got a receivebulktransfer 0-length transfer here. so request 16bytes will got 0bytes return.
Here is odin what to do.
@iamtag Okay, that does seem a bit strange as the buffer size shouldn't really make a difference given that we are expecting a 0-byte response.
Nonetheless, I'll test the change out on all the devices I have to make sure it doesn't break support for those. If all tested devices work with the change, then I'll commit it to the repo.
Thanks
I had usblog i9100g, i879, sh-g7108, i9500 by odin. The flow of sendEmptyTransferFlags/receiveEmptyTransferFlags has a little diffs. I don't know Odin how to detect this diffs in the same flash flow.
@Benjamin-Dobell I have send a mail to you(service@glassechidna.com.au). There are 5 models odin flash usblogs.
@Benjamin-Dobell There are 2 case at flashing diffrent model phone.
->ODIN <-LOKE ->[BEGIN SESSION] <-[SESSION RESPONSE] ->NULL ->[CHANGE FILE PACK SIZE] <-[RESPONSE SUCCED] ->NULL ->[TOTAL BYTES] <-[RESPONSE SUCCED] //TAG:!!!<---diff begin here ->NULL ->[CMD1] <-[RESONSE...] ->NULL ->[CMD2] <-[RESPONSE...] ... It is use SendPacket(kEmptyTransferBefore) after TAG.
->ODIN
<-LOKE
->[BEGIN SESSION]
<-[SESSION RESPONSE]
->NULL
->[CHANGE FILE PACK SIZE]
<-[RESPONSE SUCCED]
->NULL
->[TOTAL BYTES]
->NULL //TAG:!!!<---diff begin here
<-[RESPONSE SUCCED]
->[CMD1]
->NULL
<-[RESONSE...]
->[CMD2]
->NULL
<-[RESPONSE...]
...
It is use SendPacket(kEmptyTransferAfter) after TAG.
I use below solution to detect this differents.
enum
{
kEmptyTransferNone = 0,
kEmptyTransferBefore = 1,
kEmptyTransferAfter = 1 << 1,
kEmptyTransferBeforeAndAfter = kEmptyTransferBefore | kEmptyTransferAfter,
//use default setting every call
kEmptyTransferBySetting = 0x100,
//call kEmptyTransferBeforeAndAfter in SEND_TOTAL_BYTES of flow,
//if fail at after, it's only support kEmptyTransferBefore
//else only support kEmptyTransferAfter
kEmptyTransferSetSetting = kEmptyTransferBeforeAndAfter | kEmptyTransferBySetting,
};
bool BridgeManager::SendPacket(OutboundPacket *packet, int timeout, int emptyTransferFlags) const
{
static int g_defaultEmptyTransferFlags = kEmptyTransferBefore;
if (kEmptyTransferBySetting == emptyTransferFlags)
{
emptyTransferFlags = g_defaultEmptyTransferFlags;
}
packet->Pack();
if (emptyTransferFlags & kEmptyTransferBefore)
{
if (!SendBulkTransfer(nullptr, 0, kDefaultTimeoutEmptyTransfer, false) && verbose)
{
Interface::PrintWarning("Empty bulk transfer before sending packet failed. Continuing anyway...\n");
}
}
if (!SendBulkTransfer(packet->GetData(), packet->GetSize(), timeout))
return (false);
if (emptyTransferFlags & kEmptyTransferAfter)
{
const bool bRET = SendBulkTransfer(nullptr, 0, kDefaultTimeoutEmptyTransfer, false);
if (!bRET && verbose)
{
Interface::PrintWarning("Empty bulk transfer after sending packet failed. Continuing anyway...\n");
}
if (kEmptyTransferSetSetting == emptyTransferFlags)
{
g_defaultEmptyTransferFlags = (bRET ? kEmptyTransferAfter : kEmptyTransferBefore);
Interface::PrintWarning("Setting protocol to %d\n", g_defaultEmptyTransferFlags);
}
}
return (true);
}
//change default to kEmptyTransferBySetting
bool SendPacket(OutboundPacket *packet, int timeout = kDefaultTimeoutSend, int emptyTransferFlags = kEmptyTransferBySetting) const;
//update beginsession use kEmptyTransferNone
bool BridgeManager::BeginSession(void)
{
Interface::Print("Beginning session...\n");
BeginSessionPacket beginSessionPacket;
//***** BEGIN SESSION *****
if (!SendPacket(&beginSessionPacket, kDefaultTimeoutSend, kEmptyTransferNone))
{
Interface::PrintError("Failed to begin session!\n");
return (false);
}
SessionSetupResponse beginSessionResponse;
if (!ReceivePacket(&beginSessionResponse))
return (false);
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.
{
fileTransferSequenceTimeout = 120000; // 2 minutes!
fileTransferPacketSize = 1048576; // 1 MiB
fileTransferSequenceMaxLength = 30; // Therefore, fileTransferPacketSize * fileTransferSequenceMaxLength == 30 MiB per sequence.
FilePartSizePacket filePartSizePacket(fileTransferPacketSize);
//***** CHANGE FILE PACK SIZE *****
if (!SendPacket(&filePartSizePacket, kDefaultTimeoutSend, kEmptyTransferBefore))
{
Interface::PrintError("Failed to send file part size packet!\n");
return (false);
}
SessionSetupResponse filePartSizeResponse;
if (!ReceivePacket(&filePartSizeResponse))
return (false);
if (filePartSizeResponse.GetResult() != 0)
{
Interface::PrintError("Unexpected file part size response!\nExpected: 0\nReceived: %d\n", filePartSizeResponse.GetResult());
return (false);
}
}
Interface::Print("Session begun.\n\n");
return (true);
}
//in here to detect the differents and store it
static bool sendTotalTransferSize(BridgeManager *bridgeManager, const vector<PartitionFile>& partitionFiles, FILE *pitFile, bool repartition)
{
unsigned int totalBytes = 0;
for (vector<PartitionFile>::const_iterator it = partitionFiles.begin(); it != partitionFiles.end(); it++)
{
FileSeek(it->file, 0, SEEK_END);
totalBytes += (unsigned int)FileTell(it->file);
FileRewind(it->file);
}
if (repartition)
{
FileSeek(pitFile, 0, SEEK_END);
totalBytes += (unsigned int)FileTell(pitFile);
FileRewind(pitFile);
}
bool success;
TotalBytesPacket *totalBytesPacket = new TotalBytesPacket(totalBytes);
//***** SEND TOTAL BYTES *****
success = bridgeManager->SendPacket(totalBytesPacket,
BridgeManager::kDefaultTimeoutSend,
BridgeManager::kEmptyTransferSetSetting);
.........
}
System: Archlinux Smartphone: Samsung Galaxy S3 NFC
$ heimdall flash --RECOVERY recovery.img --no-reboot --verbose
Heimdall v1.4.1
Copyright (c) 2010-2014 Benjamin Dobell, Glass Echidna http://www.glassechidna.com.au/
This software is provided free of charge. Copying and redistribution is encouraged.
If you appreciate this software and you would like to support future development please consider donating: http://www.glassechidna.com.au/donate/
Initialising connection... Detecting device... Manufacturer: "SAMSUNG" Product: "Gadget Serial"
length: 18
device class: 2
S/N: 0
VID:PID: 04E8:685D
bcdDevice: 021B
iMan:iProd:iSer: 1:2:0 nb confs: 1
interface[0].altsetting[0]: num endpoints = 1 Class.SubClass.Protocol: 02.02.01 endpoint[0].address: 83 max packet size: 0010 polling interval: 09
interface[1].altsetting[0]: num endpoints = 2 Class.SubClass.Protocol: 0A.00.00 endpoint[0].address: 81 max packet size: 0200 polling interval: 00 endpoint[1].address: 02 max packet size: 0200 polling interval: 00 Claiming interface... Setting up interface...
Initialising protocol... ERROR: Failed to receive handshake response. Result: -7 ERROR: Protocol initialisation failed!
Releasing device interface...
./Heimdall/heimdall/source/BridgeManager.cpp line=932,50-64 74%
<-success = ReceivePacket(receiveFilePartPacket, receiveEmptyTransferFlags); ->success = ReceivePacket(receiveFilePartPacket, kDefaultTimeOutEmptyTransfer, receiveEmptyTransferFlags);
./Heimdall/heimdall/source/BridgeManager.cpp line=747,7-21 59%
<-if (ReceiveBulkTransfer(null, 0, kDefaultTimeoutEmptyTransfer, false) < 0 && verbose) -> //in my side receivebulktransfer to a null buffer will get a error. unsigned char szTempBuffer[16]; if (ReceiveBulkTransfer(szTempBuffer, 16, kDefaultTimeoutEmptyTransfer, false)<0 && verbose)