
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1328 8e941d3f-bd1b-0410-a28a-d453659cc2b4
243 lines
6.1 KiB
ObjectPascal
243 lines
6.1 KiB
ObjectPascal
unit mainform;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
|
|
EditBtn, ExtCtrls, ComCtrls,
|
|
synaser;
|
|
|
|
type
|
|
|
|
{ TformSerial }
|
|
|
|
TformSerial = class(TForm)
|
|
btnConnect: TButton;
|
|
comboClientServer: TComboBox;
|
|
editDevice: TEdit;
|
|
editFileName: TFileNameEdit;
|
|
Label1: TLabel;
|
|
Label2: TLabel;
|
|
Label3: TLabel;
|
|
Label4: TLabel;
|
|
Label5: TLabel;
|
|
editFileSize: TLabeledEdit;
|
|
editReceivedFileName: TLabeledEdit;
|
|
ScrollBox1: TScrollBox;
|
|
StatusBar: TStatusBar;
|
|
timerClientConnect: TTimer;
|
|
timerServerConnect: TTimer;
|
|
procedure btnConnectClick(Sender: TObject);
|
|
procedure FormCreate(Sender: TObject);
|
|
procedure FormDestroy(Sender: TObject);
|
|
procedure timerClientConnectTimer(Sender: TObject);
|
|
procedure timerServerConnectTimer(Sender: TObject);
|
|
private
|
|
{ private declarations }
|
|
connected: Boolean;
|
|
ser: TBlockSerial;
|
|
procedure ServerSendFile();
|
|
procedure ClientReceiveFile();
|
|
public
|
|
{ public declarations }
|
|
end;
|
|
|
|
var
|
|
formSerial: TformSerial;
|
|
|
|
implementation
|
|
|
|
const
|
|
INT_COMBO_SERVER = 0;
|
|
INT_COMBO_CLIENT = 1;
|
|
|
|
// Data records
|
|
|
|
BYTE_REQUEST_CONNECTION = $00;
|
|
// Followed by nothing else
|
|
|
|
BYTE_ACCEPT_CONNECTION = $01;
|
|
// Followed by nothing else
|
|
|
|
BYTE_FILE_NAME = $02;
|
|
// Followed by:
|
|
// File name size - 1 Byte indicating the size sz_size. The name doesn't include path.
|
|
// File name - sz_size bytes in UTF-8
|
|
|
|
BYTE_FILE_DATA = $03;
|
|
// Followed by:
|
|
// File size - 8 Bytes, a Int64 in Little Endian, indicates sz_size
|
|
// File data - sz_size bytes
|
|
|
|
{$R *.lfm}
|
|
|
|
{ TformSerial }
|
|
|
|
procedure TformSerial.FormCreate(Sender: TObject);
|
|
begin
|
|
ser := TBlockSerial.Create;
|
|
end;
|
|
|
|
procedure TformSerial.btnConnectClick(Sender: TObject);
|
|
begin
|
|
btnConnect.Enabled := False;
|
|
|
|
try
|
|
if connected then raise Exception.Create('Already connected');
|
|
|
|
// Check the input data
|
|
if (editDevice.Text = '') then raise Exception.Create('Invalid serial port name');
|
|
|
|
if (editFileName.Text = '') then raise Exception.Create('Invalid file path');
|
|
|
|
if (comboClientServer.ItemIndex = INT_COMBO_SERVER)
|
|
and (not FileExists(editFileName.Text)) then raise Exception.Create('Invalid input file. It doesn''t exist');
|
|
|
|
if (comboClientServer.ItemIndex = INT_COMBO_CLIENT)
|
|
and (not DirectoryExists(editFileName.Text)) then raise Exception.Create('Invalid output directory. It doesn''t exist');
|
|
|
|
StatusBar.SimpleText := 'Connecting';
|
|
Application.ProcessMessages;
|
|
ser.Connect(editDevice.Text); //ComPort
|
|
Sleep(1000);
|
|
Application.ProcessMessages;
|
|
ser.config(115000, 8, 'N', SB1, False, False);
|
|
Sleep(1000);
|
|
Application.ProcessMessages;
|
|
|
|
StatusBar.SimpleText := 'Device: ' + ser.Device +
|
|
' Status: ' + ser.LastErrorDesc + ' ' +
|
|
Inttostr(ser.LastError);
|
|
|
|
if ser.LastError = 0 then connected := True;
|
|
|
|
if comboClientServer.ItemIndex = INT_COMBO_SERVER then
|
|
timerServerConnect.Enabled := True
|
|
else
|
|
timerClientConnect.Enabled := True;
|
|
finally
|
|
btnConnect.Enabled := True;
|
|
end;
|
|
end;
|
|
|
|
procedure TformSerial.FormDestroy(Sender: TObject);
|
|
begin
|
|
ser.free;
|
|
end;
|
|
|
|
procedure TformSerial.timerClientConnectTimer(Sender: TObject);
|
|
var
|
|
Data: Byte;
|
|
begin
|
|
Data := ser.RecvByte(timerClientConnect.Interval div 2);
|
|
|
|
if (Data = BYTE_REQUEST_CONNECTION) and (ser.LastError = 0) then
|
|
begin
|
|
Connected := True;
|
|
timerClientConnect.Enabled := False;
|
|
ser.SendByte(BYTE_ACCEPT_CONNECTION);
|
|
ClientReceiveFile();
|
|
end;
|
|
end;
|
|
|
|
procedure TformSerial.timerServerConnectTimer(Sender: TObject);
|
|
var
|
|
Data: Byte;
|
|
begin
|
|
ser.SendByte(BYTE_REQUEST_CONNECTION);
|
|
|
|
Data := ser.RecvByte(timerServerConnect.Interval div 2);
|
|
|
|
if (Data = BYTE_ACCEPT_CONNECTION) and (ser.LastError = 0) then
|
|
begin
|
|
Connected := True;
|
|
timerServerConnect.Enabled := False;
|
|
ServerSendFile();
|
|
end;
|
|
end;
|
|
|
|
procedure TformSerial.ServerSendFile();
|
|
var
|
|
ShortStr: shortstring;
|
|
Data, StrLen: Byte;
|
|
i: Integer;
|
|
lStream: TFileStream;
|
|
lSize: Int64;
|
|
begin
|
|
StatusBar.SimpleText := 'Sending file';
|
|
Application.ProcessMessages;
|
|
|
|
// Send the file name:
|
|
ShortStr := ExtractFileName(editFileName.Text);
|
|
StrLen := Length(ShortStr);
|
|
ser.SendByte(BYTE_FILE_NAME);
|
|
ser.SendByte(StrLen);
|
|
for i := 1 to StrLen do
|
|
ser.SendByte(Byte(ShortStr[i]));
|
|
|
|
// Send the file data:
|
|
lStream := TFileStream.Create(editFileName.Text, fmOpenRead);
|
|
try
|
|
lSize := Length(ShortStr);
|
|
ser.SendByte(BYTE_FILE_DATA);
|
|
ser.SendBuffer(@lSize, 8);
|
|
for i := 0 to lSize - 1 do
|
|
begin
|
|
Data := lStream.ReadByte();
|
|
ser.SendByte(Data);
|
|
// Process messages each 100 bytes
|
|
if (i div 100) = 0 then Application.ProcessMessages();
|
|
end;
|
|
finally
|
|
lStream.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TformSerial.ClientReceiveFile();
|
|
var
|
|
ShortStr: shortstring;
|
|
Data, StrLen: Byte;
|
|
i: Integer;
|
|
lStream: TFileStream;
|
|
lSize: Int64;
|
|
filePath: string;
|
|
begin
|
|
StatusBar.SimpleText := 'Receiving file';
|
|
Application.ProcessMessages;
|
|
|
|
// Read the file name:
|
|
Data := ser.RecvByte(5000);
|
|
// Process any remaining connect messages
|
|
while (Data = BYTE_REQUEST_CONNECTION) do
|
|
Data := ser.RecvByte(5000);
|
|
if (Data <> BYTE_FILE_NAME) then raise Exception.Create('Expected record BYTE_FILE_SIZE, but received: ' + IntToStr(Data));
|
|
StrLen := ser.RecvByte(5000);
|
|
ShortStr := '';
|
|
for i := 1 to StrLen do
|
|
ShortStr := ShortStr + Char(ser.RecvByte(1000));
|
|
editReceivedFileName.Text := ShortStr;
|
|
|
|
// Read the file data:
|
|
Data := ser.RecvByte(5000);
|
|
if (Data <> BYTE_FILE_DATA) then raise Exception.Create('Expected record BYTE_FILE_DATA, but received: ' + IntToStr(Data));
|
|
filePath := IncludeTrailingPathDelimiter(editFileName.Text) + editReceivedFileName.Text;
|
|
lStream := TFileStream.Create(filePath, fmOpenWrite or fmCreate);
|
|
try
|
|
ser.RecvBuffer(@lSize, 8);
|
|
for i := 0 to lSize - 1 do
|
|
begin
|
|
Data := ser.RecvByte(1000);
|
|
lStream.WriteByte(Data);
|
|
// Process messages each 100 bytes
|
|
if (i div 100) = 0 then Application.ProcessMessages();
|
|
end;
|
|
finally
|
|
lStream.Free;
|
|
end;
|
|
end;
|
|
|
|
end.
|
|
|