Exemple #1
0
        public List <UserLevelObject> PackUp(byte[] data)
        {
            if (data[0] != 0x05 || data[1] != 0x64)
            {
                return(null);
            }

            BitArray ctrl = new BitArray(new byte[1] {
                data[3]
            });

            if (ctrl[7])
            {
                IsMaster = true;
            }
            else
            {
                IsMaster = false;
            }
            if (ctrl[6])
            {
                IsPrm = true;
            }
            else
            {
                IsPrm = false;
            }

            int length = data.Count();

            int actualTransportLength = 0;

            byte[] temp = new byte[length];

            length -= 8; // minus header
            length -= 2; // minus header crc

            int i = 10, j = 0;

            while (length > 0)
            {
                if (length < 18)
                {
                    // last chunk
                    actualTransportLength += (byte)(length - 2);

                    int k = 0;
                    for (k = 0; k < length - 2; k++)
                    {
                        temp[j + k] = data[i + k];
                    }

                    i += k + 2;
                    j += k;
                    break;
                }

                for (int k = 0; k < 16; k++)
                {
                    temp[j + k] = data[i + k];
                }

                i += 16;
                j += 18;

                actualTransportLength += (byte)(16);
                length -= 18;
            }

            byte[] transportMessage = new byte[actualTransportLength];

            for (i = 0; i < actualTransportLength; i++)
            {
                transportMessage[i] = temp[i];
            }

            DNP3TransportFunctionHandler = new TransportFunctionHandler();
            return(DNP3TransportFunctionHandler.PackUp(transportMessage));
        }
        public List <byte[]> PackDown(List <UserLevelObject> userLevelObjects, ApplicationFunctionCodes functionCode, bool isRequest, bool isMaster)
        {
            if (userLevelObjects.Count == 0)
            {
                return(null);
            }

            List <byte[]> fragments = new List <byte[]>();

            byte[] tempFragment       = new byte[maxFragmentSize];
            byte[] finalFragment      = null;
            int    index              = 0;
            bool   fragmentInProgress = true;

            Header header = null;

            if (functionCode == ApplicationFunctionCodes.RESPONSE)
            {
                header = new ResponseHeader();

                ((ResponseHeader)header).InternalIndications[0]  = false;
                ((ResponseHeader)header).InternalIndications[1]  = false;
                ((ResponseHeader)header).InternalIndications[2]  = false;
                ((ResponseHeader)header).InternalIndications[3]  = false;
                ((ResponseHeader)header).InternalIndications[4]  = false;
                ((ResponseHeader)header).InternalIndications[5]  = false;
                ((ResponseHeader)header).InternalIndications[6]  = false;
                ((ResponseHeader)header).InternalIndications[7]  = false;
                ((ResponseHeader)header).InternalIndications[8]  = false;
                ((ResponseHeader)header).InternalIndications[9]  = false;
                ((ResponseHeader)header).InternalIndications[10] = false;
                ((ResponseHeader)header).InternalIndications[11] = false;
                ((ResponseHeader)header).InternalIndications[12] = false;
                ((ResponseHeader)header).InternalIndications[13] = false;
                ((ResponseHeader)header).InternalIndications[14] = false;
                ((ResponseHeader)header).InternalIndications[15] = false;

                lock (lockObject)
                {
                    if (sequence == -1)
                    {
                        sequence = 0;
                    }
                    header.ApplicationControl = new BitArray(new byte[1] {
                        BitConverter.GetBytes(sequence)[0]
                    });
                }
            }
            else
            {
                header = new RequestHeader();

                lock (lockObject)
                {
                    //if (++sequence > 15)
                    //{
                    //    sequence = 0;
                    //}
                    header.ApplicationControl = new BitArray(new byte[1] {
                        BitConverter.GetBytes(sequence)[0]
                    });
                }
            }

            header.ApplicationControl[7] = false;    // FIR
            header.ApplicationControl[6] = false;    // FIN
            header.ApplicationControl[5] = false;    // CON
            header.ApplicationControl[4] = false;    // UNS

            header.FunctionCode = functionCode;

            byte[] tempHeader = header.ToBytes();
            tempHeader.CopyTo(tempFragment, index);
            index += tempHeader.Count();

            byte[] tempObjHeader = null;

            foreach (UserLevelObject userLevelObject in userLevelObjects)
            {
                ObjectHeader objectHeader = new ObjectHeader();

                switch (userLevelObject.PointType)
                {
                case PointType.ANALOG_INPUT:
                    objectHeader.Group = 30;

                    switch (userLevelObject.Variation)
                    {
                    case Variations.BIT_32_NO_FLAG:
                        objectHeader.Variation = 3;
                        break;
                    }
                    break;
                }

                objectHeader.QualifierField[7] = false;
                if (userLevelObject.IndicesPresent)
                {
                    objectHeader.QualifierField[6] = false;
                    objectHeader.QualifierField[5] = false;
                    objectHeader.QualifierField[4] = true;
                }
                else if (userLevelObject.ObjectSizePresent)
                {
                    // TO DO
                }
                else
                {
                    objectHeader.QualifierField[6] = false;
                    objectHeader.QualifierField[5] = false;
                    objectHeader.QualifierField[4] = false;
                }

                if (userLevelObject.RangeFieldPresent)
                {
                    if (userLevelObject.RangePresent)
                    {
                        objectHeader.RangeField    = new byte[2];
                        objectHeader.RangeField[0] = (byte)userLevelObject.StartIndex;
                        objectHeader.RangeField[1] = (byte)userLevelObject.StopIndex;
                    }
                    else if (userLevelObject.ObjectCountPresent)
                    {
                        objectHeader.RangeField = new byte[2];
                        byte[] temp = BitConverter.GetBytes(userLevelObject.ObjectCount);
                        objectHeader.RangeField[0] = temp[0];
                        objectHeader.RangeField[1] = temp[1];
                    }
                }

                tempObjHeader = objectHeader.ToBytes();

                if ((index += tempObjHeader.Count()) > maxFragmentSize)
                {
                    finalFragment = new byte[index];
                    for (int i = 0; i < index; i++)
                    {
                        finalFragment[i] = tempFragment[i];
                    }

                    fragments.Add(finalFragment);

                    index = objectHeader.ToBytes().Count();
                }

                int startIndex, stopIndex;
                startIndex = userLevelObject.StartIndex;
                stopIndex  = userLevelObject.StopIndex;

                byte[] tempQualifier = new byte[1];
                objectHeader.QualifierField.CopyTo(tempQualifier, 0);
                byte qualifierByte = tempQualifier[0];

                switch (qualifierByte)
                {
                case 0x00:
                case 0x01:

                    int counter = -1;
                    foreach (byte[] value in userLevelObject.Values)
                    {
                        counter++;
                        if ((index + value.Count()) <= maxFragmentSize)
                        {
                            value.CopyTo(tempFragment, index);
                            index += value.Count();

                            if (userLevelObject.Values.Count() != 1)
                            {
                                stopIndex = userLevelObject.Indices[counter];
                            }
                            else
                            {
                                stopIndex = startIndex;
                            }

                            fragmentInProgress = true;
                        }
                        else
                        {
                            objectHeader.RangeField[0] = (byte)startIndex;
                            objectHeader.RangeField[1] = (byte)stopIndex;

                            tempObjHeader = objectHeader.ToBytes();
                            tempObjHeader.CopyTo(tempFragment, tempHeader.Count());

                            finalFragment = new byte[index];
                            for (int i = 0; i < index; i++)
                            {
                                finalFragment[i] = tempFragment[i];
                            }

                            fragments.Add(finalFragment);

                            tempHeader = header.ToBytes();
                            tempHeader.CopyTo(tempFragment, index);
                            index = tempHeader.Count();

                            index += objectHeader.ToBytes().Count();

                            value.CopyTo(tempFragment, index);
                            index     += value.Count();
                            startIndex = stopIndex = userLevelObject.Indices[counter];

                            fragmentInProgress = false;
                        }
                    }

                    if (fragmentInProgress)
                    {
                        objectHeader.RangeField[0] = (byte)startIndex;
                        objectHeader.RangeField[1] = (byte)stopIndex;

                        tempObjHeader = objectHeader.ToBytes();
                        tempObjHeader.CopyTo(tempFragment, tempHeader.Count());
                    }

                    break;

                case 0x07:
                case 0x08:
                    break;

                case 0x06:
                    break;

                case 0x17:
                    if (functionCode == ApplicationFunctionCodes.RESPONSE ||
                        functionCode == ApplicationFunctionCodes.WRITE)
                    {
                        for (int i = 0; i < userLevelObject.Values.Count(); i++)
                        {
                            tempFragment[index++] = (byte)userLevelObject.Indices[i];
                            byte[] tempValue = userLevelObject.Values[i];
                            tempValue.CopyTo(tempFragment, index);
                            index += tempValue.Count();
                        }
                    }
                    else
                    {
                        for (int i = 0; i < userLevelObject.Indices.Count(); i++)
                        {
                            tempFragment[index++] = (byte)userLevelObject.Indices[i];
                        }
                    }

                    break;

                case 0x28:
                    if (functionCode == ApplicationFunctionCodes.RESPONSE ||
                        functionCode == ApplicationFunctionCodes.WRITE)
                    {
                        for (int i = 0; i < userLevelObject.Values.Count(); i++)
                        {
                            byte[] tempIndices = BitConverter.GetBytes(userLevelObject.Indices[i]);
                            tempFragment[index++] = tempIndices[0];
                            tempFragment[index++] = tempIndices[1];
                            byte[] tempValue = userLevelObject.Values[i];
                            tempValue.CopyTo(tempFragment, index);
                            index += tempValue.Count();
                        }
                    }
                    else
                    {
                        for (int i = 0; i < userLevelObject.Indices.Count(); i++)
                        {
                            byte[] tempIndices = BitConverter.GetBytes(userLevelObject.Indices[i]);
                            tempFragment[index++] = tempIndices[0];
                            tempFragment[index++] = tempIndices[1];
                        }
                    }

                    break;

                case 0x5b:

                    break;
                }
            }

            finalFragment = new byte[index];
            for (int i = 0; i < index; i++)
            {
                finalFragment[i] = tempFragment[i];
            }

            fragments.Add(finalFragment);
            byte[] tempControl = new byte[1];

            if (fragments.Count() == 1)
            {
                BitArray appControl = new BitArray(new byte[1] {
                    fragments.First()[0]
                });
                appControl[7] = true;
                appControl[6] = true;
                appControl.CopyTo(tempControl, 0);
                fragments.First()[0] = tempControl[0];
            }
            else
            {
                BitArray appControl = new BitArray(new byte[1] {
                    fragments.First()[0]
                });
                appControl[7] = true;
                appControl.CopyTo(tempControl, 0);
                fragments.First()[0] = tempControl[0];

                appControl = new BitArray(new byte[1] {
                    fragments.Last()[0]
                });
                appControl[6]       = true;
                fragments.Last()[0] = tempControl[0];
            }

            List <byte[]> returnValue = new List <byte[]>();

            DNP3TransportFunctionHandler = new TransportFunctionHandler();

            foreach (byte[] fragment in fragments)
            {
                List <byte[]> segments = DNP3TransportFunctionHandler.PackDown(fragment, isRequest, isMaster);

                foreach (byte[] segment in segments)
                {
                    returnValue.Add(segment);
                }
            }

            return(returnValue);
        }