Merge pull request #51 from lategoodbye/master

Improve data parsing
This commit is contained in:
Robert Johansson 2013-06-22 02:47:17 -07:00
commit 158208c2b1
13 changed files with 111 additions and 13 deletions

View File

@ -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++)

View File

@ -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)
//

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View File

@ -0,0 +1 @@
68 08 08 68 08 02 72 78 56 34 12 24 B4 16