public void DeactivateNVL(NodeVL vl) { Iec61850State iecs = vl.GetIecs(); if (iecs != null) { if (vl.urcb != null) { NodeData d = (NodeData)vl.urcb.Parent; List <NodeData> ndar = new List <NodeData>(); NodeBase b; if ((b = d.FindChildNode("RptEna")) != null) { NodeData n = new NodeData(b.Name); n.DataType = ((NodeData)b).DataType; n.DataValue = false; ndar.Add(n); } if ((b = d.FindChildNode("GI")) != null) { NodeData n = new NodeData(b.Name); n.DataType = ((NodeData)b).DataType; n.DataValue = false; ndar.Add(n); } iecs.Send(ndar.ToArray(), d.CommAddress, ActionRequested.Write); vl.Activated = false; vl.urcb = null; } } else { Logger.getLogger().LogError("Basic structure not found!"); } }
public int Receive(Iec61850State iecs) { iecs.logger.LogDebug("Iso.Receive"); IsoCotp.CotpReceiveResult res = isoCotp.Receive(iecs); byte[] buffer = iecs.msMMS.GetBuffer(); long len = iecs.msMMS.Length; iecs.logger.LogDebugBuffer("Rec buffer", buffer, 0, len); if (res == IsoCotp.CotpReceiveResult.DATA) { // Incoming data iecs.logger.LogDebug(String.Format("Calling isoSess.parseMessage with data len {0}", iecs.msMMS.Length)); IsoSess.IsoSessionIndication sess = isoSess.parseMessage(buffer, (int)len); if (sess == IsoSess.IsoSessionIndication.SESSION_DATA) { int dataPos = isoPres.parseUserData(buffer, (int)isoSess.UserDataIndex, (int)(len - isoSess.UserDataIndex)); if (dataPos > 0) { // Adjust the stream position to the MMS message start iecs.msMMS.Seek(dataPos, SeekOrigin.Begin); iecs.mms.ReceiveData(iecs); } else { iecs.ostate = IsoProtocolState.OSI_STATE_SHUTDOWN; } } else if (sess == IsoSess.IsoSessionIndication.SESSION_CONNECT) { iecs.ostate = IsoProtocolState.OSI_STATE_SHUTDOWN; int dataPosPres = isoPres.parseAcceptMessage(buffer, isoSess.UserDataIndex, (int)(len - isoSess.UserDataIndex)); if (dataPosPres > 0) { IsoAcse.AcseIndication acseRes = isoAcse.parseMessage(buffer, isoPres.UserDataIndex, (int)(len - isoPres.UserDataIndex)); if (acseRes == IsoAcse.AcseIndication.ACSE_ASSOCIATE) { iecs.msMMS.Seek(isoAcse.UserDataIndex, SeekOrigin.Begin); iecs.logger.LogDebug("Read at " + isoAcse.UserDataIndex); iecs.mms.ReceiveData(iecs); iecs.ostate = IsoProtocolState.OSI_CONNECTED; } } } else { iecs.ostate = IsoProtocolState.OSI_STATE_SHUTDOWN; } iecs.msMMS = new MemoryStream(); } else if (res == IsoCotp.CotpReceiveResult.INIT) { iecs.ostate = IsoProtocolState.OSI_CONNECT_PRES; } else if (res == IsoCotp.CotpReceiveResult.ERROR) { iecs.ostate = IsoProtocolState.OSI_STATE_SHUTDOWN; } return(0); }
void OnReadDataClick(object sender, EventArgs e) { NodeBase data = (NodeBase)(sender as ToolStripItem).Tag; Iec61850State iecs = data.GetIecs(); NodeBase[] ndarr = new NodeBase[1]; ndarr[0] = data; iecs.Send(ndarr, data.CommAddress, ActionRequested.Read); }
void OnSendCommandAsStructureClick(object sender, EventArgs e) { NodeBase data = (NodeBase)(sender as ToolStripItem).Tag; Iec61850State iecs = data.GetIecs(); NodeBase[] ndarr = new NodeBase[1]; SendCommand(data, iecs, ActionRequested.WriteAsStructure); }
void OnDeleteNVLClick(object sender, EventArgs e) { NodeVL nvl = (NodeVL)(sender as ToolStripItem).Tag; Iec61850State iecs = nvl.GetIecs(); NodeBase[] ndarr = new NodeBase[1]; ndarr[0] = nvl; iecs.Send(ndarr, nvl.CommAddress, ActionRequested.DefineNVL); }
public int SendReleaseAcse(Iec61850State iecs) { byte[] b1 = new byte[1024]; int len = isoAcse.createReleaseRequestMessage(b1, 0); b1.CopyTo(iecs.sendBuffer, IsoCotp.COTP_HDR_DT_SIZEOF + IsoTpkt.TPKT_SIZEOF); iecs.sendBytes = len; isoCotp.Send(iecs); return(0); }
void OnFileGetClick(object sender, EventArgs e) { NodeBase nfi = (NodeBase)(sender as ToolStripItem).Tag; Iec61850State iecs = nfi.GetIecs(); CommAddress ad = new CommAddress(); NodeBase[] ndarr = new NodeBase[1]; ndarr[0] = nfi; iecs.Send(ndarr, ad, ActionRequested.OpenFile); }
void OnDefineNVLClick(object sender, EventArgs e) { NodeVL nvl = (NodeVL)(sender as ToolStripItem).Tag; Iec61850State iecs = nvl.GetIecs(); List <NodeBase> ndar = new List <NodeBase>(); foreach (NodeBase n in nvl.GetChildNodes()) { ndar.Add(n); } iecs.Send(ndar.ToArray(), nvl.CommAddress, ActionRequested.DefineNVL); }
public int Send(Iec61850State iecs) { if (iecs.ostate == IsoProtocolState.OSI_CONNECT_PRES) { iecs.ostate = IsoProtocolState.OSI_CONNECT_PRES_WAIT; SendPresentationInit(iecs); } else { SendData(iecs); } return(0); }
public int Send(Iec61850State iecs) { // Make COTP data telegramm int offs = IsoTpkt.TPKT_SIZEOF; int maxLen = 1 << options.tpduSize; // max COTP len int maxDataLen = maxLen - COTP_HDR_DT_SIZEOF; // max DATA len if (iecs.sendBytes <= maxDataLen) { // Original handling, same as before / short datagram without fragmenting iecs.sendBuffer[offs++] = COTP_HDR_DT_SIZEOF - 1; // cotp.hdrlen wihout this field iecs.sendBuffer[offs++] = COTP_CODE_DT; // code iecs.sendBuffer[offs++] = COTP_PACKET_COMPLETE; // number "complete" for "short" datagrams iecs.sendBytes += offs; IsoTpkt.Send(iecs); } else { // Long data, need to fragment to TPKT + COTP fragments // Technique: allocate a new buffer. Keep the original data. // Copy original data "per partes" to the new buffer, adding TPKT and COTP headers // and sending the fragments via TCP. // Last COTP fragments must be marked 0x80, others 0x00 // Possible optimization: for the first fragment use the original buffer (spare 1 copy operation) NOT IMPLEMENTED int dLen = iecs.sendBytes; // Actual data length int sLen = 0; // Actual sent data length byte[] originalData = iecs.sendBuffer; iecs.sendBuffer = dataReserveBuffer; // Use saved / recycled buffer dataReserveBuffer = originalData; // Save original buffer to reserve for future use / recycling saves allocation oper. const int dOffs = IsoTpkt.TPKT_SIZEOF + COTP_HDR_DT_SIZEOF; while (dLen > 0) { iecs.sendBytes = Math.Min(dLen, maxDataLen); Array.Copy(originalData, dOffs + sLen, iecs.sendBuffer, dOffs, iecs.sendBytes); dLen -= iecs.sendBytes; sLen += iecs.sendBytes; offs = IsoTpkt.TPKT_SIZEOF; // reinit offset iecs.sendBuffer[offs++] = COTP_HDR_DT_SIZEOF - 1; // cotp.hdrlen wihout this field iecs.sendBuffer[offs++] = COTP_CODE_DT; // code iecs.sendBuffer[offs++] = (byte)((dLen > 0) ? COTP_PACKET_FRAGMENT : COTP_PACKET_COMPLETE); // number "fragment" or "complete" iecs.sendBytes += offs; IsoTpkt.Send(iecs); } } return(0); }
public int Receive(Iec61850State iecs) { int ret = 0; if (ret == 0) { iecs.ostate = IsoProtocolState.OSI_CONNECTED; } else { iecs.ostate = IsoProtocolState.OSI_STATE_SHUTDOWN; } return(ret); }
int layeredSend(Iec61850State iecs) { // Make COTP data telegramm directly // MMS already encoded in iecs.msMMSout iecs.sendBytes = (int)iecs.msMMSout.Length; int spos = isoSess.createDataSpdu(iecs.sendBuffer, IsoCotp.COTP_HDR_DT_SIZEOF + IsoTpkt.TPKT_SIZEOF); int dpos = isoPres.createUserData(iecs.sendBuffer, spos, iecs.sendBytes); iecs.msMMSout.Seek(0, SeekOrigin.Begin); iecs.msMMSout.Read(iecs.sendBuffer, dpos, iecs.sendBytes); iecs.sendBytes += dpos - IsoCotp.COTP_HDR_DT_SIZEOF - IsoTpkt.TPKT_SIZEOF; isoCotp.Send(iecs); return(0); }
public Iec61850Model(Iec61850State iecs) { ied = new NodeIed("ied", this); iec = new NodeIed("iec", this); lists = new NodeIed("lists", this); urcbs = new NodeIed("urcbs", this); brcbs = new NodeIed("brcbs", this); files = new NodeIed("files", this); enums = new NodeIed("enums", this); ied.iecs = iecs; iec.iecs = iecs; iec.IsIecModel = true; lists.iecs = iecs; files.iecs = iecs; urcbs.iecs = iecs; brcbs.iecs = iecs; enums.iecs = iecs; }
internal ControllableSignalsDialog(NodeBase data /*, EventHandler onNVListChanged)*/) { InitializeComponent(); this.data = data; this.TopMost = true; button2.Enabled = false; button3.Enabled = false; Iec61850State iecs = data.GetIecs(); NodeBase[] datacns = data.GetChildNodes(); foreach (NodeLN datacn in datacns) { NodeBase[] nfccns = datacn.GetChildNodes(); foreach (NodeFC nfccn in nfccns) { if (nfccn.Name == "CO") { NodeBase[] ndatacns = nfccn.GetChildNodes(); foreach (NodeDO ndatacn in ndatacns) { if (ndatacn.Name.Contains("SPCSO") || ndatacn.Name.Contains("RcdTrg") || ndatacn.Name.Contains("Pos")) { NodeBase ctlval = iecs.DataModel.ied.FindNodeByAddress(ndatacn.CommAddress.Domain + "/" + ndatacn.CommAddress.Variable + "$Oper$ctlVal"); NodeBase desc = iecs.DataModel.ied.FindNodeByAddress(ndatacn.CommAddress.Domain + "/" + ndatacn.CommAddress.Variable.Replace("$CO$", "$DC$") + "$d"); if (ctlval != null) { ListViewItem item = new ListViewItem(new[] { ctlval.IecAddress, ((desc != null) ? (desc as NodeData).StringValue : ""), }); item.Tag = ctlval; listView1.Items.Add(item); } } } } } } }
public int SendInit(Iec61850State iecs) { //Reset dstref Reset(iecs.cp); // Make COTP init telegramm int offs = IsoTpkt.TPKT_SIZEOF; int optof = COTP_HDR_IDX_OPTION; iecs.sendBuffer[offs + COTP_HDR_IDX_HDRLEN] = (byte)(COTP_HDR_CR_SIZEOF + options.getSize()); iecs.sendBuffer[offs + COTP_HDR_IDX_CODE] = COTP_CODE_CR; Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(m_COTP_dstref)), 0, iecs.sendBuffer, offs + COTP_HDR_IDX_DSTREF, 2); Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder(m_COTP_srcref)), 0, iecs.sendBuffer, offs + COTP_HDR_IDX_SRCREF, 2); iecs.sendBuffer[offs + optof++] = m_COTP_option; // Parameters iecs.sendBuffer[offs + optof++] = COTP_PCODE_TSIZ; iecs.sendBuffer[offs + optof++] = 1; iecs.sendBuffer[offs + optof++] = options.tpduSize; if (options.tSelDst.size > 0) { iecs.sendBuffer[offs + optof++] = COTP_PCODE_DSAP; iecs.sendBuffer[offs + optof++] = options.tSelDst.size; byte[] bt = options.tSelDst.GetBytes(); Array.Copy(bt, 0, iecs.sendBuffer, offs + optof, options.tSelDst.size); optof += options.tSelDst.size; } if (options.tSelSrc.size > 0) { iecs.sendBuffer[offs + optof++] = COTP_PCODE_SSAP; iecs.sendBuffer[offs + optof++] = options.tSelSrc.size; Array.Copy(options.tSelSrc.GetBytes(), 0, iecs.sendBuffer, offs + optof, options.tSelSrc.size); } iecs.sendBytes = offs + COTP_HDR_CR_SIZEOF + 1 + options.getSize(); IsoTpkt.Send(iecs); return(0); }
public CotpReceiveResult Receive(Iec61850State iecs) { CotpReceiveResult res = CotpReceiveResult.ERROR; int ret; iecs.logger.LogDebug("IsoCotp.Receive"); if (iecs.dataBuffer[1] == COTP_CODE_DT) // Data Transfer { iecs.msMMS.Write(iecs.dataBuffer, 3, iecs.dataBufferIndex - 3); if ((iecs.dataBuffer[2] & COTP_PACKET_COMPLETE) == 0) { return(CotpReceiveResult.WAIT); // waiting for the rest of the datagram from other COTP frames } //iecs.logger.LogDebug(String.Format("Calling IsoSess.Receive with data len {0}", iecs.msMMS.Length)); return(res = CotpReceiveResult.DATA); } else if (iecs.dataBuffer[1] == COTP_CODE_CC) // Connect Confirmation { iecs.msMMS.Write(iecs.dataBuffer, 0, iecs.dataBufferIndex); iecs.logger.LogDebug(String.Format("Calling ParseCOTPSessionInit with data len {0}", iecs.msMMS.Length)); ret = ParseCOTPSessionInit(iecs); if (ret == 0) { res = CotpReceiveResult.INIT; } else { res = CotpReceiveResult.ERROR; } } else if (iecs.dataBuffer[1] == COTP_CODE_DR) // DisConnect Request { iecs.logger.LogDebug(String.Format("COTP Disconnect Request received, error")); res = CotpReceiveResult.ERROR; } // Reset the stream iecs.msMMS = new MemoryStream(); return(res); }
int ParseCOTPSessionInit(Iec61850State iecs) { // Read COTP init response iecs.msMMS.Seek(1, SeekOrigin.Begin); // skip hdrlen if (iecs.msMMS.ReadByte() != COTP_CODE_CC) { return(-1); // code NOK } iecs.msMMS.Seek(2, SeekOrigin.Current); // skip dstref Byte[] b = new Byte[2]; iecs.msMMS.Read(b, 0, 2); m_COTP_dstref = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(b, 0)); // srcref iecs.msMMS.Seek(1, SeekOrigin.Current); // skip option // Parameters while (iecs.msMMS.Position < iecs.msMMS.Length - 1) { int code = iecs.msMMS.ReadByte(); if (code == COTP_PCODE_TSIZ) // option size { iecs.msMMS.Seek(1, SeekOrigin.Current); // skip len always 1 options.tpduSize = (byte)iecs.msMMS.ReadByte(); } else if (code == COTP_PCODE_DSAP) // Destination SAP = locally source SAP { options.tSelSrc.size = (byte)iecs.msMMS.ReadByte(); // len Byte[] b2 = new Byte[4]; iecs.msMMS.Read(b2, 0, options.tSelSrc.size); options.tSelSrc.value = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(b2, 0)); // srcref } else if (code == COTP_PCODE_SSAP) // Source SAP = locally destination SAP { options.tSelDst.size = (byte)iecs.msMMS.ReadByte(); // len Byte[] b2 = new Byte[4]; iecs.msMMS.Read(b2, 0, options.tSelDst.size); options.tSelDst.value = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(b2, 0)); // dstref } } return(0); //O.K. }
void OnWriteDataClick(object sender, EventArgs e) { NodeData data = (NodeData)(sender as ToolStripItem).Tag; Iec61850State iecs = data.GetIecs(); NodeData[] ndarr = new NodeData[1]; ndarr[0] = new NodeData(data.Name); ndarr[0].DataType = data.DataType; ndarr[0].DataValue = data.DataValue; ndarr[0].DataParam = data.DataParam; EditValue ev = new EditValue(ndarr[0]); DialogResult r = ev.ShowDialog(); if (r == DialogResult.OK) { iecs.Send(ndarr, data.Parent.CommAddress, ActionRequested.Write); Thread.Sleep(300); ndarr = new NodeData[1]; ndarr[0] = data; iecs.Send(ndarr, data.CommAddress, ActionRequested.Read); } }
int fastSend(Iec61850State iecs) { // Make COTP data telegramm directly int offs = IsoTpkt.TPKT_SIZEOF; // MMS already encoded in iecs.msMMSout iecs.sendBytes = (int)iecs.msMMSout.Length; iecs.sendBuffer[offs++] = 0x02; // cotp.hdrlen iecs.sendBuffer[offs++] = IsoCotp.COTP_CODE_DT; // code iecs.sendBuffer[offs++] = 0x80; // number "complete" iecs.sendBuffer[offs++] = 0x01; // giveTokensPDU.type iecs.sendBuffer[offs++] = 0x00; // giveTokensPDU.hdrlen iecs.sendBuffer[offs++] = 0x01; // dataTransferPDU.type iecs.sendBuffer[offs++] = 0x00; // dataTransferPDU.hdrlen iecs.sendBuffer[offs++] = 0x61; // pres.dtpdu_tag iecs.sendBuffer[offs++] = 0x82; // pres.dtpdu_len_code Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)(iecs.sendBytes + 15 - 4))), 0, iecs.sendBuffer, offs, 2); // pres.dtpdu_len offs += 2; iecs.sendBuffer[offs++] = 0x30; // pres.sequ_tag iecs.sendBuffer[offs++] = 0x82; // pres.sequ_len_code Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)(iecs.sendBytes + 15 - 8))), 0, iecs.sendBuffer, offs, 2); // pres.sequ_len offs += 2; iecs.sendBuffer[offs++] = 0x02; // pres.context_tag iecs.sendBuffer[offs++] = 0x01; // pres.context_len iecs.sendBuffer[offs++] = 0x03; // pres.context_val iecs.sendBuffer[offs++] = 0xa0; // pres.data_tag iecs.sendBuffer[offs++] = 0x82; // pres.data_len_code Array.Copy(BitConverter.GetBytes(IPAddress.HostToNetworkOrder((short)(iecs.sendBytes))), 0, iecs.sendBuffer, offs, 2); // pres.sequ_len offs += 2; iecs.msMMSout.Seek(0, SeekOrigin.Begin); iecs.msMMSout.Read(iecs.sendBuffer, offs, iecs.sendBytes); iecs.sendBytes += offs; IsoTpkt.Send(iecs); return(0); }
private void button_Click(object sender, EventArgs e) { NodeData var = (NodeData)listView1.SelectedItems[0].Tag; Iec61850State iecs = var.GetIecs(); NodeData data = (NodeData)listView1.SelectedItems[0].Tag; CommandParams cPar = iecs.Controller.PrepareSendCommand((NodeBase)listView1.SelectedItems[0].Tag); if (cPar != null) { if ((String)(((Button)sender).Tag) == "true") { cPar.ctlVal = true; } else { cPar.ctlVal = false; } iecs.Controller.SendCommand(data, cPar, ActionRequested.WriteAsStructure); } return; }
private void processDataSet(XmlNode LNNodeCn, NodeBase NLNb, Iec61850State iecf, string IEDName, string LNNodeName) { NodeVL VL = new NodeVL(LNNodeName + "$" + getStringAttribute(LNNodeCn, "name")); VL.Defined = true; NodeBase VLNb = NLNb.AddChildNode(VL); foreach (XmlNode DataSetCn in LNNodeCn.ChildNodes) { if (DataSetCn.Name == "FCDA") { string addr = getAddrFromFCDA(DataSetCn); NodeBase Nb = (iecf.DataModel.ied as NodeIed).FindNodeByAddress(IEDName + getStringAttribute(DataSetCn, "ldInst"), getAddrFromFCDA(DataSetCn)); if (Nb != null) { VLNb.LinkChildNode(Nb); } } } }
int SendPresentationInit(Iec61850State iecs) { // Make session & present. init telegramm byte[] b1 = new byte[1024]; byte[] b2 = new byte[1024]; //cp = new IsoConnectionParameters(); bool dbg = false; // local debug enable var // MMS Initiate already encoded in iecs.msMMSout if (dbg) { iecs.logger.LogDebugBuffer("Send MMS", iecs.msMMSout.GetBuffer(), 0, iecs.msMMSout.Length); } int len = isoAcse.createAssociateRequestMessage(iecs.cp, b1, 0, iecs.msMMSout.GetBuffer(), (int)iecs.msMMSout.Length); if (dbg) { iecs.logger.LogDebugBuffer("Send Acse", b1, 0, len); } len = isoPres.createConnectPdu(iecs.cp, b2, b1, len); if (dbg) { iecs.logger.LogDebugBuffer("Send Pres", b2, 0, len); } len = isoSess.createConnectSpdu(iecs.cp, b1, b2, len); if (dbg) { iecs.logger.LogDebugBuffer("Send Sess", b1, 0, len); } b1.CopyTo(iecs.sendBuffer, IsoCotp.COTP_HDR_DT_SIZEOF + IsoTpkt.TPKT_SIZEOF); iecs.sendBytes = len; isoCotp.Send(iecs); return(0); }
void OnFileListClick(object sender, EventArgs e) { NodeBase nfi = (NodeBase)(sender as ToolStripItem).Tag; Iec61850State iecs = nfi.GetIecs(); CommAddress ad = new CommAddress(); NodeBase[] ndarr = new NodeBase[1]; ndarr[0] = nfi; if (!(nfi is NodeFile)) { NodeData nd = new NodeData("x"); nd.DataType = scsm_MMS_TypeEnum.visible_string; nd.DataValue = "/"; EditValue ev = new EditValue(nd); DialogResult r = ev.ShowDialog(); if (r == DialogResult.OK) { ad.Variable = nd.StringValue; } } iecs.Send(ndarr, ad, ActionRequested.GetDirectory); }
void OnDeactivateNVLClick(object sender, EventArgs e) { NodeVL vl = (NodeVL)(sender as ToolStripItem).Tag; Iec61850State iecs = vl.GetIecs(); if (iecs != null) { if (vl.urcb != null) { NodeData d = (NodeData)vl.urcb.Parent; List <NodeData> ndar = new List <NodeData>(); NodeBase b; if ((b = d.FindChildNode("RptEna")) != null) { NodeData n = new NodeData(b.Name); n.DataType = ((NodeData)b).DataType; n.DataValue = false; ndar.Add(n); } if ((b = d.FindChildNode("GI")) != null) { NodeData n = new NodeData(b.Name); n.DataType = ((NodeData)b).DataType; n.DataValue = false; ndar.Add(n); } iecs.Send(ndar.ToArray(), d.CommAddress, ActionRequested.Write); vl.Activated = false; vl.urcb = null; } } else { MessageBox.Show("Basic structure not found!"); } }
public int Send(Iec61850State iecs) { return(0); }
public IsoAcse(Iec61850State iec) { iecs = iec; }
public void ActivateNVL(NodeVL vl) { //Logger.getLogger().LogError("Function not active, try to configure an RCB!"); //return; NodeBase ur = null; Iec61850State iecs = vl.GetIecs(); bool retry; if (iecs != null) { do { ur = (NodeData)iecs.DataModel.ied.FindNodeByValue(scsm_MMS_TypeEnum.visible_string, vl.IecAddress, ref ur); if (ur == null || ur.Parent == null) { Logger.getLogger().LogError("Suitable URCB not found, list cannot be activated!"); return; } retry = !ur.Parent.Name.ToLower().Contains("rcb"); vl.urcb = (NodeData)ur; NodeData d = (NodeData)vl.urcb.Parent; NodeData b; if ((b = (NodeData)d.FindChildNode("Resv")) != null) { // Resv is always a boolean // If true then the rcb is occupied and we need to find another one if ((bool)b.DataValue) { retry = true; } } } while (retry); if (vl.urcb != null) { NodeData d = (NodeData)vl.urcb.Parent; List <NodeData> ndar = new List <NodeData>(); NodeBase b; if ((b = d.FindChildNode("Resv")) != null) { NodeData n = new NodeData(b.Name); n.DataType = ((NodeData)b).DataType; n.DataValue = true; ndar.Add(n); } if ((b = d.FindChildNode("DatSet")) != null) { NodeData n = new NodeData(b.Name); n.DataType = ((NodeData)b).DataType; n.DataValue = ((NodeData)b).DataValue; ndar.Add(n); } if ((b = d.FindChildNode("OptFlds")) != null) { NodeData n = new NodeData(b.Name); n.DataType = ((NodeData)b).DataType; n.DataValue = new byte[] { 0x7c, 0x00 }; n.DataParam = 6; ndar.Add(n); } if ((b = d.FindChildNode("TrgOps")) != null) { NodeData n = new NodeData(b.Name); n.DataType = ((NodeData)b).DataType; n.DataValue = new byte[] { 0x74 }; n.DataParam = 2; ndar.Add(n); } if ((b = d.FindChildNode("RptEna")) != null) { NodeData n = new NodeData(b.Name); n.DataType = ((NodeData)b).DataType; n.DataValue = true; ndar.Add(n); } if ((b = d.FindChildNode("GI")) != null) { NodeData n = new NodeData(b.Name); n.DataType = ((NodeData)b).DataType; n.DataValue = true; ndar.Add(n); } iecs.Send(ndar.ToArray(), d.CommAddress, ActionRequested.Write); vl.Activated = true; } } else { Logger.getLogger().LogError("Basic structure not found!"); } }
public Iec61850Controller(Iec61850State iecs, Iec61850Model model) { this.iecs = iecs; this.model = model; }
private void WorkerThreadProc(object obj) { Scsm_MMS_Worker self = (Scsm_MMS_Worker)obj; iecs = new Iec61850State(); iecs.hostname = self.isoParameters.hostname; // due to tcps inheritance iecs.port = self.isoParameters.port; // due to tcps inheritance iecs.cp = self.isoParameters; iecs.logger = Logger.getLogger(); _env.winMgr.BindToCapture(iecs); _waitHandles[0] = iecs.connectDone; _waitHandles[1] = iecs.receiveDone; _waitHandles[2] = iecs.sendDone; _waitHandles[3] = new ManualResetEvent(false); // end thread _waitHandles[4] = iecs.sendQueueWritten; //DateTime tout = null; CommAddress ad = new CommAddress(); DateTime IdentifyTimeoutBase = new DateTime(); TimeSpan IdentifyTimeout = new TimeSpan(0, 0, 5); // 5 sec while (self._run) { switch (iecs.tstate) { case TcpProtocolState.TCP_STATE_START: iecs.logger.LogInfo("[TCP_STATE_START]"); iecs.kstate = IsoTpktState.TPKT_RECEIVE_START; iecs.ostate = IsoProtocolState.OSI_STATE_START; iecs.istate = Iec61850lStateEnum.IEC61850_STATE_START; TcpRw.StartClient(iecs); break; case TcpProtocolState.TCP_STATE_SHUTDOWN: iecs.logger.LogInfo("[TCP_STATE_SHUTDOWN]"); Stop(); Thread.Sleep(10000); iecs.tstate = TcpProtocolState.TCP_STATE_START; break; case TcpProtocolState.TCP_CONNECTED: switch (iecs.ostate) { case IsoProtocolState.OSI_CONNECT_COTP: iecs.logger.LogInfo("[OSI_CONNECT_COTP]"); iecs.ostate = IsoProtocolState.OSI_CONNECT_COTP_WAIT; iecs.iso.SendCOTPSessionInit(iecs); break; case IsoProtocolState.OSI_CONNECT_PRES: iecs.logger.LogInfo("[OSI_CONNECT_PRES]"); // This cannot be before Send, but is issued inside Send chain before TCP send // iecs.ostate = IsoProtocolState.OSI_CONNECT_PRES_WAIT; iecs.mms.SendInitiate(iecs); break; case IsoProtocolState.OSI_CONNECTED: switch (iecs.istate) { case Iec61850lStateEnum.IEC61850_STATE_START: if (iecs.DataModel.ied.Identify) { iecs.logger.LogInfo("[IEC61850_STATE_START] (Send IdentifyRequest)"); iecs.istate = Iec61850lStateEnum.IEC61850_CONNECT_MMS_WAIT; iecs.mms.SendIdentify(iecs); IdentifyTimeoutBase = DateTime.UtcNow; } else { iecs.istate = Iec61850lStateEnum.IEC61850_READ_NAMELIST_DOMAIN; } break; case Iec61850lStateEnum.IEC61850_CONNECT_MMS_WAIT: // If we wait for Identify response too long, continue without it if (DateTime.UtcNow.Subtract(IdentifyTimeout).CompareTo(IdentifyTimeoutBase) > 0) { // Timeout expired iecs.istate = Iec61850lStateEnum.IEC61850_READ_NAMELIST_DOMAIN; iecs.logger.LogWarning("MMS Identify message not supported by server, although declared in ServicesSupportedCalled bitstring"); } break; case Iec61850lStateEnum.IEC61850_READ_NAMELIST_DOMAIN: iecs.logger.LogDebug("[IEC61850_READ_NAMELIST_DOMAIN]"); iecs.istate = Iec61850lStateEnum.IEC61850_READ_NAMELIST_DOMAIN_WAIT; iecs.mms.SendGetNameListDomain(iecs); break; case Iec61850lStateEnum.IEC61850_READ_NAMELIST_VAR: iecs.logger.LogDebug("[IEC61850_READ_NAMELIST_VAR]"); iecs.istate = Iec61850lStateEnum.IEC61850_READ_NAMELIST_VAR_WAIT; iecs.mms.SendGetNameListVariables(iecs); break; case Iec61850lStateEnum.IEC61850_READ_ACCESSAT_VAR: iecs.logger.LogDebug("[IEC61850_READ_ACCESSAT_VAR]"); iecs.istate = Iec61850lStateEnum.IEC61850_READ_ACCESSAT_VAR_WAIT; iecs.mms.SendGetVariableAccessAttributes(iecs); break; case Iec61850lStateEnum.IEC61850_READ_MODEL_DATA: if (_env.dataReadOnStartup) { iecs.logger.LogDebug("[IEC61850_READ_MODEL_DATA]"); CommAddress adr = new CommAddress(); adr.Domain = null; adr.Variable = null; adr.owner = null; NodeBase[] data = new NodeBase[1]; // Issue reads by FC level data[0] = iecs.DataModel.ied.GetActualChildNode().GetActualChildNode().GetActualChildNode(); WriteQueueElement wqel = new WriteQueueElement(data, adr, ActionRequested.Read); iecs.istate = Iec61850lStateEnum.IEC61850_READ_MODEL_DATA_WAIT; iecs.mms.SendRead(iecs, wqel); } else { iecs.logger.LogDebug("[IEC61850_READ_MODEL_DATA] - Skipped due to a presetting"); iecs.istate = Iec61850lStateEnum.IEC61850_READ_NAMELIST_NAMED_VARIABLE_LIST; } break; case Iec61850lStateEnum.IEC61850_READ_NAMELIST_NAMED_VARIABLE_LIST: iecs.logger.LogDebug("[IEC61850_READ_NAMELIST_NAMED_VARIABLE_LIST]"); iecs.istate = Iec61850lStateEnum.IEC61850_READ_NAMELIST_NAMED_VARIABLE_LIST_WAIT; iecs.mms.SendGetNameListNamedVariableList(iecs); break; case Iec61850lStateEnum.IEC61850_READ_ACCESSAT_NAMED_VARIABLE_LIST: iecs.logger.LogDebug("[IEC61850_READ_ACCESSAT_NAMED_VARIABLE_LIST]"); iecs.istate = Iec61850lStateEnum.IEC61850_READ_ACCESSAT_NAMED_VARIABLE_LIST_WAIT; if (iecs.mms.SendGetNamedVariableListAttributes(iecs) != 0) { // No VarLists iecs.logger.LogInfo("Init end: [IEC61850_FREILAUF]"); iecs.istate = Iec61850lStateEnum.IEC61850_MAKEGUI; } break; case Iec61850lStateEnum.IEC61850_MAKEGUI: iecs.logger.LogDebug("[IEC61850_MAKEGUI]"); iecs.DataModel.BuildIECModelFromMMSModel(); self._env.winMgr.MakeIedTree(iecs); self._env.winMgr.MakeIecTree(iecs); self._env.winMgr.mainWindow.Set_iecf(iecs); iecs.istate = Iec61850lStateEnum.IEC61850_FREILAUF; break; case Iec61850lStateEnum.IEC61850_FREILAUF: // File service handling switch (iecs.fstate) { case FileTransferState.FILE_DIRECTORY: if (iecs.lastFileOperationData[0] is NodeIed) { self._env.winMgr.MakeFileTree(iecs); } iecs.fstate = FileTransferState.FILE_NO_ACTION; break; case FileTransferState.FILE_OPENED: case FileTransferState.FILE_READ: // issue a read iecs.Send(iecs.lastFileOperationData, ad, ActionRequested.ReadFile); iecs.fstate = FileTransferState.FILE_NO_ACTION; break; case FileTransferState.FILE_COMPLETE: // issue a close // file can be saved from context menu iecs.Send(iecs.lastFileOperationData, ad, ActionRequested.CloseFile); iecs.fstate = FileTransferState.FILE_NO_ACTION; break; } break; } break; case IsoProtocolState.OSI_STATE_SHUTDOWN: TcpRw.StopClient(iecs); break; } break; default: break; } int waitres = WaitHandle.WaitAny(_waitHandles, 500); switch (waitres) { case 0: // connect if (iecs.ostate == IsoProtocolState.OSI_STATE_START) { iecs.ostate = IsoProtocolState.OSI_CONNECT_COTP; } iecs.connectDone.Reset(); TcpRw.Receive(iecs); // issue a Receive call break; case 1: // receive iecs.receiveDone.Reset(); TcpRw.Receive(iecs); // issue a new Receive call break; case 2: // send iecs.sendDone.Reset(); break; case 3: // endthread self._run = false; break; case 4: // send data iecs.sendQueueWritten.Reset(); Logger.getLogger().LogDebug("SendQueue Waiting for lock in Worker!"); WriteQueueElement el; while (iecs.SendQueue.TryDequeue(out el)) { switch (el.Action) { case ActionRequested.Write: iecs.mms.SendWrite(iecs, el); break; case ActionRequested.WriteAsStructure: iecs.mms.SendWriteAsStructure(iecs, el); break; case ActionRequested.Read: if (el.Data[0] is NodeVL) { iecs.mms.SendReadVL(iecs, el); } else { iecs.mms.SendRead(iecs, el); } break; case ActionRequested.DefineNVL: iecs.mms.SendDefineNVL(iecs, el); break; case ActionRequested.DeleteNVL: iecs.mms.SendDeleteNVL(iecs, el); break; case ActionRequested.GetDirectory: iecs.mms.SendFileDirectory(iecs, el); break; case ActionRequested.OpenFile: iecs.mms.SendFileOpen(iecs, el); break; case ActionRequested.ReadFile: iecs.mms.SendFileRead(iecs, el); break; case ActionRequested.CloseFile: iecs.mms.SendFileClose(iecs, el); break; case ActionRequested.FileDelete: iecs.mms.SendFileDelete(iecs, el); break; } } break; case WaitHandle.WaitTimeout: break; } } TcpRw.StopClient(iecs); _env.winMgr.UnBindFromCapture(iecs); if (restart_allowed) { restart_allowed = false; try { _env.winMgr.mainWindow.BeginInvoke((Action) delegate { _env.winMgr.mainWindow.Restart(); }); } catch { } } }
public int SendCOTPSessionInit(Iec61850State iecs) { // Make COTP init telegramm return(isoCotp.SendInit(iecs)); }