• Welcome to Forum.Deepsoftware.Com. Please login or sign up.
 
April 25, 2024, 10:58:19 am

News:

SMF - Just Installed!


Separate ZMODEM usage

Started by Kolan, August 13, 2009, 05:58:51 am

Previous topic - Next topic

Kolan

Is it possible to use TnrZModem component alone with out TnrComm? And if yes, are there any examples available?

I've found a ZModem.DataReceive method, but there is nothing said about in help.

Roman Novgorodov

Hello

You can try to use the following:
TnrZModem.DoProcessing() method for transmit incoming data from remote client to ZModem class and
You should handle TnrZModem.OnDataSend event for transmit bytes from ZModem to remote client.

Sorry if my answer is too late.

Roman Novgorodov
DeepSoftware llc - The professional components for Delphi/CBuilder/.NET. The high quality custom software development.
Forums.nrCommLib.Com - DeepSoftware Tech Support Forum.

Kolan

Thanks Roman!

Can you provide OnDataSend event interface. Since this event is not described in help file I tried to compose it my self using IDE hint.
procedure ZModemDataSend(Sender: TObject; ptrBuffer: PAnsiChar;
      Len: Cardinal; flSyncro: Boolean; flHandled: Boolean);


But this interface is wrong, IDE says that: E2009 Incompatible types: 'Parameter lists differ'

Can you also, please, explain the meaning of params, especially flSyncro and flHandled.

Any additional information, examples etc would be great.

Roman Novgorodov

Hello

The following handler sample should work:

procedure TForm1.nrZModem1DataSend(Sender: TObject; ptrBuffer: PAnsiChar;
  Len: Cardinal; flSynchro: Boolean; var flHandled: Boolean);
begin
  // code for data output ...
end;

Roman Novgorodov
DeepSoftware llc - The professional components for Delphi/CBuilder/.NET. The high quality custom software development.
Forums.nrCommLib.Com - DeepSoftware Tech Support Forum.

Kolan

Thanks, and one more thing, where TIngnoreTypes type is declared?

This value is required for DoProcessing method.

Roman Novgorodov

Hello

You can use somthing like this:

uses nrclasses;

var it:TIgnoreTypes;

begin
  it := [];
  nrZMoedm.DoProcessing(data, len, it);
end;


Roman Novgorodov
DeepSoftware llc - The professional components for Delphi/CBuilder/.NET. The high quality custom software development.
Forums.nrCommLib.Com - DeepSoftware Tech Support Forum.

Kolan

OK, it compiles now, thanks. But there are still problems...

I've created a tread that constantly read data from the port via FTDI Dxx2.dll. When data is got it is being forwarded to the ZModem:

procedure TFTDIUSBPortWrapper.PortDataReadEvent(Data: AnsiString);
var
  R: TIgnoreTypes;
begin
  ShowMessage(Data);
  R := [];
{Если Z-модем акÑ,ивен, Ñ,о полученые байÑ,Ñ‹ перенаправляюÑ,ся ему.}
  if FZModem.Active then
    FZModem.DoProcessing(@Data, Length(Data), R)
  else
    MyAnswerHandler(Data);
end;


And there is also a DataSend event handler.

procedure TFTDIUSBPortWrapper.ZModemDataSend(Sender: TObject;
  ptrBuffer: PAnsiChar; Len: Cardinal; flSyncro: Boolean; var flHandled: Boolean);
var
  Msg: AnsiString;
  I: Integer;
begin
  Msg := '';
  for I := 0 to Len - 1 do
    Msg := Msg + ptrBuffer[I];
  MySendCommand(Msg);
end;


ZModem gets data in PortDataReadEvent, but nothing happens. I tried to use logfile component to debug:

constructor TFTDIUSBPortWrapper.Create;
begin
  inherited;
  FUSBReadThread := nil;
  FnrLog := TnrLogFile.Create(nil);

  FZModem := TnrZModem.Create(nil);
  FZModem.OnAfterFileReceived := FileDownloadedEvent;
  FZModem.OnAfterFileSent := FileUploadedEvent;
  FZModem.Options := FZModem.Options + [zoOverwrite] - [zoCreateWithNewName];
  FZModem.OnDataSend := ZModemDataSend;
  [b]FZModem.Log := FnrLog;[/b]

// FZModem.OnDataSend := ZModemDataSend;
end;


But it is empty. What it can mean?

Kolan

Forgot to say, ZModemDataSend is also never called.

Roman Novgorodov

Hello

I don't see anywhere the following code:

FZModem.Active := True;


Roman Novgorodov
DeepSoftware llc - The professional components for Delphi/CBuilder/.NET. The high quality custom software development.
Forums.nrCommLib.Com - DeepSoftware Tech Support Forum.

Kolan

TFTDIUSBPortWrapper has a parent TCustomPortWrapper.

When somebody sends command (a linux command) it is first processed by the parent:

procedure TCustomPortWrapper.SendCommandFromQueue;
var
  StringCommand: AnsiString;
begin
{Если в очереди есÑ,ÑŒ команды, Ñ,о послаÑ,ÑŒ следующую.}
  if FCommandsQueue.Count > 0 then
  begin
   {СкомпоноваÑ,ÑŒ команду.}
    StringCommand := FCommandsQueue.Peek.CommandForDevice+#13;

   {ОчисÑ,иÑ,ÑŒ переменную в коÑ,орую будеÑ, накапливаÑ,ься оÑ,веÑ,.}
    FTempPackage := '';
    if FFilter <> nil then
      MySendCommand(FFilter.FilterCommand(StringCommand))
    else
      MySendCommand(StringCommand);

   {Ð'ключиÑ,ÑŒ Ñ,айм-ауÑ, Ñ,аймер.}
    FTimeOutTimer.Enabled := True;

    if FCommandsQueue.Peek.LinuxCommand = lcDownloadFileViaZModem then
    begin
      MyDownloadFile((FCommandsQueue.Peek as TFileDownloadCommand).DirectoryToSaveFile);
    end;
  end;
end;


Case «if FCommandsQueue.Peek.LinuxCommand = lcDownloadFileViaZModem then» means that when there is a «lsz» in command the MyDownloadFile abstract method is called.


MyDownloadFile is implemented in descendant:

procedure TFTDIUSBPortWrapper.MyDownloadFile(const DirectoryToSaveFile: string);
begin
  inherited;
  FZModem.DefaultPath := DirectoryToSaveFile;
  FZModem.Active := True;
end;


Where FZModem.Active := True; is eventually done.