diff options
author | Benjamin Dobell <benjamin.dobell+github@glassechidna.com.au> | 2010-12-04 14:43:30 +0100 |
---|---|---|
committer | Benjamin Dobell <benjamin.dobell+github@glassechidna.com.au> | 2010-12-04 14:43:30 +0100 |
commit | 7675cd8a8714406193c28331c9956699ff7d4226 (patch) | |
tree | e2a3c6d3b607211d7f9f15e7568a283919fa2f25 /Heimdall/heimdall/source/BridgeManager.cpp | |
parent | Removed the "Heimdall" folder and moved its contents to the root directory. (diff) | |
download | Heimdall-7675cd8a8714406193c28331c9956699ff7d4226.tar Heimdall-7675cd8a8714406193c28331c9956699ff7d4226.tar.gz Heimdall-7675cd8a8714406193c28331c9956699ff7d4226.tar.bz2 Heimdall-7675cd8a8714406193c28331c9956699ff7d4226.tar.lz Heimdall-7675cd8a8714406193c28331c9956699ff7d4226.tar.xz Heimdall-7675cd8a8714406193c28331c9956699ff7d4226.tar.zst Heimdall-7675cd8a8714406193c28331c9956699ff7d4226.zip |
Diffstat (limited to 'Heimdall/heimdall/source/BridgeManager.cpp')
-rw-r--r-- | Heimdall/heimdall/source/BridgeManager.cpp | 1086 |
1 files changed, 0 insertions, 1086 deletions
diff --git a/Heimdall/heimdall/source/BridgeManager.cpp b/Heimdall/heimdall/source/BridgeManager.cpp deleted file mode 100644 index 0b94dfb..0000000 --- a/Heimdall/heimdall/source/BridgeManager.cpp +++ /dev/null @@ -1,1086 +0,0 @@ -/* Copyright (c) 2010 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 - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE.*/ - -// C Standard Library -#include <stdio.h> - -// libusb -#include <libusb.h> - -// Heimdall -#include "BeginDumpPacket.h" -#include "BridgeManager.h" -#include "DumpPartFileTransferPacket.h" -#include "DumpPartPitFilePacket.h" -#include "DumpResponse.h" -#include "EndModemFileTransferPacket.h" -#include "EndPhoneFileTransferPacket.h" -#include "FileTransferPacket.h" -#include "FlashPartFileTransferPacket.h" -#include "FlashPartPitFilePacket.h" -#include "InboundPacket.h" -#include "InterfaceManager.h" -#include "OutboundPacket.h" -#include "PitFilePacket.h" -#include "PitFileResponse.h" -#include "ReceiveFilePartPacket.h" -#include "RebootDevicePacket.h" -#include "ResponsePacket.h" -#include "SendFilePartPacket.h" -#include "SendFilePartResponse.h" - -// Future versions of libusb will use usb_interface instead of interface. -#define usb_interface interface - -#define CLASS_CDC 0x0A - -using namespace Heimdall; - -const DeviceIdentifier BridgeManager::supportedDevices[BridgeManager::kSupportedDeviceCount] = { - DeviceIdentifier(BridgeManager::kVidSamsung, BridgeManager::kPidGalaxySDownloadMode)/*, - DeviceIdentifier(BridgeManager::kVidSamsung, BridgeManager::kPidGalaxySInternational), - DeviceIdentifier(BridgeManager::kVidSamsung, BridgeManager::kPidGalaxySNewInternational), - DeviceIdentifier(BridgeManager::kVidSamsung, BridgeManager::kPidVibrantCanadaBell)*/ -}; - -enum -{ - kMaxSequenceLength = 800 -}; - -BridgeManager::BridgeManager(bool verbose, int communicationDelay) -{ - this->verbose = verbose; - this->communicationDelay = communicationDelay; - - libusbContext = nullptr; - deviceHandle = nullptr; - heimdallDevice = nullptr; - inEndpoint = -1; - outEndpoint = -1; - interfaceIndex = -1; - -#ifdef OS_LINUX - - detachedDriver = false; - -#endif -} - -BridgeManager::~BridgeManager() -{ - if (interfaceIndex >= 0) - libusb_release_interface(deviceHandle, interfaceIndex); - -#ifdef OS_LINUX - - if (detachedDriver) - { - InterfaceManager::Print("Re-attaching kernel driver...\n"); - libusb_attach_kernel_driver(deviceHandle, interfaceIndex); - } - -#endif - - if (deviceHandle) - libusb_close(deviceHandle); - - if (heimdallDevice) - libusb_unref_device(heimdallDevice); - - if (libusbContext) - libusb_exit(libusbContext); -} - -bool BridgeManager::Initialise(void) -{ - // Initialise libusb-1.0 - int result = libusb_init(&libusbContext); - if (result != LIBUSB_SUCCESS) - { - InterfaceManager::PrintError("Failed to initialise libusb. Error: %i\n", result); - return (false); - } - - // Get handle to Galaxy S device - struct libusb_device **devices; - int deviceCount = libusb_get_device_list(libusbContext, &devices); - - for (int deviceIndex = 0; deviceIndex < deviceCount; deviceIndex++) - { - libusb_device_descriptor descriptor; - libusb_get_device_descriptor(devices[deviceIndex], &descriptor); - - for (int i = 0; i < BridgeManager::kSupportedDeviceCount; i++) - { - if (descriptor.idVendor == supportedDevices[i].vendorId && descriptor.idProduct == supportedDevices[i].productId) - { - heimdallDevice = devices[deviceIndex]; - libusb_ref_device(heimdallDevice); - break; - } - } - - if (heimdallDevice) - break; - } - - libusb_free_device_list(devices, deviceCount); - - if (!heimdallDevice) - { - InterfaceManager::PrintError("Failed to detect compatible device\n"); - return (false); - } - - result = libusb_open(heimdallDevice, &deviceHandle); - if (result != LIBUSB_SUCCESS) - { - InterfaceManager::PrintError("Failed to access device. Error: %i\n", result); - return (false); - } - - libusb_device_descriptor deviceDescriptor; - result = libusb_get_device_descriptor(heimdallDevice, &deviceDescriptor); - if (result != LIBUSB_SUCCESS) - { - InterfaceManager::PrintError("Failed to retrieve device description\n"); - return (false); - } - - if (verbose) - { - unsigned char stringBuffer[128]; - if (libusb_get_string_descriptor_ascii(deviceHandle, deviceDescriptor.iManufacturer, - stringBuffer, 128) >= 0) - { - InterfaceManager::Print(" Manufacturer: \"%s\"\n", stringBuffer); - } - - if (libusb_get_string_descriptor_ascii(deviceHandle, deviceDescriptor.iProduct, - stringBuffer, 128) >= 0) - { - InterfaceManager::Print(" Product: \"%s\"\n", stringBuffer); - } - - if (libusb_get_string_descriptor_ascii(deviceHandle, deviceDescriptor.iSerialNumber, - stringBuffer, 128) >= 0) - { - InterfaceManager::Print(" Serial No: \"%s\"\n", stringBuffer); - } - - InterfaceManager::Print("\n length: %d\n", deviceDescriptor.bLength); - InterfaceManager::Print(" device class: %d\n", deviceDescriptor.bDeviceClass); - InterfaceManager::Print(" S/N: %d\n", deviceDescriptor.iSerialNumber); - InterfaceManager::Print(" VID:PID: %04X:%04X\n", deviceDescriptor.idVendor, deviceDescriptor.idProduct); - InterfaceManager::Print(" bcdDevice: %04X\n", deviceDescriptor.bcdDevice); - InterfaceManager::Print(" iMan:iProd:iSer: %d:%d:%d\n", deviceDescriptor.iManufacturer, deviceDescriptor.iProduct, - deviceDescriptor.iSerialNumber); - InterfaceManager::Print(" nb confs: %d\n", deviceDescriptor.bNumConfigurations); - } - - libusb_config_descriptor *configDescriptor; - result = libusb_get_config_descriptor(heimdallDevice, 0, &configDescriptor); - if (result != LIBUSB_SUCCESS || !configDescriptor) - { - InterfaceManager::PrintError("Failed to retrieve config descriptor\n"); - return (false); - } - - int interfaceIndex = -1; - int altSettingIndex; - - for (int i = 0; i < configDescriptor->bNumInterfaces; i++) - { - for (int j = 0 ; j < configDescriptor->usb_interface[i].num_altsetting; j++) - { - if (verbose) - { - InterfaceManager::Print("\ninterface[%d].altsetting[%d]: num endpoints = %d\n", - i, j, configDescriptor->usb_interface[i].altsetting[j].bNumEndpoints); - InterfaceManager::Print(" Class.SubClass.Protocol: %02X.%02X.%02X\n", - configDescriptor->usb_interface[i].altsetting[j].bInterfaceClass, - configDescriptor->usb_interface[i].altsetting[j].bInterfaceSubClass, - configDescriptor->usb_interface[i].altsetting[j].bInterfaceProtocol); - } - - int inEndpointAddress = -1; - int outEndpointAddress = -1; - - for (int k = 0; k < configDescriptor->usb_interface[i].altsetting[j].bNumEndpoints; k++) - { - const libusb_endpoint_descriptor *endpoint = - &configDescriptor->usb_interface[i].altsetting[j].endpoint[k]; - - if (verbose) - { - InterfaceManager::Print(" endpoint[%d].address: %02X\n", k, endpoint->bEndpointAddress); - InterfaceManager::Print(" max packet size: %04X\n", endpoint->wMaxPacketSize); - InterfaceManager::Print(" polling interval: %02X\n", endpoint->bInterval); - } - - if (endpoint->bEndpointAddress & LIBUSB_ENDPOINT_IN) - inEndpointAddress = endpoint->bEndpointAddress; - else - outEndpointAddress = endpoint->bEndpointAddress; - } - - if (interfaceIndex < 0 - && configDescriptor->usb_interface[i].altsetting[j].bNumEndpoints == 2 - && configDescriptor->usb_interface[i].altsetting[j].bInterfaceClass == CLASS_CDC - && inEndpointAddress != -1 && outEndpointAddress != -1) - { - interfaceIndex = i; - altSettingIndex = j; - inEndpoint = inEndpointAddress; - outEndpoint = outEndpointAddress; - } - } - } - - libusb_free_config_descriptor(configDescriptor); - - if (result != LIBUSB_SUCCESS) - { - InterfaceManager::PrintError("Failed to find correct interface configuration\n"); - return (false); - } - - InterfaceManager::Print("\nClaiming interface..."); - result = libusb_claim_interface(deviceHandle, interfaceIndex); - -#ifdef OS_LINUX - - if (result != LIBUSB_SUCCESS) - { - detachedDriver = true; - InterfaceManager::Print(" Failed. Attempting to detach driver...\n"); - libusb_detach_kernel_driver(deviceHandle, interfaceIndex); - InterfaceManager::Print("Claiming interface again..."); - result = libusb_claim_interface(deviceHandle, interfaceIndex); - } - -#endif - - if (result != LIBUSB_SUCCESS) - { - InterfaceManager::PrintError(" Failed!\n"); - return (false); - } - - InterfaceManager::Print(" Success\n"); - - InterfaceManager::Print("Setting up interface..."); - result = libusb_set_interface_alt_setting(deviceHandle, interfaceIndex, altSettingIndex); - if (result != LIBUSB_SUCCESS) - { - InterfaceManager::PrintError(" Failed!\n"); - return (false); - } - - InterfaceManager::Print(" Success\n"); - - return (true); -} - -bool BridgeManager::BeginSession(void) const -{ - InterfaceManager::Print("Beginning session...\n"); - - unsigned char *dataBuffer = new unsigned char[7]; - - int result = libusb_control_transfer(deviceHandle, LIBUSB_REQUEST_TYPE_CLASS, 0x22, 0x3, 0, nullptr, 0, 1000); - - if (result < 0) - { - InterfaceManager::PrintError("Failed to initialise usb communication!\n"); - delete [] dataBuffer; - return (false); - } - - 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); - if (result < 0) - { - InterfaceManager::PrintError("Failed to initialise usb communication!\n"); - delete [] dataBuffer; - return (false); - } - - result = libusb_control_transfer(deviceHandle, LIBUSB_REQUEST_TYPE_CLASS, 0x22, 0x3, 0, nullptr, 0, 1000); - if (result < 0) - { - InterfaceManager::PrintError("Failed to initialise usb communication!\n"); - delete [] dataBuffer; - return (false); - } - - result = libusb_control_transfer(deviceHandle, LIBUSB_REQUEST_TYPE_CLASS, 0x22, 0x2, 0, nullptr, 0, 1000); - if (result < 0) - { - InterfaceManager::PrintError("Failed to initialise usb communication!\n"); - delete [] dataBuffer; - return (false); - } - - memset(dataBuffer, 0, 7); - dataBuffer[1] = 0xC2; - dataBuffer[2] = 0x01; - dataBuffer[6] = 0x08; - - result = libusb_control_transfer(deviceHandle, LIBUSB_REQUEST_TYPE_CLASS, 0x20, 0x0, 0, dataBuffer, 7, 1000); - if (result < 0) - { - InterfaceManager::PrintError("Failed to initialise usb communication!\n"); - delete [] dataBuffer; - return (false); - } - - result = libusb_control_transfer(deviceHandle, LIBUSB_REQUEST_TYPE_CLASS, 0x22, 0x2, 0, nullptr, 0, 1000); - if (result < 0) - { - InterfaceManager::PrintError("Failed to initialise usb communication!\n"); - delete [] dataBuffer; - return (false); - } - - InterfaceManager::Print("Handshaking with Loke..."); - - int dataTransferred; - - // Send "ODIN" - strcpy((char *)dataBuffer, "ODIN"); - - result = libusb_bulk_transfer(deviceHandle, outEndpoint, dataBuffer, 4, &dataTransferred, 1000); - if (result < 0) - { - InterfaceManager::PrintError(" Failed!\n"); - - if (verbose) - InterfaceManager::PrintError("ERROR: Failed to send data: \"%s\"\n", dataBuffer); - - delete [] dataBuffer; - return (false); - } - - if (dataTransferred != 4) - { - InterfaceManager::PrintError(" Failed!\n"); - - if (verbose) - InterfaceManager::PrintError("ERROR: Failed to complete sending data: \"%s\"\n", dataBuffer); - - delete [] dataBuffer; - return (false); - } - - // Expect "LOKE" - memset(dataBuffer, 0, 7); - - result = libusb_bulk_transfer(deviceHandle, inEndpoint, dataBuffer, 7, &dataTransferred, 1000); - if (result < 0) - { - InterfaceManager::PrintError(" Failed!\n"); - - if (verbose) - InterfaceManager::PrintError("ERROR: Failed to receive response\n"); - delete [] dataBuffer; - return (false);; - } - - if (dataTransferred != 4 || memcmp(dataBuffer, "LOKE", 4) != 0) - { - InterfaceManager::PrintError(" Failed!\n"); - - if (verbose) - InterfaceManager::PrintError("ERROR: Unexpected communication.\nExpected: \"%s\"\nReceived: \"%s\"\n", "LOKE", dataBuffer); - - delete [] dataBuffer; - return (false); - } - - InterfaceManager::Print(" Success\n\n"); - return (true); -} - -bool BridgeManager::EndSession(void) const -{ - InterfaceManager::Print("Ending session...\n"); - - RebootDevicePacket *rebootDevicePacket = new RebootDevicePacket(RebootDevicePacket::kRequestEndSession); - bool success = SendPacket(rebootDevicePacket); - delete rebootDevicePacket; - - if (!success) - { - InterfaceManager::PrintError("Failed to send end session packet!\n"); - return (false); - } - - ResponsePacket *rebootDeviceResponse = new ResponsePacket(ResponsePacket::kResponseTypeRebootDevice); - success = ReceivePacket(rebootDeviceResponse); - delete rebootDeviceResponse; - - if (!success) - { - InterfaceManager::PrintError("Failed to receive session end confirmation!\n"); - return (false); - } - - return (true); -} - -bool BridgeManager::SendPacket(OutboundPacket *packet, int timeout) const -{ - packet->Pack(); - - int dataTransferred; - int result = libusb_bulk_transfer(deviceHandle, outEndpoint, packet->GetData(), packet->GetSize(), - &dataTransferred, timeout); - - if (result < 0) - { - // max(250, communicationDelay) - int retryDelay = (communicationDelay > 250) ? communicationDelay : 250; - - if (verbose) - InterfaceManager::PrintError("Error %i whilst sending packet. ", result); - - // Retry - for (int i = 0; i < 5; i++) - { - if (verbose) - InterfaceManager::PrintError(" Retrying...\n"); - - // Wait longer each retry - Sleep(retryDelay * (i + 1)); - - result = libusb_bulk_transfer(deviceHandle, outEndpoint, packet->GetData(), packet->GetSize(), - &dataTransferred, timeout); - - if (result >= 0) - break; - - if (verbose) - InterfaceManager::PrintError("Error %i whilst sending packet. ", result); - } - - if (verbose) - InterfaceManager::PrintError("\n"); - } - - if (communicationDelay != 0) - Sleep(communicationDelay); - - if (result < 0 || dataTransferred != packet->GetSize()) - return (false); - - return (true); -} - -bool BridgeManager::ReceivePacket(InboundPacket *packet, int timeout) const -{ - int dataTransferred; - int result = libusb_bulk_transfer(deviceHandle, inEndpoint, packet->GetData(), packet->GetSize(), - &dataTransferred, timeout); - - if (result < 0) - { - // max(250, communicationDelay) - int retryDelay = (communicationDelay > 250) ? communicationDelay : 250; - - if (verbose) - InterfaceManager::PrintError("Error %i whilst receiving packet. ", result); - - // Retry - for (int i = 0; i < 5; i++) - { - if (verbose) - InterfaceManager::PrintError(" Retrying\n"); - - // Wait longer each retry - Sleep(retryDelay * (i + 1)); - - result = libusb_bulk_transfer(deviceHandle, inEndpoint, packet->GetData(), packet->GetSize(), - &dataTransferred, timeout); - - if (result >= 0) - break; - - if (verbose) - InterfaceManager::PrintError("Error %i whilst receiving packet. ", result); - - if (i >= 3) - { - int breakHere = 0; - breakHere++; - } - } - - if (verbose) - InterfaceManager::PrintError("\n"); - } - - if (communicationDelay != 0) - Sleep(communicationDelay); - - if (result < 0 || (dataTransferred != packet->GetSize() && !packet->IsSizeVariable())) - return (false); - - packet->SetReceivedSize(dataTransferred); - - return (packet->Unpack()); -} - -bool BridgeManager::SendPitFile(FILE *file) const -{ - fseek(file, 0, SEEK_END); - long fileSize = ftell(file); - rewind(file); - - // Start file transfer - PitFilePacket *pitFilePacket = new PitFilePacket(PitFilePacket::kRequestFlash); - bool success = SendPacket(pitFilePacket); - delete pitFilePacket; - - if (!success) - { - InterfaceManager::PrintError("Failed to request sending of PIT file!\n"); - return (false); - } - - PitFileResponse *pitFileResponse = new PitFileResponse(); - success = ReceivePacket(pitFileResponse); - delete pitFileResponse; - - if (!success) - { - InterfaceManager::PrintError("Failed to confirm sending of PIT file!\n"); - return (false); - } - - // Transfer file size - FlashPartPitFilePacket *flashPartPitFilePacket = new FlashPartPitFilePacket(fileSize); - success = SendPacket(flashPartPitFilePacket); - delete flashPartPitFilePacket; - - if (!success) - { - InterfaceManager::PrintError("Failed to send PIT file part information!\n"); - return (false); - } - - pitFileResponse = new PitFileResponse(); - success = ReceivePacket(pitFileResponse); - delete pitFileResponse; - - if (!success) - { - InterfaceManager::PrintError("Failed to confirm sending of PIT file part information!\n"); - return (false); - } - - // Flash pit file - SendFilePartPacket *sendFilePartPacket = new SendFilePartPacket(file, fileSize); - success = SendPacket(sendFilePartPacket); - delete sendFilePartPacket; - - if (!success) - { - InterfaceManager::PrintError("Failed to send file part packet!\n"); - return (false); - } - - pitFileResponse = new PitFileResponse(); - success = ReceivePacket(pitFileResponse); - delete pitFileResponse; - - if (!success) - { - InterfaceManager::PrintError("Failed to receive PIT file transfer count!\n"); - return (false); - } - - return (true); -} - -int BridgeManager::ReceivePitFile(unsigned char **pitBuffer) const -{ - *pitBuffer = nullptr; - - bool success; - - // Start file transfer - PitFilePacket *pitFilePacket = new PitFilePacket(PitFilePacket::kRequestDump); - success = SendPacket(pitFilePacket); - delete pitFilePacket; - - if (!success) - { - InterfaceManager::PrintError("Failed to request receival of PIT file!\n"); - return (0); - } - - PitFileResponse *pitFileResponse = new PitFileResponse(); - success = ReceivePacket(pitFileResponse); - int fileSize = pitFileResponse->GetFileSize(); - delete pitFileResponse; - - if (!success) - { - InterfaceManager::PrintError("Failed to receive PIT file size!\n"); - return (0); - } - - int transferCount = fileSize / ReceiveFilePartPacket::kDataSize; - if (fileSize % ReceiveFilePartPacket::kDataSize != 0) - transferCount++; - - unsigned char *buffer = new unsigned char[fileSize]; - int offset = 0; - - // NOTE: The PIT file appears to always be padded out to exactly 4 kilobytes. - for (int i = 0; i < transferCount; i++) - { - DumpPartPitFilePacket *requestPacket = new DumpPartPitFilePacket(i); - success = SendPacket(requestPacket); - delete requestPacket; - - if (!success) - { - InterfaceManager::PrintError("Failed to request PIT file part #%i!\n", i); - delete [] buffer; - return (0); - } - - ReceiveFilePartPacket *receiveFilePartPacket = new ReceiveFilePartPacket(); - success = ReceivePacket(receiveFilePartPacket); - - if (!success) - { - InterfaceManager::PrintError("Failed to receive PIT file part #%i!\n", i); - delete receiveFilePartPacket; - delete [] buffer; - return (0); - } - - // Copy the whole packet data into the buffer. - memcpy(buffer + offset, receiveFilePartPacket->GetData(), receiveFilePartPacket->GetReceivedSize()); - offset += receiveFilePartPacket->GetReceivedSize(); - - delete receiveFilePartPacket; - } - - // End file transfer - pitFilePacket = new PitFilePacket(PitFilePacket::kRequestEndTransfer); - success = SendPacket(pitFilePacket); - delete pitFilePacket; - - if (!success) - { - InterfaceManager::PrintError("Failed to send request to end PIT file transfer!\n"); - delete [] buffer; - return (0); - } - - pitFileResponse = new PitFileResponse(); - success = ReceivePacket(pitFileResponse); - delete pitFileResponse; - - if (!success) - { - InterfaceManager::PrintError("Failed to receive end PIT file transfer verification!\n"); - delete [] buffer; - return (0); - } - - *pitBuffer = buffer; - return (fileSize); -} - -bool BridgeManager::SendFile(FILE *file, int destination, int fileIdentifier) const -{ - if (destination != EndFileTransferPacket::kDestinationModem && destination != EndFileTransferPacket::kDestinationPhone) - { - InterfaceManager::PrintError("ERROR: Attempted to send file to unknown destination!\n"); - return (false); - } - - if (destination == EndFileTransferPacket::kDestinationModem && fileIdentifier != -1) - { - InterfaceManager::PrintError("ERROR: The modem file does not have an identifier!\n"); - return (false); - } - - FileTransferPacket *flashFileTransferPacket = new FileTransferPacket(FileTransferPacket::kRequestFlash); - bool success = SendPacket(flashFileTransferPacket); - delete flashFileTransferPacket; - - if (!success) - { - InterfaceManager::PrintError("Failed to initialise transfer!\n"); - return (false); - } - - fseek(file, 0, SEEK_END); - long fileSize = ftell(file); - rewind(file); - - ResponsePacket *fileTransferResponse = new ResponsePacket(ResponsePacket::kResponseTypeFileTransfer); - success = ReceivePacket(fileTransferResponse); - delete fileTransferResponse; - - if (!success) - { - InterfaceManager::PrintError("Failed to confirm transfer initialisation!\n"); - return (false); - } - - int sequenceCount = fileSize / (kMaxSequenceLength * SendFilePartPacket::kDefaultPacketSize); - int lastSequenceSize = kMaxSequenceLength; - int partialPacketLength = fileSize % SendFilePartPacket::kDefaultPacketSize; - if (fileSize % (kMaxSequenceLength * SendFilePartPacket::kDefaultPacketSize) != 0) - { - sequenceCount++; - - int lastSequenceBytes = fileSize % (kMaxSequenceLength * SendFilePartPacket::kDefaultPacketSize); - lastSequenceSize = lastSequenceBytes / SendFilePartPacket::kDefaultPacketSize; - if (partialPacketLength != 0) - lastSequenceSize++; - } - - long bytesTransferred = 0; - int currentPercent; - int previousPercent = 0; - InterfaceManager::Print("0%%"); - - for (int sequenceIndex = 0; sequenceIndex < sequenceCount; sequenceIndex++) - { - // Min(lastSequenceSize, 131072) - bool isLastSequence = sequenceIndex == sequenceCount - 1; - int sequenceSize = (isLastSequence) ? lastSequenceSize : kMaxSequenceLength; - - FlashPartFileTransferPacket *beginFileTransferPacket = new FlashPartFileTransferPacket(0, 2 * sequenceSize); - success = SendPacket(beginFileTransferPacket); - delete beginFileTransferPacket; - - if (!success) - { - InterfaceManager::PrintError("\nFailed to begin file transfer sequence!\n"); - return (false); - } - - fileTransferResponse = new ResponsePacket(ResponsePacket::kResponseTypeFileTransfer); - bool success = ReceivePacket(fileTransferResponse); - delete fileTransferResponse; - - if (!success) - { - InterfaceManager::PrintError("\nFailed to confirm beginning of file transfer sequence!\n"); - return (false); - } - - SendFilePartPacket *sendFilePartPacket; - SendFilePartResponse *sendFilePartResponse; - - for (int filePartIndex = 0; filePartIndex < sequenceSize; filePartIndex++) - { - // Send - sendFilePartPacket = new SendFilePartPacket(file); - success = SendPacket(sendFilePartPacket); - delete sendFilePartPacket; - - if (!success) - { - InterfaceManager::PrintError("\nFailed to send file part packet!\n"); - return (false); - } - - // Response - sendFilePartResponse = new SendFilePartResponse(); - success = ReceivePacket(sendFilePartResponse); - int receivedPartIndex = sendFilePartResponse->GetPartIndex(); - - if (verbose) - { - const unsigned char *data = sendFilePartResponse->GetData(); - InterfaceManager::Print("File Part #%i... 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) - { - InterfaceManager::PrintError("\nFailed to receive file part response!\n"); - - for (int retry = 0; retry < 4; retry++) - { - InterfaceManager::PrintError("\nRetrying..."); - - // Send - sendFilePartPacket = new SendFilePartPacket(file); - success = SendPacket(sendFilePartPacket); - delete sendFilePartPacket; - - if (!success) - { - InterfaceManager::PrintError("\nFailed to send file part packet!\n"); - return (false); - } - - // Response - sendFilePartResponse = new SendFilePartResponse(); - success = ReceivePacket(sendFilePartResponse); - int receivedPartIndex = sendFilePartResponse->GetPartIndex(); - - if (verbose) - { - const unsigned char *data = sendFilePartResponse->GetData(); - InterfaceManager::Print("File Part #%i... 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) - { - InterfaceManager::PrintError("\nERROR: Expected file part index: %i Received: %i\n", - filePartIndex, receivedPartIndex); - return (false); - } - - if (success) - break; - } - - if (!success) - return (false); - } - - if (receivedPartIndex != filePartIndex) - { - InterfaceManager::PrintError("\nERROR: Expected file part index: %i Received: %i\n", - filePartIndex, receivedPartIndex); - return (false); - } - - bytesTransferred += SendFilePartPacket::kDefaultPacketSize; - if (bytesTransferred > fileSize) - bytesTransferred = fileSize; - - currentPercent = (int)(100.0f * ((float)bytesTransferred / (float)fileSize)); - - if (!verbose) - { - if (currentPercent != previousPercent) - { - if (previousPercent < 10) - InterfaceManager::Print("\b\b%i%%", currentPercent); - else - InterfaceManager::Print("\b\b\b%i%%", currentPercent); - } - } - - previousPercent = currentPercent; - } - - int lastFullPacketIndex = 2 * ((isLastSequence && partialPacketLength != 0) ? sequenceSize - 1 : sequenceSize); - - if (destination == EndFileTransferPacket::kDestinationPhone) - { - EndPhoneFileTransferPacket *endPhoneFileTransferPacket = new EndPhoneFileTransferPacket( - (isLastSequence) ? partialPacketLength : 0, lastFullPacketIndex, 0, 0, fileIdentifier, isLastSequence); - - success = SendPacket(endPhoneFileTransferPacket, 3000); - delete endPhoneFileTransferPacket; - - if (!success) - { - InterfaceManager::PrintError("\nFailed to end phone file transfer sequence!\n"); - return (false); - } - } - else // destination == EndFileTransferPacket::kDestinationModem - { - EndModemFileTransferPacket *endModemFileTransferPacket = new EndModemFileTransferPacket( - (isLastSequence) ? partialPacketLength : 0, lastFullPacketIndex, 0, 0, isLastSequence); - - success = SendPacket(endModemFileTransferPacket, 3000); - delete endModemFileTransferPacket; - - if (!success) - { - InterfaceManager::PrintError("\nFailed to end modem file transfer sequence!\n"); - return (false); - } - } - - fileTransferResponse = new ResponsePacket(ResponsePacket::kResponseTypeFileTransfer); - success = ReceivePacket(fileTransferResponse, 30000); - delete fileTransferResponse; - - if (!success) - { - InterfaceManager::PrintError("\nFailed to confirm end of file transfer sequence!\n"); - return (false); - } - } - - if (!verbose) - InterfaceManager::Print("\n"); - - return (true); -} - -bool BridgeManager::ReceiveDump(int chipType, int chipId, FILE *file) const -{ - bool success; - - // Start file transfer - BeginDumpPacket *beginDumpPacket = new BeginDumpPacket(chipType, chipId); - success = SendPacket(beginDumpPacket); - delete beginDumpPacket; - - if (!success) - { - InterfaceManager::PrintError("Failed to request dump!\n"); - return (false); - } - - DumpResponse *dumpResponse = new DumpResponse(); - success = ReceivePacket(dumpResponse); - unsigned int dumpSize = dumpResponse->GetDumpSize(); - delete dumpResponse; - - if (!success) - { - InterfaceManager::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]; - int bufferOffset = 0; - - for (unsigned int i = 0; i < transferCount; i++) - { - DumpPartFileTransferPacket *dumpPartPacket = new DumpPartFileTransferPacket(i); - success = SendPacket(dumpPartPacket); - delete dumpPartPacket; - - if (!success) - { - InterfaceManager::PrintError("Failed to request dump part #%i!\n", i); - delete [] buffer; - return (false); - } - - ReceiveFilePartPacket *receiveFilePartPacket = new ReceiveFilePartPacket(); - success = ReceivePacket(receiveFilePartPacket); - - if (!success) - { - InterfaceManager::PrintError("Failed to receive dump part #%i!\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; - - // End file transfer - FileTransferPacket *fileTransferPacket = new FileTransferPacket(FileTransferPacket::kRequestEnd); - success = SendPacket(fileTransferPacket); - delete fileTransferPacket; - - if (!success) - { - InterfaceManager::PrintError("Failed to send request to end dump transfer!\n"); - return (false); - } - - ResponsePacket *responsePacket = new ResponsePacket(ResponsePacket::kResponseTypeFileTransfer); - success = ReceivePacket(responsePacket); - delete responsePacket; - - if (!success) - { - InterfaceManager::PrintError("Failed to receive end dump transfer verification!\n"); - return (false); - } - - return (true); -} - -bool BridgeManager::RebootDevice(void) const -{ - InterfaceManager::Print("Rebooting device...\n"); - - RebootDevicePacket *rebootDevicePacket = new RebootDevicePacket(RebootDevicePacket::kRequestRebootDevice); - bool success = SendPacket(rebootDevicePacket); - delete rebootDevicePacket; - - if (!success) - { - InterfaceManager::PrintError("Failed to send end session packet!\n"); - return (false); - } - - ResponsePacket *rebootDeviceResponse = new ResponsePacket(ResponsePacket::kResponseTypeRebootDevice); - success = ReceivePacket(rebootDeviceResponse); - delete rebootDeviceResponse; - - if (!success) - { - InterfaceManager::PrintError("Failed to receive reboot confirmation!\n"); - return (false); - } - - return (true); -} |