Skip to content

Commit

Permalink
Further implementation of issue #24.
Browse files Browse the repository at this point in the history
  • Loading branch information
whizzosoftware committed Dec 29, 2017
1 parent 957ba20 commit ee73a91
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ void processEvent(ChannelHandlerContext ctx, Object evt, long time) {
} else if (evt instanceof IncompleteDataFrameEvent) {
if (transactionContext != null) {
logger.trace("Incomplete data received from network; extending transaction timeout for {}", transactionContext.getId());
transactionContext.resetTimeout(System.currentTimeMillis());
transactionContext.resetTimeout(time);
}
ctx.fireUserEventTriggered(evt);
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/
package com.whizzosoftware.wzwave.codec;

import com.whizzosoftware.wzwave.channel.event.IncompleteDataFrameEvent;
import com.whizzosoftware.wzwave.frame.*;
import com.whizzosoftware.wzwave.util.ByteUtil;
import io.netty.buffer.ByteBuf;
Expand Down Expand Up @@ -84,6 +85,9 @@ protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) t
}
if (!foundFrame) {
previousBuf = data.copy();
if (ctx != null) {
ctx.fireUserEventTriggered(new IncompleteDataFrameEvent());
}
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
import java.util.ArrayList;
import java.util.List;

import com.whizzosoftware.wzwave.channel.MockChannelHandlerContext;
import com.whizzosoftware.wzwave.channel.event.IncompleteDataFrameEvent;
import com.whizzosoftware.wzwave.commandclass.VersionCommandClass;
import com.whizzosoftware.wzwave.controller.MockZWaveControllerContext;
import com.whizzosoftware.wzwave.frame.*;
import io.netty.buffer.ByteBuf;
import static io.netty.buffer.Unpooled.*;
Expand All @@ -27,119 +30,141 @@ public class ZWaveFrameDecoderTest {
@Test
public void testACK() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<Object>();
ByteBuf in = wrappedBuffer(new byte[] {0x06});
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(1, out.size());
assertTrue(out.get(0) instanceof ACK);
assertEquals(0, ctx.getUserEvents().size());
}

@Test
public void testNAK() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<Object>();
ByteBuf in = wrappedBuffer(new byte[] {0x15});
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(1, out.size());
assertTrue(out.get(0) instanceof NAK);
assertEquals(0, ctx.getUserEvents().size());
}

@Test
public void testCAN() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<Object>();
ByteBuf in = wrappedBuffer(new byte[] {0x18});
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(1, out.size());
assertTrue(out.get(0) instanceof CAN);
assertEquals(0, ctx.getUserEvents().size());
}

@Test
public void testACKPlusMessage() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<Object>();
ByteBuf in = wrappedBuffer(new byte[] {0x06,0x01,0x10,0x01,0x15,0x5A,0x2D,0x57,0x61,0x76,0x65,0x20,0x32,0x2E,0x37,0x38,0x00,0x01,(byte)0x9B});
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(2, out.size());
assertTrue(out.get(0) instanceof ACK);
assertTrue(out.get(1) instanceof Version);
assertEquals(0, ctx.getUserEvents().size());
}

@Test
public void testPartialMessage() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<>();
ByteBuf in = wrappedBuffer(new byte[] {0x06, 0x01, 0x10, 0x01});
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(0, in.readableBytes());
assertEquals(0, out.size());
assertEquals(1, ctx.getUserEvents().size());
assertTrue(ctx.getUserEvents().get(0) instanceof IncompleteDataFrameEvent);

in = wrappedBuffer(new byte[] {0x15,0x5A,0x2D,0x57,0x61,0x76,0x65,0x20,0x32,0x2E,0x37,0x38,0x00,0x01,(byte)0x9B});
assertEquals(15, in.readableBytes());
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(0, in.readableBytes());
assertEquals(2, out.size());
assertTrue(out.get(0) instanceof ACK);
assertTrue(out.get(1) instanceof Version);
assertEquals(1, ctx.getUserEvents().size());
}

@Test
public void testGetVersionResponse() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<Object>();
ByteBuf in = wrappedBuffer(new byte[] {0x01, 0x10, 0x01, 0x15, 0x5a, 0x2d, 0x57, 0x61, 0x76, 0x65, 0x20, 0x32, 0x2e, 0x37, 0x38, 0x00, 0x01, (byte)0x9b});
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(1, out.size());
assertTrue(out.get(0) instanceof Version);
assertEquals("Z-Wave 2.78", ((Version)out.get(0)).getLibraryVersion());
assertEquals((byte) 0x01, ((Version) out.get(0)).getLibraryType());
assertEquals(0, ctx.getUserEvents().size());
}

@Test
public void testGetMemoryId() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<Object>();
ByteBuf in = wrappedBuffer(new byte[] {0x01, 0x08, 0x01, 0x20, 0x01, 0x6a, 0x2d, (byte)0xec, 0x01, 0x7d});
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(1, out.size());
assertTrue(out.get(0) instanceof MemoryGetId);
MemoryGetId mgid = (MemoryGetId)out.get(0);
assertEquals(-20, (int)mgid.getHomeId());
assertEquals((byte)1, (byte)mgid.getNodeId());
assertEquals(0, ctx.getUserEvents().size());
// TODO
}

@Test
public void testGetSUCNodeId() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<Object>();
ByteBuf in = wrappedBuffer(new byte[] {0x01, 0x04, 0x01, 0x56, 0x00, (byte)0xac});
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(0, buffer().readableBytes());
assertEquals(1, out.size());
assertTrue(out.get(0) instanceof GetSUCNodeId);
assertEquals(0, ((GetSUCNodeId)out.get(0)).getSucNodeId());
assertEquals(0, ctx.getUserEvents().size());
}

@Test
public void testGetInitData() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<Object>();
ByteBuf in = wrappedBuffer(new byte[] {0x01, 0x25, 0x01, 0x02, 0x05, 0x00, 0x1d, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, (byte)0xc0});
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(1, out.size());
assertTrue(out.get(0) instanceof InitData);
InitData id = (InitData)out.get(0);
assertEquals(2, id.getNodes().size());
assertEquals(1, out.size());
assertEquals(0, ctx.getUserEvents().size());
// TODO
}

@Test
public void testNodeInformation() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<Object>();
ByteBuf in = wrappedBuffer(new byte[] {0x01, 0x09, 0x01, 0x41, (byte)0x92, 0x16, 0x00, 0x02, 0x02, 0x01, 0x33});
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(1, out.size());
assertTrue(out.get(0) instanceof NodeProtocolInfo);
NodeProtocolInfo pi = (NodeProtocolInfo)out.get(0);
Expand All @@ -152,125 +177,147 @@ public void testNodeInformation() throws Exception {
assertEquals(0x02, pi.getBasicDeviceClass());
assertEquals(0x02, pi.getGenericDeviceClass());
assertEquals(0x01, pi.getSpecificDeviceClass());
assertEquals(0, ctx.getUserEvents().size());
}

@Test
public void testSendData1() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<Object>();
ByteBuf in = wrappedBuffer(new byte[] {0x01, 0x04, 0x01, 0x13, 0x01, (byte)0xe8});
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(1, out.size());
assertTrue(out.get(0) instanceof SendData);
SendData sd = (SendData)out.get(0);
assertFalse(sd.hasCallbackId());
assertNull(sd.getCallbackId());
assertTrue(sd.hasRetVal());
assertEquals((byte)0x01, (byte)sd.getRetVal());
assertEquals(0, ctx.getUserEvents().size());
}

@Test
public void testRequestNodeInfo() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<Object>();
ByteBuf in = wrappedBuffer(new byte[] {0x01, 0x04, 0x01, 0x60, 0x01, (byte) 0x9b});
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(1, out.size());
assertTrue(out.get(0) instanceof RequestNodeInfo);
assertTrue(((RequestNodeInfo)out.get(0)).wasSuccessfullySent());
assertEquals(0, ctx.getUserEvents().size());
}

@Test
public void testApplicationUpdate() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<Object>();
ByteBuf in = wrappedBuffer(new byte[] {0x01, 0x06, 0x00, 0x49, (byte)0x81, 0x00, 0x00, 0x31});
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(1, out.size());
assertTrue(out.get(0) instanceof ApplicationUpdate);
assertEquals(0, ctx.getUserEvents().size());
}

@Test
public void testGetRoutingInfo() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<Object>();
ByteBuf in = wrappedBuffer(new byte[] {0x01,0x20,0x01,(byte)0x80,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5c});
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(1, out.size());
assertTrue(out.get(0) instanceof GetRoutingInfo);
assertEquals(0x02, ((GetRoutingInfo)out.get(0)).getNodeMask()[0]);
for (int i=1; i < 29; i++) {
assertEquals(0x00, ((GetRoutingInfo)out.get(0)).getNodeMask()[i]);
}
assertEquals(0, ctx.getUserEvents().size());
}

@Test
public void testSendCommandResponse() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<Object>();
ByteBuf in = wrappedBuffer(new byte[] {0x01, 0x04, 0x01, 0x13, 0x01, (byte)0xe8});
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(1, out.size());
assertTrue(out.get(0) instanceof SendData);
SendData sd = (SendData)out.get(0);
assertTrue(sd.hasRetVal());
assertEquals(Byte.valueOf((byte)0x01), sd.getRetVal());
assertEquals(DataFrameType.RESPONSE, sd.getType());
assertEquals(0, ctx.getUserEvents().size());
}

@Test
public void testSendCommandRequestCallback() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<Object>();
ByteBuf in = wrappedBuffer(new byte[] {0x01, 0x05, 0x00, 0x13, 0x02, 0x00, (byte)0xeb});
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(1, out.size());
assertTrue(out.get(0) instanceof SendData);
SendData sd = (SendData)out.get(0);
assertTrue(sd.hasCallbackId());
assertEquals(Byte.valueOf((byte)0x02), sd.getCallbackId());
assertEquals(DataFrameType.REQUEST, sd.getType());
assertEquals(0, ctx.getUserEvents().size());
}

@Test
public void testExtraneousPrefixBytes() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<>();
ByteBuf in = wrappedBuffer(new byte[] {0x02, 0x03, 0x04, 0x01, 0x05, 0x00, 0x13, 0x02, 0x00, (byte)0xeb});
assertEquals(10, in.readableBytes());
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(0, in.readableBytes());
assertEquals(1, out.size());
assertTrue(out.get(0) instanceof SendData);
SendData sd = (SendData)out.get(0);
assertTrue(sd.hasCallbackId());
assertEquals(Byte.valueOf((byte)0x02), sd.getCallbackId());
assertEquals(DataFrameType.REQUEST, sd.getType());
assertEquals(0, ctx.getUserEvents().size());
}

@Test
public void testGetNodeVersion() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<Object>();
ByteBuf in = wrappedBuffer(new byte[] {0x01, 0x0d, 0x00, 0x04, 0x00, 0x0e, 0x07, (byte)0x86, 0x12, 0x06, 0x03, 0x28, 0x03, 0x19, 0x5c});
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(1, out.size());
assertTrue(out.get(0) instanceof ApplicationCommand);
ApplicationCommand ach = (ApplicationCommand)out.get(0);
assertEquals(0x00, ach.getStatus());
assertEquals((byte)14, ach.getNodeId());
assertEquals(VersionCommandClass.ID, ach.getCommandClassId());
assertEquals(0, ctx.getUserEvents().size());
}

@Test
public void testOneFrameAcrossTwoReads() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<>();
ByteBuf buf = wrappedBuffer(new byte[] {0x01, 0x10, 0x01, 0x15, 0x5a, 0x2d, 0x57, 0x61, 0x76, 0x65});
assertEquals(10, buf.readableBytes());
decoder.decode(null, buf, out);
assertEquals(0, ctx.getUserEvents().size());
decoder.decode(ctx, buf, out);
assertEquals(0, buf.readableBytes());
assertEquals(0, out.size());
assertEquals(1, ctx.getUserEvents().size());
assertTrue(ctx.getUserEvents().get(0) instanceof IncompleteDataFrameEvent);

buf = wrappedBuffer(new byte[] {0x20, 0x32, 0x2e, 0x37, 0x38, 0x00, 0x01, (byte)0x9b});
assertEquals(8, buf.readableBytes());
decoder.decode(null, buf, out);
Expand All @@ -282,19 +329,22 @@ public void testOneFrameAcrossTwoReads() throws Exception {
@Test
public void testTwoFramesAcrossTwoReads() throws Exception {
ZWaveFrameDecoder decoder = new ZWaveFrameDecoder();
MockChannelHandlerContext ctx = new MockChannelHandlerContext();
List<Object> out = new ArrayList<Object>();
ByteBuf in = wrappedBuffer(new byte[] {0x01, 0x0d, 0x00, 0x04, 0x00, 0x0e, 0x07, (byte)0x86, 0x12, 0x06, 0x03, 0x28, 0x03, 0x19, 0x5c, 0x01, 0x0d});
assertEquals(17, in.readableBytes());
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(0, in.readableBytes());
assertEquals(1, out.size());
in = wrappedBuffer(new byte[] {0x00, 0x04, 0x00, 0x0e, 0x07, (byte)0x86, 0x12, 0x06, 0x03, 0x28, 0x03, 0x19, 0x5c});
assertEquals(13, in.readableBytes());
decoder.decode(null, in, out);
decoder.decode(ctx, in, out);
assertEquals(0, in.readableBytes());
assertEquals(2, out.size());
assertTrue(out.get(0) instanceof ApplicationCommand);
assertTrue(out.get(1) instanceof ApplicationCommand);
assertEquals(1, ctx.getUserEvents().size());
assertTrue(ctx.getUserEvents().get(0) instanceof IncompleteDataFrameEvent);
}

@Test
Expand Down

0 comments on commit ee73a91

Please sign in to comment.