private void EnviarJobBloqueImagenes(string HHID, string dataLength, byte[] dataBytes, byteArrayEventArgs e)
        {
            // Espero señal para enviar imagenes
            if (!e.stateObject.masImagenes) EsperaProximoPedidoImagenes(e.stateObject);

            if (!e.stateObject.abortFlag)
            {
                try
                {
                    dataLength = dataLength.Trim(',');  // Quito la última coma

                    // Armo el trabajo a enviar si el HH está conectado
                    if (mainApp.ComunicationSystem.communicationLAYER.isPannelConnected(HHID))
                    {
                        dataLength = Encriptar_Datos.Encriptar.encriptar(dataLength, communicationSystem.ClaveEncriptar);
                        byte[] dataLengthBytes = Encoding.ASCII.GetBytes(dataLength);

                        int chunkSize = FIXED_HEADER_LENGTH + dataLengthBytes.Length + dataBytes.Length;

                        string header = "TYPE:IMGLIST,SIZE:" + chunkSize.ToString() + ",IDLENGTH:" + dataLengthBytes.Length.ToString();

                        // Nuevo: Encriptado de datos.
                        string headerEncriptado = Encriptar_Datos.Encriptar.encriptar(header, communicationSystem.ClaveEncriptar);
                        headerEncriptado = "SIZE:" + chunkSize.ToString() + ",DATA:" + headerEncriptado;

                        string finalHeader = headerEncriptado.PadRight(FIXED_HEADER_LENGTH);
                        byte[] headerBytedata = Encoding.ASCII.GetBytes(finalHeader);

                        byte[] dataToSend = new byte[finalHeader.Length + dataLengthBytes.Length + dataBytes.Length];
                        System.Buffer.BlockCopy(headerBytedata, 0, dataToSend, 0, headerBytedata.Length);
                        System.Buffer.BlockCopy(dataLengthBytes, 0, dataToSend, headerBytedata.Length, dataLengthBytes.Length);
                        System.Buffer.BlockCopy(dataBytes, 0, dataToSend, headerBytedata.Length + dataLengthBytes.Length, dataBytes.Length);

                        JobToSendToClient j = new JobToSendToClient();

                        jobCounter++;
                        j.ID = jobCounter;
                        j.header = headerEncriptado;
                        j.byteData = dataToSend;

                        e.stateObject.pendingJobs.Enqueue(j);     // Nuevo: un pendingjobs por cada cliente.
                        e.stateObject.readyToSend.Set();
                        loguearString(HHID + "- ENVIADO TRABAJO Bloque de imágenes, largo: " + chunkSize.ToString(), TiposLOG.HH);
                    }
                }

                catch (Exception ex) { loguearString("Problema en EnviarJobBloqueImagenes: " + ex.Message, TiposLOG.HH); }
            }
        }
        void enviarListaImagenes(object sender, byteArrayEventArgs e)
        {
            loguearString(e.stateObject.HHID + " RECIBIO PEDIDO DE LISTA DE IMAGENES", TiposLOG.LENEL);
            Thread t = new Thread(() => ThreadLoopBloqueImagenes(e));
            t.Name = "ThreadLoopBloqueImagenes";
            t.Start();

            //try
            //{
            //    loguearString("RECIBIO PEDIDO DE LISTA DE IMAGENES", TiposLOG.ALUTRACK);
            //    if (e.byteData == null) return;

            //    socketServerGeneral.masImagenes = true; // Seteo indicador para enviar primer bloque de imagenes

            //    // Identifico los ID de las imagenes a enviar
            //    string dataID = Encriptar_Datos.Encriptar.desencriptar(Encoding.ASCII.GetString(e.byteData, 0, e.byteData.Length), communicationSystem.ClaveEncriptar);
            //    string[] IDs = dataID.Split(',');
            //    string HHID = e.textData["HHID"];

            //    // Se envían paquetes de 'cantImagenes' imagenes
            //    int cantImagenes = 100;
            //    int indice = 1; // Representa la cantidad de imagenes que se agregaron en el buffer

            //    byte[] dataBytes = new byte[0];
            //    byte[] aux = new byte[0];
            //    string dataLength = string.Empty;   // Va a contener el largo de cada imagen con el formato: " PersonID:VersionImagen:largoImagen "

            //    byte[] imageBytes;

            //    string imgver;
            //    string Imagen;

            //    for (int i = 0; i < IDs.Length; i++)
            //    {
            //        // Obtener los datos de la imagen
            //        Imagen = mainApp.DataManager.cargarPathImagen(IDs[i]);
            //        imgver = mainApp.DataManager.cargarVersionImagen(IDs[i]);
            //        string fileName = Path.GetFileName(Imagen);
            //        string imagePath = SystemConfiguration.ImagesPath;
            //        try
            //        {
            //            imageBytes = File.ReadAllBytes(imagePath + @"/" + fileName);

            //            // Agrego el largo al dataLength
            //            dataLength += IDs[i] + ':' + imgver + ':' + imageBytes.Length + ',';

            //            // Agrego los datos bytes nuevos a dataBytes
            //            aux = dataBytes;
            //            dataBytes = new byte[aux.Length + imageBytes.Length];
            //            System.Buffer.BlockCopy(aux, 0, dataBytes, 0, aux.Length);
            //            System.Buffer.BlockCopy(imageBytes, 0, dataBytes, aux.Length, imageBytes.Length);

            //            indice++;
            //        }
            //        catch { /* Entra acá cuando el empleado no tiene imagen */ }

            //        // Si el tamaño del buffer a enviar supera los 3 Mb (aprox), enviar el bloque y limpiar para el proximo envio
            //        if (dataBytes.Length > 2000000)
            //        {
            //            EnviarJobBloqueImagenes(HHID, dataLength, dataBytes, e);
            //            // Limpio los datos
            //            dataBytes = new byte[0];
            //            aux = new byte[0];
            //            dataLength = string.Empty;

            //            socketServerGeneral.masImagenes = false;
            //        }

            //        // Si es multiplo de 10 ó si alcanzó el final de IDs debe mandar el trabajo y limpiar los datos para armar el header nuevo
            //        //if (i == IDs.Length - 1 || (indice % cantImagenes) == 0)
            //        //{
            //        //    EnviarJobBloqueImagenes(HHID, dataLength, dataBytes, e);

            //        //    // Limpio los datos
            //        //    dataBytes = new byte[0];
            //        //    aux = new byte[0];
            //        //    dataLength = string.Empty;
            //        //}
            //    }

            //    if (!dataLength.Equals(string.Empty)) EnviarJobBloqueImagenes(HHID, dataLength, dataBytes, e);
            //}
            //catch (Exception ex) { loguearString("Problema en enviarListaImagenes: " + ex.Message, TiposLOG.ALUTRACK); }
        }
        private void addConfirmVisitJob(byteArrayEventArgs e)
        {
            int chunkSize = FIXED_HEADER_LENGTH;
            string header = "TYPE:CONFIRMVISIT,SIZE:" + chunkSize.ToString() + ",ID:" + e.textData["ID"];

            // Nuevo: Encriptado de datos.
            string headerEncriptado = Encriptar_Datos.Encriptar.encriptar(header, communicationSystem.ClaveEncriptar);
            headerEncriptado = "SIZE:" + chunkSize.ToString() + ",DATA:" + headerEncriptado;

            string finalHeader = headerEncriptado.PadRight(FIXED_HEADER_LENGTH);
            byte[] headerBytedata = Encoding.ASCII.GetBytes(finalHeader);

            byte[] dataToSend = new byte[finalHeader.Length];
            System.Buffer.BlockCopy(headerBytedata, 0, dataToSend, 0, headerBytedata.Length);

            JobToSendToClient j = new JobToSendToClient();

            jobCounter++;
            j.ID = jobCounter;
            j.header = headerEncriptado;
            j.byteData = dataToSend;

            e.stateObject.pendingJobs.Enqueue(j);     // Nuevo: un pendingjobs por cada cliente.
            e.stateObject.readyToSend.Set();
            loguearString(e.stateObject.HHID + "- Agregado trabajo de CONFIRMACION de VISITA con ID: " + e.textData["ID"], TiposLOG.HH);
        }
 void enviarEmpxVersion(object sender, byteArrayEventArgs e)
 {
     Thread t = new Thread(() => ThreadEnviarEmpxVersion(e));
     t.Name = "ThreadEnviarEmpxVersion";
     t.Start();
 }
        // Acualiza los datos en funcion de un evento de visita
        void actualizeVisit(object sneder, byteArrayEventArgs e)
        {
            Visita nuevaVisita = new Visita(e.textData["HHID"], e.textData["NOMBRE"], e.textData["APELLIDO"], e.textData["DOCUMENTO"], e.textData["EMPRESA"], e.textData["TARJETA"], e.textData["LATITUD"], e.textData["LONGITUD"], e.textData["HORA"], e.byteData, (TiposAcceso)Enum.Parse(typeof(TiposAcceso), e.textData["TIPOACCESO"]),int.Parse(e.textData["ORGID"]));
            if (!mainApp.DataManager.existeVisita(nuevaVisita))
            {

                mainApp.DataManager.addVisita(nuevaVisita);

                actualizeListViewVisitas = true;
            }
            addConfirmVisitJob(e);
        }
        void actualizeAcccess(object sender, byteArrayEventArgs e)
        {
            // Dar de alta el acceso en la lista de accesos
            Dictionary<int,Acceso> listaAccesos = mainApp.DataManager.getListaAccesos();

            string tarjeta = e.textData["TARJETA"];

            Employee emp = mainApp.DataManager.buscarEmpleadoxTarjeta(tarjeta);

            if (emp != null)
            {
                int idEmpleado = emp.Id;

                Acceso nuevoAcceso = new Acceso(idEmpleado, e.textData["HHID"], e.textData["TARJETA"], e.textData["LATITUD"], e.textData["LONGITUD"], e.textData["HORA"], e.byteData, (TiposAcceso)Enum.Parse(typeof(TiposAcceso), e.textData["TIPOACCESO"]));
                if (!mainApp.DataManager.existeAcceso(nuevoAcceso))
                {
                    mainApp.DataManager.addAcceso(nuevoAcceso);
                    actualizeListView = true;
                }
            }
            addConfirmJob(e);
        }
        private void ThreadLoopBloqueImagenes(byteArrayEventArgs e)
        {
            try
            {

                if (e.byteData == null) return;

                e.stateObject.masImagenes = true; // Seteo indicador para enviar primer bloque de imagenes

                // Identifico los ID de las imagenes a enviar
                string dataID = Encriptar_Datos.Encriptar.desencriptar(Encoding.ASCII.GetString(e.byteData, 0, e.byteData.Length), communicationSystem.ClaveEncriptar);
                string[] IDs = dataID.Split(',');
                string HHID = e.textData["HHID"];

                int indice = 1; // Representa la cantidad de imagenes que se agregaron en el buffer

                byte[] dataBytes = new byte[0];
                byte[] aux = new byte[0];
                string dataLength = string.Empty;   // Va a contener el largo de cada imagen con el formato: " PersonID:VersionImagen:largoImagen "

                byte[] imageBytes;

                string imgver;
                string Imagen;
                int cantImagenesEnviadas = 0;
                int cantImagenesEnBloque=0;        // Contador de la cantidad de imagenes en cada bloque: dato para loguear solamente

                for (int i = 0; i < IDs.Length; i++)
                {
                    if (e.stateObject.abortFlag)
                    {
                        break;
                    }
                    // Obtener los datos de la imagen
                    Imagen = mainApp.DataManager.cargarPathImagen(IDs[i]);
                    imgver = mainApp.DataManager.cargarVersionImagen(IDs[i]);
                    string fileName = Path.GetFileName(Imagen);
                    string imagePath = SystemConfiguration.ImagesPath;
                    try
                    {
                        imageBytes = File.ReadAllBytes(imagePath + @"/" + fileName);

                        // Agrego el largo al dataLength
                        dataLength += IDs[i] + ':' + imgver + ':' + imageBytes.Length + ',';

                        // Agrego los datos bytes nuevos a dataBytes
                        aux = dataBytes;
                        dataBytes = new byte[aux.Length + imageBytes.Length];
                        System.Buffer.BlockCopy(aux, 0, dataBytes, 0, aux.Length);
                        System.Buffer.BlockCopy(imageBytes, 0, dataBytes, aux.Length, imageBytes.Length);

                        indice++;
                    }
                    catch { /* Entra acá cuando el empleado no tiene imagen */ }

                    cantImagenesEnviadas++;
                    cantImagenesEnBloque++;
                    // Si el tamaño del buffer a enviar supera los 2 Mb (aprox), enviar el bloque y limpiar para el proximo envio
                    if (dataBytes.Length > 2000000)
                    {
                        loguearString("Va a enviar " + cantImagenesEnBloque + " imagenes. Total enviadas: " + cantImagenesEnviadas + " de " + IDs.Length, TiposLOG.HH);

                        EnviarJobBloqueImagenes(HHID, dataLength, dataBytes, e);
                        // Limpio los datos
                        dataBytes = new byte[0];
                        aux = new byte[0];
                        dataLength = string.Empty;

                        e.stateObject.masImagenes = false;
                        cantImagenesEnBloque = 0;
                    }

                }

                if (!dataLength.Equals(string.Empty) && !e.stateObject.abortFlag)
                {
                    EnviarJobBloqueImagenes(HHID, dataLength, dataBytes, e);
                    e.stateObject.masImagenes=false;
                }

                if (!e.stateObject.abortFlag)
                {
                    // Espero señal para enviar el ultimo FinSync
                    if (!e.stateObject.masImagenes) EsperaProximoPedidoImagenes(e.stateObject);

                    EnviarJobFinSync(HHID, e.stateObject);
                }
            }
            catch (Exception ex) { loguearString("Problema en enviarListaImagenes: " + ex.Message, TiposLOG.HH); }
        }
        void ThreadEnviarEmpxVersion(byteArrayEventArgs e)
        {
            try
            {
                if (e.byteData == null) return;

                // Identifico los ID a enviar
                string dataID = Encriptar_Datos.Encriptar.desencriptar(Encoding.ASCII.GetString(e.byteData, 0, e.byteData.Length), communicationSystem.ClaveEncriptar);
                string[] IDs = dataID.Split(',');
                string HHID = e.textData["HHID"];

                loguearString(e.stateObject.HHID + " Pide "+IDs.Length.ToString() +" empleados x Version", TiposLOG.LENEL);

                // Obtengo los datos de los empleados con el ID y los agrego a la lista para enviar
                string aux = string.Empty;
                string dataEmp = " ";       // Obligatorio, Comenzar con espacio
                string isAdmin_BETA = "true";
                string passWord_BETA = "alutel";
                int i;
                for (i = 0; i < IDs.Length; i++)
                {
                    if (e.stateObject.abortFlag)
                    {
                        break;
                    }

                    // Cargo los datos del empleado
                    Employee emp = mainApp.DataManager.buscarEmpleadoxPersonIDenBD(IDs[i]);

                    Tarjeta t = mainApp.DataManager.buscarTarjetadeEmpleado(emp.Id);
                    // Solo se envia la info de un empleado si tiene tarjeta asociada y algun accesslevel asociado
                    if ((t == null)) loguearString("El empleado con personID = " + IDs[i] + " no tiene tarjeta asociada", TiposLOG.HH);
                    else
                    {
                        string accessLevels = AccessLevelLogic.getAccessLevelsByBadgeInHH(t.NUMERODETARJETA, HHID);

                        // Agrego los datos a dataEmp
                        if (accessLevels.Trim().Length > 0)
                        {
                            aux += "TARJETA:" + t.NUMERODETARJETA + ",NOMBRE:" + emp.Nombre + ",APELLIDO:" + emp.Apellido + ",DOCUMENTO:" + emp.NumeroDocumento + ",EMPRESA:" + emp.Empresa + ",ACCESO:" + t.ESTADO.ToString() + ",ADMIN:" + isAdmin_BETA + ",PASS:"******",ACCESSID:" + accessLevels + ",VERSION:" + emp.VersionEmpleado.ToString() + ",PERSONID:" + emp.PersonID.ToString() + '|';
                            if ( (i!=0) && (i%5000 == 0) )
                            {
                                dataEmp += Encriptar_Datos.Encriptar.encriptar(aux, communicationSystem.ClaveEncriptar) + ' ';
                                aux = string.Empty;
                            }
                        }
                    }
                }
                if (!e.stateObject.abortFlag)
                {
                    if (!aux.Equals(string.Empty))
                    {
                        dataEmp += Encriptar_Datos.Encriptar.encriptar(aux, communicationSystem.ClaveEncriptar);
                    }

                    loguearString( "Server va a enviar BloqueEmpleados con " + i.ToString() + " empleados a: "+e.stateObject.HHID, TiposLOG.LENEL);

                    enviarBloqueEmpleados(dataEmp, HHID, e.stateObject);
                }
            }
            catch (Exception ex) { loguearString("Excepción en ThreadEnviarEmpxVersion: " + ex.Message, TiposLOG.HH); }
        }
        //
        /// <summary>
        /// AddJobs:  Reconoce de Headers y responde en consecuencia
        /// </summary>
        /// <param name="v_header"></param>
        /// <param name="v_byteData"></param>
        /// <param name="v_state"></param>
        public void AddJobs(string v_header, byte[] v_byteData, StateObject v_state)
        {
            Match matchHeader;
            byte[] finalBuffer = v_byteData;
            string retMessage = "";
            string resConnectMessage = "";

            // RECIBI un registro GPS
            // NUEVO EN VERSION 1.3: Se conecta al alutrack via ALUTRACK LAYER
            matchHeader = GPSdata.Match(v_header);
            if (matchHeader.Success)
            {
                loguearString(v_header);        // Loguea el GPS

                string HHID = getMatchData(matchHeader, 1).Trim();
                string latitud = getMatchData(matchHeader, 3).Trim();
                string longitud = getMatchData(matchHeader, 4).Trim();
                string hora = getMatchData(matchHeader, 5).Trim();
                string heading = getMatchData(matchHeader, 6).Trim();
                string speed =getMatchData(matchHeader, 7).Trim();

                stringEventArgs retorno = new stringEventArgs(v_header, v_state);
                retorno.textData.Add("HHID", HHID);
                retorno.textData.Add("LATITUD", latitud);
                retorno.textData.Add("LONGITUD", longitud);
                retorno.textData.Add("HORA", hora);

                // Actualiza la base LOCAL con los GPS, chequea los accesos a zonas y da de alta eventos de acceso en caso de Entrada/Salida.
                this.actualizeGPSData(this, retorno);

                mainApp.DataManager.actualizarUltimaPosGPS(latitud, longitud, hora, HHID);

                //********************************************
                // Conexion al layer ALUTRACK: Alutracklayer
                //********************************************

                if (!HHGPSLayer.isConnected(HHID))
                {
                    if (HHGPSLayer.conectar(HHID, out resConnectMessage))
                    {
                       // loguearString("HandHeld: " + HHID + " conectado al ALUTRACK LAYER");
                        if (HHGPSLayer.sendGPSData(HHID, latitud, longitud, hora, heading, speed, out retMessage))
                        {
                         //   loguearString(HHID + " envio GPS(" + latitud + "," + longitud + ") al ALUTRACK LAYER");
                        }
                        else
                        {
                           // loguearString("Error al enviar GPS desde el HH: " + HHID + ", error: " + retMessage + ". Desconectando...");
                            HHGPSLayer.desconectar(HHID);
                           // loguearString("HH: " + HHID + "desconectado");
                        }
                    }
                    else // No se pudo conectar...
                    {
                       // loguearString("Error al conectar HHID: " + HHID + "- " + resConnectMessage);
                    }
                }
                else
                {
                    if (HHGPSLayer.sendGPSData(HHID, latitud, longitud, hora, heading, speed, out retMessage))
                    {
                        loguearString(HHID + " envio GPS(" + latitud + "," + longitud + ") al ALUTRACK LAYER");
                    }
                    else
                    {
                        //loguearString("Error al enviar GPS desde el HH: " + HHID + " Error: " + retMessage);
                    }
                }

                return;
            }

            // RECIBI DUMMY
            //
            matchHeader = dummyHeader.Match(v_header);
            if (matchHeader.Success)
            {
                string HHID = getMatchData(matchHeader, 1).Trim();
                loguearString(HHID + "- DUMMY" );
                //stringEventArgs retorno = new stringEventArgs(v_header, v_state);
                //this.responderDUMMY(this, retorno);
                return;
            }

            // RECIBI el pedido de actualización de la lista de empleados.
            // Es el lugar donde se asocia el StateObject al HHID y a la Organizacion.
            // Si el dispositivo esta registrado (agregado previamente desde LENEL o desde la WEB), entonces
            // se da de alta en la lista de stateObjectClients, con clave String HHID
            matchHeader = getEmpListHeader.Match(v_header);
            if (matchHeader.Success)
            {
                if (getEmployeeList != null)
                {
                    string HHID = getMatchData(matchHeader, 1).Trim();
                    v_state.HHID = HHID;                                // registra el nombre del Dispositivo en el State del cliente.

                    stringEventArgs retorno = new stringEventArgs(v_header, v_state);

                    int orgID = mainApp.DataManager.obtenerOrganizationIDFromHHID(HHID);
                    if (orgID > 0)
                    {
                        v_state.orgID=orgID;

                        try
                        {
                            StaticTools.obtenerMutex_StateObjectClients();
                            if (!stateObjectsClients.ContainsKey(HHID))
                            {
                                stateObjectsClients.Add(HHID, v_state);
                            }
                        }
                        catch (Exception ex)
                        {
                            loguearString(HHID + " - excepcion en matchHeader= getEmpListHeader creando Stateobject: " + ex.Message);
                        }
                        finally
                        {
                            StaticTools.liberarMutex_StateObjectClients();
                        }

                        this.getEmployeeList(this, retorno);                 // hace un rise para avisar que va a comenzar el envio de lista de empleados.
                    }
                    else
                    {
                        loguearString("El HH: " + HHID + " no tiene organizacion asociada.");
                        v_state.abortAllThreads(null);
                        v_state.closeAllSockets();
                    }

                }
                return;
            }

            // Desde Lenel se eliminó un empleado
            matchHeader = DeleteEmpHeader.Match(v_header);
            if (matchHeader.Success)
            {
                string HHID = getMatchData(matchHeader, 1).Trim();
                string tarjeta = getMatchData(matchHeader, 3).Trim();

                stringEventArgs retorno = new stringEventArgs(v_header, v_state);
                retorno.textData.Add("HHID", HHID);
                retorno.textData.Add("TARJETA", tarjeta);

                this.deleteEmp(this, retorno);
                return;
            }

            // Desde Lenel se agregó un empleado
            matchHeader = AddEmpHeader.Match(v_header);
            if (matchHeader.Success)
            {
                string HHID = getMatchData(matchHeader, 1).Trim();
                string tarjeta = getMatchData(matchHeader, 3).Trim();

                stringEventArgs retorno = new stringEventArgs(v_header, v_state);
                retorno.textData.Add("HHID", HHID);
                retorno.textData.Add("TARJETA", tarjeta);

                this.addEmp(this, retorno);
                return;
            }

            // Desde el HH recibí pedido de empleados por versión
            matchHeader = EmpxVersionHeader.Match(v_header);
            if (matchHeader.Success)
            {
                string HHID = getMatchData(matchHeader, 1).Trim();
                int chunkSize = Convert.ToInt32(getMatchData(matchHeader, 2).Trim());
                byte[] byteData = getDataBytes(finalBuffer, chunkSize);

                byteArrayEventArgs retorno = new byteArrayEventArgs(v_header, byteData, v_state);
                retorno.textData.Add("HHID", HHID);

                this.sendEmpxVersion(this, retorno);
                return;
            }

            // Desde el HH recibí pedido de siguiente bloque de imagenes
            matchHeader = MasImgsHeader.Match(v_header);
            if (matchHeader.Success)
            {
                string HHID = getMatchData(matchHeader, 1).Trim();

                stringEventArgs retorno = new stringEventArgs(v_header, v_state);
                retorno.textData.Add("HHID", HHID);

                this.enviarMasImagenes(this, retorno);
                return;
            }

            // Desde el HH recibí pedido de lista de imagenes
            matchHeader = ImgVersionHeader.Match(v_header);
            if (matchHeader.Success)
            {
                string HHID = getMatchData(matchHeader, 1).Trim();

                stringEventArgs retorno = new stringEventArgs(v_header, v_state);
                retorno.textData.Add("HHID", HHID);

                this.enviarVersionImagenes(this, retorno);
                return;
            }

            // Desde el HH recibí pedido de lista de imagenes
            matchHeader = ImgListHeader.Match(v_header);
            if (matchHeader.Success)
            {
                string HHID = getMatchData(matchHeader, 1).Trim();
                int chunkSize = Convert.ToInt32(getMatchData(matchHeader, 2).Trim());
                byte[] byteData = getDataBytes(finalBuffer, chunkSize);

                byteArrayEventArgs retorno = new byteArrayEventArgs(v_header, byteData, v_state);
                retorno.textData.Add("HHID", HHID);

                this.enviarListaImagenes(this, retorno);
                return;
            }

            // RECIBI un pedido de actualización de una imagen de un usuario.
            matchHeader = getImageHeader.Match(v_header);
            if (matchHeader.Success)
            {
                string HHID = getMatchData(matchHeader, 1).Trim();
                string tarjeta = getMatchData(matchHeader, 3).Trim();

                stringEventArgs retorno = new stringEventArgs(v_header,v_state);
                retorno.textData.Add("HHID", HHID);
                retorno.textData.Add("TARJETA", tarjeta);

                this.getImage(this, retorno);                  // Hace un rise del evento registrado, el cual va a agregar el job EMPIMAGE a la lista de jobs del socket.
                return;
            }

            // RECIBI un ACCESS de una tarjeta
            matchHeader =accessHeader.Match(v_header);
            if (matchHeader.Success)
            {
                string HHID = getMatchData(matchHeader, 1).Trim();
                int chunkSize = int.Parse(getMatchData(matchHeader, 2));
                string tarjeta = getMatchData(matchHeader, 3).Trim();
                string Latitud = getMatchData(matchHeader, 4).Trim();
                string Longitud = getMatchData(matchHeader, 5).Trim();
                string hora = getMatchData(matchHeader, 6).Trim();
                string hasImage = getMatchData(matchHeader, 7).Trim();
                string tipoAcceso = getMatchData(matchHeader, 8).Trim();
                string id = getMatchData(matchHeader, 9).Trim();
                byte[] dataBytes;
                if (bool.Parse(hasImage))
                {
                    dataBytes = getDataBytes(finalBuffer, chunkSize);
                }
                else
                {
                    dataBytes = new byte[0];
                }

                byteArrayEventArgs retorno = new byteArrayEventArgs(v_header, dataBytes,v_state);
                retorno.textData.Add("HHID", HHID);
                retorno.textData.Add("TARJETA", tarjeta);
                retorno.textData.Add("LATITUD", Latitud);
                retorno.textData.Add("LONGITUD", Longitud);
                retorno.textData.Add("HORA", hora);
                retorno.textData.Add("IMAGEN", hasImage);
                retorno.textData.Add("TIPOACCESO", tipoAcceso);
                retorno.textData.Add("ID", id);

                loguearString("Reconocido ACCESO CON ID: " + id);
                this.actualizeAccess(this, retorno);                   // Llama al evento registrado para actualizar el movimiento de acceso
                return;
            }

            // RECIBI VISITA
            matchHeader = visitHeader.Match(v_header);
            if (matchHeader.Success)
            {
                string HHID = getMatchData(matchHeader, 1).Trim();
                int chunkSize = int.Parse(getMatchData(matchHeader, 2));
                string nombre = getMatchData(matchHeader, 3).Trim();
                string apellido = getMatchData(matchHeader, 4).Trim();
                string documento = getMatchData(matchHeader, 5).Trim();
                string empresa = getMatchData(matchHeader, 6).Trim();
                string tarjeta = getMatchData(matchHeader, 7).Trim();
                string latitud = getMatchData(matchHeader, 8).Trim();
                string longitud = getMatchData(matchHeader, 9).Trim();
                string hora = getMatchData(matchHeader, 10).Trim();
                string hasImage = getMatchData(matchHeader, 11).Trim();
                string tipoAcceso = getMatchData(matchHeader, 12).Trim();
                string id = getMatchData(matchHeader, 13).Trim();

                byte[] dataBytes;
                if (bool.Parse(hasImage))   // Hay imagen asociada. Viene el databytes.
                {
                    dataBytes = getDataBytes(finalBuffer, chunkSize);
                }
                else
                {
                    dataBytes = new byte[0];
                }

                byteArrayEventArgs retorno = new byteArrayEventArgs(v_header, dataBytes, v_state);
                retorno.textData.Add("HHID", HHID);
                retorno.textData.Add("TARJETA", tarjeta);
                retorno.textData.Add("NOMBRE", nombre);
                retorno.textData.Add("APELLIDO", apellido);
                retorno.textData.Add("DOCUMENTO", documento);
                retorno.textData.Add("EMPRESA", empresa);
                retorno.textData.Add("LATITUD", latitud);
                retorno.textData.Add("LONGITUD", longitud);
                retorno.textData.Add("HORA", hora);
                retorno.textData.Add("IMAGEN", hasImage);
                retorno.textData.Add("TIPOACCESO", tipoAcceso);
                retorno.textData.Add("ID", id);

                int orgID = mainApp.DataManager.obtenerOrganizationIDFromHHID(HHID);
                if (orgID > 0)
                {
                    retorno.textData.Add("ORGID", orgID.ToString());
                    this.actualizeVisit(this, retorno);

                }

                return;
            }

            // Recibi un mensaje de Fin de sincronizacion
            matchHeader = FinSyncHeader.Match(v_header);
            if (matchHeader.Success)
            {

                mainApp.DataManager.actualizarFechaSync(v_state.HHID);
                mainApp.ComunicationSystem.EnviarJobFinSync(v_state.HHID, v_state);
                return;
            }

            // RECIBI ARCHIVO DE LOG
            matchHeader = LOGFile.Match(v_header);
            if (matchHeader.Success)
            {

                string HHID = getMatchData(matchHeader, 1).Trim();
                int fileSize = int.Parse(getMatchData(matchHeader, 2));
                string logName = getMatchData(matchHeader, 3).Trim();
                try
                {
                    byte[] dataBytes;
                    dataBytes = getDataBytes(finalBuffer, fileSize);
                    if (dataBytes.Length > 0 && logName != "")
                    {
                        DateTime ahora = DateTime.Now;
                        string finalLogName = HHID + "_" + ahora.Year.ToString() + ahora.Month.ToString() + ahora.Day.ToString() + "_" + ahora.Hour.ToString() + "-" + ahora.Minute.ToString() + "-" + ahora.Second.ToString() + "_" + logName;
                        File.WriteAllBytes(SystemConfiguration.ImagesPath + @"\" + finalLogName, dataBytes);
                    }
                    loguearString(HHID + " - Server recibió log: " + logName);

                    stringEventArgs retorno = new stringEventArgs(logName, v_state);

                    retorno.textData.Add("LOGNAME", logName);
                    this.confirmarLOG(this, retorno);                   //TYPE:BORRARLOG Manda la confirmacion de recepcion del archivo de LOG para que el HH lo borre de su disco: BORRARLOG
                }
                catch (Exception ex)
                {
                    loguearString(HHID +"- Excepcion en LOGFile: " + ex.Message);
                }
                return;
            }
            /* NO RECONOCIO HEADER */
            else loguearString("ATENCION! Header no reconocido: " + v_header);
        }