#include #include #ifndef WIN32 #include #include #include #include #include #include #include #include #include #else #include #include "getopt.h" #include "printf.h" #include "buildno.h" #endif #include "hdlcio.h" #include "ptable.h" unsigned char replybuf[4096]; // Цифровые подписи struct { uint8_t type; uint32_t len; char* descr; } signbase[] = { {1,2958,"Основная прошивка"}, {1,2694,"Прошивка E3372s-stick"}, {2,1110,"Вебинтерфейс+ISO для HLINK-модема"}, {6,1110,"Вебинтерфейс+ISO для HLINK-модема"}, {2,846,"ISO (dashboard) для stick-модема"}, {99,1110,"универсальная"}, }; #define signbaselen 6 struct { uint8_t code; char* descr; } fwtypes[]={ {1,"ONLY_FW"}, {2,"ONLY_ISO"}, {3,"FW_ISO"}, {4,"ONLY_WEBUI"}, {5,"FW_WEBUI"}, {6,"ISO_WEBUI"}, {7,"FW_ISO_WEBUI"}, {99,"COMPONENT_MAX"}, {0,0} }; // результирующая строка ^signver - команды static unsigned char signver[100]; // Флаг режима цифровой подписи int gflag=0; //**************************************************** //* Получение описания типа прошивки по коду //**************************************************** char* fw_description(uint8_t code) { int i; for (i=0; (fwtypes[i].code != 0); i++) { if (code == fwtypes[i].code) return fwtypes[i].descr; } return 0; } //**************************************************** //* Получение списка параметров ключа -g //**************************************************** void glist() { int i; printf("\n # длина тип описание \n--------------------------------------"); for (i=0; i= signbaselen) goto perror; signlen=signbase[index].len; signtype=signbase[index].type; } gflag=1; sprintf(signver,"^SIGNVER=%i,0,778A8D175E602B7B779D9E05C330B5279B0661BF2EED99A20445B366D63DD697,%i",signtype,signlen); printf("\n Режим цифровой подписи: %s (%i байт)",fw_description(signtype),signlen); // printf("\nstr - %s",signver); return; perror: printf("\n Ошибка в параметрах ключа -g\n"); exit(0); } //**************************************************** //* Определение версии прошивальщика //* //* 0 - нет ответа на команду //* 1 - версия 2.0 //* -1 - версия не 2.0 //**************************************************** int dloadversion() { int res; int i; res=atcmd("^DLOADVER?",replybuf); if (res == 0) return 0; if (strncmp(replybuf+2,"2.0",3) == 0) return 1; for (i=2;i\n\n\ Допустимы следующие ключи:\n\n" #ifndef WIN32 "-p - последовательный порт для общения с загрузчиком (по умолчанию /dev/ttyUSB0)\n" #else "-p - последовательный порт для общения с загрузчиком\n" #endif "-n - режим мультифайловой прошивки из указанного каталога\n\ -g# - установка режима цифровой подписи (-gl - описание параметров)\n\ -m - вывести карту файла прошивки и завершить работу\n\ -e - разобрать файл прошивки на разделы без заголовков\n\ -s - разобрать файл прошивки на разделы с заголовками\n\ -k - не перезагружать модем по окончании прошивки\n\ -r - принудительно перезагрузить модем без прошивки разделов\n\ \n",argv[0]); return; case 'p': strcpy(devname,optarg); break; case 'm': mflag=1; break; case 'n': nflag=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 '?': case ':': return; } } printf("\n Программа для прошивки устройств на Balong-чипсете, V2.6.%i, (c) forth32, 2015, GNU GPLv3",BUILDNO); #ifdef WIN32 printf("\n Порт для Windows 32bit (c) rust3028, 2016"); #endif printf("\n--------------------------------------------------------------------------------------------------\n"); if (eflag&sflag) { printf("\n Ключи -s и -e несовместимы\n"); return; } if (kflag&rflag) { printf("\n Ключи -k и -r несовместимы\n"); return; } if (nflag&(eflag|sflag|mflag)) { printf("\n Ключ -n несовместим с ключами -s, -m и -e\n"); return; } // ------ перезагрузка без указания файла //-------------------------------------------- if ((optind>=argc)&rflag) goto sio; // Открытие входного файла //-------------------------------------------- if (optind>=argc) { if (nflag) printf("\n - Не указан каталог с файлами\n"); else printf("\n - Не указано имя файла для загрузки, используйте ключ -h для подсказки\n"); return; } if (nflag) // для -n - просто копируем префикс strncpy(fdir,argv[optind],39); else { // для однофайловых операций in=fopen(argv[optind],"rb"); if (in == 0) { printf("\n Ошибка открытия %s",argv[optind]); return; } } // Поиск разделов внутри файла //-------------------------------------------- if (!nflag) { // printf("\n Разбираем файл прошивки..."); npart=findparts(in,ptable); if (npart == 0) { printf("\nРазделы не найдены!"); return ; } } // Поиск файлов прошивок в указанном каталоге //-------------------------------------------- else { printf("\n Поиск файлов-образов разделов...\n\n ## Размер ID Имя Файл\n-----------------------------------------------------------------\n"); for (npart=0;npart<30;npart++) { if (find_file(npart, fdir, ptable[npart].filename, &ptable[npart].code, &ptable[npart].size) == 0) break; // конец поиска - раздела с таким ID не нашли // получаем символическое имя раздела find_pname(ptable[npart].code,ptable[npart].pname); printf("\n %02i %8i %08x %-8.8s %s",npart,ptable[npart].size,ptable[npart].code,ptable[npart].pname,ptable[npart].filename); } } // printf("\n Найдено %i разделов",npart); //------ Режим вывода карты файла прошивки //-------------------------------------------- if (mflag) { printf("\n\n ## Смещение Размер Имя\n-------------------------------------"); for (i=0;i2) printf("\n Идентификатор устройства: %s",replybuf+2); printf("\n----------------------------------------------------\n"); if ((optind>=argc)&rflag) goto reset; // перезагрузка без указания файла // Главный цикл записи разделов for(part=0;part