예제 #1
0
        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);
                    }
                }
            }
        }
예제 #2
0
        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;
            }
        }