530 lines
19 KiB
C
530 lines
19 KiB
C
/*
|
|
Copyright 2023 Quectel Wireless Solutions Co.,Ltd
|
|
|
|
Quectel hereby grants customers of Quectel a license to use, modify,
|
|
distribute and publish the Software in binary form provided that
|
|
customers shall have no right to reverse engineer, reverse assemble,
|
|
decompile or reduce to source code form any portion of the Software.
|
|
Under no circumstances may customers modify, demonstrate, use, deliver
|
|
or disclose any portion of the Software in source code form.
|
|
*/
|
|
|
|
#include "usb_linux.h"
|
|
#include "sahara.h"
|
|
|
|
static uint32_t le_uint32(uint32_t v32)
|
|
{
|
|
const int is_bigendian = 1;
|
|
uint32_t tmp = v32;
|
|
if ((*(char *)&is_bigendian) == 0)
|
|
{
|
|
unsigned char *s = (unsigned char *)(&v32);
|
|
unsigned char *d = (unsigned char *)(&tmp);
|
|
d[0] = s[3];
|
|
d[1] = s[2];
|
|
d[2] = s[1];
|
|
d[3] = s[0];
|
|
}
|
|
return tmp;
|
|
}
|
|
|
|
static uint64_t le_uint64(uint64_t v64)
|
|
{
|
|
const int is_bigendian = 1;
|
|
uint64_t tmp = v64;
|
|
if ((*(char *)&is_bigendian) == 0)
|
|
{
|
|
unsigned char *s = (unsigned char *)(&v64);
|
|
unsigned char *d = (unsigned char *)(&tmp);
|
|
d[0] = s[7];
|
|
d[1] = s[6];
|
|
d[2] = s[5];
|
|
d[3] = s[4];
|
|
d[4] = s[3];
|
|
d[5] = s[2];
|
|
d[6] = s[1];
|
|
d[7] = s[0];
|
|
}
|
|
return tmp;
|
|
}
|
|
|
|
#define dbg(log_level, fmt, arg...) \
|
|
do \
|
|
{ \
|
|
dbg_time(fmt "\n", ##arg); \
|
|
} while (0)
|
|
|
|
static int sahara_tx_data(void *usb_handle, void *tx_buffer, size_t bytes_to_send)
|
|
{
|
|
int need_zlp = 0; // zlp is not mandatory
|
|
return qusb_noblock_write(usb_handle, tx_buffer, bytes_to_send, bytes_to_send, 3000, need_zlp);
|
|
}
|
|
|
|
int qusb_use_usbfs_interface(const void *handle);
|
|
static int sahara_rx_data(void *usb_handle, void *rx_buffer, size_t bytes_to_read)
|
|
{
|
|
q_sahara_packet_h *command_packet_header = NULL;
|
|
size_t bytes_read = 0;
|
|
|
|
const char *q_sahara_cmd_str[Q_SAHARA_NINETEEN] = {
|
|
"Q_SAHARA_ZERO", // = 0x00,
|
|
"Q_SAHARA_ONE", // = 0x01, // sent from target to host
|
|
"Q_SAHARA_TWO", // = 0x02, // sent from host to target
|
|
"Q_SAHARA_THREE", // = 0x03, // sent from target to host
|
|
"Q_SAHARA_FOUR", // = 0x04, // sent from target to host
|
|
"Q_SAHARA_FIVE", // = 0x05, // sent from host to target
|
|
"Q_SAHARA_SIX", // = 0x06, // sent from target to host
|
|
"Q_SAHARA_SEVEN", // = 0x07, // sent from host to target
|
|
"Q_SAHARA_EIGTH", // = 0x08, // sent from target to host
|
|
"Q_SAHARA_NINE", // = 0x09, // sent from target to host
|
|
"Q_SAHARA_TEN", // = 0x0A, // sent from host to target
|
|
"Q_SAHARA_ELEVEN", // = 0x0B, // sent from target to host
|
|
"Q_SAHARA_TWELEVE", // = 0x0C, // sent from host to target
|
|
"Q_SAHARA_THIRTEEN", // = 0x0D, // sent from host to target
|
|
"Q_SAHARA_FOURTEEN", // = 0x0E, // sent from target to host
|
|
"Q_SAHARA_FIFTEEN", // = 0x0F, // sent from host to target
|
|
"Q_SAHARA_SIXTEEN", // = 0x10, // sent from target to host
|
|
"Q_SAHARA_SEVENTEEN", // = 0x11, // sent from host to target
|
|
"Q_SAHARA_EIGHTEEN", // = 0x12,
|
|
};
|
|
|
|
if (0 == bytes_to_read)
|
|
{
|
|
if (qusb_use_usbfs_interface(usb_handle))
|
|
{
|
|
bytes_read = qusb_noblock_read(usb_handle, rx_buffer, Q_SAHARA_RAW_BUF_SZ, 0, 5000);
|
|
if (bytes_read < sizeof(q_sahara_packet_h)) return 0;
|
|
}
|
|
else
|
|
{
|
|
bytes_read =
|
|
qusb_noblock_read(usb_handle, rx_buffer, sizeof(q_sahara_packet_h), 0, 5000);
|
|
if (bytes_read != sizeof(q_sahara_packet_h)) return 0;
|
|
}
|
|
|
|
command_packet_header = (q_sahara_packet_h *)rx_buffer;
|
|
if (le_uint32(command_packet_header->q_cmd) < Q_SAHARA_NINETEEN)
|
|
{
|
|
dbg(LOG_EVENT, "<=== %s", q_sahara_cmd_str[le_uint32(command_packet_header->q_cmd)]);
|
|
|
|
if (!qusb_use_usbfs_interface(usb_handle))
|
|
{
|
|
bytes_read += qusb_noblock_read(
|
|
usb_handle, (uint8_t *)rx_buffer + sizeof(q_sahara_packet_h),
|
|
le_uint32(command_packet_header->q_len) - sizeof(q_sahara_packet_h), 0, 5000);
|
|
}
|
|
|
|
if (bytes_read != (le_uint32(command_packet_header->q_len)))
|
|
{
|
|
dbg(LOG_INFO, "Read %zd bytes, Header indicates q_cmd %d and packet q_len %d bytes",
|
|
bytes_read, le_uint32(command_packet_header->q_cmd),
|
|
le_uint32(command_packet_header->q_len));
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dbg(LOG_EVENT, "<=== SAHARA_CMD_UNKONOW_%d", le_uint32(command_packet_header->q_cmd));
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bytes_read = qusb_noblock_read(usb_handle, rx_buffer, bytes_to_read, bytes_to_read, 5000);
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int send_reset_command(void *usb_handle, void *tx_buffer)
|
|
{
|
|
struct sahara_pkt *sahara_reset;
|
|
sahara_reset = (struct sahara_pkt *)tx_buffer;
|
|
sahara_reset->q_header.q_cmd = le_uint32(Q_SAHARA_SEVEN);
|
|
sahara_reset->q_header.q_len =
|
|
le_uint32(sizeof(sahara_reset->q_sahara_reset_packet) + sizeof(q_sahara_packet_h));
|
|
|
|
/* Send the Reset Request */
|
|
dbg(LOG_EVENT, "SAHARA_RESET ===>");
|
|
if (0 ==
|
|
sahara_tx_data(usb_handle, tx_buffer,
|
|
sizeof(sahara_reset->q_sahara_reset_packet) + sizeof(q_sahara_packet_h)))
|
|
{
|
|
dbg(LOG_ERROR, "Sending RESET packet failed");
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int send_done_packet(void *usb_handle, void *tx_buffer)
|
|
{
|
|
struct sahara_pkt *sahara_done;
|
|
sahara_done = (struct sahara_pkt *)tx_buffer;
|
|
|
|
sahara_done->q_header.q_cmd = le_uint32(Q_SAHARA_FIVE);
|
|
sahara_done->q_header.q_len =
|
|
le_uint32(sizeof(sahara_done->q_sahara_done_packet) + sizeof(q_sahara_packet_h));
|
|
// Send the image data
|
|
dbg(LOG_EVENT, "Q_SAHARA_FIVE ===>");
|
|
if (0 == sahara_tx_data(usb_handle, tx_buffer,
|
|
sizeof(sahara_done->q_sahara_done_packet) + sizeof(q_sahara_packet_h)))
|
|
{
|
|
dbg(LOG_ERROR, "Sending DONE packet failed");
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static int start_image_transfer(void *usb_handle, void *tx_buffer,
|
|
const struct sahara_pkt *pr_sahara_pkt, FILE *file_handle)
|
|
{
|
|
int retval = 0;
|
|
uint32_t bytes_read = 0, bytes_to_read_next;
|
|
uint32_t q_image_id = le_uint32(pr_sahara_pkt->q_sahara_read_packet_data.q_image_id);
|
|
uint32_t DataOffset = le_uint32(pr_sahara_pkt->q_sahara_read_packet_data.q_data_offset);
|
|
uint32_t DataLength = le_uint32(pr_sahara_pkt->q_sahara_read_packet_data.q_data_length);
|
|
|
|
if (le_uint32(pr_sahara_pkt->q_header.q_cmd) == Q_SAHARA_EIGHTEEN)
|
|
{
|
|
q_image_id = le_uint64(pr_sahara_pkt->q_sahara_read_packet_data_64bit.q_image_id);
|
|
DataOffset = le_uint64(pr_sahara_pkt->q_sahara_read_packet_data_64bit.q_data_offset);
|
|
DataLength = le_uint64(pr_sahara_pkt->q_sahara_read_packet_data_64bit.q_data_length);
|
|
}
|
|
|
|
dbg(LOG_INFO, "0x%08x 0x%08x 0x%08x", q_image_id, DataOffset, DataLength);
|
|
|
|
if (fseek(file_handle, (long)DataOffset, SEEK_SET))
|
|
{
|
|
dbg(LOG_INFO, "%d errno: %d (%s)", __LINE__, errno, strerror(errno));
|
|
return 0;
|
|
}
|
|
|
|
while (bytes_read < DataLength)
|
|
{
|
|
bytes_to_read_next = MIN((uint32_t)DataLength - bytes_read, Q_SAHARA_RAW_BUF_SZ);
|
|
retval = fread(tx_buffer, 1, bytes_to_read_next, file_handle);
|
|
|
|
if (retval < 0)
|
|
{
|
|
dbg(LOG_ERROR, "file read failed: %s", strerror(errno));
|
|
return 0;
|
|
}
|
|
|
|
if ((uint32_t)retval != bytes_to_read_next)
|
|
{
|
|
dbg(LOG_ERROR, "Read %d bytes, but was asked for 0x%08x bytes", retval, DataLength);
|
|
return 0;
|
|
}
|
|
|
|
/*send the image data*/
|
|
if (0 == sahara_tx_data(usb_handle, tx_buffer, bytes_to_read_next))
|
|
{
|
|
dbg(LOG_ERROR, "Tx Sahara Image Failed");
|
|
return 0;
|
|
}
|
|
|
|
bytes_read += bytes_to_read_next;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int send_hello_response(void *usb_handle, void *tx_buffer,
|
|
const struct sahara_pkt *sahara_hello)
|
|
{
|
|
struct sahara_pkt *sahara_hello_resp;
|
|
sahara_hello_resp = (struct sahara_pkt *)tx_buffer;
|
|
|
|
// Recieved hello, send the hello response
|
|
// Create a Hello request
|
|
sahara_hello_resp->q_header.q_cmd = le_uint32(Q_SAHARA_TWO);
|
|
sahara_hello_resp->q_header.q_len = le_uint32(
|
|
sizeof(sahara_hello_resp->q_sahara_hello_packet_response) + sizeof(q_sahara_packet_h));
|
|
sahara_hello_resp->q_sahara_hello_packet_response.q_ver =
|
|
sahara_hello->q_sahara_hello_packet.q_ver;
|
|
sahara_hello_resp->q_sahara_hello_packet_response.q_ver_sup =
|
|
sahara_hello->q_sahara_hello_packet.q_ver_sup;
|
|
sahara_hello_resp->q_sahara_hello_packet_response.q_status = le_uint32(Q_SAHARA_STATUS_ZERO);
|
|
sahara_hello_resp->q_sahara_hello_packet_response.q_mode =
|
|
sahara_hello->q_sahara_hello_packet.q_mode;
|
|
sahara_hello_resp->q_sahara_hello_packet_response.q_reserve1 = le_uint32(1);
|
|
sahara_hello_resp->q_sahara_hello_packet_response.q_reserve2 = le_uint32(2);
|
|
sahara_hello_resp->q_sahara_hello_packet_response.q_reserve3 = le_uint32(3);
|
|
sahara_hello_resp->q_sahara_hello_packet_response.q_reserve4 = le_uint32(4);
|
|
sahara_hello_resp->q_sahara_hello_packet_response.q_reserve5 = le_uint32(5);
|
|
sahara_hello_resp->q_sahara_hello_packet_response.q_reserve6 = le_uint32(6);
|
|
|
|
if (le_uint32(sahara_hello->q_sahara_hello_packet.q_mode) != Q_SAHARA_MODE_ZERO)
|
|
{
|
|
dbg(LOG_ERROR, "ERROR NOT Q_SAHARA_MODE_ZERO");
|
|
sahara_hello_resp->q_sahara_hello_packet_response.q_mode = Q_SAHARA_MODE_ZERO;
|
|
}
|
|
|
|
/*Send the Hello Resonse Request*/
|
|
dbg(LOG_EVENT, "Q_SAHARA_TWO ===>");
|
|
if (0 == sahara_tx_data(usb_handle, tx_buffer,
|
|
sizeof(sahara_hello_resp->q_sahara_hello_packet_response) +
|
|
sizeof(q_sahara_packet_h)))
|
|
{
|
|
dbg(LOG_ERROR, "Tx Sahara Data Failed ");
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
static int sahara_flash_all(void *usb_handle, void *tx_buffer, void *rx_buffer, FILE *file_handle)
|
|
{
|
|
uint32_t q_image_id = 0;
|
|
struct sahara_pkt *pr_sahara_pkt;
|
|
|
|
pr_sahara_pkt = (struct sahara_pkt *)rx_buffer;
|
|
|
|
if (0 == sahara_rx_data(usb_handle, rx_buffer, 0))
|
|
{
|
|
sahara_tx_data(usb_handle, tx_buffer, 1);
|
|
if (0 == sahara_rx_data(usb_handle, rx_buffer, 0)) return 0;
|
|
}
|
|
|
|
if (le_uint32(pr_sahara_pkt->q_header.q_cmd) != Q_SAHARA_ONE)
|
|
{
|
|
dbg(LOG_ERROR, "Received a different q_cmd: %x while waiting for hello packet",
|
|
pr_sahara_pkt->q_header.q_cmd);
|
|
send_reset_command(usb_handle, rx_buffer);
|
|
return 0;
|
|
}
|
|
|
|
if (0 == send_hello_response(usb_handle, tx_buffer, pr_sahara_pkt))
|
|
{
|
|
dbg(LOG_ERROR, "send_hello_response failed\n");
|
|
return 0;
|
|
}
|
|
|
|
while (1)
|
|
{
|
|
if (0 == sahara_rx_data(usb_handle, rx_buffer, 0)) return 0;
|
|
|
|
if (le_uint32(pr_sahara_pkt->q_header.q_cmd) == Q_SAHARA_THREE)
|
|
{
|
|
start_image_transfer(usb_handle, tx_buffer, pr_sahara_pkt, file_handle);
|
|
}
|
|
else if (le_uint32(pr_sahara_pkt->q_header.q_cmd) == Q_SAHARA_EIGHTEEN)
|
|
{
|
|
start_image_transfer(usb_handle, tx_buffer, pr_sahara_pkt, file_handle);
|
|
}
|
|
else if (le_uint32(pr_sahara_pkt->q_header.q_cmd) == Q_SAHARA_FOUR)
|
|
{
|
|
dbg(LOG_EVENT, "q_image_id = %d, q_status = %d",
|
|
le_uint32(pr_sahara_pkt->q_sahara_end_packet_image_tx.q_image_id),
|
|
le_uint32(pr_sahara_pkt->q_sahara_end_packet_image_tx.q_status));
|
|
if (le_uint32(pr_sahara_pkt->q_sahara_end_packet_image_tx.q_status) ==
|
|
Q_SAHARA_STATUS_ZERO)
|
|
{
|
|
q_image_id = le_uint32(pr_sahara_pkt->q_sahara_end_packet_image_tx.q_image_id);
|
|
send_done_packet(usb_handle, tx_buffer);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
else if (le_uint32(pr_sahara_pkt->q_header.q_cmd) == Q_SAHARA_ONE)
|
|
{
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
dbg(LOG_ERROR, "Received an unknown q_cmd: %d ",
|
|
le_uint32(pr_sahara_pkt->q_header.q_cmd));
|
|
send_reset_command(usb_handle, tx_buffer);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (0 == sahara_rx_data(usb_handle, rx_buffer, 0)) return 0;
|
|
|
|
dbg(LOG_INFO, "q_image_tx_status = %d",
|
|
le_uint32(pr_sahara_pkt->q_sahara_done_packet_response.q_image_tx_status));
|
|
|
|
if (Q_SAHARA_MODE_ZERO ==
|
|
le_uint32(pr_sahara_pkt->q_sahara_done_packet_response.q_image_tx_status))
|
|
{
|
|
if (q_image_id == 13) // prog_nand_firehose_9x07.mbn
|
|
return 1;
|
|
if (q_image_id == 7) // NPRG9x55.mbn
|
|
return 1;
|
|
if (q_image_id == 21) // sbl1.mbn, October 22 2020 2:12 PM, AG35CEVAR05A07T4G
|
|
return 1;
|
|
}
|
|
else if (Q_SAHARA_MODE_ONE ==
|
|
le_uint32(pr_sahara_pkt->q_sahara_done_packet_response.q_image_tx_status))
|
|
{
|
|
dbg(LOG_EVENT, "Successfully flash all images");
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
dbg(LOG_ERROR, "Received unrecognized q_status %d at Q_SAHARA_WAIT_FOUR state",
|
|
le_uint32(pr_sahara_pkt->q_sahara_done_packet_response.q_image_tx_status));
|
|
return 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int sahara_main(const char *firehose_dir, const char *firehose_mbn, void *usb_handle,
|
|
int edl_mode_05c69008)
|
|
{
|
|
int retval = 0;
|
|
char full_path[512];
|
|
FILE *file_handle;
|
|
void *tx_buffer;
|
|
void *rx_buffer;
|
|
|
|
if (edl_mode_05c69008)
|
|
{
|
|
if (is_upgrade_fimeware_zip_7z)
|
|
{
|
|
snprintf(full_path, sizeof(full_path), "/tmp/%.240s", firehose_mbn);
|
|
dbg_time("%s full_path:%s\n", __func__, full_path);
|
|
}
|
|
else
|
|
{
|
|
snprintf(full_path, sizeof(full_path), "%.255s/%.240s", firehose_dir, firehose_mbn);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
char *prog_nand_firehose_filename = NULL;
|
|
|
|
if (is_upgrade_fimeware_zip_7z)
|
|
{
|
|
int i;
|
|
char prog_nand_firehose_filename_tmp[128] = {0};
|
|
char prog_nand_firehose_filename_dir_tmp[256] = {0};
|
|
|
|
prog_nand_firehose_filename = (char *)malloc(256);
|
|
if (prog_nand_firehose_filename == NULL)
|
|
{
|
|
return ENOENT;
|
|
}
|
|
|
|
for (i = 0; i < file_name_b.file_name_count; i++)
|
|
{
|
|
if ((strstr(file_name_b.file_backup_c[i].zip_file_name_backup, "NPRG9x") &&
|
|
strstr(file_name_b.file_backup_c[i].zip_file_name_backup, ".mbn")))
|
|
{
|
|
dbg_time("file_name_b.file_backup_c[i].zip_file_name_backup:%s\n",
|
|
file_name_b.file_backup_c[i].zip_file_name_backup);
|
|
dbg_time("file_name_b.file_backup_c[i].zip_file_dir_backup:%s\n",
|
|
file_name_b.file_backup_c[i].zip_file_dir_backup);
|
|
|
|
if (strstr(file_name_b.file_backup_c[i].zip_file_dir_backup, "update/firehose"))
|
|
{
|
|
memmove(prog_nand_firehose_filename_tmp,
|
|
file_name_b.file_backup_c[i].zip_file_name_backup,
|
|
strlen(file_name_b.file_backup_c[i].zip_file_name_backup));
|
|
memmove(prog_nand_firehose_filename_dir_tmp,
|
|
file_name_b.file_backup_c[i].zip_file_dir_backup,
|
|
strlen(file_name_b.file_backup_c[i].zip_file_dir_backup));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (prog_nand_firehose_filename_tmp[0] != '\0')
|
|
{
|
|
memset(zip_cmd_buf, 0, sizeof(zip_cmd_buf));
|
|
if (is_upgrade_fimeware_only_zip)
|
|
{
|
|
snprintf(zip_cmd_buf, sizeof(zip_cmd_buf),
|
|
"unzip -o -q %.240s '*%.200s' -d /tmp/ > %s", firehose_dir,
|
|
prog_nand_firehose_filename_dir_tmp, ZIP_PROCESS_INFO);
|
|
}
|
|
else
|
|
{
|
|
snprintf(zip_cmd_buf, sizeof(zip_cmd_buf), "7z x %.240s -o/tmp/ %.200s > %s",
|
|
firehose_dir, prog_nand_firehose_filename_dir_tmp, ZIP_PROCESS_INFO);
|
|
}
|
|
dbg_time("%s zip_cmd_buf:%s\n", __func__, zip_cmd_buf);
|
|
if (-1 == system(zip_cmd_buf))
|
|
{
|
|
dbg_time("%s system return error\n", __func__);
|
|
safe_free(prog_nand_firehose_filename);
|
|
return ENOENT;
|
|
}
|
|
usleep(1000);
|
|
|
|
memmove(prog_nand_firehose_filename, prog_nand_firehose_filename_dir_tmp, 240);
|
|
dbg(LOG_INFO, "prog_nand_firehose_filename = %s", prog_nand_firehose_filename);
|
|
|
|
snprintf(full_path, sizeof(full_path), "/tmp/%.240s", prog_nand_firehose_filename);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
snprintf(full_path, sizeof(full_path), "%.255s/..", firehose_dir);
|
|
if (!qfile_find_file(full_path, "NPRG9x", ".mbn", &prog_nand_firehose_filename) &&
|
|
!qfile_find_file(full_path, "NPRG9x", ".mbn", &prog_nand_firehose_filename))
|
|
{
|
|
dbg(LOG_ERROR, "retrieve NPRG MBN failed.");
|
|
safe_free(prog_nand_firehose_filename);
|
|
return ENOENT;
|
|
}
|
|
dbg(LOG_INFO, "prog_nand_firehose_filename = %s", prog_nand_firehose_filename);
|
|
|
|
snprintf(full_path, sizeof(full_path), "%.255s/../%.240s", firehose_dir,
|
|
prog_nand_firehose_filename);
|
|
}
|
|
|
|
safe_free(prog_nand_firehose_filename);
|
|
}
|
|
|
|
file_handle = fopen(full_path, "rb");
|
|
if (file_handle == NULL)
|
|
{
|
|
dbg(LOG_INFO, "%s %d %s errno: %d (%s)", __func__, __LINE__, full_path, errno,
|
|
strerror(errno));
|
|
return ENOENT;
|
|
}
|
|
|
|
rx_buffer = malloc(Q_SAHARA_RAW_BUF_SZ);
|
|
tx_buffer = malloc(Q_SAHARA_RAW_BUF_SZ);
|
|
|
|
if (NULL == rx_buffer || NULL == tx_buffer)
|
|
{
|
|
dbg(LOG_ERROR, "Failed to allocate sahara buffers");
|
|
safe_free(rx_buffer);
|
|
safe_free(tx_buffer);
|
|
fclose(file_handle);
|
|
file_handle = NULL;
|
|
return ENOMEM;
|
|
}
|
|
|
|
retval = sahara_flash_all(usb_handle, tx_buffer, rx_buffer, file_handle);
|
|
if (0 == retval)
|
|
{
|
|
dbg(LOG_ERROR, "Sahara protocol error");
|
|
}
|
|
else
|
|
{
|
|
dbg(LOG_STATUS, "Sahara protocol completed");
|
|
}
|
|
|
|
safe_free(rx_buffer);
|
|
safe_free(tx_buffer);
|
|
fclose(file_handle);
|
|
file_handle = NULL;
|
|
|
|
if (is_upgrade_fimeware_zip_7z)
|
|
{
|
|
unlink(full_path);
|
|
}
|
|
|
|
if (retval) return 0;
|
|
|
|
return __LINE__;
|
|
}
|