unit uconstantes_nettopos;

{$IFDEF FPC}
  {$MODE Delphi}
{$ENDIF}

interface
uses
{$IFDEF LINUX}
   uEmuladorWinIPC, uWinMsgs, baseunix;
{$ELSE}
   messages, windows;
{$ENDIF}

const
{$IFDEF LINUX}
  BinName = 'topo';
{$ELSE}
  BinName = 'topo.exe';
{$ENDIF}

  AppName_Topo = 'topo';

  sleepComs = 50;
  MAX_REINTENTOS_COMUNICACION = 2;
  timeOutComsCte = 1500;
  timeOutComsPorByte = 1.2 * 1.0E3 / ( 128 *1024 / 8 ); //Un byte puede tardar timeOutComsPorByte milisegundos
                            //La comunicación podrá tardar a lo sumo
                            //timeOutComsCte + timeOutComsPorByte * nBytes milisegundos
  charIndentacion = '  ';
  formatoFechasConMSecs = 'hh:mm:ss.zzz';

  PuertoTopo= 2010;

  nom_Smf_Peticiones = 'smf_Peticiones';
  nom_Smf_Aplics = 'smf_Aplics';
  nom_Smf_NextNIDPeticion = 'smf_NextNIDPeticion';
  nom_Smf_DbgLog = 'smf_archiDbgLog';
  nom_Smf_ErrLog = 'smf_archiErrLog';
  //para comunicarse a traves de un socket en una ficha de conexion se pedira un
  //mutex de nombre base_nom_Smf_Conexion + getCurrentProcessId + i, con i el indice
  //de la ficha en la lista
  base_nom_Smf_Conexion = 'base_nom_Smf_Conexion';
  nom_SharedMem = 'NetTopos_SharedMem';
  nom_Smf_ListaConexiones = 'smf_ListaConexiones';
  nom_Smf_CntDBG = 'smf_CntDBG';
  nom_Smf_topo_tareassincronas = 'smf_topo_tareassincronas';  

  nom_smf_initfin_nettopos = 'smf_initfin_nettopos';
  nom_smf_get_lanzar_topo = 'smf_get_lanzar_topo';

  nom_smf_mens_retardados = 'smf_mens_retardados';

  ERROR_NoConseguiSemaforo = -1;
  ERROR_NombreAplicacionRepetido = -2;
  ERROR_NoEncontreAplicacion = -3;
  ERROR_NoHayPeticionesLibres = -4;
  ERROR_FalloPostMessage = -5;
  ERROR_LargoBufferLecturaInsuficiente= -6;
  ERROR_idAplicacion_NoEncontrado= -7;
  ERROR_idPeticion_NoEncontrado= -8;
  ERROR_idAplicacionNulo= -9;
  ERROR_NoHayAplicacionesLibres= -10;
  ERROR_NoHayTopoLocalRegistrado= -11;
  ERROR_FALTA_IMPLEMENTAR= -12;
  ERROR_TamanioDeBufferInsuficienteParaLosDatos= -13;
  ERROR_SupereElTiempoDeEsperaAsignado = -14;
  ERROR_IntentoDeDesregistrarOtraAplicacion = -15;
  ERROR_CreandoLongBufferPeticion= -16;
  ERROR_mapLongBuffer= -17;
  ERROR_FALLO_REWRITE= -18;
  ERROR_FALLO_RESET= -19;
  ERROR_FALLO_BLOCKREAD= -20;
  ERROR_FALLO_BLOCKWRITE= -21;
  ERROR_LARGO_COMUNICADOS= -22;
  ERROR_FALLO_DELETEFILE= -23;
  ERROR_FM_INVALIDO= -24;
  ERROR_NO_SE_PUDO_TRAER_EL_COMUNICADO_DESDE_LA_DLL= -25;
  ERROR_FalloComunicarRemoto = -26;
  ERROR_NO_SE_PUDO_TRAER_LOS_DATOS_DEL_COMUNICADO_DESDE_LA_DLL= -27;
  ERROR_Comunicar_NoHayBloqueLongBufferLibre = -28;
  ERROR_Comunicar_MAX_SIZE_BUFFER_CHICO_insuficiente = -29;

{$IFDEF LINUX}
  WM_CLOSE= WM_USER - 1;
{$ENDIF}

  WM_TOPO_GET_APLICID= WM_USER +2002;
  MSGP_TOPO_MEMO_ADD= WM_USER + 2003;
  WM_TOPO_MEMO_CLEAR= WM_USER + 2004;
  WM_TOPO_FILE_EXIST= WM_USER+2005;
  WM_TOPO_LANZAR= WM_USER + 2006;
  WM_TOPO_GETNOW= WM_USER + 2007;
//  MSG_EJECUTAR_TS= WM_USER + 2008;
  MSG_RESPUESTA_TS= WM_USER + 2009;
  MSGP_GET_NAPLICS= WM_USER + 2010;
  MSGP_DUMPAPLICS= WM_USER + 2011;
  MSGP_GETIDAPLICBYNAME= WM_USER + 2012;

  //params: ninguno
  //retorna: res: TDAOfNCardinal
  //Retorna los identificadores de los nodos contenidos en la lista nodos
  MSGP_GETNODOS= WM_USER+ 2013;
  MSGP_GETNAMEAPLICBYID= WM_USER + 2014;

  //params: nombreAplic: String
  //retorna: res: Integer;
  //         [msjError: String]
  //Busca en la lista de aplicaciones conocidas la aplicacion de nombre nombreAplic
  //e intenta ejecutarla.
  //Si la encuentra y la puede ejecutar res = 1 y no va msjError
  //Si la encuentra y no la puede ejecutar res = 0 y no va msjError
  //Si no la encuentra res = -1 y en msjError va un string indicando el problema
  MSGP_RUNCMD= WM_USER + 2015;
  //params: nombreAplic: String
  //retorna: res: Integer;
  //Busca en la lista de aplicaciones conocidas la aplicacion de nombre nombreAplic
  //e intenta cerrarla.
  //Si la encuentra y la puede cerrar res = 1
  //Si no la encuentra res = 0
  //Si la encuentra y no la puede cerrar res = -1  
  MSGP_CLOSEAPP= WM_USER + 2016;
  MSGx_TOPO_MEMO_ADD_SINCRONO= WM_USER + 2017;
  MSGR_TOPO_MEMO_ADD= WM_USER + 2018;

  MSGP_ArchiWRITE= WM_USER + 2025;
  MSGP_ArchiREAD= WM_USER + 2026;
  MSGP_ArchiLIST= WM_USER + 2027;
  MSGP_ArchiDELETE= WM_USER + 2028;


  MSGP_AppConocida = WM_USER + 2030;

  MSGP_MensajeRetardado = WM_USER + 2031;

  MSGP_PUNTITO = WM_USER + 2032;
  MSGP_APLIC_CLOSING = WM_USER + 2033;


  // mensajes de respuesta
  MSGR_NAPLICS= MSGP_GET_NAPLICS +2000;
  MSGR_DUMPAPLICS= MSGP_DUMPAPLICS + 2000;
  MSGR_TOPO_GETIDAPLICBYNAME= MSGP_GETIDAPLICBYNAME + 2000;
  MSGR_GETNAMEAPLICBYID= MSGP_GETNAMEAPLICBYID+ 2000;
  MSGR_GETNODOS= MSGP_GETNODOS+ 2000;
  MSGR_RUNCMD= MSGP_RUNCMD + 2000;
  MSGR_CLOSEAPP= MSGP_CLOSEAPP + 2000;
  MSGR_ArchiWRITE= MSGP_ArchiWRITE + 2000;
  MSGR_ArchiREAD= MSGP_ArchiREAD + 2000;
  MSGR_ArchiLIST= MSGP_ArchiLIST + 2000;
  MSGR_ArchiDELETE= MSGP_ArchiDELETE + 2000;

  MSGR_AppConocida = MSGP_AppConocida + 2000;

  FM_CREATE= 1; // crea con rewrite el archivo y escribe desde la posición CERO
  FM_WRITE= 2; // intenta escribir en la psición indicada, puede venir con FM_FILL
  FM_APPEND= 4; // intenta agregar al archivo si no existe lo crea
  FM_FILL= 8; // Rellena con ceros los bloques que falten para poder escribir
  FM_READALL= 16; // lee el resto del archivo desde la posición indicada.
  FM_READ= 32; // lee los bytes indicados desde la posición indicada.

var
  dirBase, dir_workers, dir_temp: string;
  archiListadoDeTopos, archiListadoDeAplicacionesConocidas,
  ARCHI_GLOBAL_NID,
  ARCHI_DBGLOG, ARCHI_ERRLOG,
  ARCHI_ROSX_CFG: String;
{$IFDEF NID_PETICION_CON_PERMANENCIA}
  ARCHI_NEXT_NID_PETICION: String;
{$ENDIF}

function getNetTopos_StrError( codigo: integer ): pchar; stdcall;
(*+doc
Crea una cadena para que sirva de nombre para un semáforo en función
del nombre de un archivo. agrega 'smf_' al inicio y cambia las barras
'\' por 'X'
-doc*)
//function  ArchiSMFName( const archi: string ): string;
implementation
(*

function ArchiSMFName( const archi: string ): string;
var
  s: string;
  I: integer;
begin
  s:= 'smf_'+archi;
  for I := 5 to length( s ) do
    if s[I]='\' then s[I]:= 'X';
  result:= s;
end;
  *)

function getNetTopos_StrError( codigo: integer ): pchar; stdcall;
begin
  case codigo of
    ERROR_NoConseguiSemaforo: result:= 'No conseguí el semáforo.';
    ERROR_NombreAplicacionRepetido: result:= 'Nombre de aplicación repetido.';
    ERROR_NoEncontreAplicacion: result:= 'No encontré la aplicación.';
    ERROR_NoHayPeticionesLibres: result:= 'No hay fichas de peticiones libres.';
    ERROR_FalloPostMessage: result:= 'Falló PostMessage. ';
    ERROR_LargoBufferLecturaInsuficiente: result:= 'Largo de buffer de lectura insuficiente.';
    ERROR_idAplicacion_NoEncontrado: result:= 'Id de aplicación no encontrado.';
    ERROR_idPeticion_NoEncontrado: result:= 'Id de la petición no encontrado.';
    ERROR_idAplicacionNulo: result:= 'Id aplicación NULO.';
    ERROR_NoHayAplicacionesLibres: result:= 'No hay fichas de aplicaciones libres.';
    ERROR_NoHayTopoLocalRegistrado: result := 'No hay topo local registrado';
    ERROR_FALTA_IMPLEMENTAR: result:= 'Falta Implementar';
    ERROR_TamanioDeBufferInsuficienteParaLosDatos: result:= 'Tamanio De Buffer Insuficiente Para Los Datos';
    ERROR_SupereElTiempoDeEsperaAsignado: result:= 'Supere El Tiempo De Espera Asignado';
    ERROR_IntentoDeDesregistrarOtraAplicacion: result:= 'Intento De Desregistrar Otra Aplicacion';
    ERROR_CreandoLongBufferPeticion: result:= 'No pude crear LongBuffer para una petición.';
    ERROR_mapLongBuffer: result:= 'Falló al mapear un LongBuffer para una petición.';
    ERROR_FALLO_REWRITE: result:= 'ERROR_FALLO_REWRITE';
    ERROR_FALLO_RESET: result:= 'ERROR_FALLO_RESET';
    ERROR_FALLO_BLOCKREAD: result:= 'ERROR_FALLO_BLOCKREAD';
    ERROR_FALLO_BLOCKWRITE: result:= 'ERROR_FALLO_BLOCKWRITE';
    ERROR_LARGO_COMUNICADOS: result:= 'ERROR_LARGO_COMUNICADOS';
    ERROR_FALLO_DELETEFILE: result:= 'ERROR_FALLO_DELETEFILE';
    ERROR_FM_INVALIDO: result:= 'ERROR_FM_INVALIDO';
    ERROR_NO_SE_PUDO_TRAER_EL_COMUNICADO_DESDE_LA_DLL: result:= 'ERROR_NO_SE_PUDO_TRAER_EL_COMUNICADO_DESDE_LA_DLL';
    ERROR_NO_SE_PUDO_TRAER_LOS_DATOS_DEL_COMUNICADO_DESDE_LA_DLL: result:= 'ERROR_NO_SE_PUDO_TRAER_LOS_DATOS_DEL_COMUNICADO_DESDE_LA_DLL';
    ERROR_FalloComunicarRemoto : result:= 'ERROR_FalloComunicarRemoto';
    ERROR_Comunicar_NoHayBloqueLongBufferLibre:  result:= 'ERROR Comunicar No hay bloque de memoria libre para LongBuffer';
  else
    result:= 'Codigo de error desconocido.';
  end;
end;

procedure initArchis;
begin
{$IFDEF LINUX}
  dirbase:= fpgetenv('HOME') + '/nettopos/rundir';
{$ELSE}
  dirbase:= '\nettopos\rundir';
{$ENDIF}
  ARCHI_ROSX_CFG := dirbase + DirectorySeparator+ 'config'+ DirectorySeparator + 'nettopos_rosx.cfg';
  archiListadoDeTopos:= dirbase + DirectorySeparator + 'config' + DirectorySeparator + 'listadoDeTopos.txt';
  ARCHI_GLOBAL_NID:= dirbase + DirectorySeparator + 'config' + DirectorySeparator + 'global_nid.txt';
  archiListadoDeAplicacionesConocidas:= dirbase + DirectorySeparator + 'config' + DirectorySeparator + 'listadoAplicacionesConocidas.txt';
  ARCHI_DBGLOG:= dirbase + DirectorySeparator + 'archlogs' + DirectorySeparator + 'dbglog.log';
  ARCHI_ERRLOG:= dirbase + DirectorySeparator + 'archlogs' + DirectorySeparator + 'errorlog.log';
{$IFDEF NID_PETICION_CON_PERMANENCIA}
  ARCHI_NEXT_NID_PETICION:= dirbase + DirectorySeparator + 'nextnidpeticion.nid';
{$ENDIF}
end;

initialization
  initArchis;


end.
