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.
balong-flash/balong-flash.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();
}