public void PacketConsumer() { PacketStruct packetStruct; try { while (!terminate) { if (packetStructs.Count() > 0) { lock (packetLockObject) { packetStruct = packetStructs.Dequeue(); } int offset = packetStruct.dataOffset; byte len = packetStruct.packet[offset + 2]; int actualLen = packetStruct.dataLength; byte[] message = new byte[actualLen]; for (int i = 0; i < actualLen; i++) { message[i] = packetStruct.packet[offset + i]; } List <UserLevelObject> userLevelObjects = dataLinkHandler.PackUp(message); if (userLevelObjects == null) { continue; } Task.Factory.StartNew(() => ProcessObjects(userLevelObjects, packetStruct)); Thread.Sleep(100); } } } catch (Exception e) { } }
/// <summary> /// Processing answers from Simulator - Process Controller /// </summary> public void ProcessPCAnwers(TimeSpan timeout, CancellationToken token) { DataLinkHandler dataLinkHandler = new DataLinkHandler(); while (!token.IsCancellationRequested) { bool isSuccessful; IORequestBlock answer = IORequests.DequeueAnswer(out isSuccessful, timeout); if (isSuccessful) { bool isChange = false; RTU rtu; if ((rtu = dbContext.GetRTUByName(answer.ProcessControllerName)) != null) { switch (rtu.Protocol) { case IndustryProtocols.ModbusTCP: ModbusHandler mdbHandler = new ModbusHandler(); try { mdbHandler.UnpackData(answer.RcvBuff, answer.RcvMsgLength); switch (mdbHandler.Response.FunCode) { case FunctionCodes.ReadDiscreteInput: { BitReadResponse response = (BitReadResponse)mdbHandler.Response; var responsePVCount = answer.Flags; ushort varAddr = answer.ReqAddress; for (int i = 0; i < responsePVCount; i++, varAddr++) { ProcessVariable pv; if (rtu.GetProcessVariableByAddress(varAddr, out pv)) { Digital target = (Digital)pv; try { bool isOpened = response.BitValues[i]; if (target.State != target.ValidStates[isOpened ? 1 : 0]) { isChange = true; target.State = target.ValidStates[isOpened ? 1 : 0]; Console.WriteLine(" CHANGE! Digital variable {0}, state: {1}", target.Name, target.State); dMSProxy.ChangeOnSCADADigital(target.Name, target.State); } } catch { Console.WriteLine("Digital variable {0}, state: INVALID", target.Name); } } } if (isChange) { ScadaModelParser parser = new ScadaModelParser(); parser.SerializeScadaModel(); } } break; // analog input case FunctionCodes.ReadInputRegisters: { RegisterReadResponse response = (RegisterReadResponse)mdbHandler.Response; var responsePVCount = answer.Flags; ushort varAddr = answer.ReqAddress; for (int i = 0; i < responsePVCount; i++, varAddr++) { ProcessVariable pv; if (rtu.GetProcessVariableByAddress(varAddr, out pv)) { Analog target = (Analog)pv; try { ushort newRawAcqValue = response.RegValues[target.RelativeAddress]; float newAcqValue; AnalogProcessor.RawValueToEGU(target, newRawAcqValue, out newAcqValue); if (target.AcqValue != newAcqValue) { isChange = true; target.RawAcqValue = newRawAcqValue; target.AcqValue = newAcqValue; Console.WriteLine(" CHANGE! Analog variable {0}, AcqValue: {1}", target.Name, target.AcqValue); //to do: propagacija analogih promena(ako se secate Pavlica je prvo rekao da nam to ne treba da samo jednom zakucamo vrednost na pocetku) xD dMSProxy.ChangeOnSCADAAnalog(target.Name, target.AcqValue); } } catch { // Console.WriteLine("Digital variable {0}, state: INVALID", target.Name); } } } if (isChange) { ScadaModelParser parser = new ScadaModelParser(); parser.SerializeScadaModel(); } } break; } } catch (Exception e) { Console.WriteLine(e.Message); } break; case IndustryProtocols.DNP3TCP: byte len = answer.RcvBuff[2]; byte actualLen = (byte)(2 + 1 + 5 + 2); // start + len + ctrl + dest + source + crc len -= 5; // minus header while (len > 0) { if (len < 16) { // last chunk actualLen += (byte)(len + 2); break; } actualLen += (byte)(16 + 2); len -= 16; } byte[] message = new byte[actualLen]; for (int i = 0; i < actualLen; i++) { message[i] = answer.RcvBuff[i]; } List <UserLevelObject> userLevelObjects = dataLinkHandler.PackUp(message); if (userLevelObjects == null) { continue; } DNP3UserLayerHandler dNP3UserLayerHandler = new DNP3UserLayerHandler(new DNP3Handler(), dbContext); List <Tuple <string, float> > tuples = dNP3UserLayerHandler.ReadAllAnalogInputPointsReadResponse(userLevelObjects, rtu.Name); foreach (Tuple <string, float> tuple in tuples) { try { dMSProxy.ChangeOnSCADAAnalog(tuple.Item1, tuple.Item2); } catch { dMSProxy = new DMSSCADAProxy(); } } break; } } } } Console.WriteLine("ProcessPCAnswers.shutdown=true"); return; }
void ProcessRequest(TcpClient client) { DataLinkHandler dataLinkHandler = new DataLinkHandler(); Byte[] bytes = new Byte[1000]; NetworkStream stream = client.GetStream(); byte actualLen = 0; int i = 0; while ((i = stream.Read(bytes, 0, bytes.Length)) != 0) { byte len = bytes[2]; actualLen = (byte)(2 + 1 + 5 + 2); // start + len + ctrl + dest + source + crc len -= 5; // minus header while (len > 0) { if (len < 16) { // last chunk actualLen += (byte)(len + 2); break; } actualLen += (byte)(16 + 2); len -= 16; } byte[] message = new byte[actualLen]; for (i = 0; i < actualLen; i++) { message[i] = bytes[i]; } List <UserLevelObject> userLevelObjects = dataLinkHandler.PackUp(message); if (userLevelObjects == null) { continue; } DNP3Handler dNP3Handler = new DNP3Handler(); DNP3UserLayerHandler userLayer = new DNP3UserLayerHandler(dNP3Handler); List <byte[]> segments = userLayer.ReadAllAnalogInputPointsResponse(userLevelObjects); int offset = 0; foreach (byte[] segment in segments) { try { stream.Write(segment, offset, segment.Count()); } catch (Exception e) { } } } }