/// <summary> /// Salva i dati ricevuti nella tabella dei dati "raw" /// </summary> /// <param name="packets">Lista dei pacchetti da salvare</param> /// <param name="ipAddress">Ip del dispositivo che ha catturato i pacchetti</param> public void saveReceivedData(PacketsInfo packets, IPAddress ipAddress) { if (packets.listPacketInfo.Count == 0) { return; } StringBuilder query = new StringBuilder(""); query.Append("INSERT INTO [dbo].[Packets] (SourceAddress, SSID, signalStrength, hashCode, timestamp_packet, device) VALUES "); foreach (PacketInfo packet in packets.listPacketInfo) { query.Append("('" + packet.sourceAddress + "',"); query.Append("'" + packet.SSID + "',"); query.Append(packet.signalStrength + ","); query.Append("'" + packet.hashCode + "',"); query.Append(packet.timestamp * 1000 + ","); //*1000 per passare dai secondi ai millisecondi query.Append("'" + ipAddress.ToString() + "'),"); } query.Remove(query.Length - 1, 1); //elimino l'ultima virgola int queryResult = runInsertDelete(query.ToString(), null); if (queryResult == packets.listPacketInfo.Count) { Utils.logMessage(this.ToString(), Utils.LogCategory.Info, "INSERT in Packets effettuata con successo"); } else { Utils.logMessage(this.ToString(), Utils.LogCategory.Info, "INSERT in Packets fallita"); return; } updateAssembled(); }
///<summary>metodo che gestisce la connessione socket con un rilevatore</summary> ///<exception cref = "SnifferAppSocketException">Eccezione lanciata in caso di errore su una operazione sul socket</exception> public void gestioneDevice(TcpClient client) { IPEndPoint remoteIpEndPoint = null; Device device; NetworkStream stream = client.GetStream(); stream.ReadTimeout = 120000; //timeout in lettura in millis stream.WriteTimeout = 15000; //timeout in scrittura in millis try { remoteIpEndPoint = client.Client.RemoteEndPoint as IPEndPoint; } catch (Exception e) { string message = "Errore nel riconoscere il socket remoto"; Utils.logMessage(this.ToString(), Utils.LogCategory.Error, message); throw new SnifferAppSocketException(message, e); } //verifico che non scattino timeout sulla connessione socket try { //verifico se il dispositivo con quell'IP era già connesso (l'IP del dispositivo era contentuto già nella lstConfDevices) if (ConfDevice.lstConfDevices.TryGetValue(remoteIpEndPoint.Address.ToString(), out device)) { //il dispositivo era gia configurato Utils.logMessage(this.ToString(), Utils.LogCategory.Info, "RECONNECTED with device: " + remoteIpEndPoint.Address.ToString()); } else { //se non era già configurato aspetto l'evento di Configurazione dall'interfaccia grafica Utils.logMessage(this.ToString(), Utils.LogCategory.Info, "CONNECTED with device: " + remoteIpEndPoint.Address.ToString()); //event per gestire la sincronizzazione con il thread della GUI ManualResetEvent deviceConfEvent = new ManualResetEvent(false); //aggiungo il dispositivo (con il rispettivo Event) nella lista dei dispositivi non configurati NoConfDevice.lstNoConfDevices.TryAdd(remoteIpEndPoint.Address.ToString(), deviceConfEvent); //delegato per gestire la variazione della lista dei device da configurare NoConfDevice.OnLstNoConfDevicesChanged(this, EventArgs.Empty); //mi risveglio quando dalla GUI è richiesta la configurazione del dispositivo o si vuole inviare al rilevatore il segnale "IDENTIFICA" bool isSignalled = false; while (!isSignalled && !stopThreadElaboration) { isSignalled = deviceConfEvent.WaitOne(TimeSpan.FromSeconds(20)); } //mi sono risvegliato dall'evento ma il thread deve fermarsi if (stopThreadElaboration) { //chiudo il client TCP client.Close(); Utils.logMessage(this.ToString(), Utils.LogCategory.Info, "Socket chiuso"); return; } do { //controllo se il device è stato eliminato dalla lista dei device non configurati if (!NoConfDevice.lstNoConfDevices.TryGetValue(remoteIpEndPoint.Address.ToString(), out deviceConfEvent)) { //il device è stato configurato break; } else { //il device non è stato configurato e quindi il thread si è risvegliato per richiedere un "IDENTIFICA" Utils.sendMessage(stream, remoteIpEndPoint, "IDENTIFICA"); deviceConfEvent.Reset(); //come su, volutare se realizzare un wrapper sull'evento isSignalled = false; while (!isSignalled && !stopThreadElaboration) { isSignalled = deviceConfEvent.WaitOne(TimeSpan.FromSeconds(20)); } //mi sono risvegliato dall'evento ma il thread deve fermarsi if (stopThreadElaboration) { //chiudo il client TCP client.Close(); Utils.logMessage(this.ToString(), Utils.LogCategory.Info, "Socket chiuso"); return; } } } while (true); } //incremento il numero di socket associati al device //non faccio il check se il device c'è nella lista perchè in questo punto del codice c'è sicuramente ConfDevice.lstConfDevices.TryGetValue(remoteIpEndPoint.Address.ToString(), out device); device.openSocket = device.openSocket + 1; ConfDevice.lstConfDevices.AddOrUpdate(device.ipAddress, device, (k, v) => v); Utils.logMessage(this.ToString(), Utils.LogCategory.Info, "Socket aperti con " + remoteIpEndPoint.Address.ToString() + ": " + device.openSocket); string messageReceived; //count per triggerare la sincronizzazione dei clock tra il server e il rilevatore int countSyncTimestamp = 0; //ciclo fin quando non viene invocato il metodo stop in attesa di messaggi da parte dei rilevatori while (!stopThreadElaboration) { //se il count è a 0 eseguo la sincronizzazione if (countSyncTimestamp == 0) { //invio il messaggio per iniziare la sincronizzazione Utils.sendMessage(stream, remoteIpEndPoint, "SYNC_CLOCK"); messageReceived = Utils.receiveMessage(stream, remoteIpEndPoint); //posso ricevere SYNC_CLOCK_START (devo sincronizzare) o SYNC_CLOCK_STOP (sincronizzazione terminata) while (messageReceived == "SYNC_CLOCK_START") { //invio il segnale di sincronizzazione Utils.syncClock(client.Client); messageReceived = Utils.receiveMessage(stream, remoteIpEndPoint); } //resetto il count; sincronizzo i timestamp ogni 50 interazioni countSyncTimestamp = 50; } //invio messaggio per indicare che può iniziare l'invio dei dati Utils.sendMessage(stream, remoteIpEndPoint, "START_SEND"); //attendo il JSON dal rilevatore con i pacchetti catturati dall'ultima interazione messageReceived = Utils.receiveMessage(stream, remoteIpEndPoint); PacketsInfo packetsInfo = null; try { //deserializzazione del JSON ricevuto packetsInfo = Newtonsoft.Json.JsonConvert.DeserializeObject <PacketsInfo>(messageReceived); } catch (Exception) { Utils.logMessage(this.ToString(), Utils.LogCategory.Warning, "Errore nella deserializzazione del messaggio JSON. Il messaggio verrà scartato"); } //controllo che ci siano messaggi e che ci siano almeno 2 device configurati if (packetsInfo != null && packetsInfo.listPacketInfo.Count > 0 && ConfDevice.lstConfDevices.Count >= 2) { //salvo i dati nella tabella raw del DB dbManager.saveReceivedData(packetsInfo, remoteIpEndPoint.Address); } Utils.logMessage(this.ToString(), Utils.LogCategory.Info, "Device: " + remoteIpEndPoint.Address.ToString() + " -- Numero pacchetti ricevuti: " + packetsInfo.listPacketInfo.Count); //decremento il contatore per la sincronizzazione dei timestamp countSyncTimestamp--; } } catch (SnifferAppSocketTimeoutException e) { Utils.logMessage(this.ToString(), Utils.LogCategory.Warning, "Device:" + remoteIpEndPoint.Address.ToString() + " -- " + e.Message); } //chiudo il client TCP stream.Close(); client.Close(); Utils.logMessage(this.ToString(), Utils.LogCategory.Info, "Socket con " + remoteIpEndPoint.Address.ToString() + " chiuso"); //decremento il numero di socket aperti sul device ConfDevice.lstConfDevices.TryGetValue(remoteIpEndPoint.Address.ToString(), out device); device.openSocket = device.openSocket - 1; ConfDevice.lstConfDevices.AddOrUpdate(device.ipAddress, device, (k, v) => v); Utils.logMessage(this.ToString(), Utils.LogCategory.Info, "Socket aperti con " + remoteIpEndPoint.Address.ToString() + ": " + device.openSocket); //se il numero di socket aperti è zero devo togliere il device dalla lista dei configurati if (device.openSocket <= 0 && !stopThreadElaboration) { ConfDevice.lstConfDevices.TryRemove(remoteIpEndPoint.Address.ToString(), out device); Utils.logMessage(this.ToString(), Utils.LogCategory.Info, "Device " + remoteIpEndPoint.Address.ToString() + " eliminato dalla lista dei device configurati"); ConfDevice.OnLstConfDevicesChanged(this, EventArgs.Empty); } }