Skip to content

Commit 96d2c60

Browse files
authored
Add Wireless M-Bus, Mode T Downlink (#2366)
1 parent 1eb23fd commit 96d2c60

File tree

1 file changed

+40
-7
lines changed

1 file changed

+40
-7
lines changed

src/devices/m_bus.c

+40-7
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ static int m_bus_decode_3of6_buffer(uint8_t const *bits, unsigned bit_offset, ui
6363
for (unsigned n=0; n<num_bytes; ++n) {
6464
uint8_t nibble_h = m_bus_decode_3of6(bitrow_get_byte(bits, n*12+bit_offset) >> 2);
6565
uint8_t nibble_l = m_bus_decode_3of6(bitrow_get_byte(bits, n*12+bit_offset+6) >> 2);
66+
if (nibble_h > 0xf || nibble_l > 0xf) {
67+
return -1;
68+
}
6669
output[n] = (nibble_h << 4) | nibble_l;
6770
}
6871
return 0;
@@ -984,7 +987,8 @@ static int m_bus_mode_c_t_callback(r_device *decoder, bitbuffer_t *bitbuffer)
984987
data_in.length = (bitbuffer->bits_per_row[0]-bit_offset)/8;
985988
bitbuffer_extract_bytes(bitbuffer, 0, bit_offset, data_in.data, data_in.length*8);
986989
// Decode
987-
if (!m_bus_decode_format_a(decoder, &data_in, &data_out, &block1)) return 0;
990+
if (!m_bus_decode_format_a(decoder, &data_in, &data_out, &block1))
991+
return DECODE_FAIL_SANITY;
988992
} // Format A
989993
// Format B
990994
else if (next_byte == 0x3D) {
@@ -993,8 +997,9 @@ static int m_bus_mode_c_t_callback(r_device *decoder, bitbuffer_t *bitbuffer)
993997
data_in.length = (bitbuffer->bits_per_row[0]-bit_offset)/8;
994998
bitbuffer_extract_bytes(bitbuffer, 0, bit_offset, data_in.data, data_in.length*8);
995999
// Decode
996-
if (!m_bus_decode_format_b(decoder, &data_in, &data_out, &block1)) return 0;
997-
} // Format B
1000+
if (!m_bus_decode_format_b(decoder, &data_in, &data_out, &block1))
1001+
return DECODE_FAIL_SANITY;
1002+
} // Format B
9981003
// Unknown Format
9991004
else {
10001005
decoder_logf_bitbuffer(decoder, 1, __func__, bitbuffer, "M-Bus: Mode C, Unknown format: 0x%X", next_byte);
@@ -1014,10 +1019,13 @@ static int m_bus_mode_c_t_callback(r_device *decoder, bitbuffer_t *bitbuffer)
10141019
decoder_logf(decoder, 1, __func__, "MBus telegram length: %u", data_in.length);
10151020
if (m_bus_decode_3of6_buffer(bitbuffer->bb[0], bit_offset, data_in.data, data_in.length) < 0) {
10161021
decoder_log(decoder, 1, __func__, "M-Bus: Decoding error");
1017-
return 0;
1022+
return DECODE_FAIL_SANITY;
10181023
}
10191024
// Decode
1020-
if (!m_bus_decode_format_a(decoder, &data_in, &data_out, &block1)) return 0;
1025+
if (!m_bus_decode_format_a(decoder, &data_in, &data_out, &block1)) {
1026+
decoder_log_bitrow(decoder, 1, __func__, data_in.data, data_in.length, "MBus telegram unknown format");
1027+
return DECODE_FAIL_SANITY;
1028+
}
10211029
} // Mode T
10221030

10231031
m_bus_output_data(decoder, bitbuffer, &data_out, &block1, mode);
@@ -1119,6 +1127,7 @@ Wireless M-Bus, Mode S.
11191127
static int m_bus_mode_s_callback(r_device *decoder, bitbuffer_t *bitbuffer)
11201128
{
11211129
static const uint8_t PREAMBLE_S[] = {0x54, 0x76, 0x96}; // Mode S Preamble
1130+
static const uint8_t PREAMBLE_T_DN[] = {0xaa, 0xab, 0x32}; // Mode T Downlink Preamble
11221131
bitbuffer_t packet_bits = {0};
11231132
m_bus_data_t data_in = {0}; // Data from Physical layer decoded to bytes
11241133
m_bus_data_t data_out = {0}; // Data from Data Link layer
@@ -1129,9 +1138,22 @@ static int m_bus_mode_s_callback(r_device *decoder, bitbuffer_t *bitbuffer)
11291138
return DECODE_ABORT_LENGTH;
11301139
}
11311140

1141+
// Find a Mode T-downlink data package
1142+
unsigned offset = bitbuffer_search(bitbuffer, 0, 0, PREAMBLE_T_DN, sizeof(PREAMBLE_T_DN) * 8);
1143+
offset += sizeof(PREAMBLE_T_DN) * 8;
1144+
if (offset < bitbuffer->bits_per_row[0]) { // Did find a big enough package
1145+
bitbuffer_invert(bitbuffer);
1146+
decoder_logf_bitbuffer(decoder, 1, __func__, bitbuffer, "M-Bus: Mode T Downlink");
1147+
return DECODE_ABORT_EARLY;
1148+
}
1149+
11321150
// Find a Mode S data package
11331151
unsigned bit_offset = bitbuffer_search(bitbuffer, 0, 0, PREAMBLE_S, sizeof(PREAMBLE_S)*8);
1134-
bitbuffer_manchester_decode(bitbuffer, 0, bit_offset+sizeof(PREAMBLE_S)*8, &packet_bits, 800);
1152+
bit_offset += sizeof(PREAMBLE_S) * 8;
1153+
if (bit_offset >= bitbuffer->bits_per_row[0]) { // Did not find a big enough package
1154+
return DECODE_ABORT_EARLY;
1155+
}
1156+
bitbuffer_manchester_decode(bitbuffer, 0, bit_offset, &packet_bits, 800);
11351157
data_in.length = (bitbuffer->bits_per_row[0]);
11361158
bitbuffer_extract_bytes(&packet_bits, 0, 0, data_in.data, data_in.length);
11371159

@@ -1188,7 +1210,7 @@ static char *output_fields[] = {
11881210
};
11891211

11901212
// Mode C1, C2 (Meter TX), T1, T2 (Meter TX),
1191-
// Frequency 868.95 MHz, Bitrate 100 kbps, Modulation NRZ FSK
1213+
// Frequency 868.95 MHz, Bitrate 100 kbps (uplink), Modulation NRZ FSK
11921214
r_device const m_bus_mode_c_t = {
11931215
.name = "Wireless M-Bus, Mode C&T, 100kbps (-f 868.95M -s 1200k)", // Minimum samplerate = 1.2 MHz (12 samples of 100kb/s)
11941216
.modulation = FSK_PULSE_PCM,
@@ -1199,6 +1221,17 @@ r_device const m_bus_mode_c_t = {
11991221
.fields = output_fields,
12001222
};
12011223

1224+
// Mode T communication in downlink direction at 32.768 kbps
1225+
r_device const m_bus_mode_c_t_downlink = {
1226+
.name = "Wireless M-Bus, Mode T, 32.768kbps (-f 868.3M -s 1000k)", // Minimum samplerate = 1 MHz (15 samples of 32kb/s manchester coded)
1227+
.modulation = FSK_PULSE_PCM,
1228+
.short_width = (1000.0 / 32.768), // ~31 us per bit
1229+
.long_width = (1000.0 / 32.768),
1230+
.reset_limit = ((1000.0 / 32.768) * 9), // 9 bit periods
1231+
.decode_fn = &m_bus_mode_c_t_callback,
1232+
.fields = output_fields,
1233+
};
1234+
12021235
// Mode S1, S1-m, S2, T2 (Meter RX), (Meter RX not so interesting)
12031236
// Frequency 868.3 MHz, Bitrate 32.768 kbps, Modulation Manchester FSK
12041237
r_device const m_bus_mode_s = {

0 commit comments

Comments
 (0)