gbcflsh/ReadFlashThread.cpp

178 lines
3.9 KiB
C++

/*****************************************************************************
** ReadFlashThread.cpp
** Author: Kraku
*****************************************************************************/
#include "ReadFlashThread.h"
#include "Settings.h"
#include "Logic.h"
#include "const.h"
void
ReadFlashThread::run ()
{
end = FALSE;
unsigned char packet[72], data[16384];
int character, data_type = 0x00, recived = 0, retries =
0, page_number, packet_number, prv_count = 0;
config_t cfg;
cfg.operation = RROM;
cfg.mbc = mbc;
cfg.algorythm = algorythm;
cfg.dap = Settings::dap;
cfg.page_count = page_count;
if (file == NULL)
{
port->close_port ();
emit error (FILEERROR_O);
return;
}
do
{ /* send start packet and wait for first one of response */
if (Logic::send_start_packet (port, cfg) == FALSE)
{
port->close_port ();
fclose (file);
emit error (SEND_ERROR);
return;
}
character = port->receive_packet (packet);
if (character == END || character == TIMEOUT)
{
port->close_port ();
fclose (file);
emit error (character);
return;
}
if (character == DATA) /* if packet received - check it */
data_type = Logic::check_packet (packet);
}
while (data_type != NORMAL_DATA && ++retries < 10);
if (retries == 10)
{
port->close_port ();
fclose (file);
emit error (TIMEOUT);
return;
}
retries = 0;
/* work until LAST_DATA */
do
{
if (recived != 0) /* if first packet, don't need to get it */
character = port->receive_packet (packet);
if (character == TIMEOUT || character == END)
{
port->close_port ();
fclose (file);
emit error (character);
return;
}
//end of thread!!!!
if (end)
{
port->send_char (END);
port->close_port ();
fclose (file);
emit error (END);
return;
}
data_type = Logic::check_packet (packet);
if (data_type == NORMAL_DATA || data_type == LAST_DATA)
{ /* valid data packet */
page_number = recived / 256; /* 256 packets = page */
packet_number = recived % 256;
retries = 0;
/* current packet */
if (packet_number == packet[3]
&& page_number == packet[4] * 256 + packet[5])
{
memcpy (&data[packet_number * 64], &packet[6], FRAMESIZE);
if (packet_number == 255) /* if entire page - save it to file */
if (fwrite (data, 1, sizeof data, file) < sizeof data)
{
port->close_port ();
fclose (file);
emit error (FILEERROR_W);
return;
}
port->send_char (ACK); /* send confirmation */
recived++;
prv_count = 0;
/* set progress bar status */
emit set_progress (recived, page_count * 256 - 1);
}
/* last packet received- packet is lost */
else if (((packet_number - 1) % 255) == packet[3])
{
/* device is sending last packets - end of transmision */
if (++prv_count == 10)
{
port->send_char (END);
port->close_port ();
fclose (file);
emit error (END);
return;
}
else
port->send_char (ACK);
/* confirm receivment, force device to send current packet */
}
else
{ /* valid packet, but not current nor last */
port->send_char (END);
port->close_port ();
fclose (file);
emit error (END);
return;
}
}
else
{ /* bad data or NAK */
if (++retries < 10)
port->send_char (NAK);
else
{
port->send_char (END);
port->close_port ();
fclose (file);
emit error (END);
return;
}
}
}
while (data_type != LAST_DATA);
/* if correct data size received - end */
if (recived * 64 == page_count * 16384)
{
port->close_port ();
fclose (file);
emit error (TRUE);
}
else
{
port->close_port ();
fclose (file);
emit error (END);
}
}
void
ReadFlashThread::canceled (void)
{
end = TRUE;
}