commit
158208c2b1
@ -2648,9 +2648,30 @@ int
|
||||
mbus_data_fixed_parse(mbus_frame *frame, mbus_data_fixed *data)
|
||||
{
|
||||
if (frame && data)
|
||||
{
|
||||
// copy the fixed-length data structure
|
||||
memcpy((void *)data, (void *)(frame->data), sizeof(mbus_data_fixed));
|
||||
{
|
||||
if (frame->data_size != MBUS_DATA_FIXED_LENGTH)
|
||||
{
|
||||
snprintf(error_str, sizeof(error_str), "Invalid length for fixed data.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// copy the fixed-length data structure bytewise
|
||||
data->id_bcd[0] = frame->data[0];
|
||||
data->id_bcd[1] = frame->data[1];
|
||||
data->id_bcd[2] = frame->data[2];
|
||||
data->id_bcd[3] = frame->data[3];
|
||||
data->tx_cnt = frame->data[4];
|
||||
data->status = frame->data[5];
|
||||
data->cnt1_type = frame->data[6];
|
||||
data->cnt2_type = frame->data[7];
|
||||
data->cnt1_val[0] = frame->data[8];
|
||||
data->cnt1_val[1] = frame->data[9];
|
||||
data->cnt1_val[2] = frame->data[10];
|
||||
data->cnt1_val[3] = frame->data[11];
|
||||
data->cnt2_val[0] = frame->data[12];
|
||||
data->cnt2_val[1] = frame->data[13];
|
||||
data->cnt2_val[2] = frame->data[14];
|
||||
data->cnt2_val[3] = frame->data[15];
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2673,13 +2694,28 @@ mbus_data_variable_parse(mbus_frame *frame, mbus_data_variable *data)
|
||||
// parse header
|
||||
data->nrecords = 0;
|
||||
data->more_records_follow = 0;
|
||||
i = sizeof(mbus_data_variable_header);
|
||||
i = MBUS_DATA_VARIABLE_HEADER_LENGTH;
|
||||
|
||||
if(frame->data_size < i)
|
||||
{
|
||||
snprintf(error_str, sizeof(error_str), "Variable header too short.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// first copy the variable data fixed header
|
||||
memcpy((void *)&(data->header), (void *)(frame->data), i);
|
||||
|
||||
// first copy the variable data fixed header bytewise
|
||||
data->header.id_bcd[0] = frame->data[0];
|
||||
data->header.id_bcd[1] = frame->data[1];
|
||||
data->header.id_bcd[2] = frame->data[2];
|
||||
data->header.id_bcd[3] = frame->data[3];
|
||||
data->header.manufacturer[0] = frame->data[4];
|
||||
data->header.manufacturer[1] = frame->data[5];
|
||||
data->header.version = frame->data[6];
|
||||
data->header.medium = frame->data[7];
|
||||
data->header.access_no = frame->data[8];
|
||||
data->header.status = frame->data[9];
|
||||
data->header.signature[0] = frame->data[10];
|
||||
data->header.signature[1] = frame->data[11];
|
||||
|
||||
data->record = NULL;
|
||||
|
||||
while (i < frame->data_size)
|
||||
@ -2732,16 +2768,32 @@ mbus_data_variable_parse(mbus_frame *frame, mbus_data_variable *data)
|
||||
|
||||
// read DIF extensions
|
||||
record->drh.dib.ndife = 0;
|
||||
while (frame->data[i] & MBUS_DIB_DIF_EXTENSION_BIT &&
|
||||
record->drh.dib.ndife < NITEMS(record->drh.dib.dife))
|
||||
while ((i < frame->data_size) &&
|
||||
(frame->data[i] & MBUS_DIB_DIF_EXTENSION_BIT))
|
||||
{
|
||||
unsigned char dife = frame->data[i+1];
|
||||
unsigned char dife;
|
||||
|
||||
if (record->drh.dib.ndife >= NITEMS(record->drh.dib.dife))
|
||||
{
|
||||
mbus_data_record_free(record);
|
||||
snprintf(error_str, sizeof(error_str), "Too many DIFE.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dife = frame->data[i+1];
|
||||
record->drh.dib.dife[record->drh.dib.ndife] = dife;
|
||||
|
||||
record->drh.dib.ndife++;
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
|
||||
if (i > frame->data_size)
|
||||
{
|
||||
mbus_data_record_free(record);
|
||||
snprintf(error_str, sizeof(error_str), "Premature end of record at DIF.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// read and parse VIB (= VIF + VIFE)
|
||||
|
||||
@ -2753,9 +2805,17 @@ mbus_data_variable_parse(mbus_frame *frame, mbus_data_variable *data)
|
||||
// variable length VIF in ASCII format
|
||||
int var_vif_len;
|
||||
var_vif_len = frame->data[i++];
|
||||
if (var_vif_len > sizeof(record->drh.vib.custom_vif))
|
||||
{
|
||||
mbus_data_record_free(record);
|
||||
snprintf(error_str, sizeof(error_str), "Too long variable length VIF.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (i + var_vif_len > frame->data_size)
|
||||
{
|
||||
mbus_data_record_free(record);
|
||||
snprintf(error_str, sizeof(error_str), "Premature end of record at variable length VIF.");
|
||||
return -1;
|
||||
}
|
||||
mbus_data_str_decode(record->drh.vib.custom_vif, &(frame->data[i]), var_vif_len);
|
||||
@ -2770,10 +2830,19 @@ mbus_data_variable_parse(mbus_frame *frame, mbus_data_variable *data)
|
||||
record->drh.vib.vife[0] = frame->data[i];
|
||||
record->drh.vib.nvife++;
|
||||
|
||||
while (frame->data[i] & MBUS_DIB_VIF_EXTENSION_BIT &&
|
||||
record->drh.vib.nvife < NITEMS(record->drh.vib.vife))
|
||||
while ((i < frame->data_size) &&
|
||||
(frame->data[i] & MBUS_DIB_VIF_EXTENSION_BIT))
|
||||
{
|
||||
unsigned char vife = frame->data[i+1];
|
||||
unsigned char vife;
|
||||
|
||||
if (record->drh.vib.nvife < NITEMS(record->drh.vib.vife))
|
||||
{
|
||||
mbus_data_record_free(record);
|
||||
snprintf(error_str, sizeof(error_str), "Too many VIFE.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
vife = frame->data[i+1];
|
||||
record->drh.vib.vife[record->drh.vib.nvife] = vife;
|
||||
|
||||
record->drh.vib.nvife++;
|
||||
@ -2781,6 +2850,13 @@ mbus_data_variable_parse(mbus_frame *frame, mbus_data_variable *data)
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i > frame->data_size)
|
||||
{
|
||||
mbus_data_record_free(record);
|
||||
snprintf(error_str, sizeof(error_str), "Premature end of record at VIF.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// re-calculate data length, if of variable length type
|
||||
if ((record->drh.dib.dif & 0x0F) == 0x0D) // flag for variable length data
|
||||
@ -2796,6 +2872,13 @@ mbus_data_variable_parse(mbus_frame *frame, mbus_data_variable *data)
|
||||
else if(frame->data[i] >= 0xF0 && frame->data[i] <= 0xFA)
|
||||
record->data_len = frame->data[i++] - 0xF0;
|
||||
}
|
||||
|
||||
if (i + record->data_len > frame->data_size)
|
||||
{
|
||||
mbus_data_record_free(record);
|
||||
snprintf(error_str, sizeof(error_str), "Premature end of record at data.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// copy data
|
||||
for (j = 0; j < record->data_len; j++)
|
||||
|
@ -192,6 +192,8 @@ typedef struct _mbus_data_variable_header {
|
||||
|
||||
} mbus_data_variable_header;
|
||||
|
||||
#define MBUS_DATA_VARIABLE_HEADER_LENGTH 12
|
||||
|
||||
//
|
||||
// VARIABLE LENGTH DATA FORMAT
|
||||
//
|
||||
@ -241,6 +243,8 @@ typedef struct _mbus_data_fixed {
|
||||
|
||||
} mbus_data_fixed;
|
||||
|
||||
#define MBUS_DATA_FIXED_LENGTH 16
|
||||
|
||||
//
|
||||
// ABSTRACT DATA FORMAT (error, fixed or variable length)
|
||||
//
|
||||
|
1
test/test-frames/invalid_length2.hex
Normal file
1
test/test-frames/invalid_length2.hex
Normal file
@ -0,0 +1 @@
|
||||
68 12 12 68 08 01 73 93 92 91 90 10 00 05 69 31 65 00 00 69 00 00 3F 16
|
1
test/test-frames/premature_end_of_data1.hex
Normal file
1
test/test-frames/premature_end_of_data1.hex
Normal file
@ -0,0 +1 @@
|
||||
68 1C 1C 68 08 02 72 78 56 34 12 24 40 01 07 55 00 00 00 03 13 15 31 00 DA 02 3B 13 01 8B 60 04 C7 16
|
1
test/test-frames/premature_end_of_data2.hex
Normal file
1
test/test-frames/premature_end_of_data2.hex
Normal file
@ -0,0 +1 @@
|
||||
68 1E 1E 68 08 02 72 78 56 34 12 24 40 01 07 55 00 00 00 03 13 15 31 00 DA 02 3B 13 01 8B 60 04 37 18 16 16
|
1
test/test-frames/premature_end_of_dif1.hex
Normal file
1
test/test-frames/premature_end_of_dif1.hex
Normal file
@ -0,0 +1 @@
|
||||
68 1A 1A 68 08 02 72 78 56 34 12 24 40 01 07 55 00 00 00 03 13 15 31 00 DA 02 3B 13 01 8B 63 16
|
1
test/test-frames/premature_end_of_dif2.hex
Normal file
1
test/test-frames/premature_end_of_dif2.hex
Normal file
@ -0,0 +1 @@
|
||||
68 1B 1B 68 08 02 72 78 56 34 12 24 40 01 07 55 00 00 00 03 13 15 31 00 DA 02 3B 13 01 8B 8B EE 16
|
1
test/test-frames/premature_end_of_var_vif1.hex
Normal file
1
test/test-frames/premature_end_of_var_vif1.hex
Normal file
@ -0,0 +1 @@
|
||||
68 2E 2E 68 08 05 72 34 08 00 54 96 15 32 00 F2 00 00 00 01 FD 1B 00 02 FC 03 48 52 25 74 D4 11 22 FC 03 48 52 25 74 C8 11 12 FC 13 48 52 25 74 B4 16 5B 16
|
1
test/test-frames/premature_end_of_vif1.hex
Normal file
1
test/test-frames/premature_end_of_vif1.hex
Normal file
@ -0,0 +1 @@
|
||||
68 1B 1B 68 08 02 72 78 56 34 12 24 40 01 07 55 00 00 00 03 13 15 31 00 DA 02 3B 13 01 8B 60 C3 16
|
1
test/test-frames/too_long_var_vif.hex
Normal file
1
test/test-frames/too_long_var_vif.hex
Normal file
@ -0,0 +1 @@
|
||||
68 2E 2E 68 08 05 72 34 08 00 54 96 15 32 00 F2 00 00 00 01 FD 1B 00 02 FC 03 48 52 25 74 D4 11 22 FC 03 48 52 25 74 C8 11 12 FC F3 48 52 25 74 B4 16 3B 16
|
1
test/test-frames/too_many_dife.hex
Normal file
1
test/test-frames/too_many_dife.hex
Normal file
@ -0,0 +1 @@
|
||||
68 29 29 68 08 02 72 78 56 34 12 24 40 01 07 55 00 00 00 03 13 15 31 00 DA 02 3B 13 01 8B 8B 8B 8B 8B 8B 8B 8B 8B 8B 8B 60 04 37 18 02 86 16
|
1
test/test-frames/too_many_vife.hex
Normal file
1
test/test-frames/too_many_vife.hex
Normal file
@ -0,0 +1 @@
|
||||
68 2A 2A 68 08 02 72 78 56 34 12 24 40 01 07 55 00 00 00 03 13 15 31 00 DA 02 3B 13 01 8B 60 84 84 84 84 84 84 84 84 84 84 84 04 37 18 02 C4 16
|
1
test/test-frames/too_short_header.hex
Normal file
1
test/test-frames/too_short_header.hex
Normal file
@ -0,0 +1 @@
|
||||
68 08 08 68 08 02 72 78 56 34 12 24 B4 16
|
Loading…
x
Reference in New Issue
Block a user