public override void DoRequest(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { DataPacket newPacket = (DataPacket)packet.Clone(); UInt32 gwioid = CidGenerator.Next(); Record record = InfoService.IOID.Create(gwioid); record.Destination = packet.Sender; record.IOID = packet.Parameter2; record = InfoService.ChannelCid[packet.Parameter1]; // Lost the CID if (record == null) { if (Log.WillDisplay(TraceEventType.Error)) Log.TraceEvent(System.Diagnostics.TraceEventType.Error, chain.ChainId, "Readnotify not linked to a correct channel"); packet.Chain.Dispose(); return; } if (record.SID == null) { if (Log.WillDisplay(TraceEventType.Error)) Log.TraceEvent(System.Diagnostics.TraceEventType.Error, chain.ChainId, "Readnotify without SID"); chain.Dispose(); return; } newPacket.Destination = record.Destination; newPacket.Parameter1 = record.SID.Value; newPacket.Parameter2 = gwioid; sendData(newPacket); }
public override void ProcessData(DataPacket packet) { if (this.Chain.Gateway.IsDisposed) return; if (this.Chain.IsDisposed) return; if (!isTcpMember.HasValue) isTcpMember = !(this.Chain[0] is UdpReceiver); if (!isTcpMember.Value && packet.Command != 6) return; if (Log.WillDisplay(System.Diagnostics.TraceEventType.Verbose)) { if (isTcpMember.Value) Log.TraceEvent(System.Diagnostics.TraceEventType.Verbose, this.Chain.ChainId, "Side: " + this.Chain.Side + " " + packet.Sender + " TCP Request: " + Handlers.CommandHandler.GetCommandName(packet.Command) + " " + packet.Command); else Log.TraceEvent(System.Diagnostics.TraceEventType.Verbose, this.Chain.ChainId, "Side: " + this.Chain.Side + " UDP Request: " + Handlers.CommandHandler.GetCommandName(packet.Command) + " " + packet.Command); } // Unkown command => drop connection if (!Handlers.CommandHandler.IsAllowed(packet.Command)) { if (packet.Chain[0] is TcpReceiver) { packet.Chain.Dispose(); //packet.Dispose(); } return; } Handlers.CommandHandler.ExecuteRequestHandler(packet.Command, packet, this.Chain, PreSendData); //packet.Dispose(); }
void PreSendData(DataPacket i) { /*if (i.Kind == DataPacketKind.HEAD) savedDestination = i.Destination;*/ this.SendData(i); }
private static void writeDataPacket(Stream stream, DataPacket dataPacket) { if (stream != null) { dataPacket.WriteDelimitedTo(stream); } }
public override void ProcessData(DataPacket packet) { if (packet.Command != 6) { return; } if (packet.Destination == null) return; lock (storage) { // Checks if we have a storage for this destination if (storage.ContainsKey(packet.Destination)) { // Buffer is too full, let's send it and start a new one if (storage[packet.Destination].Length + packet.BufferSize > Gateway.MAX_UDP_SEND_PACKET) { SendData(storage[packet.Destination].Packet); storage[packet.Destination] = new DataQueue(packet); } else // add packet to the end of the buffer storage[packet.Destination].Enqueue(packet); } // None, let's create one else storage.Add(packet.Destination, new DataQueue(packet)); } //packet.Dispose(); }
public override void ProcessData(DataPacket packet) { Socket socket; // For a search with direct answer don't use the usual rules if (packet.ReverseAnswer) { if (this.Chain.Side == ChainSide.SIDE_A || this.Chain.Side == ChainSide.UDP_RESP_SIDE_B) socket = this.Chain.Gateway.Configuration.UdpReceiverA; else socket = this.Chain.Gateway.Configuration.UdpReceiverB; } else { if (this.Chain.Side == ChainSide.SIDE_A || this.Chain.Side == ChainSide.UDP_RESP_SIDE_B) socket = this.Chain.Gateway.Configuration.UdpReceiverB; else socket = this.Chain.Gateway.Configuration.UdpReceiverA; } if (packet.Destination != null) { try { socket.SendTo(packet.Data, packet.Offset, packet.BufferSize, SocketFlags.None, packet.Destination); } catch { } } //packet.Dispose(); }
public override void ProcessData(DataPacket packet) { if (packet.Destination == null) return; /*try { if (Log.WillDisplay(System.Diagnostics.TraceEventType.Verbose)) Log.TraceEvent(System.Diagnostics.TraceEventType.Verbose, (this.Chain == null ? 0 : this.Chain.ChainId), "Sending " + Handlers.CommandHandler.GetCommandName(packet.Command) + " " + packet.Command + " to " + packet.Destination + " size: " + packet.BufferSize); } catch { }*/ if (object.ReferenceEquals(packet.Sender, packet.Destination)) { TcpManager.SendClientPacket(packet); } else { // ReSharper disable PossibleNullReferenceException this.Chain.UseChain(TcpManager.GetIocChain(this.Chain.Gateway, packet.Destination)); // ReSharper restore PossibleNullReferenceException TcpManager.SendIocPacket(this.Chain.Gateway, packet); } }
public override void DoRequest(DataPacket packet, PBCaGw.Workers.WorkerChain chain, DataPacketDelegate sendData) { /*DataPacket newPacket = (DataPacket)packet.Clone(); newPacket.Destination = packet.Sender; newPacket.DataType = 0; newPacket.DataCount = Gateway.CA_PROTO_VERSION; SendData(newPacket);*/ }
public void DataLength_invalid_args() { DataPacket packet = new DataPacket(); ArgumentException ex = Assert.Throws<ArgumentOutOfRangeException>(() => packet.DataLength = -1); Assert.AreEqual("value", ex.ParamName); packet.Dispose(); }
void PreSendData(DataPacket i) { if (i.Kind == DataPacketKind.HEAD) savedDestination = i.Destination; this.SendData(i); /*if (isTcpMember.Value && i.NeedToFlush) TcpManager.FlushBuffer(i.Destination);*/ }
static TcpReceiver() { echoPacket = DataPacket.Create(16); echoPacket.Command = (ushort)CommandID.CA_PROTO_ECHO; echoPacket.DataType = 0; echoPacket.DataCount = 0; echoPacket.Parameter1 = 0; echoPacket.Parameter2 = 0; }
public void DestinationId() { DataPacket packet = new DataPacket(); packet.DestinationId = Int32.MaxValue; Assert.AreEqual(0, packet.DataLength); Assert.AreEqual(Int32.MaxValue, packet.DestinationId); Assert.IsFalse(packet.InOrder); Assert.AreEqual(MessageBoundary.None, packet.MessageBoundary); Assert.AreEqual(0, packet.MessageNumber); Assert.AreEqual(0, packet.PacketNumber); Assert.AreEqual(TimeSpan.Zero, packet.TimeStamp); packet.DestinationId = 1; Assert.AreEqual(0, packet.DataLength); Assert.AreEqual(1, packet.DestinationId); Assert.IsFalse(packet.InOrder); Assert.AreEqual(MessageBoundary.None, packet.MessageBoundary); Assert.AreEqual(0, packet.MessageNumber); Assert.AreEqual(0, packet.PacketNumber); Assert.AreEqual(TimeSpan.Zero, packet.TimeStamp); packet.DestinationId = 0; Assert.AreEqual(0, packet.DataLength); Assert.AreEqual(0, packet.DestinationId); Assert.IsFalse(packet.InOrder); Assert.AreEqual(MessageBoundary.None, packet.MessageBoundary); Assert.AreEqual(0, packet.MessageNumber); Assert.AreEqual(0, packet.PacketNumber); Assert.AreEqual(TimeSpan.Zero, packet.TimeStamp); packet.DestinationId = -1; Assert.AreEqual(0, packet.DataLength); Assert.AreEqual(-1, packet.DestinationId); Assert.IsFalse(packet.InOrder); Assert.AreEqual(MessageBoundary.None, packet.MessageBoundary); Assert.AreEqual(0, packet.MessageNumber); Assert.AreEqual(0, packet.PacketNumber); Assert.AreEqual(TimeSpan.Zero, packet.TimeStamp); packet.DestinationId = Int32.MinValue; Assert.AreEqual(0, packet.DataLength); Assert.AreEqual(Int32.MinValue, packet.DestinationId); Assert.IsFalse(packet.InOrder); Assert.AreEqual(MessageBoundary.None, packet.MessageBoundary); Assert.AreEqual(0, packet.MessageNumber); Assert.AreEqual(0, packet.PacketNumber); Assert.AreEqual(TimeSpan.Zero, packet.TimeStamp); packet.Dispose(); }
/// <summary> /// Creates a new DataQueue based on a packet message /// </summary> /// <param name="packet"></param> public DataQueue(DataPacket packet) { CreationTime = new Stopwatch(); CreationTime.Start(); buff = new byte[packet.BufferSize]; Array.Copy(packet.Data, packet.Offset, buff, 0, buff.Length); Destination = packet.Destination; Chain = packet.Chain; ReverseAnswer = packet.ReverseAnswer; }
/// <summary> /// Processes the parameter information sent by the server -- SNAC(09,03) /// </summary> /// <param name="dp">A <see cref="DataPacket"/> object with a buffer containing SNAC(09,03)</param> public static void ProcessParametersList(DataPacket dp) { using (TlvBlock tlvs = new TlvBlock(dp.Data.ReadByteArrayToEnd())) { ushort max_visiblelist_size = tlvs.ReadUshort(0x0001); ushort max_invisiblelist_size = tlvs.ReadUshort(0x0002); dp.ParentSession.ParameterSetArrived(); } }
public override void DoResponse(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { Record record = InfoService.ChannelCid[packet.Parameter1]; if (Log.WillDisplay(TraceEventType.Critical)) { if (record != null) Log.TraceEvent(TraceEventType.Critical, chain.ChainId, "Proto Error (" + packet.Parameter2 + ") on CID: " + packet.Parameter1 + " (" + record.Channel + "), SID = " + record.SID); else Log.TraceEvent(TraceEventType.Critical, chain.ChainId, "Proto Error (" + packet.Parameter2 + ") on CID: " + packet.Parameter1); } }
public Client(string address, int port) { gsv = Game.GetInstance().GUI.GameSetupView; Console.WriteLine("Connecting to " + address + " at " + port); gsv.addStatusText("Connecting to " + address + " at " + port); try { gameIP = new IPEndPoint(IPAddress.Parse(address),port); } catch (System.FormatException e) { gsv.addStatusText("Looking up " + address + " ..."); try { gameIP = new IPEndPoint(System.Net.Dns.GetHostByName(address).AddressList[0], port); } catch (Exception ex) { gsv.reenableConnectButton(); gsv.addStatusText("Could not lookup " + address + " on port " + port + ": " + ex.Message); return; } } catch (Exception e) { gsv.reenableConnectButton(); gsv.addStatusText("Unknown error parsing address " + address + " on port " + port + ": " + e.Message); return; } try { gameSocket = new Socket(System.Net.Sockets.AddressFamily.InterNetwork,System.Net.Sockets.SocketType.Stream,System.Net.Sockets.ProtocolType.Tcp); gameSocket.Connect(gameIP); gameConnection = new Connection(gameSocket); } catch (Exception e) { gsv.reenableConnectButton(); gsv.addStatusText("Could not connect to " + address + " on port " + port + ": " + e.Message); return; } listenData = new Thread(new ThreadStart(listenForData)); listenData.Start(); gsv.addStatusText("Connected."); DataPacket pkt = new DataPacket("Connected", null); gameConnection.sendObject(pkt); participants = new ArrayList(); }
public QdafValidationResult Validate(DataPacket dataPacket) { var errors = new Lazy<List<string>>(() => new List<string>()); var result = new QdafValidationResult(); if (dataPacket == null) { errors.Value.Add(string.Format(CoreResources.CannotBeNullMessage, "dataPacket")); result.Errors = errors.Value; return result; } if (dataPacket.Commands == null) { errors.Value.Add(string.Format(CoreResources.CannotBeNullMessage, "dataPacket.Commands")); result.Errors = errors.Value; return result; } var commands = dataPacket.Commands.ToList(); for (var i = 0; i < commands.Count(); i++) { try { Validate(commands[i]); } catch (Exception ex) { var command = commands[i]; if (command == null || command.Command == null) { throw new QdafException(string.Format("Command at index {0} is null", i)); } command.Errors = new List<string>(command.Errors ?? new string[0]) { ex.Message }; } } if (errors.IsValueCreated && errors.Value.Any()) { result.Errors = errors.Value; } result.Valid = true; return result; }
/// <summary> /// Player move /// </summary> /// <param name="dp">Incoming packet data</param> public void OnPlayerMove(DataPacket dp) { Int32 _angle = dp.Read<Int32>(); // ??? Int32 _x = dp.Read<Int32>(); Int32 _y = dp.Read<Int32>(); Int32 _z = dp.Read<Int32>(); this.Player.Destination.X = _x / 1000f; this.Player.Destination.Y = _y / 1000f; this.Player.Destination.Z = _z / 1000f; this.Player.SendMoverDestination(); }
/// <summary> /// Paquet envoyé par le client pour mettre à jour la position du personnage /// </summary> /// <param name="dp"></param> public void OnPlayerCorrMovement(DataPacket dp) { this.Player.Position.X = dp.Read<Single>(); this.Player.Position.Y = dp.Read<Single>(); this.Player.Position.Z = dp.Read<Single>(); this.Player.Angle = dp.Read<Single>(); int angleX = dp.Read<Int32>(); //pure supposition short motion = dp.Read<Int16>(); //sure byte nloop = dp.Read<Byte>(); //sure ANILOOP_1PLAY int nMotionEx = dp.Read<Int32>(); //pure supposition int dwMotionOption = dp.Read<Int32>(); //pure supposition uint dwTicks = dp.Read<UInt32>(); //pure supposition }
public async Task should_timeout() { var transaction = new Transaction(50, new DefaultTimer(), new LongDelayFakeTransactionProcessors(250)); var packet = new DataPacket(); var result = await transaction.BeginTransactionAsync(packet); Assert.AreEqual(TransactionStaus.Timeout, result.Status); Assert.IsNotNull(result.Exceptions); Assert.IsNotNull(result.TransactionId); Assert.IsTrue(result.Exceptions.Any()); }
public void Constructor() { DataPacket packet = new DataPacket(); Assert.AreEqual(0, packet.DataLength); Assert.AreEqual(0, packet.DestinationId); Assert.IsFalse(packet.InOrder); Assert.AreEqual(MessageBoundary.None, packet.MessageBoundary); Assert.AreEqual(0, packet.MessageNumber); Assert.AreEqual(0, packet.PacketNumber); Assert.AreEqual(TimeSpan.Zero, packet.TimeStamp); packet.Dispose(); }
public override void DoResponse(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { DataPacket newPacket = (DataPacket)packet.Clone(); Record record = InfoService.IOID[packet.Parameter2]; if (record == null || record.IOID == null) return; InfoService.IOID.Remove(packet.Parameter2); CidGenerator.ReleaseCid(packet.Parameter2); newPacket.Destination = record.Destination; newPacket.Parameter2 = record.IOID.Value; sendData(newPacket); }
public override void ProcessData(DataPacket packet) { if (packet.Kind != DataPacketKind.COMPLETE) return; if (packet.Command != 13) return; if (Log.WillDisplay(System.Diagnostics.TraceEventType.Verbose)) Log.TraceEvent(System.Diagnostics.TraceEventType.Verbose, this.Chain.ChainId, "Side: " + this.Chain.Side + " UDP (Beacon) Request: " + Handlers.CommandHandler.GetCommandName(packet.Command) + " " + packet.Command); Handlers.CommandHandler.ExecuteRequestHandler(packet.Command, packet, this.Chain, this.SendData); /*List<DataPacket> result = Handlers.CommandHandler.ExecuteRequestHandler(packet.Command, packet, this.Chain); foreach (var i in result) { this.SendData(i); }*/ }
/// <summary> /// Collect client log /// </summary> /// <param name="dp">Incoming packet</param> public void OnCollectClientLog(DataPacket dp) { Int32 _playerId = dp.Read<Int32>(); Byte _systemId = dp.Read<Byte>(); String _logString = dp.Read<String>(); if (this.Player != null && this.Player.Id == _playerId) { Log.Write(LogType.Debug, "[{0}]: {1}", this.Player.Name, _logString); } else { this.Disconnect(); } }
public override void DoRequest(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { try { EventAdd.Unsubscribe(chain.Subscriptions[packet.Parameter2]); uint res; chain.Subscriptions.TryRemove(packet.Parameter2, out res); } catch { if (Log.WillDisplay(System.Diagnostics.TraceEventType.Critical)) Log.TraceEvent(System.Diagnostics.TraceEventType.Critical, chain.ChainId, "Error while cancelling a monitor."); chain.Dispose(); } }
public override void DoResponse(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { DataPacket newPacket = (DataPacket)packet.Clone(); Record record = InfoService.IOID[packet.Parameter2]; if (record == null) return; // Removes it to avoid the cleaup InfoService.IOID.Remove(packet.Parameter2); CidGenerator.ReleaseCid(packet.Parameter2); lock (EventAdd.lockObject) { // It's the initial answer as get of "cached" monitor. if (record.IOID.HasValue && record.IOID.Value == 0) { if (!record.SID.HasValue) return; if (record.CID.HasValue && InfoService.ChannelSubscription.Knows(record.CID.Value)) { if (InfoService.ChannelSubscription[record.CID.Value].PacketCount == 0 && InfoService.ChannelSubscription[record.CID.Value].FirstValue == true) { if (Log.WillDisplay(TraceEventType.Verbose)) Log.TraceEvent(TraceEventType.Verbose, chain.ChainId, "Sending readnotify data on " + record.SID.Value); newPacket.Command = 1; newPacket.Parameter1 = 1; newPacket.Parameter2 = record.SID.Value; newPacket.Destination = record.Destination; newPacket.DataCount = record.DataCount.Value; newPacket.DataType = record.DBRType.Value; sendData(newPacket); InfoService.ChannelSubscription[record.CID.Value].FirstValue = false; InfoService.ChannelSubscription[record.CID.Value].PacketCount = 1; } } return; } } newPacket.Destination = record.Destination; newPacket.Parameter1 = 1; newPacket.Parameter2 = record.IOID.Value; sendData(newPacket); }
public override void DoRequest(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { Record channelInfo = InfoService.ChannelCid[packet.Parameter1]; // Lost the CID if (channelInfo == null) { if (Log.WillDisplay(System.Diagnostics.TraceEventType.Error)) Log.TraceEvent(System.Diagnostics.TraceEventType.Error, chain.ChainId, "Write not linked to a correct channel"); packet.Chain.Dispose(); return; } SecurityAccess access; switch (chain.Side) { case Workers.ChainSide.SIDE_A: access = chain.Gateway.Configuration.Security.EvaluateSideA(channelInfo.Channel, chain.Username, chain.Hostname, packet.Sender.Address.ToString()); break; default: access = chain.Gateway.Configuration.Security.EvaluateSideB(channelInfo.Channel, chain.Username, chain.Hostname, packet.Sender.Address.ToString()); break; } // We don't have write access quit! if (!access.Has(SecurityAccess.WRITE)) { return; } DataPacket newPacket = (DataPacket)packet.Clone(); UInt32 gwioid = CidGenerator.Next(); newPacket.Destination = channelInfo.Destination; // No SID? Can't write if (channelInfo.SID == null) { if (Log.WillDisplay(TraceEventType.Critical)) Log.TraceEvent(TraceEventType.Critical, chain.ChainId, "Write without SID"); WorkerChain ioc = TcpManager.GetIocChain(null, channelInfo.Destination); if (ioc != null) ioc.Dispose(); chain.Dispose(); return; } newPacket.Parameter1 = channelInfo.SID.Value; newPacket.Parameter2 = gwioid; sendData(newPacket); }
public async Task should_receive_and_validate_empty_packet_and_process() { var data = new DataPacket { Success = false, Commands = new IPacketCommand[0] }; await Receiver.ProcessPacketAsync(data); Assert.AreEqual(true, data.Success); MockPacketValidator.Verify(x => x.Validate(It.Is<DataPacket>(a => a == data)), Times.Once); MockPacketProcessor.Verify(x => x.ProcessAsync(It.Is<DataPacket>(a => a == data)), Times.Once); LogAsserter.VerifyNoExcptions(MockLogger); }
public override void DoRequest(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate sendData) { IPAddress senderAddress=packet.Sender.Address; if (senderAddress.Equals(chain.Gateway.Configuration.LocalSideA.Address) || senderAddress.Equals(chain.Gateway.Configuration.LocalSideB.Address)) return; // Use only the 5th beacon as restart if (packet.Parameter1 != 5) return; // Reset the beacon sender if (chain.Side == Workers.ChainSide.SIDE_A && chain.Gateway.beaconB != null) chain.Gateway.beaconB.ResetBeacon(); else if (chain.Side == Workers.ChainSide.SIDE_B && chain.Gateway.beaconA != null) chain.Gateway.beaconA.ResetBeacon(); }
/// <summary> /// Both request / answer should be handled in the same way. /// If we didn't sent the first packet then we should answer, /// otherwise it's the answer to our own echo, therefore drop it. /// </summary> /// <param name="packet"></param> /// <param name="chain"></param> void HandleEcho(DataPacket packet, Workers.WorkerChain chain, DataPacketDelegate SendData) { // Answer to our own? if (InfoService.EchoSent[packet.Sender] != null) { // Yes then drop the packet and remove the info from our list InfoService.EchoSent.Remove(packet.Sender); } else { // No then let's answer with the same content just changing the destination as the sender DataPacket newPacket = (DataPacket)packet.Clone(); newPacket.Destination = packet.Sender; //newPacket.NeedToFlush = true; SendData(newPacket); } }
/// <summary> /// 消息处理 /// </summary> private async void ProcessMessage() { while (EnableProcessMessage) { Thread.Sleep(50); Tuple <ISocketSession, ReceivedEventArgs> e; try { if (_messageQueue.TryDequeue(out e)) { #if DEBUG //System.Diagnostics.Stopwatch sp = new System.Diagnostics.Stopwatch(); //sp.Start(); #endif var session = e.Item1; if (session.Disposed) { continue; } var id = Guid.NewGuid().ToString(); //新会话ID SmartIot.Service.Core.ServiceLogger._sessionDictionary.Add(id, session); //使用字典记录会话 var message = e.Item2.ToStr(); if (message.IsNullOrWhiteSpace()) { continue; } var dataPackage = new DataPacket { Id = id, Data = message, Date = DateTime.Now }; //对当前接受数据进行封装 //ProtocalType = DataProtocalType.Json;//json //string packet = Formatter.Serialize(dataPackage);//序列化封装好的数据包 redis.Delete("packetKey"); //redis.Delete("facility"); //redis.Delete("device"); redis.Sadd("packetKey", dataPackage, DataType.Protobuf);//保存数据包(名为packetKey) //var responseMessage = await ApiProcessor.Process(message); //string str = responseMessage == null ? "" : responseMessage.ToString(); //session.Send(str); Task.Factory.StartNew(() => AnalyticMessage(session));//开启新的线程执行对redis缓存中数据包的处理任务 #if DEBUG //sp.Stop(); //if (sp.ElapsedMilliseconds > 100) // ServiceLogger.Current.WriteDebugLog("ProcessMessage: " + sp.ElapsedMilliseconds.ToString() + "ms" + ""); #endif } } catch (ObjectDisposedException odex) { ServiceLogger.Current.WriteException(odex); } catch (Exception ex) { ServiceLogger.Current.WriteException(ex); } } WriteLog("处理数据线程退出:" + Thread.CurrentThread.Name); }
/// <summary> /// Restores a connection with the server. /// </summary> protected void RestoreConnection() { DateTime utcNow = DateTime.UtcNow; bool connectNeeded = false; if (ClientState == ClientState.LoggedIn) { if (utcNow - responseDT > PingPeriod) { try { // check connection DataPacket request = CreateRequest(FunctionID.GetStatus, 10); SendRequest(request); ReceiveResponse(request); } catch { connectNeeded = true; } } } else if (utcNow - connAttemptDT > ReconnectPeriod) { connectNeeded = true; } try { if (connectNeeded) { connAttemptDT = utcNow; Disconnect(); Connect(); GetSessionInfo(out long sessionID, out ushort protocolVersion, out string serverName); SessionID = sessionID; ServerName = serverName; if (protocolVersion != ProtocolVersion) { throw new ScadaException(Locale.IsRussian ? "Несовместимая версия протокола." : "Incompatible protocol version."); } Login(out bool loggedIn, out _, out _, out string errorMessage); if (loggedIn) { ClientState = ClientState.LoggedIn; CommLog?.WriteAction("User is logged in"); } else { throw new ScadaException(errorMessage); } } else if (ClientState == ClientState.LoggedIn) { ClearNetStream(netStream, inBuf); } else { throw new ScadaException(Locale.IsRussian ? "Клиент не вошёл в систему. Попробуйте позже." : "Client is not logged in. Try again later."); } } catch { ClientState = ClientState.Error; throw; } }
// Processes a file and extracts the packet data private void processFile(string path) { string[] lines; { List <string> linesList = File.ReadLines(@path).ToList(); linesList.RemoveAll(string.IsNullOrEmpty); lines = linesList.ToArray(); } int lineCount = lines.Length; byte entryPort; byte exitPort; List <string> allPacketTimes = new List <string>(); List <string> allPacketEndMarkers = new List <string>(); List <List <byte> > allPacketBytes = new List <List <byte> >(); List <bool> duplicatePacket = new List <bool>(); if (lineCount >= 2) { int lineIndex = 0; // First two lines are timestamp for measurement start and port { DateTime tmpTime = Packet.parseDateString(lines[lineIndex++]); if (startTime == DateTime.MinValue || tmpTime.Ticks < startTime.Ticks) { startTime = tmpTime; if (endTime == DateTime.MinValue || startTime.Ticks > endTime.Ticks) { endTime = startTime; } } } entryPort = Convert.ToByte(lines[lineIndex++]); if (!m_portsLoaded.Contains(entryPort)) { m_portsLoaded.Add(entryPort); m_portsLoaded.Sort(); } exitPort = (byte)(entryPort + (entryPort % 2 == 0 ? -1 : 1)); string lastByteString = ""; while (lineIndex < lineCount) { string time, startCode, endCode, byteString, errorText; // Next line is a timestamp time = lines[lineIndex]; // Store this time in case file ends { DateTime tmpTime = Packet.parseDateString(time); if (tmpTime.Ticks > endTime.Ticks) { endTime = tmpTime; } } if (++lineIndex >= lines.Length) { break; } // Start code (E or P) startCode = lines[lineIndex]; if (++lineIndex >= lines.Length) { break; } if (startCode.Equals("E", StringComparison.Ordinal)) { // This is an error packet errorText = lines[lineIndex]; ErrorPacket errorMessage = new ErrorPacket(entryPort, exitPort, time, errorText); errorMessage.TimeStamp = errorMessage.TimeStamp.AddTicks(2); m_packets.Add(errorMessage); } else if (startCode.Equals("P", StringComparison.Ordinal)) { // This is a packet byteString = lines[lineIndex]; duplicatePacket.Add(byteString == lastByteString); lastByteString = byteString; if (++lineIndex >= lines.Length) { break; } endCode = lines[lineIndex]; string[] byteStringSplit = byteString.Split(' '); int byteCount = byteStringSplit.Count(); List <byte> packetBytes = new List <byte>(byteCount); for (int i = 0; i < byteCount; ++i) { packetBytes.Add(Convert.ToByte(byteStringSplit[i], 16)); } allPacketTimes.Add(time); allPacketBytes.Add(packetBytes); allPacketEndMarkers.Add(endCode); } else { // Unknown start code // throw error? break; } ++lineIndex; } int sequenceIdIndex = -1; int lastSequenceId = -1; for (int i = 0; i < allPacketBytes.Count; ++i) { bool sequenceIdError = false; Type packetType = DataPacket.GetPacketType(allPacketBytes[i]); object[] args; if (packetType == typeof(NonRmapPacket)) { if (sequenceIdIndex == -1) { sequenceIdIndex = getSequenceIdIndex(allPacketBytes); } int sequenceId = sequenceIdIndex == -1 ? 0 : allPacketBytes[i][sequenceIdIndex]; if (lastSequenceId == -1) { lastSequenceId = sequenceId; } else { sequenceIdError = !((sequenceId == 0 && lastSequenceId == 255) || sequenceId == lastSequenceId + 1); lastSequenceId = sequenceId; } args = new object[] { entryPort, exitPort, allPacketTimes[i], allPacketBytes[i], allPacketEndMarkers[i], sequenceIdIndex }; } else { args = new object[] { entryPort, exitPort, allPacketTimes[i], allPacketBytes[i], allPacketEndMarkers[i] }; } dynamic packet = Activator.CreateInstance(packetType, args); packet.SequenceIdError = sequenceIdError; packet.DuplicatePacketError = duplicatePacket[i]; if (!packet.Valid) { packet.TimeStamp = packet.TimeStamp.AddTicks(1); } if (packet.GetType() == typeof(DataPacket)) { packet.FormatError = true; } m_packets.Add(packet); } } }
/// <summary> /// Uploads the file. /// </summary> public void UploadFile(string srcFileName, RelativePath destPath, out bool fileAccepted) { if (!File.Exists(srcFileName)) { throw new ScadaException(CommonPhrases.FileNotFound); } RestoreConnection(); using (FileStream stream = new FileStream(srcFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { // request permission to upload file const int FileDataIndex = ArgumentIndex + 9; const int BlockCapacity = BufferLenght - FileDataIndex; long bytesToReadTotal = stream.Length; int blockCount = (int)Math.Ceiling((double)bytesToReadTotal / BlockCapacity); DataPacket request = CreateRequest(FunctionID.UploadFile); int index = ArgumentIndex; CopyInt32(0, outBuf, ref index); CopyInt32(blockCount, outBuf, ref index); CopyFileName(destPath.GetDirectoryID(), destPath.Path, outBuf, ref index); request.BufferLength = index; SendRequest(request); ReceiveResponse(request); fileAccepted = inBuf[ArgumentIndex] > 0; // upload file if (fileAccepted) { int blockNumber = 0; long bytesReadTotal = 0; bool endOfFile = false; request = null; while (!endOfFile) { // read from file int bytesToRead = (int)Math.Min(bytesToReadTotal - bytesReadTotal, BlockCapacity); int bytesRead = stream.Read(outBuf, FileDataIndex, bytesToRead); bytesReadTotal += bytesRead; endOfFile = bytesRead < bytesToRead || bytesReadTotal == bytesToReadTotal; // send data request = CreateRequest(FunctionID.UploadFile, 0, false); index = ArgumentIndex; CopyInt32(++blockNumber, outBuf, ref index); CopyBool(endOfFile, outBuf, ref index); CopyInt32(bytesRead, outBuf, ref index); request.BufferLength = FileDataIndex + bytesRead; SendRequest(request); OnProgress(blockNumber, blockCount); } if (request != null) { ReceiveResponse(request); } } } }
/// <summary> /// Downloads the file. /// </summary> public void DownloadFile(RelativePath relativePath, long offset, int count, bool readFromEnd, DateTime newerThan, Func <Stream> createStreamFunc, out DateTime fileAge, out FileReadingResult readingResult, out Stream stream) { if (createStreamFunc == null) { throw new ArgumentNullException(nameof(createStreamFunc)); } RestoreConnection(); DataPacket request = CreateRequest(FunctionID.DownloadFile); int index = ArgumentIndex; CopyFileName(relativePath.GetDirectoryID(), relativePath.Path, outBuf, ref index); CopyInt64(offset, outBuf, ref index); CopyInt32(count, outBuf, ref index); CopyBool(readFromEnd, outBuf, ref index); CopyTime(newerThan, outBuf, ref index); request.BufferLength = index; SendRequest(request); int prevBlockNumber = 0; fileAge = DateTime.MinValue; readingResult = FileReadingResult.Successful; stream = null; try { while (readingResult == FileReadingResult.Successful) { ReceiveResponse(request); index = ArgumentIndex; int blockNumber = GetInt32(inBuf, ref index); int blockCount = GetInt32(inBuf, ref index); fileAge = GetTime(inBuf, ref index); readingResult = (FileReadingResult)GetByte(inBuf, ref index); if (blockNumber != prevBlockNumber + 1) { ThrowBlockNumberException(); } if (readingResult == FileReadingResult.Successful || readingResult == FileReadingResult.EndOfFile) { if (stream == null) { stream = createStreamFunc(); } int bytesToWrite = GetInt32(inBuf, ref index); stream.Write(inBuf, index, bytesToWrite); } prevBlockNumber = blockNumber; OnProgress(blockNumber, blockCount); } } catch { stream?.Dispose(); stream = null; throw; } }
/// <summary> /// Receives a response from the server. /// </summary> protected DataPacket ReceiveResponse(DataPacket request) { DataPacket response = null; bool formatError = true; string errDescr = ""; int bytesToRead = HeaderLength + 2; int bytesRead; try { bytesRead = netStream.Read(inBuf, 0, bytesToRead); CommLog?.WriteAction(BuildReadingText(inBuf, 0, bytesToRead, bytesRead)); } catch (IOException) { ClientState = ClientState.Error; throw; } if (bytesRead == bytesToRead) { response = new DataPacket { TransactionID = BitConverter.ToUInt16(inBuf, 0), DataLength = BitConverter.ToInt32(inBuf, 2), SessionID = BitConverter.ToInt64(inBuf, 6), FunctionID = BitConverter.ToUInt16(inBuf, 14), Buffer = inBuf }; if (response.DataLength + 6 > inBuf.Length) { errDescr = Locale.IsRussian ? "длина данных слишком велика" : "data length is too big"; } else if (response.TransactionID != request.TransactionID) { errDescr = Locale.IsRussian ? "неверный идентификатор транзакции" : "incorrect transaction ID"; } else if (response.SessionID != SessionID && SessionID != 0) { errDescr = Locale.IsRussian ? "неверный идентификатор сессии" : "incorrect session ID"; } else if ((response.FunctionID & 0x7FFF) != request.FunctionID) { errDescr = Locale.IsRussian ? "неверный идентификатор функции" : "incorrect function ID"; } else { // read the rest of the data bytesToRead = response.DataLength - 10; bytesRead = ReadData(netStream, tcpClient.ReceiveTimeout, inBuf, HeaderLength + 2, bytesToRead); CommLog?.WriteAction(BuildReadingText(inBuf, HeaderLength + 2, bytesToRead, bytesRead)); if (bytesRead == bytesToRead) { formatError = false; responseDT = DateTime.UtcNow; // handle error response if ((response.FunctionID & 0x8000) > 0) { ErrorCode errorCode = (ErrorCode)inBuf[ArgumentIndex]; CommLog?.WriteError(errorCode.ToString()); throw new ProtocolException(errorCode); } } else { errDescr = Locale.IsRussian ? "не удалось прочитать все данные" : "unable to read all data"; } } } else { errDescr = Locale.IsRussian ? "не удалось прочитать заголовок пакета данных" : "unable to read data packet header"; } if (formatError) { throw new ScadaException(Locale.IsRussian ? "Некорректный формат данных, полученных от сервера: {0}" : "Incorrect format of data received from the server: {0}", errDescr); } return(response); }