public async void processAPDURead(List <byte> apduPkt) { stationConsole.Text += "processAPDURead" + Environment.NewLine; CancellationToken ct; //We know this is a read, we need to find out what the indices are and return the values //we also need to know the Group and Variation to perform the action //we need to know the qualifier depending on this we make sense of the range values APDU responseAPDU = new APDU(); //prepare to respond TPDU responseTPDU = new TPDU(); DPDU responseDPDU = new DPDU(); List <byte> dnpResponse = new List <byte>(); Console.Write("processAPDURead" + Environment.NewLine); FormBasedTCPListenOutstation.groupID group = (FormBasedTCPListenOutstation.groupID)apduPkt[2]; FormBasedTCPListenOutstation.variationID var = (FormBasedTCPListenOutstation.variationID)apduPkt[3]; FormBasedTCPListenOutstation.prefixAndRange prefixRange = (FormBasedTCPListenOutstation.prefixAndRange)apduPkt[4]; if (group == FormBasedTCPListenOutstation.groupID.G1) { if (var == FormBasedTCPListenOutstation.variationID.V1) { //this is a group 1 variation 1, report the state of one or more binary points //since this is a read function code, we need to return values of the binary points //now get the qualifier if (prefixRange == FormBasedTCPListenOutstation.prefixAndRange.IndexOneOctetObjectSize) { //this means range field contains one octet count of objects and //each object is preceded by its index } else if (prefixRange == FormBasedTCPListenOutstation.prefixAndRange.NoIndexOneOctetStartStop) { //this means objects are NOT preceded by an index but the range field contains //one start octet with start index value and one stop octet with stop index value //example 00-02-01-01-01 means start index is 00, end index is 02 //index 00 = 01, index 01=01 index 02=01 byte startIndex = apduPkt[5]; byte stopIndex = apduPkt[6]; //params should be in the following order //Confirm, Unsolicited, function, group, variation, prefixQualifier, [range] OR [start index, stop index] responseAPDU.buildAPDU(ref dnpResponse, 0x00, 0x00, 0x81, (byte)group, (byte)var, (byte)prefixRange, startIndex, stopIndex, binaryData[0], binaryData[1], binaryData[2]); responseTPDU.buildTPDU(ref dnpResponse); responseDPDU.buildDPDU(ref dnpResponse, 0xC4, 65519, 1); //dst=1, src=65519 byte[] msgBytes = dnpResponse.ToArray(); string msg = BitConverter.ToString(msgBytes); stationConsole.Text += msg; await sendReadData(msgBytes, ct); } } } }
public async Task buildISP(string dsIpAddr, string splitClientAddr, string hwAddr) { if (!String.IsNullOrEmpty(dsIpAddr) && !String.IsNullOrEmpty(splitClientAddr) && !String.IsNullOrEmpty(hwAddr)) { splitProtocol = true; //set it //send an ISP to the Outstation try { dsAddr = IPAddress.Parse(dsIpAddr); //store this, we need to use this to forward traffic from splitClient to it IPAddress splitClientIP = IPAddress.Parse(splitClientAddr); splitClientList.Add(splitClientIP); APDU ispAPDU = new APDU(); //prepare to respond TPDU ispTPDU = new TPDU(); DPDU ispDPDU = new DPDU(); List <byte> ispPkt = new List <byte>(); string localAddrString = localAddr.ToString(); byte[] selfAddrBytes = localAddr.GetAddressBytes(); byte[] clientAddrBytes = IPAddress.Parse(splitClientAddr).GetAddressBytes(); //long value = long.Parse(hwAddr, NumberStyles.HexNumber, CultureInfo.CurrentCulture.NumberFormat); byte[] macBytes = hwAddr.Split('-').Select(x => Convert.ToByte(x, 16)).ToArray(); Array.Reverse(macBytes); //params should be in the following order //confirm, unsolicited, function, group, variation, prefixQualifier, [range] OR [start index, stop index] ispAPDU.buildAPDU(ref ispPkt, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x0D, selfAddrBytes[0], selfAddrBytes[1], selfAddrBytes[2], selfAddrBytes[3], clientAddrBytes[0], clientAddrBytes[1], clientAddrBytes[2], clientAddrBytes[3], macBytes[0], macBytes[1], macBytes[2], macBytes[3], macBytes[4], macBytes[5]); ispTPDU.buildTPDU(ref ispPkt); ispDPDU.buildDPDU(ref ispPkt, 0xC5, 65519, 1); //dst=1, src=65519 byte[] msgBytes = ispPkt.ToArray(); string ISPData = BitConverter.ToString(msgBytes); stationConsole.Text += "Sending ISP :" + ISPData + Environment.NewLine; IPAddress addr = IPAddress.Parse(dsIpAddr); await sendISP(msgBytes, addr); } catch { stationConsole.Text += "ERROR! DS/SplitClient IP Address could not be read" + Environment.NewLine; } } else { stationConsole.Text += "ERROR! Need both Data Server and Split Client IP addresses" + Environment.NewLine; } }