📄 sftupload.cpp
字号:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <stdio.h>
#include "time.h"
#include "Comport.h"
#include "SFTUpload.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// Important: Methods and properties of objects in VCL can only be
// used in a method called using Synchronize, for example:
//
// Synchronize(UpdateCaption);
//
// where UpdateCaption could look like:
//
// void __fastcall SFTUpload::UpdateCaption()
// {
// Form1->Caption = "Updated in a thread";
// }
//---------------------------------------------------------------------------
__fastcall SFTUpload::SFTUpload(bool CreateSuspended)
: TThread(CreateSuspended)
{
Stop=True;
}
//---------------------------------------------------------------------------
void __fastcall SFTUpload::Execute()
{
int r;
reupload:
Suspend();
Stop=False;
SFTSendFile();
Stop=True;
r=ErrorNo;
if( r!=0 && r!=-3 )
{
Application->MessageBox( ErrorString,"ERROR",MB_OK|MB_ICONERROR );
};
goto reupload;
//---- Place thread code here ----
}
//---------------------------------------------------------------------------
#define ACK 0x6
#define NAK 0x15
#define STX 0x2
#define ETX 0x3
#define DLE 0x10
#define EOT 0x4
#define ENQ 0x5
#undef ERROR
#define ERROR -1
#define BLOCK_SIZE 1+1+1+2048+1+1+1 /* "%[FF] .... DLE ETX BCC */
#define UNKNOWN "&&&&&&"
#define DATA_FILE 0x03
#define PRIORITY 0x80
#define TRANSM_REQ 0x21
#define RECV_FILE_REQ 0x22
#define SEND_FILE_REQ 0x23
#define FILE_INFO 0x24
#define TRANSM_DATA 0x25
#define RETRIES 3
#define TIMEOUT 3000 /* timeout of 3 seconds */
#define LAST_BLOCK 0xFF
#define NOT_LAST_BLOCK 0x00
#define OK 0
#define NOT_OK -1 /* error after 3 retries */
#define ERR_BCC_FAIL -2 /* checksum error (internal) */
#define ERR_USER_BREAK -3 /* user pressed termination key */
#define ERR_TIME_OUT -4 /* time out error (internal) */
#define ERR_EOT_HOST -5 /* host aborted transmission */
#define ERR_HOST_REQ -6 /* host and terminal request did not match */
#define ERR_HOST_LOST -7 /* time out on first char (internal) */
#define ERR_OPEN_FILE -8 /* Could not open file */
#define ERR_WRITE_FILE -9 /* Could not write to file */
#define ERR_READ_FILE -10 /* Could not read from file */
#define ERR_NAK_RECV -11 /* NAK received from host (internal) */
#define ERR_OUT_SYNC -12 /* Serial number of blocks out of sync */
void SFTUpload::transmit_eot(void)
{
Com->WriteChar(DLE,-1);
Com->WriteChar(EOT,-1);
}
void SFTUpload::transmit_ack(void)
{
Com->WriteChar(DLE,-1);
Com->WriteChar(ACK,-1);
}
void SFTUpload::transmit_nak(void)
{
Com->WriteChar(DLE,-1);
Com->WriteChar(NAK,-1);
}
long SFTUpload::asc_to_long(unsigned char *buf)
{
long temp;
temp = ((long) buf[0] << 24);
temp += ((long) buf[1] << 16);
temp += ((long) buf[2] << 8);
temp += ((long) buf[3]);
return (temp);
}
int SFTUpload::asc_to_int(unsigned char *buf)
{
int temp;
temp = (int) buf[0] * 256;
temp += (int) buf[1];
return (temp);
}
void SFTUpload::long_to_asc(unsigned char *buf, unsigned long value)
{
*buf++ = (unsigned char) ((value & 0xFF000000L) >> 24); // split up long
*buf++ = (unsigned char) ((value & 0x00FF0000L) >> 16); // in motorola
*buf++ = (unsigned char) ((value & 0x0000FF00L) >> 8); // format
*buf = (unsigned char) (value & 0x000000FFL); // high .. low
}
void SFTUpload::int_to_asc(unsigned char *buf, unsigned int value)
{
*buf++ = (unsigned char) (value / 256);
*buf = (unsigned char) (value % 256);
}
void SFTUpload::conv_filename(char *buf, char *filename)
// 12345678.123 => 12345678123
{
char *ptr;
int count;
if ((ptr = strchr(filename, '.')) == NULL)
{
strcpy(buf, filename);
}
else
{
count = ptr - filename;
strncpy(buf, filename, count);
buf[count] = '\0';
};
for (count = strlen(buf); count < 8; count++)strcat(buf, " ");
if (ptr != NULL)strcat(buf, ++ptr);
for (count = strlen(buf); count < 11; count++)strcat(buf, " ");
}
void SFTUpload::filename_conv(char *filename, const char *buf)
// 12345678123 => 12345678.123
{
char *ptr;
strncpy(filename, buf, 8);
filename[8] = '\0';
if ((ptr = strchr(filename, ' ')) != NULL) *ptr = '\0';
strcat(filename, ".");
strncat(filename, buf + 8, 3);
filename[12] = '\0';
if ((ptr = strchr(filename, ' ')) != NULL) *ptr = '\0';
}
int SFTUpload::transmit_block(unsigned char *buffer, int len )
{
int bcc;
int count;
int ch;
Com->WriteChar(DLE,-1);
Com->WriteChar(STX,-1);
bcc = STX ^ ETX;
for (count = 0; count < len; count++)
{
ch = *buffer++;
if (Stop==True)return ERR_USER_BREAK;
bcc ^= ch;
if (ch == DLE)
{
bcc ^= DLE;
Com->WriteChar( DLE,-1 );
};
Com->WriteChar( (char)ch,-1 );
};
Com->WriteChar( DLE,-1 );
Com->WriteChar( ETX,-1 );
Com->WriteChar( (char)bcc,-1 );
return (OK);
}
int SFTUpload::receive_block(unsigned char *buffer, int time_out)
{
short int bcc;
short int count;
short int ch;
bcc = 0;
for (;;)
{
for (;;)
{
if (Stop==True)return ERR_USER_BREAK;
if (Com->ReadChar( (char *)&ch,time_out )!=0 )return ERR_HOST_LOST;
if (ch == DLE) break;
};
if (Com->ReadChar( (char *)&ch,time_out )!=0 )return ERR_TIME_OUT;
if (ch == NAK) return (ERR_NAK_RECV);
if (ch == ACK) { *buffer = ACK; return (1); };
if (ch == EOT) return (ERR_EOT_HOST);
if (ch == STX) break;
if (Stop==True) return (ERR_USER_BREAK);
};
bcc = DLE ^ STX;
for (count = 0; count < BLOCK_SIZE; count++)
{
if ( Com->ReadChar( (char *)&ch,time_out ) !=0 ) return ERR_TIME_OUT;
if (Stop==True) return ERR_USER_BREAK;
if (ch == DLE)
{
bcc ^= DLE;
if( Com->ReadChar( (char *)&ch,time_out ) !=0 )return ERR_TIME_OUT;
switch (ch)
{
case DLE: bcc ^= DLE;
*buffer++ = (char)ch;
break;
case ETX: bcc ^= ETX;
if( Com->ReadChar( (char *)&ch,time_out )!=0 )return ERR_TIME_OUT;
if (ch == bcc) return (count);
else return (ERR_BCC_FAIL);
case EOT: return (ERR_EOT_HOST);
default: break;
};
}
else
{
bcc ^= ch;
*buffer++ = ch;
};
};
return (ERROR);
}
void __fastcall SFTUpload::ShowProgress()
{
char buf[32];
int percent;
sprintf(buf,"%d",FileCount);
LabelFileCount->Caption=buf;
sprintf(buf,"%d",TotalFileSize);
LabelTotalFileSize->Caption=buf;
sprintf(buf,"%d",CurrentFileSize);
LabelCurrentFileSize->Caption=buf;
sprintf(buf,"%d",UploadedLen);
LabelUploadedLen->Caption=buf;
LabelCurrentFileName->Caption=CurrentFileName;
if( TotalFileSize>0 ){ percent=TotalUploadedLen*100/TotalFileSize; }
else { percent=0; };
sprintf(buf,"%d",percent);
ProgressBar1->Position=percent;
if( CurrentFileSize>0 ){ percent=UploadedLen*100/CurrentFileSize; }
else { percent=0; };
ProgressBar->Position=percent;
}
void SFTUpload::StopUpload(void)
{
Stop=True;
}
long SFTUpload::fsize( String FileName )
{
FILE *fp;
long len;
fp=fopen( FileName.c_str(),"rb" );
if( fp==NULL )return -1;
fseek(fp,0,SEEK_END);
len=ftell(fp);
fclose(fp);
return len;
}
int SFTUpload::ComReadString(char *Str,int timeout)
{
char ch;
int i=0;
while(1)
{
if( Com->ReadChar( &ch,timeout )==0 )
{
Str[i]=ch;
i++;
if( i>=32 )return -1;
if( ch==0 )return 0;
};
if( Stop==True )return -3;
};
}
void SFTUpload::ComWriteString(char *Str,int timeout)
{
Com->WriteStr( Str,strlen(Str)+1,timeout );
}
void SFTUpload::SFTSendFile(void)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -