unit uTestNettopos;

interface

uses
{$IFDEF WINDOWS}
  Windows, Messages, Variants, Forms, Dialogs, Controls,
  StdCtrls, Graphics, ipcthrd,
{$ELSE}
  ERRORS,
  baseunix,
  unix,
  ipc,
  uSemaforoPolenta,
  uWinMsgs,
  ctypes,
  uEmuladorWinIPC,
{$ENDIF}
  SysUtils, Classes, uLibFuncionesComunes,
//   uauxiliares,
   ubuffrw,
{$IFDEF NETTOPOS_DLL}
  uimpnettopos,
{$ELSE}
  unettopos,
  unettopostypes,
  uglobsharedmem,
{$ENDIF}
  uconstantes_nettopos, uMsgsTestNettopos, uTestNettoposHandler,
  uMsgsDespachador;

type
  tiposOrdenes = (to_Ayuda,
                  to_x2Sincrono, to_x2Asincrono,
                  to_testMemoAddSincrono, to_testMemoAddAsincrono,
                  to_CloseAppSincrono, to_CloseAppAsincrono,
                  to_RunCmdSincrono, to_RunCmdAsincrono,
                  to_TestUnoContraTodos, to_TestUnoContraTodos_Despachador);

{$IFDEF LINUX}
  TfTestNettopos = class(TComponent)
{$ELSE}
  TfTestNettopos = class(TForm)
    EIP: TEdit;
    Ex: TEdit;
    LIP: TLabel;
    Lx: TLabel;
    lRes: TLabel;
    BPedirX2Sincrono: TButton;
    BPedirX2Asincrono: TButton;
    memoRes: TMemo;
    Ls: TLabel;
    Es: TEdit;
    cbTestLongBuffer: TCheckBox;
    bPedirMemoAddSincrono: TButton;
    bPedirMemoAddAsincrono: TButton;
    eAppName: TEdit;
    lAppName: TLabel;
    bPedirCloseAppSincrono: TButton;
    bPedirCloseAppAsincrono: TButton;
    bPedirRunCmdSincrono: TButton;
    bPedirRunCmdAsincrono: TButton;
    BTestUnoContraTodosAsincrono: TButton;
    bResultados: TButton;
    BTestUnoContraTodosDespachador: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure BPedirX2SincronoClick(Sender: TObject);
    procedure BPedirX2AsincronoClick(Sender: TObject);
    procedure bPedirMemoAddSincronoClick(Sender: TObject);
    procedure bPedirMemoAddAsincronoClick(Sender: TObject);
    procedure bPedirCloseAppSincronoClick(Sender: TObject);
    procedure bPedirCloseAppAsincronoClick(Sender: TObject);
    procedure bPedirRunCmdSincronoClick(Sender: TObject);
    procedure bPedirRunCmdAsincronoClick(Sender: TObject);
    procedure BTestUnoContraTodosAsincronoClick(Sender: TObject);
    procedure BTestUnoContraTodosSincronoClick(Sender: TObject);
    procedure bResultadosClick(Sender: TObject);
    procedure BTestUnoContraTodosDespachadorClick(Sender: TObject);
{$ENDIF}
  private
    testeador: TTestNettoposHandler;

    function getAyuda: String;

    procedure pedirX2Sincrono(ip: String; x: Integer);
    procedure pedirX2Asincrono(ip: String; x: Integer);
    procedure msgr_PedirX2(var Msg: TMessage); message MSGR_PEDIRX2;
    procedure pedirTestMemoAddSincrono(ip: String; s: String; testearLongBuffer: Boolean);
    procedure pedirTestMemoAddAsincrono(ip: String; s: String; testearLongBuffer: Boolean);
    procedure msgr_pedirTestMemoAdd(var Msg: TMessage); message MSGR_TESTMEMOADD;
    procedure pedirCloseAppSincrono(ip: String; nomApp: String);
    procedure pedirCloseAppAsincrono(ip: String; nomApp: String);
    procedure msgr_CloseApp(var Msg: TMessage); message MSGR_CLOSEAPP;
    procedure pedirRunCmdSincrono(ip: String; binName: String);
    procedure pedirRunCmdAsincrono(ip: String; binName: String);
    procedure msgr_RunCmd(var Msg: TMessage); message MSGR_RUNCMD;

    //Obtiene todos los nodos que conozca el topo y les envía comunicados de
    //pedirX2AsincronoParaUnoContraTodos, si testearLongBuffer es true repite
    //s hasta obtener un msj de tamaño mayor al máximo tamaño de un buffer chico
    procedure pedirUnoContraTodosAsincrono(s: STring; testearLongBuffer: boolean);
    procedure pedirUnoContraTodosDespachador(s: STring; testearLongBuffer: boolean);

    procedure msgp_PedirX2(var Msg: TMessage); message MSGP_PEDIRX2;
    procedure msgp_testMemoAdd(var Msg: TMessage); message MSGP_TESTMEMOADD;

    procedure msgp_PedirDelayedToUpperCase(var Msg: TMessage); message MSGP_DELAYED_TO_UPPER_CASE;
    procedure msgr_PedirPedirDelayedToUpperCase(var Msg: TMessage); message MSGR_DELAYED_TO_UPPER_CASE;
    procedure recibirRespuesta(var Msg: TMessage); message MSGP_RECIBIR_RESPUESTA;
    procedure liberarRobot_TCU_Despachador(var MSG: TMessage); message MSG_LIBERAR_ROBOT_T_C_U_DESPACHADOR;

    procedure ejecutarOrden;
  public
{$IFDEF LINUX}
 	  recolectar: boolean;
    constructor Create(AOwner: TComponent); reintroduce;
    procedure Free; virtual;
{$ENDIF}
  end;

function tipoOrdenToString(tipoOrden: tiposOrdenes): String;
function descripcionTipoOrden(tipoOrden: tiposOrdenes): String;
function stringToTipoOrden(tipoOrden: String): tiposOrdenes;
function nParamsTipoOrden(tipoOrden: tiposOrdenes): Integer;
function paramsTipoOrden(tipoOrden: tiposOrdenes): String;

var
  fTestNettopos: TfTestNettopos;

implementation

function tipoOrdenToString(tipoOrden: tiposOrdenes): String;
begin
  case tipoOrden of
    to_Ayuda                            : result:= '/?';
    to_x2Sincrono                       : result:= 'X2S';
    to_x2Asincrono                      : result:= 'X2A';
    to_testMemoAddSincrono              : result:= 'MAS';
    to_testMemoAddAsincrono             : result:= 'MAA';
    to_CloseAppSincrono                 : result:= 'CAS';
    to_CloseAppAsincrono                : result:= 'CAA';
    to_RunCmdSincrono                   : result:= 'RCS';
    to_RunCmdAsincrono                  : result:= 'RCA';
    to_TestUnoContraTodos               : result:= 'UCT';
    to_TestUnoContraTodos_Despachador   : result:= 'UCTD';
  end;
end;

function descripcionTipoOrden(tipoOrden: tiposOrdenes): String;
begin
  case tipoOrden of
    to_Ayuda                          : result:= 'Muestra esta ayuda';
    to_x2Sincrono                     : result:= 'Envía un testX2 sincrono al IP especificado';
    to_x2Asincrono                    : result:= 'Envía un testX2 asincrono al IP especificado';
    to_testMemoAddSincrono            : result:= 'Envía un testMemoAdd sincrono al IP especificado';
    to_testMemoAddAsincrono           : result:= 'Envía un testMemoAdd asincrono al IP especificado';
    to_CloseAppSincrono               : result:= 'Envía un closeApp sincrono al IP especificado';
    to_CloseAppAsincrono              : result:= 'Envía un closeApp asincrono al IP especificado';
    to_RunCmdSincrono                 : result:= 'Envía un runCmd sincrono al IP especificado';
    to_RunCmdAsincrono                : result:= 'Envía un runCmd asincrono al IP especificado';
    to_TestUnoContraTodos             : result:= 'Hace un testUnoContraTodos envíando multiples mensajes y recibiendo respuestas desde este nodo';
    to_TestUnoContraTodos_Despachador : result:= 'Hace un testUnoContraTodos envíando multiples mensajes y recibiendo respuestas desde este nodo a traves de la clase TDespachador';
  end;
end;

function stringToTipoOrden(tipoOrden: String): tiposOrdenes;
begin
  tipoOrden:= AnsiLowerCase(tipoOrden);
  if tipoOrden = '/?' then result:= to_Ayuda
  else if tipoOrden = 'x2s' then result:= to_x2Sincrono
  else if tipoOrden = 'x2a' then result:= to_x2Asincrono
  else if tipoOrden = 'mas' then result:= to_testMemoAddSincrono
  else if tipoOrden = 'maa' then result:= to_testMemoAddAsincrono
  else if tipoOrden = 'cas' then result:= to_CloseAppSincrono
  else if tipoOrden = 'caa' then result:= to_CloseAppAsincrono
  else if tipoOrden = 'rcs' then result:= to_RunCmdSincrono
  else if tipoOrden = 'rca' then result:= to_RunCmdAsincrono
  else if tipoOrden = 'uct' then result:= to_TestUnoContraTodos
  else if tipoOrden = 'uctd' then result:= to_TestUnoContraTodos_Despachador
  else
    raise Exception.Create('Error, tipoOrden desconocido: ' + tipoOrden);
end;

function nParamsTipoOrden(tipoOrden: tiposOrdenes): Integer;
begin
  case tipoOrden of
    to_Ayuda                                                  : result:= 0;
    to_x2Sincrono, to_x2Asincrono                             : result:= 2;
    to_testMemoAddSincrono, to_testMemoAddAsincrono           : result:= 3;
    to_CloseAppSincrono, to_CloseAppAsincrono                 : result:= 2;
    to_RunCmdSincrono, to_RunCmdAsincrono                     : result:= 2;
    to_TestUnoContraTodos, to_TestUnoContraTodos_Despachador  : result:= 2;
    else
      result:= 0;
  end;
end;

function paramsTipoOrden(tipoOrden: tiposOrdenes): String;
begin
  case tipoOrden of
    to_x2Sincrono, to_x2Asincrono                             : result:= 'IP(string), x(integer)';
    to_testMemoAddSincrono, to_testMemoAddAsincrono           : result:= 'IP(string), s(string), testLongBuffer(boolean)';
    to_CloseAppSincrono, to_CloseAppAsincrono                 : result:= 'IP(string), nomApp(string)';
    to_RunCmdSincrono, to_RunCmdAsincrono                     : result:= 'IP(string), nomApp(string)';
    to_TestUnoContraTodos, to_TestUnoContraTodos_Despachador  : result:= 's(string), testLongBuffer(boolean)';
    else
      result:= '';
  end;
end;

{$IFNDEF LINUX}
{$R *.dfm}
{$ELSE}
{ Procedimientos agregados para el manejo de señales
del sistema.
   SIGALRM la usamos para el manejo de los timeout
   de los semáforos.}
var
  SActionRec: SigActionRec;

procedure Handler(Sig : Integer); cdecl;
begin
  writeln('--estoy en el Handler---');
  case Sig of
    SIGALRM:
    begin
//      umensajesretardados.tic_Barrer;
      exit;
    end;
    SIGINT, SIGTERM :
    begin
      writeln('--- recibi SIGINT o SIGTERM --- pongo recolectar=false ' );
      fTestNettopos.recolectar:= false;
      exit;
    end;
    //  SIGIO: writeln('SIGIO');
  end; { case }
end;

procedure InstallHandlers;
begin
 with SActionRec do
  begin
	sa_handler:= SigActionHandler(@Handler);
	fpsigemptyset(sa_mask);
	sa_flags:= 0;
	fpsigaction(SIGINT, @SActionRec, nil);
	fpsigaction(SIGTERM, @SActionRec, nil);
	fpsigaction(SIGALRM, @SActionRec, nil);
//   sigaction(SIGIO, @SActionRec, nil );
  end; { with }
//  umensajesretardados.IniciarBarridos;
end;
{$ENDIF}

function TfTestNettopos.getAyuda: String;
var
  i: tiposOrdenes;
  res: String;
begin
  res:= 'Comandos Posibles:' + #13#10;
  for i:= Low(tiposOrdenes) to high(tiposOrdenes) do
  begin
    res:= res + tipoOrdenToString(i) + ' ' + paramsTipoOrden(i) + ' - ' + descripcionTipoOrden(i) + #13#10;
  end;
  result:= res;    
end;

procedure TfTestNettopos.pedirX2Sincrono(ip: String; x: Integer);
var
  res: Integer;
begin
{$IFDEF WINDOWS}
  memoRes.Lines.Add('TfTestNettopos.pedirX2Sincrono: x= ' + IntToStr(x));
{$ENDIF}
  Writeln('TfTestNettopos.pedirX2Sincrono: x= ', x);
  res:= testeador.pedirX2Sincrono(IP4StrToCardinal(ip), x);
{$IFDEF WINDOWS}
  memoRes.Lines.Add(IntToStr(res));
{$ENDIF}
  Writeln('TfTestNettopos.pedirX2Sincrono: x2= ', res);
end;

procedure TfTestNettopos.pedirX2Asincrono(ip: String; x: Integer);
begin
{$IFDEF WINDOWS}
  memoRes.Lines.Add('TfTestNettopos.pedirX2Asincrono: x= ' + IntToStr(x));
{$ENDIF}
  Writeln('TfTestNettopos.pedirX2Asincrono: x= ', x);
  testeador.pedirX2Asincrono(IP4StrToCardinal(ip), x);
end;

procedure TfTestNettopos.msgr_PedirX2(var Msg: TMessage);
var
  res: Integer;
begin
  res:= testeador.recibirX2Asincrono(Msg);
{$IFDEF WINDOWS}
  memoRes.Lines.Add('TfTestNettopos.msgr_PedirX2: x2= ' + IntToStr(res));
{$ENDIF}
  Writeln('TfTestNettopos.msgr_PedirX2: x2= ', res);
end;

procedure TfTestNettopos.pedirTestMemoAddSincrono(ip: String; s: String; testearLongBuffer: Boolean);
var
  res: Cardinal;
begin
{$IFDEF WINDOWS}
  memoRes.Lines.Add('TfTestNettopos.pedirTestMemoAddSincrono: s= ' + s + ', testearLongBuffer= ' + BoolToStr(testearLongBuffer, true));
{$ENDIF}
  Writeln('TfTestNettopos.pedirTestMemoAddSincrono: s= ' + s + ', testearLongBuffer= ' + BoolToStr(testearLongBuffer, true));
  res:= testeador.pedirTestMemoAddSincrono(IP4StrToCardinal(ip), s, testearLongBuffer);
{$IFDEF WINDOWS}
  memoRes.Lines.Add('TfTestNettopos.pedirTestMemoAddSincrono: nBytesRecibidos= ' + IntToStr(res));
{$ENDIF}
  Writeln('TfTestNettopos.pedirTestMemoAddSincrono: nBytesRecibidos= ' + IntToStr(res));
end;

procedure TfTestNettopos.pedirTestMemoAddAsincrono(ip: String; s: String; testearLongBuffer: Boolean);
begin
{$IFDEF WINDOWS}
  memoRes.Lines.Add('TfTestNettopos.pedirTestMemoAddAsincrono: s= ' + s + ', testearLongBuffer= ' + BoolToStr(testearLongBuffer, true));
{$ENDIF}
  Writeln('TfTestNettopos.pedirTestMemoAddAsincrono: s= ' + s + ', testearLongBuffer= ' + BoolToStr(testearLongBuffer, true));
  testeador.pedirTestMemoAddAsincrono(IP4StrToCardinal(ip), s, testearLongBuffer);
end;

procedure TfTestNettopos.msgr_pedirTestMemoAdd(var Msg: TMessage);
var
  res: Cardinal;
begin
  res:= testeador.recibirTestMemoAddAsincrono(Msg);
{$IFDEF WINDOWS}
  memoRes.Lines.Add('TfTestNettopos.msgr_pedirTestMemoAdd: nBytesRecibidos= ' + IntToStr(res));
{$ENDIF}
  Writeln('TfTestNettopos.msgr_pedirTestMemoAdd: nBytesRecibidos= ' + IntToStr(res));
end;

procedure TfTestNettopos.pedirCloseAppSincrono(ip: String; nomApp: String);
var
  res: Integer;
begin
{$IFDEF WINDOWS}
  memoRes.Lines.Add('TfTestNettopos.pedirCloseAppSincrono: nomApp= ' + nomApp);
{$ENDIF}
  Writeln('TfTestNettopos.pedirCloseAppSincrono: IP= ' + ip + ', idNodo= ' + IntToStr(IP4StrToCardinal(ip)));
  Writeln('TfTestNettopos.pedirCloseAppSincrono: nomApp= ' + nomApp);
  res:= testeador.pedirCloseAppSincrono(IP4StrToCardinal(ip), nomApp);
{$IFDEF WINDOWS}
  memoRes.Lines.Add('TfTestNettopos.pedirCloseAppSincrono: res= ' + IntToStr(res));
{$ENDIF}
  Writeln('TfTestNettopos.pedirCloseAppSincrono: res= ' + IntToStr(res));
end;

procedure TfTestNettopos.pedirCloseAppAsincrono(ip: String; nomApp: String);
begin
{$IFDEF WINDOWS}
  memoRes.Lines.Add('TfTestNettopos.pedirCloseAppAsincrono: nomApp= ' + nomApp);
{$ENDIF}
  Writeln('TfTestNettopos.pedirCloseAppAsincrono: nomApp= ' + nomApp);
  testeador.pedirCloseAppAsincrono(IP4StrToCardinal(ip), nomApp);
end;

procedure TfTestNettopos.msgr_CloseApp(var Msg: TMessage);
var
  res: Integer;
begin
  res:= testeador.recibirCloseAppAsincrono(Msg);
{$IFDEF WINDOWS}
  memoRes.Lines.Add('TfTestNettopos.msgr_CloseApp: res= ' + IntToStr(res));
{$ENDIF}
  Writeln('TfTestNettopos.msgr_CloseApp: res= ' + IntToStr(res));
end;

procedure TfTestNettopos.pedirRunCmdSincrono(ip: String; binName: String);
var
  res: Integer;
begin
{$IFDEF WINDOWS}
  memoRes.Lines.Add('TfTestNettopos.pedirRunCmdSincrono: nomApp= ' + binName);
{$ENDIF}
  Writeln('TfTestNettopos.pedirRunCmdSincrono: IP= ' + ip + ', idNodo= ' + IntToStr(IP4StrToCardinal(ip)));
  Writeln('TfTestNettopos.pedirRunCmdSincrono: nomApp= ' + binName);
  res:= testeador.pedirRunCmdSincrono(IP4StrToCardinal(ip), binName);
{$IFDEF WINDOWS}
  memoRes.Lines.Add('TfTestNettopos.pedirRunCmdSincrono: res= ' + IntToStr(res));
{$ENDIF}
  Writeln('TfTestNettopos.pedirRunCmdSincrono: res= ' + IntToStr(res));
end;

procedure TfTestNettopos.pedirRunCmdAsincrono(ip: String; binName: String);
begin
{$IFDEF WINDOWS}
  memoRes.Lines.Add('TfTestNettopos.pedirRunCmdAsincrono: nomApp= ' + binName);
{$ENDIF}
  Writeln('TfTestNettopos.pedirRunCmdAsincrono: nomApp= ' + binName);
  testeador.pedirRunCmdAsincrono(IP4StrToCardinal(ip), binName);
end;

procedure TfTestNettopos.msgr_RunCmd(var Msg: TMessage);
var
  res: Integer;
begin
  res:= testeador.recibirRunCmdAsincrono(Msg);
{$IFDEF WINDOWS}
  memoRes.Lines.Add('TfTestNettopos.msgr_RunCmd: res= ' + IntToStr(res));
{$ENDIF}
  Writeln('TfTestNettopos.msgr_RunCmd: res= ' + IntToStr(res));
end;

procedure TfTestNettopos.pedirUnoContraTodosAsincrono(s: STring; testearLongBuffer: boolean);
begin
  testeador.pedirUnoContraTodosAsincrono(s, testearLongBuffer);
end;

procedure TfTestNettopos.pedirUnoContraTodosDespachador(s: STring; testearLongBuffer: boolean);
begin
  testeador.pedirUnoContraTodosDespachador(s, testearLongBuffer);
end;

procedure TfTestNettopos.msgp_PedirX2(var Msg: TMessage);
var
  comunicado: TFichaComunicado;
  datos: Pointer;
begin
  if leerFichaComunicado(msg.WParam, @comunicado) <> 0 then
  begin
    GetMem(datos, comunicado.nBytesDatos);
    if levantarDatosComunicado(msg.WParam, datos, comunicado.nBytesDatos) <> 0 then
    begin
      invertirComunicado(comunicado);
      comunicado.codigoMsg:= uMsgsTestNettopos.MSGR_PEDIRX2;
      Writeln('TfX2.msgp_PedirX2: x= ', IntToStr(Integer(datos^)));
      Integer(datos^):= Integer(datos^) * 2;

      if comunicar(@Comunicado, datos, 1000000) = 0 then
        logError('TfTestNettopos.msgp_PedirX2: no se pudo comunicar la respuesta');
    end
    else
      logError('TfTestNettopos.msgp_PedirX2: no se pudo levantar los datos del comunicado. idPeticion: ' + IntToStr(msg.WParam));

    assert( comunicado.nBytesDatos= sizeOf(Integer), 'msgp_PedirX2, comunicado.nBytesDatos <> 4');
    assert( datos <> nil, 'msgp_PedirX2, datos <> nil');
    if datos <> nil then
      FreeMem(datos, comunicado.nBytesDatos);
  end
  else
    logError('TfTestNettopos.msgp_PedirX2: no se pudo leer la ficha del comunicado. idPeticion: ' + IntToStr(msg.WParam));
end;

//EN DESARROLLO
procedure TfTestNettopos.msgp_testMemoAdd(var Msg: TMessage);
var
  comunicado: TFichaComunicado;
  datosEntrantes: TBuffReader;
  s: String;

  datosSalientes: TBuffWriter;
  res: Cardinal;
begin
  if leerFichaComunicado(msg.WParam, @comunicado) <> 0 then
  begin
    datosEntrantes:= TBuffReader.Create(comunicado.pdatos, comunicado.nBytesDatos);
    datosEntrantes.xString(s);
    datosEntrantes.Free;

    if levantarDatosComunicado(msg.WParam, nil, 0) <> 0 then
    begin
{$IFDEF WINDOWS}
      memoRes.Lines.Add('TfTestNettopos.msgp_testMemoAdd: s= ' + s);
{$ENDIF}
      writeln('TfTestNettopos.msgp_testMemoAdd: s= ', s);

      invertirComunicado(comunicado);
      comunicado.codigoMsg:= uMsgsTestNettopos.MSGR_TESTMEMOADD;
      res:= Length(s);
      comunicado.nBytesDatos:= xSizeOf(res);
      datosSalientes:= TBuffWriter.Create(comunicado.nBytesDatos);
      datosSalientes.xCardinal(res);

      if comunicar(@comunicado, datosSalientes.pBuff, trunc(timeOutComsCte + timeOutComsPorByte * comunicado.nBytesDatos)) = 0 then
        logError('TfTestNettopos.msgp_testMemoAdd: no se pudo comunicar la respuesta');
      datosSalientes.Free;
    end
    else
      logError('TfTestNettopos.msgp_testMemoAdd: no se pudo levantar los datos del comunicado. idPeticion: ' + IntToStr(msg.WParam));
  end
  else
    logError('TfTestNettopos.msgp_testMemoAdd: no se pudo leer la ficha del comunicado. idPeticion: ' + IntToStr(msg.WParam));
end;

procedure TfTestNettopos.msgp_PedirDelayedToUpperCase(var Msg: TMessage);
var
  comunicado: TFichaComunicado;
  datosEntrantes: TBuffReader;
  s: String;
  paraTestearDespachador: boolean;

  datosSalientes: TBuffWriter;
begin
  if leerFichaComunicado(msg.WParam, @comunicado) = 0 then
    raise Exception.Create('TfTestNettopos.msgp_PedirDelayedToUpperCase: no pude leer la ficha del comunicado');
  datosEntrantes:= TBuffReader.Create(comunicado.pdatos, comunicado.nBytesDatos);
  datosEntrantes.xString(s);
  datosEntrantes.xBoolean(paraTestearDespachador);
  datosEntrantes.Free;
  if levantarDatosComunicado(msg.WParam, nil, 0) = 0 then
    raise Exception.Create('TfTestNettopos.msgp_PedirDelayedToUpperCase: no pude levantar los datos del comunicado');
  Sleep(trunc(Random * tSleepDelayedToUpperCase + 0.5));
  s:= AnsiUpperCase(s);
  invertirComunicado(comunicado);
  if paraTestearDespachador then
    comunicado.codigoMsg:= uMsgsDespachador.MSGP_RECIBIR_RESPUESTA
  else
    comunicado.codigoMsg:= uMsgsTestNettopos.MSGR_DELAYED_TO_UPPER_CASE;
  comunicado.nBytesDatos:= xSizeOf(s);
  datosSalientes:= TBuffWriter.Create(comunicado.nBytesDatos);
  datosSalientes.xString(s);
  if comunicar(@comunicado, datosSalientes.pBuff, trunc(timeOutComsCte + timeOutComsPorByte * comunicado.nBytesDatos)) = 0 then
    raise Exception.Create('TfTestNettopos.msgp_PedirDelayedToUpperCase: no pude levantar los datos del comunicado');
  datosSalientes.Free;
end;

procedure TfTestNettopos.msgr_PedirPedirDelayedToUpperCase(var Msg: TMessage);
begin
  testeador.recibirDelayedToUpperCaseParaUnoContraTodos(Msg);
end;

procedure TfTestNettopos.recibirRespuesta(var Msg: TMessage);
begin
  testeador.despachador.recibirRespuesta(Msg);
end;

procedure TfTestNettopos.liberarRobot_TCU_Despachador(var MSG: TMessage);
begin
  testeador.msg_LiberarRobotTCU_Despachador(MSG);
end;

procedure TfTestNettopos.ejecutarOrden;
var
  orden: tiposOrdenes;
begin
  orden:= stringToTipoOrden(ParamStr(1));
  if ParamCount - 1 = nParamsTipoOrden(orden) then
  begin
    case orden of
      to_Ayuda                          : writeln(getAyuda);
      to_x2Sincrono                     : pedirX2Sincrono(ParamStr(2), StrToInt(ParamStr(3)));
      to_x2Asincrono                    : pedirX2Asincrono(ParamStr(2), StrToInt(ParamStr(3)));
      to_testMemoAddSincrono            : pedirTestMemoAddSincrono(ParamStr(2), ParamStr(3), StrToBool(ParamStr(4)));
      to_testMemoAddAsincrono           : pedirTestMemoAddAsincrono(ParamStr(2), ParamStr(3), StrToBool(ParamStr(4)));
      to_CloseAppSincrono               : pedirCloseAppSincrono(ParamStr(2), ParamStr(3));
      to_CloseAppAsincrono              : pedirCloseAppAsincrono(ParamStr(2), ParamStr(3));
      to_RunCmdSincrono                 : pedirRunCmdSincrono(ParamStr(2), ParamStr(3));
      to_RunCmdAsincrono                : pedirRunCmdAsincrono(ParamStr(2), ParamStr(3));
      to_TestUnoContraTodos             : pedirUnoContraTodosAsincrono(ParamStr(2), StrToBool(ParamStr(3)));
      to_TestUnoContraTodos_Despachador : pedirUnoContraTodosDespachador(ParamStr(2), StrToBool(ParamStr(3)));
    end;
  end
  else
    writeln('Error: la orden ' + ParamStr(1) + ' debe recibir los siguientes parametros ' + paramsTipoOrden(orden));
end;

{$IFDEF WINDOWS}
procedure TfTestNettopos.bPedirCloseAppAsincronoClick(Sender: TObject);
begin
  pedirCloseAppAsincrono(EIP.Text, eAppName.Text);
end;

procedure TfTestNettopos.bPedirCloseAppSincronoClick(Sender: TObject);
begin
  pedirCloseAppSincrono(EIP.Text, eAppName.Text);
end;

procedure TfTestNettopos.bPedirMemoAddAsincronoClick(Sender: TObject);
begin
  pedirTestMemoAddAsincrono(EIP.Text, Es.Text, cbTestLongBuffer.Checked);
end;

procedure TfTestNettopos.bPedirMemoAddSincronoClick(Sender: TObject);
begin
  pedirTestMemoAddSincrono(EIP.Text, Es.Text, cbTestLongBuffer.Checked);
end;

procedure TfTestNettopos.bPedirRunCmdAsincronoClick(Sender: TObject);
begin
  pedirRunCmdAsincrono(EIP.Text, eAppName.Text);
end;

procedure TfTestNettopos.bPedirRunCmdSincronoClick(Sender: TObject);
begin
  pedirRunCmdSincrono(EIP.Text, eAppName.Text);
end;

procedure TfTestNettopos.BPedirX2AsincronoClick(Sender: TObject);
begin
  pedirX2Asincrono(EIP.Text, StrToInt(Ex.Text));
end;

procedure TfTestNettopos.BPedirX2SincronoClick(Sender: TObject);
begin
  pedirX2Sincrono(EIP.Text, StrToInt(Ex.Text));
end;

procedure TfTestNettopos.bResultadosClick(Sender: TObject);
begin
  memoRes.Lines.Add(uTestNettoposHandler.escribirResultadosDelayedToUpperCase(
                                            testeador.recibidoPedirUnoContraTodosAsincrono,
                                            testeador.resultadosPedirUnoContraTodosAsincrono));  
end;

procedure TfTestNettopos.BTestUnoContraTodosAsincronoClick(Sender: TObject);
begin
  pedirUnoContraTodosAsincrono(Es.Text, cbTestLongBuffer.Checked);
end;

procedure TfTestNettopos.BTestUnoContraTodosDespachadorClick(Sender: TObject);
begin
  pedirUnoContraTodosDespachador(Es.Text, cbTestLongBuffer.Checked);
end;

procedure TfTestNettopos.BTestUnoContraTodosSincronoClick(Sender: TObject);
begin

end;

{$ENDIF}

{$IFDEF LINUX}
constructor TfTestNettopos.Create(AOwner: TComponent);
{$ELSE}
procedure TfTestNettopos.FormCreate(Sender: TObject);
{$ENDIF}
begin
{$IFDEF LINUX}
  inherited Create( AOwner );
  installHandlers;
  recolectar:= false;
{$ENDIF}
  inicializar;
{$IFDEF LINUX}
  registrarAplicacion(AppName, fpGetPid);
{$ELSE}
  registrarAplicacion(AppName, handle);
{$ENDIF}
  if idAplicYo = 0 then
  begin
    ShowMessage('Error al registrarme en la dll');
{$IFDEF WINDOWS}
    PostQuitMessage(0);
{$ENDIF}
  end
  else
  begin
    lanzarTopoLocal;
    testeador:= TTestNettoposHandler.Create;
    writeln('TestNettopos.idAplic= ', idAplicYo);
{$IFDEF LINUX}
    recolectar:= true;
{$ENDIF}
    if ParamCount > 0 then
      ejecutarOrden
{$IFDEF LINUX}
    else
      Writeln(getAyuda);
{$ENDIF}      
  end;
end;

{$IFDEF LINUX}
procedure TfTestNettopos.Free;
{$ELSE}
procedure TfTestNettopos.FormDestroy(Sender: TObject);
{$ENDIF}
begin
  testeador.Free;
  if idAplicYo > 0 then
    desregistrarAplicacion(idAplicYo);
  finalizar;
{$IFDEF LINUX}
  inherited Free;
{$ENDIF}
end;

end.
