Beispiel #1
0
        public async Task <List <byte> > processDPDU(List <byte> dnpPkt)
        {
            Console.Write("processDPDU" + Environment.NewLine);
            //Check the start bytes first
            List <byte> tpduExtract = new List <byte>();

            if (dnpPkt[0] == 0x05)
            {
                if (dnpPkt[1] == 0x64)
                {
                    //Check control byte function code
                    int controlByte = dnpPkt[2];
                    int fnCodeMask  = 0x0000000F;
                    int fnCode      = controlByte & fnCodeMask; //last 4 bits
                    if ((DPDU.functionCode)fnCode == DPDU.functionCode.ISP)
                    {
                        ispPkt = true;
                        stationConsole.Text += "Recvd DS Request" + Environment.NewLine;
                    }
                    int userDatalength = dnpPkt[2];
                    userDatalength -= 5; //reduce 5 for header,i.e. CTRL(1)+DST(2)+SRC(2)

                    //Now calculate the header CRC, the length excludes the 2 CRC bytes at the very end
                    //Calculate header CRC
                    byte[] hdrCRC = dpdu.makeCRC(ref dnpPkt, 0, 7);

                    if (dnpPkt[8] == hdrCRC[0] && dnpPkt[9] == hdrCRC[1])
                    {
                        //Now we can proceed to the Block CRC
                        //We are limiting ourselves to <= 16 bytes but it could be greater so check it
                        //first block starts at dnpPkt[10]

                        if (userDatalength > 16)
                        {
                            byte lenBlock2 = (byte)(userDatalength - (byte)16);
                            //we need two blocks each with its own CRC bytes
                            byte[] crcBlock1 = dpdu.makeCRC(ref dnpPkt, 10, ((10 + 16) - 1));
                            byte[] crcBlock2 = dpdu.makeCRC(ref dnpPkt, (10 + 16), (dnpPkt.Count() - 1));
                        }
                        else
                        {
                            byte[] crcBlock = dpdu.makeCRC(ref dnpPkt, 10, (dnpPkt.Count() - 3));

                            int crcIndex1 = dnpPkt.Count - 2;
                            int crcIndex2 = dnpPkt.Count - 1;

                            if (crcBlock[0] == dnpPkt[crcIndex1] && crcBlock[1] == dnpPkt[crcIndex2])
                            {
                                //we can now proceed with processing the data link function code
                                Console.WriteLine("Datalink CRC correct!");
                                //now we can extract the TPDU from the DPDU

                                for (int i = 0; i < (int)userDatalength; i++)
                                {
                                    tpduExtract.Add(dnpPkt[i + 10]);
                                }
                            }
                        }
                    }
                }
            }

            return(tpduExtract);
        }
Beispiel #2
0
        public async Task <List <byte> > processDPDU(List <byte> dnpPkt)
        {
            Console.Write("processDPDU" + Environment.NewLine);
            //Check the start bytes first
            List <byte> tpduExtract  = new List <byte>();
            List <byte> correctedPkt = new List <byte>();

            correctedPkt = checkDuplicates(dnpPkt);
            byte lenBlock2;

            if (correctedPkt[0] == 0x05)
            {
                //Lets extract only one DNP3 packet here
                //Check control byte function code
                int controlByte = correctedPkt[3];
                int fnCodeMask  = 0x0000000F;
                int fnCode      = controlByte & fnCodeMask; //last 4 bits
                if ((DPDU.functionCode)fnCode == DPDU.functionCode.ISP)
                {
                    ispPkt = true;
                    stationConsole.Text += "Recvd DS Request" + Environment.NewLine;
                }
                int userDatalength = correctedPkt[2];
                userDatalength -= 5;     //reduce 5 for header,i.e. CTRL(1)+DST(2)+SRC(2)

                //Now calculate the header CRC, the length excludes the 2 CRC bytes at the very end
                //Calculate header CRC
                byte[] hdrCRC = dpdu.makeCRC(ref correctedPkt, 0, 7);

                if (correctedPkt[8] == hdrCRC[0] && correctedPkt[9] == hdrCRC[1])
                {
                    //Now we can proceed to the Block CRC
                    //We are limiting ourselves to <= 16 bytes but it could be greater so check it
                    //first block starts at dnpPkt[10]

                    if (userDatalength > 16)
                    {
                        lenBlock2 = (byte)(userDatalength - (byte)16);
                        //we need two blocks each with its own CRC bytes
                        byte[] crcBlock1 = dpdu.makeCRC(ref correctedPkt, 10, ((10 + 16) - 1));
                        byte[] crcBlock2 = dpdu.makeCRC(ref correctedPkt, (10 + 16 + 2), (correctedPkt.Count() - 3));
                        int    crcIndex3 = correctedPkt.Count - 2;
                        int    crcIndex4 = correctedPkt.Count - 1;
                        int    crcIndex1 = correctedPkt.Count - (lenBlock2 + 2 + 2);  //2 for CRC of 2nd block and 2 for 1st block CRC
                        int    crcIndex2 = crcIndex1 + 1;

                        if ((crcBlock1[0] == correctedPkt[crcIndex1]) && (crcBlock1[1] == correctedPkt[crcIndex2]) &&
                            (crcBlock2[0] == correctedPkt[crcIndex3]) && (crcBlock2[1] == correctedPkt[crcIndex4]))
                        {
                            //we can now proceed with processing the data link function code
                            Console.WriteLine("Datalink CRC correct!");
                            //now we can extract the TPDU from the DPDU

                            for (int i = 10; i < (correctedPkt.Count - 2); i++)   //start from 10 since first 10 bytes is header
                            {
                                if (i == crcIndex1)
                                {
                                    i = i + 2;     //skip over first block CRC
                                }

                                tpduExtract.Add(correctedPkt[i]);
                            }
                        }
                    }
                    else
                    {
                        byte[] crcBlock = dpdu.makeCRC(ref correctedPkt, 10, (correctedPkt.Count() - 3));

                        int crcIndex1 = correctedPkt.Count - 2;
                        int crcIndex2 = correctedPkt.Count - 1;

                        if (crcBlock[0] == correctedPkt[crcIndex1] && crcBlock[1] == correctedPkt[crcIndex2])
                        {
                            //we can now proceed with processing the data link function code
                            Console.WriteLine("Datalink CRC correct!");
                            //now we can extract the TPDU from the DPDU

                            for (int i = 10; i <= (correctedPkt.Count - 2); i++)
                            {
                                tpduExtract.Add(correctedPkt[i]);
                            }
                        }
                        else
                        {
                            MessageBox.Show("CRC ERROR");
                        }
                    }
                }
            }

            if (tpduExtract.Count == 0)
            {
                MessageBox.Show("CRC ERROR");
            }
            return(tpduExtract);
        }