public List <byte[]> ReadAllAnalogInputPointsRequest(string rtuName)
        {
            List <UserLevelObject> userLevelObjects = new List <UserLevelObject>();
            UserLevelObject        userLevelObject  = new UserLevelObject()
            {
                PointType         = PointType.ANALOG_INPUT,
                Variation         = Variations.BIT_32_NO_FLAG,
                RangeFieldPresent = true,
                RangePresent      = true,
            };

            int i = 0;

            foreach (Analog analog in database.GetProcessVariableByTypeAndRTU(VariableTypes.ANALOG, rtuName))
            {
                userLevelObject.StopIndex = analog.RelativeAddress;

                if (i++ == 0)
                {
                    userLevelObject.StartIndex = analog.RelativeAddress;
                }
            }

            userLevelObjects.Add(userLevelObject);

            return(dNP3Handler.DNP3ApplicationHandler.PackDown(userLevelObjects, ApplicationFunctionCodes.READ, true, true));
        }
        public List <UserLevelObject> PackUp(byte[] data)
        {
            int length = data.Length;

            BitArray applicationCtrl     = new BitArray(new byte[] { data[0] });
            BitArray tempApplicationCtrl = new BitArray(applicationCtrl);

            tempApplicationCtrl[7] = false;
            tempApplicationCtrl[6] = false;
            tempApplicationCtrl[5] = false;
            tempApplicationCtrl[4] = false;

            byte[] tempSeq = new byte[1];
            tempApplicationCtrl.CopyTo(tempSeq, 0);

            ApplicationFunctionCodes functionCode = (ApplicationFunctionCodes)data[1];
            byte newSeq = tempSeq[0];

            if (applicationCtrl[7] == true)
            {
                sequence = newSeq;
                //Fir = true;
                //if (sequence == -1)
                //{
                //    sequence = newSeq;
                //}
                //else if (functionCode != ApplicationFunctionCodes.RESPONSE)
                //{
                //    if (newSeq != sequence + 1)
                //    {
                //        // log error
                //    }

                //    lock (lockObject)
                //    {
                //        sequence = newSeq;
                //    }
                //}

                ObjectsUpProcess.Clear();
            }
            else if (!Fir)
            {
                // LOG ERROR
                //return null;
            }
            else if (functionCode != ApplicationFunctionCodes.RESPONSE && newSeq != sequence + 1)
            {
                // LOG ERROR
                //return null;
            }

            Fin = applicationCtrl[6];

            int index = 0;

            if (functionCode == ApplicationFunctionCodes.RESPONSE)
            {
                length -= 4;
                index   = 4;
            }
            else
            {
                length -= 2;
                index   = 2;
            }

            while (length > 0)
            {
                length -= 3;

                UserLevelObject userLevelObject = new UserLevelObject();
                userLevelObject.FunctionCode = functionCode;

                ObjectHeader objectHeader = new ObjectHeader();
                objectHeader.Group          = data[index++];
                objectHeader.Variation      = data[index++];
                objectHeader.QualifierField = new BitArray(new byte[] { data[index++] });

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

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

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

                int count = 0;

                switch (qualifierByte)
                {
                case 0x00:
                    userLevelObject.IndicesPresent     = false;
                    userLevelObject.RangeFieldPresent  = true;
                    userLevelObject.RangePresent       = true;
                    userLevelObject.ObjectCountPresent = false;

                    count = 2;
                    objectHeader.RangeField = new byte[count];
                    for (int i = 0; i < count; i++)
                    {
                        objectHeader.RangeField[i] = data[index++];
                    }

                    length -= count;

                    userLevelObject.StartIndex = objectHeader.RangeField[0];
                    userLevelObject.StopIndex  = objectHeader.RangeField[1];

                    if (functionCode == ApplicationFunctionCodes.RESPONSE ||
                        functionCode == ApplicationFunctionCodes.WRITE)
                    {
                        byte[] value = new byte[valueSize];
                        for (int i = userLevelObject.StartIndex; i <= userLevelObject.StopIndex; i++)
                        {
                            for (int j = 0; j < valueSize; j++)
                            {
                                value[j] = data[index++];
                                --length;
                            }
                        }

                        userLevelObject.Values.Add(value);
                    }

                    break;

                case 0x01:
                    userLevelObject.IndicesPresent     = false;
                    userLevelObject.RangeFieldPresent  = true;
                    userLevelObject.RangePresent       = true;
                    userLevelObject.ObjectCountPresent = false;

                    count = 4;
                    objectHeader.RangeField = new byte[count];
                    for (int i = 0; i < count; i++)
                    {
                        objectHeader.RangeField[i] = data[index++];
                    }

                    length -= count;

                    byte[] tempStart = new byte[2];
                    byte[] tempStop  = new byte[2];
                    for (int i = 0; i < 2; i++)
                    {
                        tempStart[i] = objectHeader.RangeField[i];
                    }
                    for (int i = 0; i < 2; i++)
                    {
                        tempStop[i] = objectHeader.RangeField[i + 2];
                    }

                    short[] start = new short[1];
                    short[] stop  = new short[1];
                    tempStart.CopyTo(start, 0);
                    tempStop.CopyTo(stop, 0);

                    userLevelObject.StartIndex = start[0];
                    userLevelObject.StopIndex  = stop[0];

                    if (functionCode == ApplicationFunctionCodes.RESPONSE ||
                        functionCode == ApplicationFunctionCodes.WRITE)
                    {
                        byte[] value = new byte[valueSize];
                        for (int i = userLevelObject.StartIndex; i < userLevelObject.StopIndex; i++)
                        {
                            for (int j = 0; j < valueSize; j++)
                            {
                                value[j] = data[index++];
                                --length;
                            }
                        }

                        userLevelObject.Values.Add(value);
                    }

                    break;

                case 0x06:
                    userLevelObject.IndicesPresent     = false;
                    userLevelObject.RangeFieldPresent  = false;
                    userLevelObject.RangePresent       = false;
                    userLevelObject.ObjectCountPresent = false;
                    break;

                case 0x07:
                    userLevelObject.IndicesPresent     = false;
                    userLevelObject.ObjectSizePresent  = false;
                    userLevelObject.RangeFieldPresent  = true;
                    userLevelObject.RangePresent       = false;
                    userLevelObject.ObjectCountPresent = true;

                    count = 1;
                    objectHeader.RangeField = new byte[count];
                    for (int i = 0; i < count; i++)
                    {
                        objectHeader.RangeField[i] = data[index++];
                    }

                    length -= count;

                    userLevelObject.ObjectCount = objectHeader.RangeField[0];

                    if (functionCode == ApplicationFunctionCodes.RESPONSE ||
                        functionCode == ApplicationFunctionCodes.WRITE)
                    {
                        byte[] value = new byte[valueSize];
                        for (int i = 0; i < userLevelObject.ObjectCount; i++)
                        {
                            for (int j = 0; j < valueSize; j++)
                            {
                                value[j] = data[index++];
                                --length;
                            }
                        }

                        userLevelObject.Values.Add(value);
                    }

                    break;

                case 0x08:
                    userLevelObject.IndicesPresent     = false;
                    userLevelObject.ObjectSizePresent  = false;
                    userLevelObject.RangeFieldPresent  = true;
                    userLevelObject.RangePresent       = false;
                    userLevelObject.ObjectCountPresent = true;

                    count = 2;
                    objectHeader.RangeField = new byte[count];
                    for (int i = 0; i < count; i++)
                    {
                        objectHeader.RangeField[i] = data[index++];
                    }

                    length -= count;

                    short[] tempCount = new short[1];
                    objectHeader.RangeField.CopyTo(tempCount, 0);

                    userLevelObject.ObjectCount = tempCount[0];

                    if (functionCode == ApplicationFunctionCodes.RESPONSE ||
                        functionCode == ApplicationFunctionCodes.WRITE)
                    {
                        byte[] value = new byte[valueSize];
                        for (int i = 0; i < userLevelObject.ObjectCount; i++)
                        {
                            for (int j = 0; j < valueSize; j++)
                            {
                                value[j] = data[index++];
                                --length;
                            }
                        }

                        userLevelObject.Values.Add(value);
                    }

                    break;

                case 0x17:
                    userLevelObject.IndicesPresent     = true;
                    userLevelObject.ObjectSizePresent  = false;
                    userLevelObject.RangeFieldPresent  = true;
                    userLevelObject.RangePresent       = false;
                    userLevelObject.ObjectCountPresent = true;

                    count = 1;
                    objectHeader.RangeField = new byte[count];
                    for (int i = 0; i < count; i++)
                    {
                        objectHeader.RangeField[i] = data[index++];
                    }

                    length -= count;

                    userLevelObject.ObjectCount = objectHeader.RangeField[0];

                    if (functionCode == ApplicationFunctionCodes.RESPONSE ||
                        functionCode == ApplicationFunctionCodes.WRITE)
                    {
                        byte[] value = new byte[valueSize];
                        for (int i = 0; i < userLevelObject.ObjectCount; i++)
                        {
                            byte[] tempIndex = new byte[1];
                            tempIndex[0] = data[index++];
                            userLevelObject.Indices.Add(BitConverter.ToInt32(tempIndex, 0));
                            length -= 1;
                            for (int j = 0; j < valueSize; j++)
                            {
                                value[j] = data[index++];
                                --length;
                            }
                        }

                        userLevelObject.Values.Add(value);
                    }
                    else
                    {
                        for (int i = 0; i < userLevelObject.ObjectCount; i++)
                        {
                            byte[] tempIndex = new byte[1];
                            tempIndex[0] = data[index++];
                            userLevelObject.Indices.Add(BitConverter.ToInt32(tempIndex, 0));
                            length -= 1;
                        }
                    }

                    break;

                case 0x28:
                    userLevelObject.IndicesPresent     = true;
                    userLevelObject.ObjectSizePresent  = false;
                    userLevelObject.RangeFieldPresent  = true;
                    userLevelObject.RangePresent       = false;
                    userLevelObject.ObjectCountPresent = true;

                    count = 2;
                    objectHeader.RangeField = new byte[count];
                    for (int i = 0; i < count; i++)
                    {
                        objectHeader.RangeField[i] = data[index++];
                    }

                    length -= count;

                    tempCount = new short[1];
                    objectHeader.RangeField.CopyTo(tempCount, 0);

                    userLevelObject.ObjectCount = tempCount[0];

                    if (functionCode == ApplicationFunctionCodes.RESPONSE ||
                        functionCode == ApplicationFunctionCodes.WRITE)
                    {
                        byte[] value = new byte[valueSize];
                        for (int i = 0; i < userLevelObject.ObjectCount; i++)
                        {
                            byte[] tempIndex = new byte[2];
                            tempIndex[0] = data[index++];
                            tempIndex[1] = data[index++];
                            userLevelObject.Indices.Add(BitConverter.ToInt32(tempIndex, 0));
                            length -= 1;
                            for (int j = 0; j < valueSize; j++)
                            {
                                value[j] = data[index++];
                                --length;
                            }
                        }

                        userLevelObject.Values.Add(value);
                    }
                    else
                    {
                        byte[] tempIndex = new byte[2];
                        tempIndex[0] = data[index++];
                        tempIndex[1] = data[index++];
                        userLevelObject.Indices.Add(BitConverter.ToInt32(tempIndex, 0));
                        length -= 2;
                    }

                    break;

                case 0x5b:
                    userLevelObject.IndicesPresent     = false;
                    userLevelObject.ObjectSizePresent  = true;
                    userLevelObject.RangeFieldPresent  = false;
                    userLevelObject.RangePresent       = false;
                    userLevelObject.ObjectCountPresent = false;

                    count = 1;
                    objectHeader.RangeField = new byte[count];
                    for (int i = 0; i < count; i++)
                    {
                        objectHeader.RangeField[i] = data[index++];
                    }

                    break;
                }

                ObjectsUpProcess.Add(userLevelObject);
            }

            if (Fin)
            {
                Fir = false;
                Fin = false;

                List <UserLevelObject> returnVal = new List <UserLevelObject>(ObjectsUpProcess);
                ObjectsUpProcess.Clear();
                return(returnVal);
            }
            else
            {
                return(null);
            }
        }