diff --git a/mbus/mbus-protocol-aux.c b/mbus/mbus-protocol-aux.c index ec0f6f0..e655323 100755 --- a/mbus/mbus-protocol-aux.c +++ b/mbus/mbus-protocol-aux.c @@ -17,6 +17,7 @@ #include #include +#include #define MBUS_ERROR(...) fprintf (stderr, __VA_ARGS__) @@ -1024,14 +1025,15 @@ mbus_vib_unit_normalize(mbus_value_information_block *vib, double value, char ** return -1; } } - else if (vib->vif == 0x7C) + else if ((vib->vif == 0x7C) || + (vib->vif == 0xFC)) { // custom VIF *unit_out = strdup("-"); *quantity_out = strdup(vib->custom_vif); - *value_out = 0.0; - } - else + *value_out = value; + } + else { int code = (vib->vif) & 0x7f; if (0 != mbus_vif_unit_normalize(code, value, unit_out, value_out, quantity_out)) @@ -1041,6 +1043,37 @@ mbus_vib_unit_normalize(mbus_value_information_block *vib, double value, char ** } } } + + if ((vib->vif & MBUS_DIB_VIF_EXTENSION_BIT) && + (vib->vif != 0xFD) && + (vib->vif != 0xFB)) /* codes for VIF extention: see table 8.4.5 */ + { + int code = (vib->vif) & 0x7f; + switch (code) + { + case 0x70: + case 0x71: + case 0x72: + case 0x73: + case 0x74: + case 0x75: + case 0x76: + case 0x77: /* Multiplicative correction factor: 10^nnn-6 */ + *value_out *= pow(10.0, (vib->vife[0] & 0x07) - 6); + break; + + case 0x78: + case 0x79: + case 0x7A: + case 0x7B: /* Additive correction constant: 10^nn-3 unit of VIF (offset) */ + *value_out += pow(10.0, (vib->vife[0] & 0x03) - 3); + break; + + case 0x7D: /* Multiplicative correction factor: 10^3 */ + *value_out *= 1000.0; + break; + } + } return 0; } diff --git a/mbus/mbus-protocol.c b/mbus/mbus-protocol.c index 91957e7..3c94b16 100755 --- a/mbus/mbus-protocol.c +++ b/mbus/mbus-protocol.c @@ -2104,6 +2104,13 @@ mbus_vib_unit_lookup(mbus_value_information_block *vib) snprintf(buff, sizeof(buff), "%s", vib->custom_vif); return buff; } + else if (vib->vif == 0xFC && (vib->vife[0] & 0x78) == 0x70) + { + // custom VIF + n = (vib->vife[0] & 0x07); + snprintf(buff, sizeof(buff), "%s %s", mbus_unit_prefix(n-6), vib->custom_vif); + return buff; + } return mbus_vif_unit_lookup(vib->vif); // no extention, use VIF } @@ -2686,21 +2693,30 @@ mbus_data_variable_parse(mbus_frame *frame, mbus_data_variable *data) // read and parse VIB (= VIF + VIFE) // VIF - record->drh.vib.vif = frame->data[i]; - - if (record->drh.vib.vif == 0x7C) + record->drh.vib.vif = frame->data[i++]; + + if ((record->drh.vib.vif & 0x7F) == 0x7C) { // variable length VIF in ASCII format int var_vif_len; - i++; var_vif_len = frame->data[i++]; + if (i + var_vif_len > frame->data_size) + { + mbus_data_record_free(record); + return -1; + } mbus_data_str_decode(record->drh.vib.custom_vif, &(frame->data[i]), var_vif_len); i += var_vif_len; } - else + + // VIFE + record->drh.vib.nvife = 0; + + if (record->drh.vib.vif & MBUS_DIB_VIF_EXTENSION_BIT) { - // VIFE - record->drh.vib.nvife = 0; + 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)) { @@ -2710,7 +2726,7 @@ mbus_data_variable_parse(mbus_frame *frame, mbus_data_variable *data) record->drh.vib.nvife++; i++; } - i++; + i++; } // re-calculate data length, if of variable length type