2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.dsmr.internal.device;
15 import static org.hamcrest.CoreMatchers.equalTo;
16 import static org.hamcrest.CoreMatchers.is;
17 import static org.hamcrest.MatcherAssert.assertThat;
19 import java.nio.charset.StandardCharsets;
20 import java.util.concurrent.atomic.AtomicReference;
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.junit.jupiter.api.Test;
24 import org.openhab.binding.dsmr.internal.TelegramReaderUtil;
25 import org.openhab.binding.dsmr.internal.device.p1telegram.TelegramParser;
28 * Test class for the {@link SmartyDecrypter}.
30 * @author Hilbrand Bouwkamp - Initial contribution
33 public class SmartyDecrypterTest {
35 private static final String KEY = "D491470F47126332B07D1923B3504188";
36 private static final int[] TELEGRAM = new int[] {
39 // System title length
42 0x53, 0x41, 0x47, 0x67, 0x70, 0x01, 0xBD, 0x54,
45 // Length of the subsequent bytes
50 0x00, 0x05, 0xA8, 0xE3,
52 0x80, 0x6E, 0xE6, 0xE6, 0x39, 0x27, 0x4C, 0x7B, 0xC5, 0x70, 0x95, 0xF8, 0x72, 0xB0, 0x8D, 0xDE, 0x62, 0x1F,
53 0xB7, 0x4E, 0xE8, 0x1E, 0x5E, 0xBE, 0x34, 0x2C, 0x93, 0xD8, 0xE7, 0x37, 0x81, 0xFB, 0x2A, 0x1E, 0xB8, 0x71,
54 0x00, 0x74, 0xA5, 0x4F, 0xC5, 0x7A, 0xA7, 0xD1, 0xD9, 0x92, 0x36, 0xC4, 0x2E, 0x2E, 0xC0, 0x1A, 0x03, 0x24,
55 0xEF, 0xC7, 0xF0, 0x2E, 0x3B, 0xA2, 0xFA, 0x43, 0x19, 0x6C, 0xA6, 0x03, 0x83, 0x8A, 0xB8, 0x32, 0x2D, 0xFF,
56 0xA8, 0x3F, 0x7E, 0x83, 0x93, 0x2E, 0x60, 0x07, 0x40, 0x6B, 0x11, 0x2B, 0x41, 0x74, 0x5F, 0x38, 0x80, 0x56,
57 0x46, 0xD5, 0x3F, 0xEA, 0x7A, 0x02, 0x9F, 0xA7, 0x9C, 0x36, 0xD9, 0xD7, 0x77, 0xDA, 0x8B, 0x46, 0x3D, 0xD3,
58 0x3E, 0xDF, 0xE3, 0x8C, 0xDE, 0xDD, 0xC1, 0x90, 0x7E, 0x48, 0xC0, 0xBE, 0x10, 0x58, 0x22, 0x8B, 0x1F, 0xF1,
59 0x6E, 0xDF, 0x9F, 0x6F, 0x14, 0xDB, 0x9C, 0x3D, 0xEC, 0x32, 0x0C, 0x89, 0x8B, 0x30, 0xC7, 0x64, 0x11, 0x8D,
60 0xA8, 0x3A, 0x77, 0xBE, 0xFF, 0x44, 0x43, 0x7A, 0xE2, 0x56, 0x16, 0x76, 0xB0, 0x09, 0x0A, 0x65, 0x24, 0x09,
61 0x41, 0x9A, 0xA0, 0x1D, 0xB7, 0x8D, 0x95, 0xA1, 0x01, 0x3A, 0xD5, 0x2D, 0x3A, 0x46, 0x52, 0x9B, 0x2C, 0x1A,
62 0xA9, 0xD5, 0xAA, 0xB8, 0xAE, 0x54, 0xFD, 0x86, 0x45, 0x6F, 0x23, 0xFE, 0xB2, 0x79, 0xDE, 0x06, 0x88, 0x10,
63 0xAF, 0x56, 0xBE, 0x1E, 0x9D, 0xE0, 0x56, 0x93, 0x73, 0x29, 0x18, 0x13, 0x56, 0xB5, 0xA0, 0xF2, 0xBF, 0xE0,
64 0xFD, 0x19, 0xD6, 0x85, 0xC8, 0xC2, 0xD8, 0x96, 0x92, 0x31, 0x5D, 0xCD, 0xA8, 0xE5, 0x31, 0xC8, 0xA6, 0x0F,
65 0x5B, 0xA1, 0xD4, 0x8C, 0x0C, 0xFC, 0x85, 0xA9, 0xAD, 0xB2, 0xEE, 0xCA, 0x0E, 0x79, 0x56, 0x51, 0x35, 0x83,
66 0xCB, 0xA7, 0x56, 0xB6, 0x5A, 0x8E, 0xC6, 0x80, 0x9B, 0xD5, 0xA8, 0xC9, 0xE0, 0xC5, 0xF8, 0x9F, 0xC9, 0x02,
67 0xB1, 0x2E, 0xAD, 0xD8, 0xCE, 0x3B, 0x93, 0xAC, 0xE4, 0x5C, 0x36, 0xC0, 0xD1, 0x39, 0x81, 0x65, 0x8E, 0x29,
68 0xC2, 0x42, 0xE5, 0x58, 0xA5, 0xCB, 0xE8, 0xBD, 0x33, 0xBB, 0x68, 0x8A, 0x93, 0xE5, 0x4C, 0x03, 0x03, 0xAB,
69 0x6F, 0xFC, 0xFB, 0xD5, 0xDC, 0x46, 0xAA, 0xED, 0x53, 0xAC, 0x3D, 0xF6, 0x7A, 0xA4, 0xC4, 0x06, 0xAB, 0xA6,
70 0xA3, 0x41, 0xEF, 0x8E, 0xA1, 0x52, 0xAA, 0xCD, 0x7E, 0x10, 0x98, 0x2D, 0x0D, 0x43, 0x8F, 0xBF, 0x08, 0x5E,
71 0x48, 0xB0, 0xD4, 0xF8, 0x0B, 0x1F, 0x2A, 0x3F, 0xE9, 0x5B, 0xE1, 0xCE, 0x88, 0x00, 0x62, 0xED, 0xA7, 0xAD,
72 0x94, 0x25, 0xC6, 0x05, 0x07, 0x56, 0x0C, 0xFF, 0x45, 0x78, 0x79, 0x8E, 0xD7, 0x65, 0xD3, 0x27, 0x85, 0xB4,
73 0xE8, 0xF5, 0xD2, 0xA9, 0x43, 0x4D, 0x99, 0x93, 0xB1, 0x51, 0xCB, 0xF8, 0x74, 0x78, 0x3E, 0x64, 0x4A, 0xB7,
74 0x30, 0x60, 0x70, 0x60, 0x8D, 0x68, 0xD2, 0x6D, 0x2B, 0xAE, 0x84, 0x95, 0xA7, 0x03, 0xFA, 0xD4, 0x0B, 0x24,
75 0x69, 0xB2, 0xE4, 0xA6, 0x69, 0x12, 0xA6, 0x27, 0x2D, 0x3B, 0x0A, 0xFC, 0x60, 0xA1, 0xFE, 0x38, 0x94, 0x4A,
76 0xEA, 0xDF, 0x75, 0x4B, 0xC6, 0xF2, 0x2F, 0x2B, 0x9C, 0x32, 0xD3, 0xD2, 0x1E, 0x34, 0xD8, 0xF7, 0x82, 0x04,
77 0x83, 0x03, 0xBC, 0x71, 0x53, 0x6F, 0x0E, 0x54, 0x2C, 0x99, 0x51, 0xCC, 0x75, 0xE3, 0xAA, 0xAB, 0x95, 0x5A,
78 0xA3, 0x67, 0xE1, 0x09, 0x0E, 0x40, 0x56, 0x6F, 0x56, 0x1F, 0xEA, 0x24, 0x74, 0xDE, 0x5D, 0x13, 0xF2, 0x13,
79 0x16, 0x74, 0x41, 0x06, 0xD1, 0xE1, 0x02, 0x01, 0x0F, 0x16, 0xD5, 0xF2, 0xA6, 0x63, 0x41, 0x0B, 0xBE, 0x4A,
80 0x85, 0x8A, 0x5C, 0x32, 0x0B, 0xEC, 0x4C, 0xA4, 0x28, 0x6C, 0xC5, 0x3C, 0x55, 0x5A, 0x57, 0xE6, 0x84, 0x33,
81 0x57, 0x14, 0x8E, 0x93, 0xB5, 0x7C, 0x12, 0x86, 0xDD, 0xBB, 0x07, 0xDB, 0xDD, 0x3A, 0x38, 0x1C, 0xD6, 0xBC,
82 0x39, 0xA9, 0xA9, 0xF5, 0x12, 0xDF, 0xF6, 0x5E, 0xBD, 0x6E, 0xB5, 0x4B, 0xD5, 0x54, 0xEA, 0xA3, 0x46, 0xB4,
83 0x96, 0xD6, 0xAD, 0x58, 0x45, 0x1B, 0xB2, 0x9B, 0x71, 0xD7, 0xBD, 0x5E, 0xE1, 0xF1, 0x06, 0x99, 0xAF, 0x0B,
84 0x75, 0x4D, 0x41, 0x05, 0x6E, 0x43, 0x76, 0xC2, 0x21, 0x14, 0x37, 0x4E, 0x84, 0xCC, 0x08, 0xAD, 0x2B, 0x04,
85 0xF6, 0xF5, 0xC4, 0x9D, 0x6B, 0xF7, 0xF9, 0x2C, 0x6E, 0x6C, 0x26, 0x5B, 0x4B, 0x55, 0xB7, 0x04, 0xD3, 0x68,
86 0x21, 0xDC, 0x19, 0x2F, 0x3A, 0x90, 0x1C, 0x3E, 0x7C, 0x07, 0x16, 0x05, 0x53, 0x70, 0xCE, 0x9A, 0xD1, 0x45,
87 0x78, 0x39, 0x3B, 0x43, 0xF5, 0x59, 0x80, 0x24, 0xE3, 0x7D, 0x2B, 0x8C, 0x0A, 0xE1, 0xEC, 0xCF, 0xEA, 0x99,
88 0xB9, 0xE3, 0x57, 0xCD, 0xDA, 0xF1, 0x98, 0x8D, 0xCD, 0x6E, 0xE9, 0x57, 0xDE, 0x50, 0x6C, 0x8A, 0x15, 0xB8,
89 0xE8, 0x72, 0xC4, 0x1D, 0xD3, 0xB2, 0x9F, 0x0B, 0x8E, 0x40, 0x15, 0xD4, 0xCC, 0xAD, 0x9C,
91 0xE6, 0x8A, 0xEC, 0x23, 0x21, 0x1C, 0x87, 0x60, 0x78, 0xAE, 0x3F, 0x03 };
94 * Tests decrypting of a single complete Smarty telegram.
97 public void testSmartyDecrypter() {
98 final AtomicReference<String> dataRead = new AtomicReference<>();
99 final SmartyDecrypter decoder = new SmartyDecrypter(new TelegramParser() {
101 public void parse(final byte[] data, final int length) {
102 dataRead.set(new String(data, StandardCharsets.UTF_8));
104 }, new DSMRTelegramListener(KEY, ""), KEY, "");
105 decoder.setLenientMode(true);
106 final byte[] data = new byte[TELEGRAM.length];
108 for (int i = 0; i < TELEGRAM.length; i++) {
109 data[i] = (byte) TELEGRAM[i];
112 decoder.parse(data, data.length);
113 final String expected = new String(TelegramReaderUtil.readRawTelegram("smarty_long"), StandardCharsets.UTF_8);
115 assertThat("Should have correctly decrypted the telegram", dataRead.get(), is(equalTo(expected)));