mirror of
https://git.zaage.it/robert/balong-usbload.git
synced 2024-11-10 01:11:03 +00:00
Исправлена ошибка, которая принимала пустой ответ модема за нормальный
This commit is contained in:
parent
48ccacd011
commit
79d31d67fd
@ -1,102 +1,102 @@
|
||||
// Загрузчик usbloader.bin через аварийный порт для модемов на платформе Balong V7R2.
|
||||
//
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
//#include <termios.h>
|
||||
//#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
//#include <arpa/inet.h>
|
||||
#ifndef WIN32
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#include "wingetopt.h"
|
||||
#include "printf.h"
|
||||
#endif
|
||||
|
||||
|
||||
// Загрузчик usbloader.bin через аварийный порт для модемов на платформе Balong V7R2.
|
||||
//
|
||||
//
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
//#include <termios.h>
|
||||
//#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
//#include <arpa/inet.h>
|
||||
#ifndef WIN32
|
||||
int siofd;
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <arpa/inet.h>
|
||||
#else
|
||||
#include <windows.h>
|
||||
#include "wingetopt.h"
|
||||
#include "printf.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef WIN32
|
||||
int siofd;
|
||||
struct termios sioparm;
|
||||
#else
|
||||
static HANDLE hSerial;
|
||||
#endif
|
||||
FILE* ldr;
|
||||
|
||||
|
||||
//*************************************************
|
||||
//* HEX-дамп области памяти *
|
||||
//*************************************************
|
||||
|
||||
void dump(unsigned char buffer[],int len) {
|
||||
int i,j;
|
||||
unsigned char ch;
|
||||
|
||||
printf("\n");
|
||||
for (i=0;i<len;i+=16) {
|
||||
printf("%04x: ",i);
|
||||
for (j=0;j<16;j++){
|
||||
if ((i+j) < len) printf("%02x ",buffer[i+j]&0xff);
|
||||
else printf(" ");}
|
||||
printf(" *");
|
||||
for (j=0;j<16;j++) {
|
||||
if ((i+j) < len) {
|
||||
// преобразование байта для символьного отображения
|
||||
ch=buffer[i+j];
|
||||
if ((ch < 0x20)||((ch > 0x7e)&&(ch<0xc0))) putchar('.');
|
||||
else putchar(ch);
|
||||
}
|
||||
// заполнение пробелами для неполных строк
|
||||
else printf(" ");
|
||||
}
|
||||
printf("*\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//*************************************************
|
||||
//* Рассчет контрольной суммы командного пакета
|
||||
//*************************************************
|
||||
void csum(unsigned char* buf, int len) {
|
||||
|
||||
unsigned int i,c,csum=0;
|
||||
|
||||
unsigned int cconst[]={0,0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF};
|
||||
|
||||
for (i=0;i<(len-2);i++) {
|
||||
c=(buf[i]&0xff);
|
||||
csum=((csum<<4)&0xffff)^cconst[(c>>4)^(csum>>12)];
|
||||
csum=((csum<<4)&0xffff)^cconst[(c&0xf)^(csum>>12)];
|
||||
}
|
||||
buf[len-2]=(csum>>8)&0xff;
|
||||
buf[len-1]=csum&0xff;
|
||||
|
||||
}
|
||||
|
||||
//*************************************************
|
||||
//* Отсылка командного пакета модему
|
||||
//*************************************************
|
||||
int sendcmd(unsigned char* cmdbuf, int len) {
|
||||
|
||||
unsigned char replybuf[1024];
|
||||
unsigned int replylen;
|
||||
|
||||
FILE* ldr;
|
||||
|
||||
|
||||
//*************************************************
|
||||
//* HEX-дамп области памяти *
|
||||
//*************************************************
|
||||
|
||||
void dump(unsigned char buffer[],int len) {
|
||||
int i,j;
|
||||
unsigned char ch;
|
||||
|
||||
printf("\n");
|
||||
for (i=0;i<len;i+=16) {
|
||||
printf("%04x: ",i);
|
||||
for (j=0;j<16;j++){
|
||||
if ((i+j) < len) printf("%02x ",buffer[i+j]&0xff);
|
||||
else printf(" ");}
|
||||
printf(" *");
|
||||
for (j=0;j<16;j++) {
|
||||
if ((i+j) < len) {
|
||||
// преобразование байта для символьного отображения
|
||||
ch=buffer[i+j];
|
||||
if ((ch < 0x20)||((ch > 0x7e)&&(ch<0xc0))) putchar('.');
|
||||
else putchar(ch);
|
||||
}
|
||||
// заполнение пробелами для неполных строк
|
||||
else printf(" ");
|
||||
}
|
||||
printf("*\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//*************************************************
|
||||
//* Рассчет контрольной суммы командного пакета
|
||||
//*************************************************
|
||||
void csum(unsigned char* buf, int len) {
|
||||
|
||||
unsigned int i,c,csum=0;
|
||||
|
||||
unsigned int cconst[]={0,0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF};
|
||||
|
||||
for (i=0;i<(len-2);i++) {
|
||||
c=(buf[i]&0xff);
|
||||
csum=((csum<<4)&0xffff)^cconst[(c>>4)^(csum>>12)];
|
||||
csum=((csum<<4)&0xffff)^cconst[(c&0xf)^(csum>>12)];
|
||||
}
|
||||
buf[len-2]=(csum>>8)&0xff;
|
||||
buf[len-1]=csum&0xff;
|
||||
|
||||
}
|
||||
|
||||
//*************************************************
|
||||
//* Отсылка командного пакета модему
|
||||
//*************************************************
|
||||
int sendcmd(unsigned char* cmdbuf, int len) {
|
||||
|
||||
unsigned char replybuf[1024];
|
||||
unsigned int replylen;
|
||||
|
||||
#ifndef WIN32
|
||||
csum(cmdbuf,len);
|
||||
write(siofd,cmdbuf,len); // отсылка команды
|
||||
tcdrain(siofd);
|
||||
replylen=read(siofd,replybuf,1024);
|
||||
csum(cmdbuf,len);
|
||||
write(siofd,cmdbuf,len); // отсылка команды
|
||||
tcdrain(siofd);
|
||||
replylen=read(siofd,replybuf,1024);
|
||||
#else
|
||||
DWORD bytes_written = 0;
|
||||
DWORD t;
|
||||
|
||||
csum(cmdbuf, len);
|
||||
csum(cmdbuf, len);
|
||||
WriteFile(hSerial, cmdbuf, len, &bytes_written, NULL);
|
||||
FlushFileBuffers(hSerial);
|
||||
|
||||
@ -105,104 +105,105 @@ replylen=read(siofd,replybuf,1024);
|
||||
ReadFile(hSerial, replybuf, 1024, (LPDWORD)&replylen, NULL);
|
||||
} while (replylen == 0 && GetTickCount() - t < 1000);
|
||||
#endif
|
||||
if ((replylen == 0) || (replybuf[0] == 0xaa)) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
|
||||
void main(int argc, char* argv[]) {
|
||||
|
||||
if (replylen == 0) return 0;
|
||||
if (replybuf[0] == 0xaa) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
||||
|
||||
void main(int argc, char* argv[]) {
|
||||
|
||||
#ifndef WIN32
|
||||
struct termios sioparm;
|
||||
#else
|
||||
#else
|
||||
char device[20] = "\\\\.\\COM";
|
||||
DCB dcbSerialParams = {0};
|
||||
COMMTIMEOUTS CommTimeouts;
|
||||
#endif
|
||||
//char* lptr;
|
||||
unsigned int i,res,opt,datasize,pktcount,adr;
|
||||
int nblk; // число блоков для загрузки
|
||||
int bl; // текущий блок
|
||||
|
||||
unsigned char cmdhead[14]={0xfe,0, 0xff};
|
||||
unsigned char cmddata[1040]={0xda,0,0};
|
||||
unsigned char cmdeod[5]={0xed,0,0,0,0};
|
||||
|
||||
struct {
|
||||
int lmode; // режим загрузки: 1 - прямой старт, 2 - через перезапуск A-core
|
||||
int size; // размер блока
|
||||
int adr; // адрес загрузки блока в память
|
||||
int offset; // смещение до блока от начала файла
|
||||
} blk[10];
|
||||
|
||||
#ifndef WIN32
|
||||
unsigned char devname[50]="/dev/ttyUSB0";
|
||||
#else
|
||||
char devname[50]="";
|
||||
#endif
|
||||
//char* lptr;
|
||||
unsigned int i,res,opt,datasize,pktcount,adr;
|
||||
int nblk; // число блоков для загрузки
|
||||
int bl; // текущий блок
|
||||
|
||||
while ((opt = getopt(argc, argv, "hp:sa:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
|
||||
printf("\n Утилита предназначена для аварийной USB-загрузки модемов E3372S\n\n\
|
||||
%s [ключи] <имя файла для загрузки>\n\n\
|
||||
Допустимы следующие ключи:\n\n\
|
||||
-p <tty> - последовательный порт для общения с загрузчиком (по умолчанию /dev/ttyUSB0\n\
|
||||
\n",argv[0]);
|
||||
return;
|
||||
|
||||
case 'p':
|
||||
strcpy(devname,optarg);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (optind>=argc) {
|
||||
printf("\n - Не указано имя файла для загрузки\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
if (*devname == '\0')
|
||||
{
|
||||
printf("\n - Последовательный порт не задан\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
// Настройка SIO
|
||||
siofd = open(devname, O_RDWR | O_NOCTTY |O_SYNC);
|
||||
if (siofd == -1) {
|
||||
printf("\n - Последовательный порт %s не открывается\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
bzero(&sioparm, sizeof(sioparm));
|
||||
sioparm.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
|
||||
sioparm.c_iflag = 0; // INPCK;
|
||||
sioparm.c_oflag = 0;
|
||||
sioparm.c_lflag = 0;
|
||||
sioparm.c_cc[VTIME]=1; // таймаут
|
||||
sioparm.c_cc[VMIN]=1; // 1 байт минимального ответа
|
||||
|
||||
tcsetattr(siofd, TCSANOW, &sioparm);
|
||||
tcflush(siofd,TCIOFLUSH); // очистка выходного буфера
|
||||
#else
|
||||
unsigned char cmdhead[14]={0xfe,0, 0xff};
|
||||
unsigned char cmddata[1040]={0xda,0,0};
|
||||
unsigned char cmdeod[5]={0xed,0,0,0,0};
|
||||
|
||||
struct {
|
||||
int lmode; // режим загрузки: 1 - прямой старт, 2 - через перезапуск A-core
|
||||
int size; // размер блока
|
||||
int adr; // адрес загрузки блока в память
|
||||
int offset; // смещение до блока от начала файла
|
||||
} blk[10];
|
||||
|
||||
#ifndef WIN32
|
||||
unsigned char devname[50]="/dev/ttyUSB0";
|
||||
#else
|
||||
char devname[50]="";
|
||||
#endif
|
||||
|
||||
while ((opt = getopt(argc, argv, "hp:sa:")) != -1) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
|
||||
printf("\n Утилита предназначена для аварийной USB-загрузки модемов E3372S\n\n\
|
||||
%s [ключи] <имя файла для загрузки>\n\n\
|
||||
Допустимы следующие ключи:\n\n\
|
||||
-p <tty> - последовательный порт для общения с загрузчиком (по умолчанию /dev/ttyUSB0\n\
|
||||
\n",argv[0]);
|
||||
return;
|
||||
|
||||
case 'p':
|
||||
strcpy(devname,optarg);
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (optind>=argc) {
|
||||
printf("\n - Не указано имя файла для загрузки\n");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
if (*devname == '\0')
|
||||
{
|
||||
printf("\n - Последовательный порт не задан\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef WIN32
|
||||
// Настройка SIO
|
||||
siofd = open(devname, O_RDWR | O_NOCTTY |O_SYNC);
|
||||
if (siofd == -1) {
|
||||
printf("\n - Последовательный порт %s не открывается\n", argv[1]);
|
||||
return;
|
||||
}
|
||||
|
||||
bzero(&sioparm, sizeof(sioparm));
|
||||
sioparm.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
|
||||
sioparm.c_iflag = 0; // INPCK;
|
||||
sioparm.c_oflag = 0;
|
||||
sioparm.c_lflag = 0;
|
||||
sioparm.c_cc[VTIME]=1; // таймаут
|
||||
sioparm.c_cc[VMIN]=1; // 1 байт минимального ответа
|
||||
|
||||
tcsetattr(siofd, TCSANOW, &sioparm);
|
||||
tcflush(siofd,TCIOFLUSH); // очистка выходного буфера
|
||||
#else
|
||||
strcat(device, /*(char*)*/devname);
|
||||
|
||||
hSerial = CreateFileA(device, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
||||
if (hSerial == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
printf("\n - Последовательный порт COM%s не открывается\n", devname);
|
||||
printf("\n - Последовательный порт COM%s не открывается\n", devname);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -217,7 +218,7 @@ tcflush(siofd,TCIOFLUSH); // очистка выходного буфера
|
||||
dcbSerialParams.fRtsControl = RTS_CONTROL_ENABLE;
|
||||
if (!SetCommState(hSerial, &dcbSerialParams))
|
||||
{
|
||||
printf("\n - Ошибка при инициализации COM-порта\n", devname);
|
||||
printf("\n - Ошибка при инициализации COM-порта\n", devname);
|
||||
CloseHandle(hSerial);
|
||||
return;
|
||||
}
|
||||
@ -229,96 +230,96 @@ tcflush(siofd,TCIOFLUSH); // очистка выходного буфера
|
||||
CommTimeouts.WriteTotalTimeoutMultiplier = 0;
|
||||
if (!SetCommTimeouts(hSerial, &CommTimeouts))
|
||||
{
|
||||
printf("\n - Ошибка при инициализации COM-порта\n", devname);
|
||||
printf("\n - Ошибка при инициализации COM-порта\n", devname);
|
||||
CloseHandle(hSerial);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
ldr=fopen(argv[optind],"rb");
|
||||
if (ldr == 0) {
|
||||
printf("\n Ошибка открытия %s",argv[optind]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Прверяем сигнатуру usloader
|
||||
fread(&i,1,4,ldr);
|
||||
if (i != 0x20000) {
|
||||
printf("\n Файл %s не является загрузчиком usbloader\n",argv[optind]);
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(ldr,36,SEEK_SET); // начало описателей блоков для загрузки
|
||||
|
||||
// Разбираем заголовок
|
||||
|
||||
for(nblk=0;nblk<10;nblk++) {
|
||||
fread(&blk[nblk].lmode,1,4,ldr);
|
||||
fread(&blk[nblk].size,1,4,ldr);
|
||||
fread(&blk[nblk].adr,1,4,ldr);
|
||||
fread(&blk[nblk].offset,1,4,ldr);
|
||||
if (blk[nblk].lmode == 0) break;
|
||||
}
|
||||
printf("\n Найдено %i блоков для загрузки",nblk);
|
||||
|
||||
// главный цикл загрузки - загружаем все блоки, найденные в заголовке
|
||||
|
||||
for(bl=0;bl<nblk;bl++) {
|
||||
|
||||
printf("\n Загрузка блока %i, адрес=%08x, размер=%i\n",bl,blk[bl].adr,blk[bl].size);
|
||||
fseek(ldr,blk[bl].offset,SEEK_SET);
|
||||
// фрмируем пакет начала блока
|
||||
*((unsigned int*)&cmdhead[4])=htonl(blk[bl].size);
|
||||
*((unsigned int*)&cmdhead[8])=htonl(blk[bl].adr);
|
||||
cmdhead[3]=blk[bl].lmode;
|
||||
|
||||
// отправляем пакет начала блока
|
||||
res=sendcmd(cmdhead,14);
|
||||
if (!res) {
|
||||
printf("\nМодем отверг пакет заголовка\nОбраз пакета:");
|
||||
dump(cmdhead,14);
|
||||
return;
|
||||
}
|
||||
|
||||
// Цикл поблочной загрузки данных
|
||||
datasize=1024;
|
||||
pktcount=1;
|
||||
|
||||
for(adr=0;adr<blk[bl].size;adr+=1024) {
|
||||
if ((adr+1024)>=blk[bl].size) datasize=blk[bl].size-adr;
|
||||
#ifndef WIN32
|
||||
fprintf(stderr,"\r Адрес: %08x, пакет# %i размер: %i",blk[bl].adr+adr,pktcount,datasize);
|
||||
#else
|
||||
printf("\r Адрес: %08x, пакет# %i размер: %i",blk[bl].adr+adr,pktcount,datasize);
|
||||
#endif
|
||||
|
||||
// читаем порцию данных
|
||||
if (datasize != fread(cmddata+3,1,datasize,ldr)) {
|
||||
printf("\n Неожиданный конец файла\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// готовим пакет данных
|
||||
cmddata[1]=pktcount;
|
||||
cmddata[2]=(~pktcount)&0xff;
|
||||
pktcount++;
|
||||
if (!sendcmd(cmddata,datasize+5)) {
|
||||
printf("\nМодем отверг пакет данных\nОбраз пакета:");
|
||||
dump(cmddata,datasize+5);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Фрмируем пакет конца данных
|
||||
cmdeod[1]=pktcount;
|
||||
cmdeod[2]=(~pktcount)&0xff;
|
||||
|
||||
if (!sendcmd(cmdeod,5)) {
|
||||
printf("\nМодем отверг пакет конца данных\nОбраз пакета:");
|
||||
dump(cmdeod,5);
|
||||
}
|
||||
}
|
||||
printf("\n Загрузка окончена\n");
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
ldr=fopen(argv[optind],"rb");
|
||||
if (ldr == 0) {
|
||||
printf("\n Ошибка открытия %s",argv[optind]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Прверяем сигнатуру usloader
|
||||
fread(&i,1,4,ldr);
|
||||
if (i != 0x20000) {
|
||||
printf("\n Файл %s не является загрузчиком usbloader\n",argv[optind]);
|
||||
return;
|
||||
}
|
||||
|
||||
fseek(ldr,36,SEEK_SET); // начало описателей блоков для загрузки
|
||||
|
||||
// Разбираем заголовок
|
||||
|
||||
for(nblk=0;nblk<10;nblk++) {
|
||||
fread(&blk[nblk].lmode,1,4,ldr);
|
||||
fread(&blk[nblk].size,1,4,ldr);
|
||||
fread(&blk[nblk].adr,1,4,ldr);
|
||||
fread(&blk[nblk].offset,1,4,ldr);
|
||||
if (blk[nblk].lmode == 0) break;
|
||||
}
|
||||
printf("\n Найдено %i блоков для загрузки",nblk);
|
||||
|
||||
// главный цикл загрузки - загружаем все блоки, найденные в заголовке
|
||||
|
||||
for(bl=0;bl<nblk;bl++) {
|
||||
|
||||
printf("\n Загрузка блока %i, адрес=%08x, размер=%i\n",bl,blk[bl].adr,blk[bl].size);
|
||||
fseek(ldr,blk[bl].offset,SEEK_SET);
|
||||
// фрмируем пакет начала блока
|
||||
*((unsigned int*)&cmdhead[4])=htonl(blk[bl].size);
|
||||
*((unsigned int*)&cmdhead[8])=htonl(blk[bl].adr);
|
||||
cmdhead[3]=blk[bl].lmode;
|
||||
|
||||
// отправляем пакет начала блока
|
||||
res=sendcmd(cmdhead,14);
|
||||
if (!res) {
|
||||
printf("\nМодем отверг пакет заголовка\nОбраз пакета:");
|
||||
dump(cmdhead,14);
|
||||
return;
|
||||
}
|
||||
|
||||
// Цикл поблочной загрузки данных
|
||||
datasize=1024;
|
||||
pktcount=1;
|
||||
|
||||
for(adr=0;adr<blk[bl].size;adr+=1024) {
|
||||
if ((adr+1024)>=blk[bl].size) datasize=blk[bl].size-adr;
|
||||
#ifndef WIN32
|
||||
fprintf(stderr,"\r Адрес: %08x, пакет# %i размер: %i",blk[bl].adr+adr,pktcount,datasize);
|
||||
#else
|
||||
printf("\r Адрес: %08x, пакет# %i размер: %i",blk[bl].adr+adr,pktcount,datasize);
|
||||
#endif
|
||||
|
||||
// читаем порцию данных
|
||||
if (datasize != fread(cmddata+3,1,datasize,ldr)) {
|
||||
printf("\n Неожиданный конец файла\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// готовим пакет данных
|
||||
cmddata[1]=pktcount;
|
||||
cmddata[2]=(~pktcount)&0xff;
|
||||
pktcount++;
|
||||
if (!sendcmd(cmddata,datasize+5)) {
|
||||
printf("\nМодем отверг пакет данных\nОбраз пакета:");
|
||||
dump(cmddata,datasize+5);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Фрмируем пакет конца данных
|
||||
cmdeod[1]=pktcount;
|
||||
cmdeod[2]=(~pktcount)&0xff;
|
||||
|
||||
if (!sendcmd(cmdeod,5)) {
|
||||
printf("\nМодем отверг пакет конца данных\nОбраз пакета:");
|
||||
dump(cmdeod,5);
|
||||
}
|
||||
}
|
||||
printf("\n Загрузка окончена\n");
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user