From 5654f304336c818f0c2780bff1a3a452431b6282 Mon Sep 17 00:00:00 2001 From: Stefan Feuerhahn Date: Sun, 27 Aug 2017 23:42:28 +0200 Subject: [PATCH] fixed bug decoding and encoding presentation layer, introduced when removing ANY_NODECODES from ASN1 code of presentation layer --- .../openmuc/josistack/AcseAssociation.java | 16 +- .../openiec61850/ClientAssociation.java | 6 +- .../openiec61850/ServerAssociation.java | 6 +- .../openmuc/josistack/ClientServerITest.java | 157 ------------------ 4 files changed, 17 insertions(+), 168 deletions(-) delete mode 100644 src/test/java/org/openmuc/josistack/ClientServerITest.java diff --git a/src/main/java/org/openmuc/josistack/AcseAssociation.java b/src/main/java/org/openmuc/josistack/AcseAssociation.java index f7c744e..2602c53 100644 --- a/src/main/java/org/openmuc/josistack/AcseAssociation.java +++ b/src/main/java/org/openmuc/josistack/AcseAssociation.java @@ -638,10 +638,6 @@ public final class AcseAssociation { ssduList.add(berOStream.buffer); ssduOffsets.add(berOStream.index + 1); ssduLengths.add(berOStream.buffer.length - (berOStream.index + 1)); - - ssduList.add(payload.array()); - ssduOffsets.add(payload.arrayOffset() + payload.position()); - ssduLengths.add(payload.limit() - payload.position()); } private void encodeSessionLayer(List ssduList, List ssduOffsets, List ssduLengths) @@ -678,7 +674,7 @@ public final class AcseAssociation { * @throws TimeoutException * if a timeout occurs */ - public void receive(ByteBuffer pduBuffer) throws DecodingException, IOException, TimeoutException { + public byte[] receive(ByteBuffer pduBuffer) throws DecodingException, IOException, TimeoutException { if (connected == false) { throw new IllegalStateException("ACSE Association not connected"); } @@ -686,10 +682,10 @@ public final class AcseAssociation { decodeSessionLayer(pduBuffer); - decodePresentationLayer(pduBuffer); + return decodePresentationLayer(pduBuffer); } - private void decodePresentationLayer(ByteBuffer pduBuffer) throws DecodingException { + private byte[] decodePresentationLayer(ByteBuffer pduBuffer) throws DecodingException { // decode PPDU header UserData user_data = new UserData(); @@ -698,6 +694,12 @@ public final class AcseAssociation { } catch (IOException e) { throw new DecodingException("error decoding PPDU header", e); } + + return user_data.getFullyEncodedData() + .getPDVList() + .get(0) + .getPresentationDataValues() + .getSingleASN1Type().value; } private void decodeSessionLayer(ByteBuffer pduBuffer) throws EOFException, DecodingException { diff --git a/src/main/java/org/openmuc/openiec61850/ClientAssociation.java b/src/main/java/org/openmuc/openiec61850/ClientAssociation.java index 389d3a0..65ed088 100644 --- a/src/main/java/org/openmuc/openiec61850/ClientAssociation.java +++ b/src/main/java/org/openmuc/openiec61850/ClientAssociation.java @@ -16,6 +16,7 @@ */ package org.openmuc.openiec61850; +import java.io.ByteArrayInputStream; import java.io.IOException; import java.net.InetAddress; import java.nio.ByteBuffer; @@ -129,8 +130,9 @@ public final class ClientAssociation { while (true) { pduBuffer.clear(); + byte[] buffer; try { - acseAssociation.receive(pduBuffer); + buffer = acseAssociation.receive(pduBuffer); } catch (TimeoutException e) { // Illegal state: A timeout exception was thrown. throw new IllegalStateException(); @@ -141,7 +143,7 @@ public final class ClientAssociation { MMSpdu decodedResponsePdu = new MMSpdu(); try { - decodedResponsePdu.decode(new ByteBufferInputStream(pduBuffer), null); + decodedResponsePdu.decode(new ByteArrayInputStream(buffer), null); } catch (IOException e) { // Error decoding the received MMS PDU continue; diff --git a/src/main/java/org/openmuc/openiec61850/ServerAssociation.java b/src/main/java/org/openmuc/openiec61850/ServerAssociation.java index b587e2c..55c1731 100644 --- a/src/main/java/org/openmuc/openiec61850/ServerAssociation.java +++ b/src/main/java/org/openmuc/openiec61850/ServerAssociation.java @@ -16,6 +16,7 @@ */ package org.openmuc.openiec61850; +import java.io.ByteArrayInputStream; import java.io.EOFException; import java.io.IOException; import java.net.SocketTimeoutException; @@ -397,9 +398,10 @@ final class ServerAssociation { while (true) { MMSpdu mmsRequestPdu = null; + byte[] buffer; pduBuffer.clear(); try { - acseAssociation.receive(pduBuffer); + buffer = acseAssociation.receive(pduBuffer); } catch (EOFException e) { logger.debug("Connection was closed by client."); return null; @@ -422,7 +424,7 @@ final class ServerAssociation { mmsRequestPdu = new MMSpdu(); try { - mmsRequestPdu.decode(new ByteBufferInputStream(pduBuffer), null); + mmsRequestPdu.decode(new ByteArrayInputStream(buffer), null); } catch (IOException e) { logger.warn("IOException decoding received MMS request PDU.", e); continue; diff --git a/src/test/java/org/openmuc/josistack/ClientServerITest.java b/src/test/java/org/openmuc/josistack/ClientServerITest.java deleted file mode 100644 index 5ae4442..0000000 --- a/src/test/java/org/openmuc/josistack/ClientServerITest.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2011-17 Fraunhofer ISE, energy & meteo Systems GmbH and other contributors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ -package org.openmuc.josistack; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; - -import java.io.IOException; -import java.net.InetAddress; -import java.nio.ByteBuffer; -import java.util.Arrays; -import java.util.Collections; -import java.util.concurrent.TimeoutException; - -import org.junit.Assert; -import org.junit.Test; - -public class ClientServerITest { - - private final byte[] mmsInitRequestPDU = new byte[] { (byte) 0xa8, 0x26, (byte) 0x80, 0x03, 0x00, (byte) 0xfd, - (byte) 0xe8, (byte) 0x81, 0x01, 0x06, (byte) 0x82, 0x01, 0x06, (byte) 0x83, 0x01, 0x06, (byte) 0xa4, 0x16, - (byte) 0x80, 0x01, 0x01, (byte) 0x81, 0x03, 0x05, (byte) 0xf1, 0x00, (byte) 0x82, 0x0c, 0x03, (byte) 0xee, - 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, (byte) 0xef, 0x18 }; - - private final byte[] testData = { 2, 1, 1 }; - - public class SampleServer implements AcseAssociationListener { - - @Override - public void serverStoppedListeningIndication(IOException e) { - } - - @Override - public void connectionIndication(AcseAssociation acseAssociation, ByteBuffer data) { - - try { - acseAssociation.accept(data); - } catch (IOException e) { - System.err.println("Caught accepting association:"); - e.printStackTrace(); - return; - } - - ByteBuffer receivedData = ByteBuffer.allocate(1000); - try { - acseAssociation.receive(receivedData); - } catch (IOException e) { - System.err.println("Caught exception receiving data:"); - e.printStackTrace(); - return; - } catch (TimeoutException e) { - e.printStackTrace(); - } catch (DecodingException e) { - e.printStackTrace(); - } - - try { - acseAssociation.send(receivedData); - } catch (IOException e) { - System.err.println("Caught exception sending data:"); - e.printStackTrace(); - return; - } - - } - } - - @Test - public void testClientServerCom() throws IOException, TimeoutException, DecodingException { - - int port = 14322; - - ServerAcseSap serverAcseSAP = new ServerAcseSap(port, 0, null, new SampleServer()); - serverAcseSAP.serverTSap.setMessageTimeout(6000); - - serverAcseSAP.startListening(); - - InetAddress address = InetAddress.getByName("127.0.0.1"); - - ClientAcseSap clientAcseSap = new ClientAcseSap(); - clientAcseSap.tSap.setMaxTPDUSizeParam(7); - clientAcseSap.tSap.setMessageTimeout(6000); - clientAcseSap.pSelLocal = new byte[] { 0x1, 0x1, 0x1, 0x1 }; - - AcseAssociation acseAssociation = clientAcseSap.associate(address, port, null, -1, null, - ByteBuffer.wrap(mmsInitRequestPDU)); - - ByteBuffer associationResponsePDU = acseAssociation.getAssociateResponseAPdu(); - - // Assert.assertThat(findSubArr(associationResponsePDU.array(), mmsInitRequestPDU), is(not(0))); - - acseAssociation.send(ByteBuffer.wrap(testData)); - - ByteBuffer receivedData = ByteBuffer.allocate(10000); - - acseAssociation.receive(receivedData); - - Assert.assertThat(findSubArr(receivedData.array(), testData), is(not(0))); - - acseAssociation.disconnect(); - - serverAcseSAP.stopListening(); - } - - public static int findArray(Byte[] array, Byte[] subArray) { - return Collections.indexOfSubList(Arrays.asList(array), Arrays.asList(subArray)); - } - - public static String getByteArrayString(byte[] byteArray) { - StringBuilder builder = new StringBuilder(); - int l = 1; - for (byte b : byteArray) { - if ((l != 1) && ((l - 1) % 8 == 0)) { - builder.append(' '); - } - if ((l != 1) && ((l - 1) % 16 == 0)) { - builder.append('\n'); - } - l++; - builder.append("0x"); - String hexString = Integer.toHexString(b & 0xff); - if (hexString.length() == 1) { - builder.append(0); - } - builder.append(hexString + " "); - } - return builder.toString(); - } - - int findSubArr(byte[] arr, byte[] subarr) { - int lim = arr.length - subarr.length; - byte[] tmpArr = new byte[subarr.length]; - for (int i = 0; i <= lim; i++) { - System.arraycopy(arr, i, tmpArr, 0, subarr.length); - if (Arrays.equals(tmpArr, subarr)) { - return i; // returns starting index of sub array - } - } - return -1;// return -1 on finding no sub-array - - } - -}