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); }
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); }