Merge pull request #11 from lategoodbye/master

More bugfixes for scan and data readout
This commit is contained in:
Robert Johansson
2012-05-29 17:59:53 -07:00
14 changed files with 369 additions and 106 deletions

View File

@ -169,7 +169,9 @@ main(int argc, char **argv)
fprintf(stderr, "Failed to generate XML representation of MBUS frames: %s\n", mbus_error_str()); fprintf(stderr, "Failed to generate XML representation of MBUS frames: %s\n", mbus_error_str());
return 1; return 1;
} }
printf("%s", xml_result); printf("%s", xml_result);
free(xml_result);
mbus_disconnect(handle); mbus_disconnect(handle);
return 0; return 0;

View File

@ -29,7 +29,7 @@ main(int argc, char **argv)
mbus_frame_data reply_data; mbus_frame_data reply_data;
mbus_handle *handle = NULL; mbus_handle *handle = NULL;
char *device, *addr_str; char *device, *addr_str, *xml_result;
int address, baudrate = 9600; int address, baudrate = 9600;
if (argc == 3) if (argc == 3)
@ -145,8 +145,15 @@ main(int argc, char **argv)
fprintf(stderr, "M-bus data parse error.\n"); fprintf(stderr, "M-bus data parse error.\n");
return 1; return 1;
} }
printf("%s", mbus_frame_data_xml(&reply_data)); if ((xml_result = mbus_frame_data_xml(&reply_data)) == NULL)
{
fprintf(stderr, "Failed to generate XML representation of MBUS frame: %s\n", mbus_error_str());
return 1;
}
printf("%s", xml_result);
free(xml_result);
// manual free // manual free
if (reply_data.data_var.record) if (reply_data.data_var.record)

View File

@ -137,6 +137,7 @@ main(int argc, char **argv)
} }
(void) mbus_recv_frame(handle, &reply); (void) mbus_recv_frame(handle, &reply);
sleep(1);
frame->control = MBUS_CONTROL_MASK_SND_NKE | MBUS_CONTROL_MASK_DIR_M2S; frame->control = MBUS_CONTROL_MASK_SND_NKE | MBUS_CONTROL_MASK_DIR_M2S;
frame->address = 0xFF; frame->address = 0xFF;
@ -149,6 +150,7 @@ main(int argc, char **argv)
} }
(void) mbus_recv_frame(handle, &reply); (void) mbus_recv_frame(handle, &reply);
sleep(1);
mbus_scan_2nd_address_range(handle, 0, addr_mask); mbus_scan_2nd_address_range(handle, 0, addr_mask);

View File

@ -20,12 +20,12 @@
static int debug = 0; static int debug = 0;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Execution starts here: // Scan for devices using secondary addressing.
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
mbus_frame reply, *reply_iter; mbus_frame *frame, reply;
mbus_frame_data reply_data; mbus_frame_data reply_data;
mbus_handle *handle = NULL; mbus_handle *handle = NULL;
@ -67,6 +67,33 @@ main(int argc, char **argv)
fprintf(stderr, "Failed to setup connection to M-bus gateway\n"); fprintf(stderr, "Failed to setup connection to M-bus gateway\n");
return 1; return 1;
} }
//
// init slave to get really the beginning of the records
//
frame = mbus_frame_new(MBUS_FRAME_TYPE_SHORT);
if (frame == NULL)
{
fprintf(stderr, "Failed to allocate mbus frame.\n");
return 1;
}
frame->control = MBUS_CONTROL_MASK_SND_NKE | MBUS_CONTROL_MASK_DIR_M2S;
frame->address = MBUS_ADDRESS_BROADCAST_NOREPLY;
if (debug)
printf("%s: debug: sending init frame\n", __PRETTY_FUNCTION__);
if (mbus_send_frame(handle, frame) == -1)
{
fprintf(stderr, "Failed to send mbus frame.\n");
mbus_frame_free(frame);
return 1;
}
mbus_recv_frame(handle, &reply);
if (strlen(addr_str) == 16) if (strlen(addr_str) == 16)
{ {
@ -125,7 +152,9 @@ main(int argc, char **argv)
fprintf(stderr, "Failed to generate XML representation of MBUS frames: %s\n", mbus_error_str()); fprintf(stderr, "Failed to generate XML representation of MBUS frames: %s\n", mbus_error_str());
return 1; return 1;
} }
printf("%s", xml_result); printf("%s", xml_result);
free(xml_result);
mbus_disconnect(handle); mbus_disconnect(handle);
return 0; return 0;

View File

@ -29,7 +29,7 @@ main(int argc, char **argv)
mbus_frame_data reply_data; mbus_frame_data reply_data;
mbus_handle *handle = NULL; mbus_handle *handle = NULL;
char *host, *addr_str, matching_addr[16]; char *host, *addr_str, matching_addr[16], *xml_result;
int port, address; int port, address;
memset((void *)&reply, 0, sizeof(mbus_frame)); memset((void *)&reply, 0, sizeof(mbus_frame));
@ -130,7 +130,15 @@ main(int argc, char **argv)
fprintf(stderr, "M-bus data parse error.\n"); fprintf(stderr, "M-bus data parse error.\n");
return 1; return 1;
} }
printf("%s", mbus_frame_data_xml(&reply_data));
if ((xml_result = mbus_frame_data_xml(&reply_data)) == NULL)
{
fprintf(stderr, "Failed to generate XML representation of MBUS frame: %s\n", mbus_error_str());
return 1;
}
printf("%s", xml_result);
free(xml_result);
// manual free // manual free
if (reply_data.data_var.record) if (reply_data.data_var.record)

View File

@ -17,8 +17,7 @@
#include <stdio.h> #include <stdio.h>
#include <mbus/mbus.h> #include <mbus/mbus.h>
static mbus_handle *handle = NULL; static int debug = 0;
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Execution starts here: // Execution starts here:
@ -28,6 +27,10 @@ main(int argc, char **argv)
{ {
char *host, *addr_mask; char *host, *addr_mask;
int port; int port;
mbus_handle *handle = NULL;
mbus_frame *frame = NULL, reply;
memset((void *)&reply, 0, sizeof(mbus_frame));
if (argc != 4 && argc != 3) if (argc != 4 && argc != 3)
{ {
@ -59,6 +62,43 @@ main(int argc, char **argv)
fprintf(stderr, "Failed to setup connection to M-bus gateway: %s\n", mbus_error_str()); fprintf(stderr, "Failed to setup connection to M-bus gateway: %s\n", mbus_error_str());
return 1; return 1;
} }
frame = mbus_frame_new(MBUS_FRAME_TYPE_SHORT);
if (frame == NULL)
{
fprintf(stderr, "Failed to allocate mbus frame.\n");
return 1;
}
//
// init slaves
//
frame->control = MBUS_CONTROL_MASK_SND_NKE | MBUS_CONTROL_MASK_DIR_M2S;
frame->address = 0xFD;
if (mbus_send_frame(handle, frame) == -1)
{
fprintf(stderr, "Failed to send SND_NKE #1.\n");
mbus_frame_free(frame);
return 1;
}
(void) mbus_recv_frame(handle, &reply);
sleep(1);
frame->control = MBUS_CONTROL_MASK_SND_NKE | MBUS_CONTROL_MASK_DIR_M2S;
frame->address = 0xFF;
if (mbus_send_frame(handle, frame) == -1)
{
fprintf(stderr, "Failed to send SND_NKE #2.\n");
mbus_frame_free(frame);
return 1;
}
(void) mbus_recv_frame(handle, &reply);
sleep(1);
mbus_scan_2nd_address_range(handle, 0, addr_mask); mbus_scan_2nd_address_range(handle, 0, addr_mask);

View File

@ -27,6 +27,7 @@ main(int argc, char **argv)
mbus_handle *handle; mbus_handle *handle;
char *host; char *host;
int port, address, debug = 0; int port, address, debug = 0;
int ret;
if (argc == 3) if (argc == 3)
{ {
@ -59,11 +60,13 @@ main(int argc, char **argv)
if (debug) if (debug)
printf("Scanning primary addresses:\n"); printf("Scanning primary addresses:\n");
for (address = 0; address < 254; address++) for (address = 0; address <= 250; address++)
{ {
mbus_frame reply; mbus_frame reply;
memset((void *)&reply, 0, sizeof(mbus_frame));
if (debug) if (debug)
{ {
printf("%d ", address); printf("%d ", address);
@ -75,16 +78,41 @@ main(int argc, char **argv)
printf("Scan failed. Could not send ping frame: %s\n", mbus_error_str()); printf("Scan failed. Could not send ping frame: %s\n", mbus_error_str());
return 1; return 1;
} }
ret = mbus_recv_frame(handle, &reply);
if (mbus_recv_frame(handle, &reply) == -1) if (ret == -1)
{ {
continue; continue;
} }
if (debug)
printf("\n");
if (ret == -2)
{
/* check for more data (collision) */
while (mbus_recv_frame(handle, &reply) != -1);
printf("Collision at address %d\n", address);
continue;
}
if (mbus_frame_type(&reply) == MBUS_FRAME_TYPE_ACK) if (mbus_frame_type(&reply) == MBUS_FRAME_TYPE_ACK)
{ {
if (debug) /* check for more data (collision) */
printf("\n"); while (mbus_recv_frame(handle, &reply) != -1)
{
ret = -2;
}
if (ret == -2)
{
printf("Collision at address %d\n", address);
continue;
}
printf("Found a M-Bus device at address %d\n", address); printf("Found a M-Bus device at address %d\n", address);
} }

View File

@ -1214,44 +1214,58 @@ mbus_data_variable_xml_normalized(mbus_data_variable *data)
{ {
mbus_data_record *record; mbus_data_record *record;
mbus_record *norm_record; mbus_record *norm_record;
static char buff[8192]; char *buff = NULL;
char str_encoded[768]; char str_encoded[768];
size_t len = 0; size_t len = 0, buff_size = 8192;
size_t i; size_t i;
if (data) if (data)
{ {
len += snprintf(&buff[len], sizeof(buff) - len, "<MBusData>\n\n"); buff = (char*) malloc(buff_size);
len += snprintf(&buff[len], sizeof(buff) - len, "%s", mbus_data_variable_header_xml(&(data->header))); if (buff == NULL)
return NULL;
len += snprintf(&buff[len], buff_size - len, "<MBusData>\n\n");
len += snprintf(&buff[len], buff_size - len, "%s", mbus_data_variable_header_xml(&(data->header)));
for (record = data->record, i = 0; record; record = record->next, i++) for (record = data->record, i = 0; record; record = record->next, i++)
{ {
norm_record = mbus_parse_variable_record(record); norm_record = mbus_parse_variable_record(record);
len += snprintf(&buff[len], sizeof(buff) - len, " <DataRecord id=\"%zd\">\n", i); if ((buff_size - len) < 1024)
{
buff_size *= 2;
buff = (char*) realloc(buff,buff_size);
if (buff == NULL)
return NULL;
}
len += snprintf(&buff[len], buff_size - len, " <DataRecord id=\"%zd\">\n", i);
if (norm_record != NULL) if (norm_record != NULL)
{ {
mbus_str_xml_encode(str_encoded, norm_record->function_medium, sizeof(str_encoded)); mbus_str_xml_encode(str_encoded, norm_record->function_medium, sizeof(str_encoded));
len += snprintf(&buff[len], sizeof(buff) - len, " <Function>%s</Function>\n", str_encoded); len += snprintf(&buff[len], buff_size - len, " <Function>%s</Function>\n", str_encoded);
mbus_str_xml_encode(str_encoded, norm_record->unit, sizeof(str_encoded)); mbus_str_xml_encode(str_encoded, norm_record->unit, sizeof(str_encoded));
len += snprintf(&buff[len], sizeof(buff) - len, " <Unit>%s</Unit>\n", str_encoded); len += snprintf(&buff[len], buff_size - len, " <Unit>%s</Unit>\n", str_encoded);
mbus_str_xml_encode(str_encoded, norm_record->quantity, sizeof(str_encoded)); mbus_str_xml_encode(str_encoded, norm_record->quantity, sizeof(str_encoded));
len += snprintf(&buff[len], sizeof(buff) - len, " <Quantity>%s</Quantity>\n", str_encoded); len += snprintf(&buff[len], buff_size - len, " <Quantity>%s</Quantity>\n", str_encoded);
if (norm_record->is_numeric) if (norm_record->is_numeric)
{ {
len += snprintf(&buff[len], sizeof(buff) - len, " <Value>%f</Value>\n", norm_record->value.real_val); len += snprintf(&buff[len], buff_size - len, " <Value>%f</Value>\n", norm_record->value.real_val);
} }
else else
{ {
mbus_str_xml_encode(str_encoded, norm_record->value.str_val.value, sizeof(str_encoded)); mbus_str_xml_encode(str_encoded, norm_record->value.str_val.value, sizeof(str_encoded));
len += snprintf(&buff[len], sizeof(buff) - len, " <Value>%s</Value>\n", str_encoded); len += snprintf(&buff[len], buff_size - len, " <Value>%s</Value>\n", str_encoded);
} }
mbus_record_free(norm_record); mbus_record_free(norm_record);
@ -1260,15 +1274,15 @@ mbus_data_variable_xml_normalized(mbus_data_variable *data)
{ {
} }
len += snprintf(&buff[len], sizeof(buff) - len, " </DataRecord>\n\n"); len += snprintf(&buff[len], buff_size - len, " </DataRecord>\n\n");
} }
len += snprintf(&buff[len], sizeof(buff) - len, "</MBusData>\n"); len += snprintf(&buff[len], buff_size - len, "</MBusData>\n");
return buff; return buff;
} }
return ""; return NULL;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -1290,7 +1304,7 @@ mbus_frame_data_xml_normalized(mbus_frame_data *data)
} }
} }
return ""; return NULL;
} }
mbus_handle * mbus_handle *
@ -1367,6 +1381,8 @@ mbus_disconnect(mbus_handle * handle)
int int
mbus_recv_frame(mbus_handle * handle, mbus_frame *frame) mbus_recv_frame(mbus_handle * handle, mbus_frame *frame)
{ {
int result = 0;
if (handle == NULL) if (handle == NULL)
{ {
MBUS_ERROR("%s: Invalid M-Bus handle for receive.\n", __PRETTY_FUNCTION__); MBUS_ERROR("%s: Invalid M-Bus handle for receive.\n", __PRETTY_FUNCTION__);
@ -1375,13 +1391,20 @@ mbus_recv_frame(mbus_handle * handle, mbus_frame *frame)
if (handle->is_serial) if (handle->is_serial)
{ {
return mbus_serial_recv_frame(handle->m_serial_handle, frame); result = mbus_serial_recv_frame(handle->m_serial_handle, frame);
} }
else else
{ {
return mbus_tcp_recv_frame(handle->m_tcp_handle, frame); result = mbus_tcp_recv_frame(handle->m_tcp_handle, frame);
} }
return 0;
if (frame != NULL)
{
/* set timestamp to receive time */
time(&(frame->timestamp));
}
return result;
} }
int int

View File

@ -754,6 +754,8 @@ mbus_data_product_name(mbus_data_variable_header *header)
static char buff[128]; static char buff[128];
unsigned int manufacturer; unsigned int manufacturer;
memset(buff, 0, sizeof(buff));
if (header) if (header)
{ {
manufacturer = (header->manufacturer[1] << 8) + header->manufacturer[0]; manufacturer = (header->manufacturer[1] << 8) + header->manufacturer[0];
@ -782,6 +784,15 @@ mbus_data_product_name(mbus_data_variable_header *header)
break; break;
} }
} }
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_EFE)
{
switch (header->version)
{
case 0x01:
strcpy(buff,"Engelmann SensoStar 2C");
break;
}
}
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_SLB) else if (manufacturer == MBUS_VARIABLE_DATA_MAN_SLB)
{ {
switch (header->version) switch (header->version)
@ -821,18 +832,6 @@ mbus_data_product_name(mbus_data_variable_header *header)
break; break;
} }
} }
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_ZRM)
{
switch (header->version)
{
case 0x81:
strcpy(buff,"Minol Minocal C2");
break;
case 0x82:
strcpy(buff,"Minol Minocal WR3");
break;
}
}
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_SVM) else if (manufacturer == MBUS_VARIABLE_DATA_MAN_SVM)
{ {
switch (header->version) switch (header->version)
@ -868,6 +867,7 @@ mbus_data_product_name(mbus_data_variable_header *header)
switch (header->version) switch (header->version)
{ {
case 0x31: case 0x31:
case 0x34:
strcpy(buff,"Sensus PolluTherm"); strcpy(buff,"Sensus PolluTherm");
break; break;
} }
@ -908,11 +908,30 @@ mbus_data_product_name(mbus_data_variable_header *header)
break; break;
} }
} }
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_TCH)
return buff; {
switch (header->version)
{
case 0x26:
strcpy(buff,"Techem m-bus S");
break;
}
}
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_ZRM)
{
switch (header->version)
{
case 0x81:
strcpy(buff,"Minol Minocal C2");
break;
case 0x82:
strcpy(buff,"Minol Minocal WR3");
break;
}
}
} }
return ""; return buff;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -2563,6 +2582,9 @@ mbus_data_variable_parse(mbus_frame *frame, mbus_data_variable *data)
// clean up... // clean up...
return (-2); return (-2);
} }
// copy timestamp
memcpy((void *)&(record->timestamp), (void *)&(frame->timestamp), sizeof(time_t));
// read and parse DIB (= DIF + DIFE) // read and parse DIB (= DIF + DIFE)
@ -3275,6 +3297,8 @@ mbus_data_variable_record_xml(mbus_data_record *record, int record_cnt, int fram
static char buff[8192]; static char buff[8192];
char str_encoded[768]; char str_encoded[768];
size_t len = 0; size_t len = 0;
struct tm * timeinfo;
char timestamp[21];
int val; int val;
if (record) if (record)
@ -3314,6 +3338,11 @@ mbus_data_variable_record_xml(mbus_data_record *record, int record_cnt, int fram
mbus_str_xml_encode(str_encoded, mbus_data_record_value(record), sizeof(str_encoded)); mbus_str_xml_encode(str_encoded, mbus_data_record_value(record), sizeof(str_encoded));
len += snprintf(&buff[len], sizeof(buff) - len, " <Value>%s</Value>\n", str_encoded); len += snprintf(&buff[len], sizeof(buff) - len, " <Value>%s</Value>\n", str_encoded);
timeinfo = gmtime ( &(record->timestamp) );
strftime(timestamp,20,"%Y-%m-%dT%H:%M:%S",timeinfo);
len += snprintf(&buff[len], sizeof(buff) - len, " <Timestamp>%s</Timestamp>\n", timestamp);
len += snprintf(&buff[len], sizeof(buff) - len, " </DataRecord>\n\n"); len += snprintf(&buff[len], sizeof(buff) - len, " </DataRecord>\n\n");
return buff; return buff;
@ -3329,29 +3358,42 @@ char *
mbus_data_variable_xml(mbus_data_variable *data) mbus_data_variable_xml(mbus_data_variable *data)
{ {
mbus_data_record *record; mbus_data_record *record;
static char buff[8192]; char *buff = NULL;
char str_encoded[768]; size_t len = 0, buff_size = 8192;
size_t len = 0;
int i; int i;
if (data) if (data)
{ {
len += snprintf(&buff[len], sizeof(buff) - len, "<MBusData>\n\n"); buff = (char*) malloc(buff_size);
len += snprintf(&buff[len], sizeof(buff) - len, "%s", if (buff == NULL)
return NULL;
len += snprintf(&buff[len], buff_size - len, "<MBusData>\n\n");
len += snprintf(&buff[len], buff_size - len, "%s",
mbus_data_variable_header_xml(&(data->header))); mbus_data_variable_header_xml(&(data->header)));
for (record = data->record, i = 0; record; record = record->next, i++) for (record = data->record, i = 0; record; record = record->next, i++)
{ {
len += snprintf(&buff[len], sizeof(buff) - len, "%s", if ((buff_size - len) < 1024)
{
buff_size *= 2;
buff = (char*) realloc(buff,buff_size);
if (buff == NULL)
return NULL;
}
len += snprintf(&buff[len], buff_size - len, "%s",
mbus_data_variable_record_xml(record, i, -1, &(data->header))); mbus_data_variable_record_xml(record, i, -1, &(data->header)));
} }
len += snprintf(&buff[len], sizeof(buff) - len, "</MBusData>\n"); len += snprintf(&buff[len], buff_size - len, "</MBusData>\n");
return buff; return buff;
} }
return ""; return NULL;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -3360,64 +3402,69 @@ mbus_data_variable_xml(mbus_data_variable *data)
char * char *
mbus_data_fixed_xml(mbus_data_fixed *data) mbus_data_fixed_xml(mbus_data_fixed *data)
{ {
static char buff[8192]; char *buff = NULL;
char str_encoded[256]; char str_encoded[256];
size_t len = 0; size_t len = 0, buff_size = 8192;
if (data) if (data)
{ {
len += snprintf(&buff[len], sizeof(buff) - len, "<MBusData>\n\n"); buff = (char*) malloc(buff_size);
if (buff == NULL)
return NULL;
len += snprintf(&buff[len], sizeof(buff) - len, " <SlaveInformation>\n"); len += snprintf(&buff[len], buff_size - len, "<MBusData>\n\n");
len += snprintf(&buff[len], sizeof(buff) - len, " <Id>%d</Id>\n", (int)mbus_data_bcd_decode(data->id_bcd, 4));
len += snprintf(&buff[len], buff_size - len, " <SlaveInformation>\n");
len += snprintf(&buff[len], buff_size - len, " <Id>%d</Id>\n", (int)mbus_data_bcd_decode(data->id_bcd, 4));
mbus_str_xml_encode(str_encoded, mbus_data_fixed_medium(data), sizeof(str_encoded)); mbus_str_xml_encode(str_encoded, mbus_data_fixed_medium(data), sizeof(str_encoded));
len += snprintf(&buff[len], sizeof(buff) - len, " <Medium>%s</Medium>\n", str_encoded); len += snprintf(&buff[len], buff_size - len, " <Medium>%s</Medium>\n", str_encoded);
len += snprintf(&buff[len], sizeof(buff) - len, " <AccessNumber>%d</AccessNumber>\n", data->tx_cnt); len += snprintf(&buff[len], buff_size - len, " <AccessNumber>%d</AccessNumber>\n", data->tx_cnt);
len += snprintf(&buff[len], sizeof(buff) - len, " <Status>%.2X</Status>\n", data->status); len += snprintf(&buff[len], buff_size - len, " <Status>%.2X</Status>\n", data->status);
len += snprintf(&buff[len], sizeof(buff) - len, " </SlaveInformation>\n\n"); len += snprintf(&buff[len], buff_size - len, " </SlaveInformation>\n\n");
len += snprintf(&buff[len], sizeof(buff) - len, " <DataRecord id=\"0\">\n"); len += snprintf(&buff[len], buff_size - len, " <DataRecord id=\"0\">\n");
mbus_str_xml_encode(str_encoded, mbus_data_fixed_function(data->status), sizeof(str_encoded)); mbus_str_xml_encode(str_encoded, mbus_data_fixed_function(data->status), sizeof(str_encoded));
len += snprintf(&buff[len], sizeof(buff) - len, " <Function>%s</Function>\n", str_encoded); len += snprintf(&buff[len], buff_size - len, " <Function>%s</Function>\n", str_encoded);
mbus_str_xml_encode(str_encoded, mbus_data_fixed_unit(data->cnt1_type), sizeof(str_encoded)); mbus_str_xml_encode(str_encoded, mbus_data_fixed_unit(data->cnt1_type), sizeof(str_encoded));
len += snprintf(&buff[len], sizeof(buff) - len, " <Unit>%s</Unit>\n", str_encoded); len += snprintf(&buff[len], buff_size - len, " <Unit>%s</Unit>\n", str_encoded);
if ((data->status & MBUS_DATA_FIXED_STATUS_FORMAT_MASK) == MBUS_DATA_FIXED_STATUS_FORMAT_BCD) if ((data->status & MBUS_DATA_FIXED_STATUS_FORMAT_MASK) == MBUS_DATA_FIXED_STATUS_FORMAT_BCD)
{ {
len += snprintf(&buff[len], sizeof(buff) - len, " <Value>%d</Value>\n", (int)mbus_data_bcd_decode(data->cnt1_val, 4)); len += snprintf(&buff[len], buff_size - len, " <Value>%d</Value>\n", (int)mbus_data_bcd_decode(data->cnt1_val, 4));
} }
else else
{ {
len += snprintf(&buff[len], sizeof(buff) - len, " <Value>%d</Value>\n", mbus_data_int_decode(data->cnt1_val, 4)); len += snprintf(&buff[len], buff_size - len, " <Value>%d</Value>\n", mbus_data_int_decode(data->cnt1_val, 4));
} }
len += snprintf(&buff[len], sizeof(buff) - len, " </DataRecord>\n\n"); len += snprintf(&buff[len], buff_size - len, " </DataRecord>\n\n");
len += snprintf(&buff[len], sizeof(buff) - len, " <DataRecord id=\"1\">\n"); len += snprintf(&buff[len], buff_size - len, " <DataRecord id=\"1\">\n");
mbus_str_xml_encode(str_encoded, mbus_data_fixed_function(data->status), sizeof(str_encoded)); mbus_str_xml_encode(str_encoded, mbus_data_fixed_function(data->status), sizeof(str_encoded));
len += snprintf(&buff[len], sizeof(buff) - len, " <Function>%s</Function>\n", str_encoded); len += snprintf(&buff[len], buff_size - len, " <Function>%s</Function>\n", str_encoded);
mbus_str_xml_encode(str_encoded, mbus_data_fixed_unit(data->cnt2_type), sizeof(str_encoded)); mbus_str_xml_encode(str_encoded, mbus_data_fixed_unit(data->cnt2_type), sizeof(str_encoded));
len += snprintf(&buff[len], sizeof(buff) - len, " <Unit>%s</Unit>\n", str_encoded); len += snprintf(&buff[len], buff_size - len, " <Unit>%s</Unit>\n", str_encoded);
if ((data->status & MBUS_DATA_FIXED_STATUS_FORMAT_MASK) == MBUS_DATA_FIXED_STATUS_FORMAT_BCD) if ((data->status & MBUS_DATA_FIXED_STATUS_FORMAT_MASK) == MBUS_DATA_FIXED_STATUS_FORMAT_BCD)
{ {
len += snprintf(&buff[len], sizeof(buff) - len, " <Value>%d</Value>\n", (int)mbus_data_bcd_decode(data->cnt2_val, 4)); len += snprintf(&buff[len], buff_size - len, " <Value>%d</Value>\n", (int)mbus_data_bcd_decode(data->cnt2_val, 4));
} }
else else
{ {
len += snprintf(&buff[len], sizeof(buff) - len, " <Value>%d</Value>\n", mbus_data_int_decode(data->cnt2_val, 4)); len += snprintf(&buff[len], buff_size - len, " <Value>%d</Value>\n", mbus_data_int_decode(data->cnt2_val, 4));
} }
len += snprintf(&buff[len], sizeof(buff) - len, " </DataRecord>\n\n"); len += snprintf(&buff[len], buff_size - len, " </DataRecord>\n\n");
len += snprintf(&buff[len], sizeof(buff) - len, "</MBusData>\n"); len += snprintf(&buff[len], buff_size - len, "</MBusData>\n");
return buff; return buff;
} }
return ""; return NULL;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -3426,20 +3473,25 @@ mbus_data_fixed_xml(mbus_data_fixed *data)
char * char *
mbus_data_error_xml(int error) mbus_data_error_xml(int error)
{ {
static char buff[512]; char *buff = NULL;
char str_encoded[256]; char str_encoded[256];
size_t len = 0; size_t len = 0, buff_size = 8192;
len += snprintf(&buff[len], sizeof(buff) - len, "<MBusData>\n\n");
len += snprintf(&buff[len], sizeof(buff) - len, " <SlaveInformation>\n"); buff = (char*) malloc(buff_size);
if (buff == NULL)
return NULL;
len += snprintf(&buff[len], buff_size - len, "<MBusData>\n\n");
len += snprintf(&buff[len], buff_size - len, " <SlaveInformation>\n");
mbus_str_xml_encode(str_encoded, mbus_data_error_lookup(error), sizeof(str_encoded)); mbus_str_xml_encode(str_encoded, mbus_data_error_lookup(error), sizeof(str_encoded));
len += snprintf(&buff[len], sizeof(buff) - len, " <Error>%s</Error>\n", str_encoded); len += snprintf(&buff[len], buff_size - len, " <Error>%s</Error>\n", str_encoded);
len += snprintf(&buff[len], sizeof(buff) - len, " </SlaveInformation>\n\n"); len += snprintf(&buff[len], buff_size - len, " </SlaveInformation>\n\n");
len += snprintf(&buff[len], sizeof(buff) - len, "</MBusData>\n"); len += snprintf(&buff[len], buff_size - len, "</MBusData>\n");
return buff; return buff;
} }
@ -3468,7 +3520,7 @@ mbus_frame_data_xml(mbus_frame_data *data)
} }
} }
return ""; return NULL;
} }
@ -3482,9 +3534,9 @@ mbus_frame_xml(mbus_frame *frame)
mbus_frame *iter; mbus_frame *iter;
mbus_data_record *record; mbus_data_record *record;
static char buff[8192]; char *buff = NULL;
size_t len = 0; size_t len = 0, buff_size = 8192;
int record_cnt = 0, frame_cnt; int record_cnt = 0, frame_cnt;
if (frame) if (frame)
@ -3515,25 +3567,39 @@ mbus_frame_xml(mbus_frame *frame)
{ {
// //
// generate XML for a sequence of variable data frames // generate XML for a sequence of variable data frames
// //
buff = (char*) malloc(buff_size);
if (buff == NULL)
return NULL;
// include frame counter in XML output if more than one frame // include frame counter in XML output if more than one frame
// is available (frame_cnt = -1 => not included in output) // is available (frame_cnt = -1 => not included in output)
frame_cnt = (frame->next == NULL) ? -1 : 0; frame_cnt = (frame->next == NULL) ? -1 : 0;
len += snprintf(&buff[len], sizeof(buff) - len, "<MBusData>\n\n"); len += snprintf(&buff[len], buff_size - len, "<MBusData>\n\n");
// only print the header info for the first frame (should be // only print the header info for the first frame (should be
// the same for each frame in a sequence of a multi-telegram // the same for each frame in a sequence of a multi-telegram
// transfer. // transfer.
len += snprintf(&buff[len], sizeof(buff) - len, "%s", len += snprintf(&buff[len], buff_size - len, "%s",
mbus_data_variable_header_xml(&(frame_data.data_var.header))); mbus_data_variable_header_xml(&(frame_data.data_var.header)));
// loop through all records in the current frame, using a global // loop through all records in the current frame, using a global
// record count as record ID in the XML output // record count as record ID in the XML output
for (record = frame_data.data_var.record; record; record = record->next, record_cnt++) for (record = frame_data.data_var.record; record; record = record->next, record_cnt++)
{ {
len += snprintf(&buff[len], sizeof(buff) - len, "%s", if ((buff_size - len) < 1024)
{
buff_size *= 2;
buff = (char*) realloc(buff,buff_size);
if (buff == NULL)
return NULL;
}
len += snprintf(&buff[len], buff_size - len, "%s",
mbus_data_variable_record_xml(record, record_cnt, frame_cnt, &(frame_data.data_var.header))); mbus_data_variable_record_xml(record, record_cnt, frame_cnt, &(frame_data.data_var.header)));
} }
@ -3557,7 +3623,16 @@ mbus_frame_xml(mbus_frame *frame)
// record count as record ID in the XML output // record count as record ID in the XML output
for (record = frame_data.data_var.record; record; record = record->next, record_cnt++) for (record = frame_data.data_var.record; record; record = record->next, record_cnt++)
{ {
len += snprintf(&buff[len], sizeof(buff) - len, "%s", if ((buff_size - len) < 1024)
{
buff_size *= 2;
buff = (char*) realloc(buff,buff_size);
if (buff == NULL)
return NULL;
}
len += snprintf(&buff[len], buff_size - len, "%s",
mbus_data_variable_record_xml(record, record_cnt, frame_cnt, &(frame_data.data_var.header))); mbus_data_variable_record_xml(record, record_cnt, frame_cnt, &(frame_data.data_var.header)));
} }
@ -3566,15 +3641,15 @@ mbus_frame_xml(mbus_frame *frame)
{ {
mbus_data_record_free(frame_data.data_var.record); mbus_data_record_free(frame_data.data_var.record);
} }
} }
len += snprintf(&buff[len], sizeof(buff) - len, "</MBusData>\n"); len += snprintf(&buff[len], buff_size - len, "</MBusData>\n");
return buff; return buff;
} }
} }
return ""; return NULL;
} }
@ -3733,7 +3808,7 @@ mbus_frame_select_secondary_pack(mbus_frame *frame, char *address)
return -1; return -1;
} }
frame->control = MBUS_CONTROL_MASK_SND_UD | MBUS_CONTROL_MASK_DIR_M2S; frame->control = MBUS_CONTROL_MASK_SND_UD | MBUS_CONTROL_MASK_DIR_M2S | MBUS_CONTROL_MASK_FCB;
frame->address = 253; // for addressing secondary slaves frame->address = 253; // for addressing secondary slaves
frame->control_information = 0x52; // mode 1 frame->control_information = 0x52; // mode 1

View File

@ -83,6 +83,7 @@ typedef struct _mbus_frame {
size_t data_size; size_t data_size;
int type; int type;
time_t timestamp;
//mbus_frame_data frame_data; //mbus_frame_data frame_data;
@ -145,6 +146,8 @@ typedef struct _mbus_data_record {
u_char data[234]; u_char data[234];
size_t data_len; size_t data_len;
time_t timestamp;
void *next; void *next;
} mbus_data_record; } mbus_data_record;
@ -462,6 +465,7 @@ typedef struct _mbus_data_secondary_address {
#define MBUS_VARIABLE_DATA_MAN_ACW 0x0477 #define MBUS_VARIABLE_DATA_MAN_ACW 0x0477
#define MBUS_VARIABLE_DATA_MAN_ABB 0x0442 #define MBUS_VARIABLE_DATA_MAN_ABB 0x0442
#define MBUS_VARIABLE_DATA_MAN_AMT 0x05B4 #define MBUS_VARIABLE_DATA_MAN_AMT 0x05B4
#define MBUS_VARIABLE_DATA_MAN_EFE 0x14C5
#define MBUS_VARIABLE_DATA_MAN_ELS 0x1593 #define MBUS_VARIABLE_DATA_MAN_ELS 0x1593
#define MBUS_VARIABLE_DATA_MAN_EMH 0x15A8 #define MBUS_VARIABLE_DATA_MAN_EMH 0x15A8
#define MBUS_VARIABLE_DATA_MAN_HYD 0x2324 #define MBUS_VARIABLE_DATA_MAN_HYD 0x2324
@ -475,7 +479,7 @@ typedef struct _mbus_data_secondary_address {
#define MBUS_VARIABLE_DATA_MAN_SON 0x4DEE #define MBUS_VARIABLE_DATA_MAN_SON 0x4DEE
#define MBUS_VARIABLE_DATA_MAN_SPX 0x4E18 #define MBUS_VARIABLE_DATA_MAN_SPX 0x4E18
#define MBUS_VARIABLE_DATA_MAN_SVM 0x4ECD #define MBUS_VARIABLE_DATA_MAN_SVM 0x4ECD
#define MBUS_VARIABLE_DATA_MAN_TCM 0x5068 #define MBUS_VARIABLE_DATA_MAN_TCH 0x5068
#define MBUS_VARIABLE_DATA_MAN_ZRM 0x6A4D #define MBUS_VARIABLE_DATA_MAN_ZRM 0x6A4D
// //

View File

@ -223,7 +223,7 @@ int
mbus_serial_recv_frame(mbus_serial_handle *handle, mbus_frame *frame) mbus_serial_recv_frame(mbus_serial_handle *handle, mbus_frame *frame)
{ {
char buff[PACKET_BUFF_SIZE]; char buff[PACKET_BUFF_SIZE];
int len, remaining, nread; int len, remaining, nread, timeouts;
if (handle == NULL || frame == NULL) if (handle == NULL || frame == NULL)
{ {
@ -238,6 +238,7 @@ mbus_serial_recv_frame(mbus_serial_handle *handle, mbus_frame *frame)
// //
remaining = 1; // start by reading 1 byte remaining = 1; // start by reading 1 byte
len = 0; len = 0;
timeouts = 0;
do { do {
//printf("%s: Attempt to read %d bytes [len = %d]\n", __PRETTY_FUNCTION__, remaining, len); //printf("%s: Attempt to read %d bytes [len = %d]\n", __PRETTY_FUNCTION__, remaining, len);
@ -249,7 +250,19 @@ mbus_serial_recv_frame(mbus_serial_handle *handle, mbus_frame *frame)
return -1; return -1;
} }
// printf("%s: Got %d byte [remaining %d, len %d]\n", __PRETTY_FUNCTION__, nread, remaining, len); // printf("%s: Got %d byte [remaining %d, len %d]\n", __PRETTY_FUNCTION__, nread, remaining, len);
if (nread == 0)
{
timeouts++;
if (timeouts >= 3)
{
// abort to avoid endless loop
fprintf(stderr, "%s: Timeout\n", __PRETTY_FUNCTION__);
break;
}
}
len += nread; len += nread;
@ -267,7 +280,7 @@ mbus_serial_recv_frame(mbus_serial_handle *handle, mbus_frame *frame)
if (_mbus_recv_event) if (_mbus_recv_event)
_mbus_recv_event(MBUS_HANDLE_TYPE_SERIAL, buff, len); _mbus_recv_event(MBUS_HANDLE_TYPE_SERIAL, buff, len);
if (remaining < 0) if (remaining != 0)
{ {
// Would be OK when e.g. scanning the bus, otherwise it is a failure. // Would be OK when e.g. scanning the bus, otherwise it is a failure.
// printf("%s: M-Bus layer failed to receive complete data.\n", __PRETTY_FUNCTION__); // printf("%s: M-Bus layer failed to receive complete data.\n", __PRETTY_FUNCTION__);

View File

@ -165,7 +165,7 @@ int
mbus_tcp_recv_frame(mbus_tcp_handle *handle, mbus_frame *frame) mbus_tcp_recv_frame(mbus_tcp_handle *handle, mbus_frame *frame)
{ {
char buff[PACKET_BUFF_SIZE]; char buff[PACKET_BUFF_SIZE];
int len, remaining, nread; int len, remaining, nread, timeouts;
if (handle == NULL || frame == NULL) if (handle == NULL || frame == NULL)
{ {
@ -180,6 +180,7 @@ mbus_tcp_recv_frame(mbus_tcp_handle *handle, mbus_frame *frame)
// //
remaining = 1; // start by reading 1 byte remaining = 1; // start by reading 1 byte
len = 0; len = 0;
timeouts = 0;
do { do {
@ -188,6 +189,18 @@ mbus_tcp_recv_frame(mbus_tcp_handle *handle, mbus_frame *frame)
mbus_error_str_set("M-Bus tcp transport layer failed to read data."); mbus_error_str_set("M-Bus tcp transport layer failed to read data.");
return -1; return -1;
} }
if (nread == 0)
{
timeouts++;
if (timeouts >= 3)
{
// abort to avoid endless loop
fprintf(stderr, "%s: Timeout\n", __PRETTY_FUNCTION__);
break;
}
}
len += nread; len += nread;
@ -205,7 +218,7 @@ mbus_tcp_recv_frame(mbus_tcp_handle *handle, mbus_frame *frame)
if (_mbus_recv_event) if (_mbus_recv_event)
_mbus_recv_event(MBUS_HANDLE_TYPE_TCP, buff, len); _mbus_recv_event(MBUS_HANDLE_TYPE_TCP, buff, len);
if (remaining < 0) if (remaining != 0)
{ {
mbus_error_str_set("M-Bus layer failed to parse data."); mbus_error_str_set("M-Bus layer failed to parse data.");
return -2; return -2;

View File

@ -28,6 +28,7 @@ main(int argc, char *argv[])
u_char buf[1024]; u_char buf[1024];
mbus_frame reply; mbus_frame reply;
mbus_frame_data frame_data; mbus_frame_data frame_data;
char *xml_result = NULL;
if (argc != 2) if (argc != 2)
{ {
@ -51,7 +52,15 @@ main(int argc, char *argv[])
mbus_parse(&reply, buf, len); mbus_parse(&reply, buf, len);
mbus_frame_data_parse(&reply, &frame_data); mbus_frame_data_parse(&reply, &frame_data);
mbus_frame_print(&reply); mbus_frame_print(&reply);
printf("%s", mbus_frame_data_xml(&frame_data));
if ((xml_result = mbus_frame_data_xml(&frame_data)) == NULL)
{
fprintf(stderr, "Failed to generate XML representation of MBUS frame: %s\n", mbus_error_str());
return 1;
}
printf("%s", xml_result);
free(xml_result);
return 0; return 0;
} }

View File

@ -28,6 +28,7 @@ main(int argc, char *argv[])
u_char raw_buff[4096], buff[4096], *ptr, *endptr; u_char raw_buff[4096], buff[4096], *ptr, *endptr;
mbus_frame reply; mbus_frame reply;
mbus_frame_data frame_data; mbus_frame_data frame_data;
char *xml_result = NULL;
if (argc != 2) if (argc != 2)
{ {
@ -89,7 +90,16 @@ main(int argc, char *argv[])
//mbus_frame_print(&reply); //mbus_frame_print(&reply);
//mbus_frame_data_print(&frame_data); //mbus_frame_data_print(&frame_data);
printf("%s", mbus_frame_data_xml(&frame_data));
if ((xml_result = mbus_frame_data_xml(&frame_data)) == NULL)
{
fprintf(stderr, "Failed to generate XML representation of MBUS frame: %s\n", mbus_error_str());
return 1;
}
printf("%s", xml_result);
free(xml_result);
return 0; return 0;
} }