예제 #1
0
        public byte[] ToBytes()
        {
            int totalSize = RequestHeader.ToBytes().Count();

            foreach (ObjectHeader objectHeader in Objects.Keys)
            {
                totalSize += objectHeader.ToBytes().Count();

                foreach (DNP3Object dnp3Object in Objects[objectHeader])
                {
                    totalSize += dnp3Object.ToBytes().Count();
                }
            }

            byte[] array = new byte[totalSize];
            RequestHeader.ToBytes().CopyTo(array, 0);

            int i = 2;

            foreach (ObjectHeader objectHeader in Objects.Keys)
            {
                byte[] temp = objectHeader.ToBytes();
                temp.CopyTo(array, i);

                i += temp.Count();

                foreach (DNP3Object dnp3Object in Objects[objectHeader])
                {
                    temp = dnp3Object.ToBytes();
                    temp.CopyTo(array, i);

                    i += temp.Count();
                }
            }

            return(array);
        }
예제 #2
0
 public Request()
 {
     RequestHeader = new RequestHeader();
     Objects       = new Dictionary <ObjectHeader, List <DNP3Object> >();
 }
        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);
        }