You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
254 lines
5.6 KiB
C
254 lines
5.6 KiB
C
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#ifndef WIN32
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <strings.h>
|
|
#include <termios.h>
|
|
#include <unistd.h>
|
|
#include <arpa/inet.h>
|
|
#else
|
|
#include <windows.h>
|
|
#include "getopt.h"
|
|
#include "printf.h"
|
|
#include "buildno.h"
|
|
#endif
|
|
|
|
#include "hdlcio.h"
|
|
#include "ptable.h"
|
|
#include "flasher.h"
|
|
#include "util.h"
|
|
#include "signver.h"
|
|
#include "zlib.h"
|
|
|
|
// file structure error flag
|
|
unsigned int errflag=0;
|
|
|
|
// digital signature flag
|
|
int gflag=0;
|
|
// firmware type flag
|
|
int dflag=0;
|
|
|
|
// firmware type from file header
|
|
int dload_id=-1;
|
|
|
|
//***********************************************
|
|
//* Partition table
|
|
//***********************************************
|
|
struct ptb_t ptable[120];
|
|
int npart=0; // number of partitions in the table
|
|
|
|
|
|
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
|
|
int main(int argc, char* argv[]) {
|
|
|
|
unsigned int opt;
|
|
int res;
|
|
FILE* in;
|
|
char devname[50] = "";
|
|
unsigned int mflag=0,eflag=0,rflag=0,sflag=0,nflag=0,kflag=0,fflag=0;
|
|
unsigned char fdir[40]; // directory for multi-file firmware
|
|
|
|
// command line parsing
|
|
while ((opt = getopt(argc, argv, "d:hp:mersng:kf")) != -1) {
|
|
switch (opt) {
|
|
case 'h':
|
|
|
|
printf("\n This utility is intended for flashing modems with a Balong V7 chipset\n\n\
|
|
%s [options] <boot file name or directory name>\n\n\
|
|
Following options are allowed:\n\n"
|
|
#ifndef WIN32
|
|
"-p <tty> - Serial port for communicating with the bootloader (by default /dev/ttyUSB0)\n"
|
|
#else
|
|
"-p # - Number of the serial port for communicating with the loader (e.g. -p8)\n"
|
|
" if the -p option is not specified, the port is auto-detected\n"
|
|
#endif
|
|
"-n - Multi-file firmware from a specified directory\n\
|
|
-g # - Set digital signature mode\n\
|
|
-gl - parameter definition\n\
|
|
-gd - disable signature autodetection\n\
|
|
-m - Display the firmware file map and exit\n\
|
|
-e - Disassemble the firmware file into partitions without headers\n\
|
|
-s - Disassemble the firmware file into partitions with headers\n\
|
|
-k - Don't restart the modem after flashing\n\
|
|
-r - Force reboot of the modem without flashing partitions\n\
|
|
-f - Flash even if there are CRC errors in the source file\n\
|
|
-d # - Set the firmware type (DLOAD_ID, 0...7), -dl - List of types\n\
|
|
\n",argv[0]);
|
|
return 0;
|
|
|
|
case 'p':
|
|
strcpy(devname,optarg);
|
|
break;
|
|
|
|
case 'm':
|
|
mflag=1;
|
|
break;
|
|
|
|
case 'n':
|
|
nflag=1;
|
|
break;
|
|
|
|
case 'f':
|
|
fflag=1;
|
|
break;
|
|
|
|
case 'r':
|
|
rflag=1;
|
|
break;
|
|
|
|
case 'k':
|
|
kflag=1;
|
|
break;
|
|
|
|
case 'e':
|
|
eflag=1;
|
|
break;
|
|
|
|
case 's':
|
|
sflag=1;
|
|
break;
|
|
|
|
case 'g':
|
|
gparm(optarg);
|
|
break;
|
|
|
|
case 'd':
|
|
dparm(optarg);
|
|
break;
|
|
|
|
case '?':
|
|
case ':':
|
|
return -1;
|
|
}
|
|
}
|
|
printf("\nProgram for flashing Balong-chipset devices, V3.0.%i, (c) forth32, 2015, GNU GPLv3\n",BUILDNO);
|
|
printf("English Version (c) robertzaage, 2022\n");
|
|
#ifdef WIN32
|
|
printf("Windows Port 32bit (c) rust3028, 2016\n");
|
|
#endif
|
|
printf("\n--------------------------------------------------------------------------------------------------\n");
|
|
|
|
if (eflag&sflag) {
|
|
printf("\n The -s and -e options are incompatible\n");
|
|
return -1;
|
|
}
|
|
|
|
if (kflag&rflag) {
|
|
printf("\n The -k and -r options are incompatible\n");
|
|
return -1;
|
|
}
|
|
|
|
if (nflag&(eflag|sflag|mflag)) {
|
|
printf("\n The -n option is incompatible with -s, -m, and -e options\n");
|
|
return -1;
|
|
}
|
|
|
|
|
|
// reboot without specifying a file
|
|
//--------------------------------------------
|
|
if ((optind>=argc)&rflag) goto sio;
|
|
|
|
|
|
// open an input file
|
|
//--------------------------------------------
|
|
if (optind>=argc) {
|
|
if (nflag)
|
|
printf("\n - Directory containing the files is not specified\n");
|
|
else
|
|
printf("\n - No file name specified, use the -h option to display help\n");
|
|
return -1;
|
|
}
|
|
|
|
if (nflag)
|
|
// for -n - just copy the prefix
|
|
strncpy(fdir,argv[optind],39);
|
|
else {
|
|
// for single-file operations
|
|
in=fopen(argv[optind],"rb");
|
|
if (in == 0) {
|
|
printf("\n Can't open file %s",argv[optind]);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
// search for partitions within a file
|
|
if (!nflag) {
|
|
findparts(in);
|
|
show_fw_info();
|
|
}
|
|
|
|
// search for firmware files in a specified directory
|
|
else findfiles(fdir);
|
|
|
|
// firmware file map output
|
|
if (mflag) show_file_map();
|
|
|
|
// CRC error ouput
|
|
if (!fflag && errflag) {
|
|
printf("\n\n! Input file contains errors - exiting\n");
|
|
return -1;
|
|
}
|
|
|
|
// split firmware file
|
|
if (eflag|sflag) {
|
|
fwsplit(sflag);
|
|
printf("\n");
|
|
return 0;
|
|
}
|
|
|
|
sio:
|
|
// standard procedure - flash firmware
|
|
|
|
// SIO setup
|
|
open_port(devname);
|
|
|
|
// define port and dload protocol version
|
|
|
|
res=dloadversion();
|
|
if (res == -1) return -2;
|
|
if (res == 0) {
|
|
printf("\n Modem is already in HDLC mode");
|
|
goto hdlc;
|
|
}
|
|
|
|
// if necessary, send a digital signature command
|
|
if (gflag != -1) send_signver();
|
|
|
|
// enter HDLC mode
|
|
usleep(100000);
|
|
enter_hdlc();
|
|
|
|
// we have entered HDLC mode
|
|
//------------------------------
|
|
hdlc:
|
|
|
|
// get the protocol version and the device identifier
|
|
protocol_version();
|
|
dev_ident();
|
|
|
|
printf("\n----------------------------------------------------\n");
|
|
|
|
if ((optind>=argc)&rflag) {
|
|
// reboot without pointing a file
|
|
restart_modem();
|
|
exit(0);
|
|
}
|
|
|
|
// flash all memory
|
|
flash_all();
|
|
printf("\n");
|
|
|
|
port_timeout(1);
|
|
|
|
// exit HDLC mode and reboot
|
|
if (rflag || !kflag) restart_modem();
|
|
// exit HDLC mode without rebooting
|
|
else leave_hdlc();
|
|
}
|