Merge pull request #10 from lategoodbye/master

A lot of bugfixes especially for serial connections
This commit is contained in:
Robert Johansson 2012-05-20 05:47:30 -07:00
commit 198a0df8f0
16 changed files with 503 additions and 138 deletions

View File

@ -35,7 +35,7 @@ POST_UNINSTALL = :
build_triplet = @build@ build_triplet = @build@
host_triplet = @host@ host_triplet = @host@
subdir = . subdir = .
DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \ DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(srcdir)/config.h.in \ $(srcdir)/Makefile.in $(srcdir)/config.h.in \
$(srcdir)/libmbus.pc.in $(top_srcdir)/configure COPYING \ $(srcdir)/libmbus.pc.in $(top_srcdir)/configure COPYING \
INSTALL config.guess config.sub depcomp install-sh ltmain.sh \ INSTALL config.guess config.sub depcomp install-sh ltmain.sh \

View File

@ -25,11 +25,11 @@ static int debug = 0;
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
mbus_frame reply; mbus_frame *frame, reply;
mbus_frame_data reply_data; mbus_frame_data reply_data;
mbus_handle *handle = NULL; mbus_handle *handle = NULL;
char *device, *addr_str, matching_addr[16], *xml_result; char *device, *addr_str, *xml_result;
int address, baudrate = 9600; int address, baudrate = 9600;
memset((void *)&reply, 0, sizeof(mbus_frame)); memset((void *)&reply, 0, sizeof(mbus_frame));
@ -85,28 +85,54 @@ main(int argc, char **argv)
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)
{ {
// secondary addressing // secondary addressing
int probe_ret; int ret;
probe_ret = mbus_probe_secondary_address(handle, addr_str, matching_addr); ret = mbus_select_secondary_address(handle, addr_str);
if (probe_ret == MBUS_PROBE_COLLISION) if (ret == MBUS_PROBE_COLLISION)
{ {
fprintf(stderr, "%s: Error: The address mask [%s] matches more than one device.\n", __PRETTY_FUNCTION__, addr_str); fprintf(stderr, "%s: Error: The address mask [%s] matches more than one device.\n", __PRETTY_FUNCTION__, addr_str);
return 1; return 1;
} }
else if (probe_ret == MBUS_PROBE_NOTHING) else if (ret == MBUS_PROBE_NOTHING)
{ {
fprintf(stderr, "%s: Error: The selected secondary address does not match any device [%s].\n", __PRETTY_FUNCTION__, addr_str); fprintf(stderr, "%s: Error: The selected secondary address does not match any device [%s].\n", __PRETTY_FUNCTION__, addr_str);
return 1; return 1;
} }
else if (probe_ret == MBUS_PROBE_ERROR) else if (ret == MBUS_PROBE_ERROR)
{ {
fprintf(stderr, "%s: Error: Failed to probe secondary address [%s].\n", __PRETTY_FUNCTION__, addr_str); fprintf(stderr, "%s: Error: Failed to select secondary address [%s].\n", __PRETTY_FUNCTION__, addr_str);
return 1; return 1;
} }
// else MBUS_PROBE_SINGLE // else MBUS_PROBE_SINGLE

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, matching_addr[16]; char *device, *addr_str;
int address, baudrate = 9600; int address, baudrate = 9600;
if (argc == 3) if (argc == 3)
@ -87,23 +87,23 @@ main(int argc, char **argv)
{ {
// secondary addressing // secondary addressing
int probe_ret; int ret;
probe_ret = mbus_probe_secondary_address(handle, addr_str, matching_addr); ret = mbus_select_secondary_address(handle, addr_str);
if (probe_ret == MBUS_PROBE_COLLISION) if (ret == MBUS_PROBE_COLLISION)
{ {
fprintf(stderr, "%s: Error: The address mask [%s] matches more than one device.\n", __PRETTY_FUNCTION__, addr_str); fprintf(stderr, "%s: Error: The address mask [%s] matches more than one device.\n", __PRETTY_FUNCTION__, addr_str);
return 1; return 1;
} }
else if (probe_ret == MBUS_PROBE_NOTHING) else if (ret == MBUS_PROBE_NOTHING)
{ {
fprintf(stderr, "%s: Error: The selected secondary address does not match any device [%s].\n", __PRETTY_FUNCTION__, addr_str); fprintf(stderr, "%s: Error: The selected secondary address does not match any device [%s].\n", __PRETTY_FUNCTION__, addr_str);
return 1; return 1;
} }
else if (probe_ret == MBUS_PROBE_ERROR) else if (ret == MBUS_PROBE_ERROR)
{ {
fprintf(stderr, "%s: Error: Failed to probe secondary address [%s].\n", __PRETTY_FUNCTION__, addr_str); fprintf(stderr, "%s: Error: Failed to select secondary address [%s].\n", __PRETTY_FUNCTION__, addr_str);
return 1; return 1;
} }
// else MBUS_PROBE_SINGLE // else MBUS_PROBE_SINGLE

View File

@ -28,7 +28,9 @@ main(int argc, char **argv)
char *device, *addr_mask; char *device, *addr_mask;
int baudrate = 9600; int baudrate = 9600;
mbus_handle *handle = NULL; mbus_handle *handle = NULL;
mbus_frame *frame = NULL, *reply = NULL; mbus_frame *frame = NULL, reply;
memset((void *)&reply, 0, sizeof(mbus_frame));
if (argc == 2) if (argc == 2)
{ {
@ -108,7 +110,7 @@ main(int argc, char **argv)
if (mbus_serial_set_baudrate(handle->m_serial_handle, baudrate) == -1) if (mbus_serial_set_baudrate(handle->m_serial_handle, baudrate) == -1)
{ {
printf("Failed to set baud rate.\n"); fprintf(stderr, "Failed to set baud rate.\n");
return 1; return 1;
} }
@ -134,7 +136,7 @@ main(int argc, char **argv)
return 1; return 1;
} }
(void) mbus_recv_frame(handle, reply); (void) mbus_recv_frame(handle, &reply);
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;
@ -146,7 +148,7 @@ main(int argc, char **argv)
return 1; return 1;
} }
(void) mbus_recv_frame(handle, reply); (void) mbus_recv_frame(handle, &reply);
mbus_scan_2nd_address_range(handle, 0, addr_mask); mbus_scan_2nd_address_range(handle, 0, addr_mask);

View File

@ -28,6 +28,7 @@ main(int argc, char **argv)
mbus_handle *handle; mbus_handle *handle;
char *device; char *device;
int address, baudrate = 9600; int address, baudrate = 9600;
int ret;
if (argc == 2) if (argc == 2)
{ {
@ -76,7 +77,7 @@ 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;
@ -94,15 +95,40 @@ main(int argc, char **argv)
return 1; return 1;
} }
if (mbus_recv_frame(handle, &reply) == -1) ret = mbus_recv_frame(handle, &reply);
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

@ -77,12 +77,15 @@ main(int argc, char **argv)
printf("No reply from device\n"); printf("No reply from device\n");
return 1; return 1;
} }
else if (mbus_frame_type(&reply) != MBUS_FRAME_TYPE_ACK)
if (mbus_frame_type(&reply) != MBUS_FRAME_TYPE_ACK)
{ {
printf("Unknown reply:\n"); printf("Unknown reply:\n");
mbus_frame_print(&reply); mbus_frame_print(&reply);
} }
else
{
printf("Switched baud rate of device to %d\n", target_baudrate);
}
mbus_disconnect(handle); mbus_disconnect(handle);
return 0; return 0;

View File

@ -72,23 +72,23 @@ main(int argc, char **argv)
{ {
// secondary addressing // secondary addressing
int probe_ret; int ret;
probe_ret = mbus_probe_secondary_address(handle, addr_str, matching_addr); ret = mbus_select_secondary_address(handle, addr_str);
if (probe_ret == MBUS_PROBE_COLLISION) if (ret == MBUS_PROBE_COLLISION)
{ {
fprintf(stderr, "%s: Error: The address mask [%s] matches more than one device.\n", __PRETTY_FUNCTION__, addr_str); fprintf(stderr, "%s: Error: The address mask [%s] matches more than one device.\n", __PRETTY_FUNCTION__, addr_str);
return 1; return 1;
} }
else if (probe_ret == MBUS_PROBE_NOTHING) else if (ret == MBUS_PROBE_NOTHING)
{ {
fprintf(stderr, "%s: Error: The selected secondary address does not match any device [%s].\n", __PRETTY_FUNCTION__, addr_str); fprintf(stderr, "%s: Error: The selected secondary address does not match any device [%s].\n", __PRETTY_FUNCTION__, addr_str);
return 1; return 1;
} }
else if (probe_ret == MBUS_PROBE_ERROR) else if (ret == MBUS_PROBE_ERROR)
{ {
fprintf(stderr, "%s: Error: Failed to probe secondary address [%s].\n", __PRETTY_FUNCTION__, addr_str); fprintf(stderr, "%s: Error: Failed to select secondary address [%s].\n", __PRETTY_FUNCTION__, addr_str);
return 1; return 1;
} }
// else MBUS_PROBE_SINGLE // else MBUS_PROBE_SINGLE

View File

@ -72,23 +72,23 @@ main(int argc, char **argv)
{ {
// secondary addressing // secondary addressing
int probe_ret; int ret;
probe_ret = mbus_probe_secondary_address(handle, addr_str, matching_addr); ret = mbus_select_secondary_address(handle, addr_str);
if (probe_ret == MBUS_PROBE_COLLISION) if (ret == MBUS_PROBE_COLLISION)
{ {
fprintf(stderr, "%s: Error: The address mask [%s] matches more than one device.\n", __PRETTY_FUNCTION__, addr_str); fprintf(stderr, "%s: Error: The address mask [%s] matches more than one device.\n", __PRETTY_FUNCTION__, addr_str);
return 1; return 1;
} }
else if (probe_ret == MBUS_PROBE_NOTHING) else if (ret == MBUS_PROBE_NOTHING)
{ {
fprintf(stderr, "%s: Error: The selected secondary address does not match any device [%s].\n", __PRETTY_FUNCTION__, addr_str); fprintf(stderr, "%s: Error: The selected secondary address does not match any device [%s].\n", __PRETTY_FUNCTION__, addr_str);
return 1; return 1;
} }
else if (probe_ret == MBUS_PROBE_ERROR) else if (ret == MBUS_PROBE_ERROR)
{ {
fprintf(stderr, "%s: Error: Failed to probe secondary address [%s].\n", __PRETTY_FUNCTION__, addr_str); fprintf(stderr, "%s: Error: Failed to select secondary address [%s].\n", __PRETTY_FUNCTION__, addr_str);
return 1; return 1;
} }
// else MBUS_PROBE_SINGLE // else MBUS_PROBE_SINGLE

View File

@ -701,6 +701,26 @@ mbus_variable_vif fixed_table[] = {
{ 0xFFFF, 0.0, "", "" }, { 0xFFFF, 0.0, "", "" },
}; };
void (*_mbus_scan_progress)(mbus_handle * handle, const char *mask) = NULL;
void (*_mbus_found_event)(mbus_handle * handle, mbus_frame *frame) = NULL;
//------------------------------------------------------------------------------
/// Register a function for the scan progress.
//------------------------------------------------------------------------------
void
mbus_register_scan_progress(void (*event)(mbus_handle * handle, const char *mask))
{
_mbus_scan_progress = event;
}
//------------------------------------------------------------------------------
/// Register a function for the found events.
//------------------------------------------------------------------------------
void
mbus_register_found_event(void (*event)(mbus_handle * handle, mbus_frame *frame))
{
_mbus_found_event = event;
}
int mbus_fixed_normalize(int medium_unit, long medium_value, char **unit_out, double *value_out, char **quantity_out) int mbus_fixed_normalize(int medium_unit, long medium_value, char **unit_out, double *value_out, char **quantity_out)
{ {
@ -708,6 +728,12 @@ int mbus_fixed_normalize(int medium_unit, long medium_value, char **unit_out, do
int i; int i;
medium_unit = medium_unit & 0x3F; medium_unit = medium_unit & 0x3F;
if (unit_out == NULL || value_out == NULL || quantity_out == NULL)
{
MBUS_ERROR("%s: Invalid parameter.\n", __PRETTY_FUNCTION__);
return -1;
}
switch (medium_unit) switch (medium_unit)
{ {
case 0x00: case 0x00:
@ -909,6 +935,12 @@ mbus_vif_unit_normalize(int vif, double value, char **unit_out, double *value_ou
int i; int i;
if (unit_out == NULL || value_out == NULL || quantity_out == NULL)
{
MBUS_ERROR("%s: Invalid parameter.\n", __PRETTY_FUNCTION__);
return -1;
}
for(i=0; vif_table[i].vif < 0xfff; ++i) for(i=0; vif_table[i].vif < 0xfff; ++i)
{ {
if (vif_table[i].vif == newVif) if (vif_table[i].vif == newVif)
@ -931,7 +963,14 @@ mbus_vif_unit_normalize(int vif, double value, char **unit_out, double *value_ou
int int
mbus_vib_unit_normalize(mbus_value_information_block *vib, double value, char **unit_out, double *value_out, char **quantity_out) mbus_vib_unit_normalize(mbus_value_information_block *vib, double value, char **unit_out, double *value_out, char **quantity_out)
{ {
if (vib == NULL || unit_out == NULL || value_out == NULL || quantity_out == NULL)
{
MBUS_ERROR("%s: Invalid parameter.\n", __PRETTY_FUNCTION__);
return -1;
}
MBUS_DEBUG("%s: vib_unit_normalize - VIF=0x%02X\n", __PRETTY_FUNCTION__, vib->vif); MBUS_DEBUG("%s: vib_unit_normalize - VIF=0x%02X\n", __PRETTY_FUNCTION__, vib->vif);
if (vib->vif == 0xFD) /* first type of VIF extention: see table 8.4.4 a */ if (vib->vif == 0xFD) /* first type of VIF extention: see table 8.4.4 a */
{ {
if (vib->nvife == 0) if (vib->nvife == 0)
@ -1006,6 +1045,8 @@ mbus_record_new()
void void
mbus_record_free(mbus_record * rec) mbus_record_free(mbus_record * rec)
{
if (rec)
{ {
if (! rec->is_numeric) if (! rec->is_numeric)
{ {
@ -1032,6 +1073,7 @@ mbus_record_free(mbus_record * rec)
} }
free(rec); free(rec);
} }
}
mbus_record * mbus_record *
@ -1080,6 +1122,12 @@ mbus_parse_variable_record(mbus_data_record *data)
int value_out_str_size = 0; int value_out_str_size = 0;
double real_val = 0.0; /**< normalized value */ double real_val = 0.0; /**< normalized value */
if (data == NULL)
{
MBUS_ERROR("%s: Invalid record.\n", __PRETTY_FUNCTION__);
return NULL;
}
if (!(record = mbus_record_new())) if (!(record = mbus_record_new()))
{ {
MBUS_ERROR("%s: memory allocation error\n", __PRETTY_FUNCTION__); MBUS_ERROR("%s: memory allocation error\n", __PRETTY_FUNCTION__);
@ -1500,37 +1548,6 @@ mbus_sendrecv_request(mbus_handle *handle, int address, mbus_frame *reply, int m
return -1; return -1;
} }
//
// init slave to get really the beginning of the records
//
frame->control = MBUS_CONTROL_MASK_SND_NKE | MBUS_CONTROL_MASK_DIR_M2S;
frame->address = address;
if (debug)
printf("%s: debug: sending init frame\n", __PRETTY_FUNCTION__);
if (mbus_send_frame(handle, frame) == -1)
{
MBUS_ERROR("%s: failed to send mbus frame.\n", __PRETTY_FUNCTION__);
mbus_frame_free(frame);
return -1;
}
if (mbus_recv_frame(handle, reply) == -1)
{
MBUS_ERROR("%s: Failed to receive M-Bus response frame.\n", __PRETTY_FUNCTION__);
mbus_frame_free(frame);
return -1;
}
if (mbus_frame_type(reply) != MBUS_FRAME_TYPE_ACK)
{
MBUS_ERROR("%s: Unknown reply.\n", __PRETTY_FUNCTION__);
mbus_frame_free(frame);
return -1;
}
frame->control = MBUS_CONTROL_MASK_REQ_UD2 | frame->control = MBUS_CONTROL_MASK_REQ_UD2 |
MBUS_CONTROL_MASK_DIR_M2S | MBUS_CONTROL_MASK_DIR_M2S |
MBUS_CONTROL_MASK_FCV | MBUS_CONTROL_MASK_FCV |
@ -1678,16 +1695,15 @@ mbus_send_ping_frame(mbus_handle *handle, int address)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Prove for the presence of a device(s) using the supplied secondary address // Select a device using the supplied secondary address (mask).
// (mask).
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int int
mbus_probe_secondary_address(mbus_handle * handle, const char *mask, char *matching_addr) mbus_select_secondary_address(mbus_handle * handle, const char *mask)
{ {
int ret; int ret;
mbus_frame reply; mbus_frame reply;
if (mask == NULL || matching_addr == NULL || strlen(mask) != 16) if (mask == NULL || strlen(mask) != 16)
{ {
MBUS_ERROR("%s: Invalid address masks.\n", __PRETTY_FUNCTION__); MBUS_ERROR("%s: Invalid address masks.\n", __PRETTY_FUNCTION__);
return MBUS_PROBE_ERROR; return MBUS_PROBE_ERROR;
@ -1730,6 +1746,34 @@ mbus_probe_secondary_address(mbus_handle * handle, const char *mask, char *match
return MBUS_PROBE_COLLISION; return MBUS_PROBE_COLLISION;
} }
return MBUS_PROBE_SINGLE;
}
MBUS_ERROR("%s: Unexpected reply for address [%s].\n", __PRETTY_FUNCTION__, mask);
return MBUS_PROBE_NOTHING;
}
//------------------------------------------------------------------------------
// Prove for the presence of a device(s) using the supplied secondary address
// (mask).
//------------------------------------------------------------------------------
int
mbus_probe_secondary_address(mbus_handle * handle, const char *mask, char *matching_addr)
{
int ret;
mbus_frame reply;
if (mask == NULL || matching_addr == NULL || strlen(mask) != 16)
{
MBUS_ERROR("%s: Invalid address masks.\n", __PRETTY_FUNCTION__);
return MBUS_PROBE_ERROR;
}
ret = mbus_select_secondary_address(handle, mask);
if (ret == MBUS_PROBE_SINGLE)
{
/* send a data request command to find out the full address */ /* send a data request command to find out the full address */
if (mbus_send_request_frame(handle, 253) == -1) if (mbus_send_request_frame(handle, 253) == -1)
{ {
@ -1755,6 +1799,12 @@ mbus_probe_secondary_address(mbus_handle * handle, const char *mask, char *match
if (mbus_frame_type(&reply) != MBUS_FRAME_TYPE_ACK) if (mbus_frame_type(&reply) != MBUS_FRAME_TYPE_ACK)
{ {
snprintf(matching_addr, 17, "%s", mbus_frame_get_secondary_address(&reply)); snprintf(matching_addr, 17, "%s", mbus_frame_get_secondary_address(&reply));
if (_mbus_found_event)
{
_mbus_found_event(handle,&reply);
}
return MBUS_PROBE_SINGLE; return MBUS_PROBE_SINGLE;
} }
else else
@ -1765,14 +1815,18 @@ mbus_probe_secondary_address(mbus_handle * handle, const char *mask, char *match
} }
} }
MBUS_ERROR("%s: Unexpected reply for address [%s].\n", __PRETTY_FUNCTION__, mask); return ret;
return MBUS_PROBE_NOTHING;
} }
int mbus_read_slave(mbus_handle * handle, mbus_address *address, mbus_frame * reply) int mbus_read_slave(mbus_handle * handle, mbus_address *address, mbus_frame * reply)
{ {
if (handle == NULL || address == NULL)
{
MBUS_ERROR("%s: Invalid handle or address.\n", __PRETTY_FUNCTION__);
return -1;
}
if (address->is_primary) if (address->is_primary)
{ {
if (mbus_send_request_frame(handle, address->primary) == -1) if (mbus_send_request_frame(handle, address->primary) == -1)
@ -1847,6 +1901,12 @@ mbus_scan_2nd_address_range(mbus_handle * handle, int pos, char *addr_mask)
int i, i_start, i_end, probe_ret; int i, i_start, i_end, probe_ret;
char *mask, matching_mask[17]; char *mask, matching_mask[17];
if (handle == NULL || addr_mask == NULL)
{
MBUS_ERROR("%s: Invalid handle or address mask.\n", __PRETTY_FUNCTION__);
return -1;
}
if (strlen(addr_mask) != 16) if (strlen(addr_mask) != 16)
{ {
fprintf(stderr, "%s: Illegal address mask [%s]. Not 16 characters long.\n", __PRETTY_FUNCTION__, addr_mask); fprintf(stderr, "%s: Illegal address mask [%s]. Not 16 characters long.\n", __PRETTY_FUNCTION__, addr_mask);
@ -1886,12 +1946,18 @@ mbus_scan_2nd_address_range(mbus_handle * handle, int pos, char *addr_mask)
{ {
mask[pos] = '0'+i; mask[pos] = '0'+i;
if (_mbus_scan_progress)
_mbus_scan_progress(handle,mask);
probe_ret = mbus_probe_secondary_address(handle, mask, matching_mask); probe_ret = mbus_probe_secondary_address(handle, mask, matching_mask);
if (probe_ret == MBUS_PROBE_SINGLE) if (probe_ret == MBUS_PROBE_SINGLE)
{
if (!_mbus_found_event)
{ {
printf("Found a device on secondary address %s [using address mask %s]\n", matching_mask, mask); printf("Found a device on secondary address %s [using address mask %s]\n", matching_mask, mask);
} }
}
else if (probe_ret == MBUS_PROBE_COLLISION) else if (probe_ret == MBUS_PROBE_COLLISION)
{ {
// collision, more than one device matching, restrict the search mask further // collision, more than one device matching, restrict the search mask further

View File

@ -128,6 +128,18 @@ typedef struct _mbus_record {
} mbus_record; } mbus_record;
/**
* Event callback functions
*/
extern void (*_mbus_scan_progress)(mbus_handle * handle, const char *mask);
extern void (*_mbus_found_event)(mbus_handle * handle, mbus_frame *frame);
/**
* Event register functions
*/
void mbus_register_scan_progress(void (*event)(mbus_handle * handle, const char *mask));
void mbus_register_found_event(void (*event)(mbus_handle * handle, mbus_frame *frame));
/** /**
* Connects to serial gateway and initializes MBus handle * Connects to serial gateway and initializes MBus handle
* *
@ -230,6 +242,16 @@ int mbus_sendrecv_request(mbus_handle *handle, int address, mbus_frame *reply, i
*/ */
int mbus_send_ping_frame(mbus_handle *handle, int address); int mbus_send_ping_frame(mbus_handle *handle, int address);
/**
* Select slave by secondary address using "unified" handle
*
* @param handle Initialized handle
* @param mask Address/mask to select
*
* @return See MBUS_PROBE_* constants
*/
int mbus_select_secondary_address(mbus_handle * handle, const char *mask);
/** /**
* Probe/address slave by secondary address using "unified" handle * Probe/address slave by secondary address using "unified" handle
* *

View File

@ -620,11 +620,15 @@ mbus_data_str_decode(u_char *dst, const u_char *src, size_t len)
size_t i; size_t i;
i = 0; i = 0;
if (src && dst)
{
dst[len] = '\0'; dst[len] = '\0';
while(len > 0) { while(len > 0) {
dst[i++] = src[--len]; dst[i++] = src[--len];
} }
} }
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/// ///
@ -639,6 +643,8 @@ mbus_data_bin_decode(u_char *dst, const u_char *src, size_t len, size_t max_len)
i = 0; i = 0;
pos = 0; pos = 0;
if (src && dst)
{
while((i < len) && ((pos+3) < max_len)) { while((i < len) && ((pos+3) < max_len)) {
pos += snprintf(&dst[pos], max_len - pos, "%.2X ", src[i]); pos += snprintf(&dst[pos], max_len - pos, "%.2X ", src[i]);
i++; i++;
@ -652,6 +658,7 @@ mbus_data_bin_decode(u_char *dst, const u_char *src, size_t len, size_t max_len)
dst[pos] = '\0'; dst[pos] = '\0';
} }
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/// ///
@ -660,6 +667,8 @@ mbus_data_bin_decode(u_char *dst, const u_char *src, size_t len, size_t max_len)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void void
mbus_data_tm_decode(struct tm *t, u_char *t_data, size_t t_data_size) mbus_data_tm_decode(struct tm *t, u_char *t_data, size_t t_data_size)
{
if (t && t_data)
{ {
t->tm_sec = 0; t->tm_sec = 0;
t->tm_min = 0; t->tm_min = 0;
@ -669,8 +678,6 @@ mbus_data_tm_decode(struct tm *t, u_char *t_data, size_t t_data_size)
t->tm_year = 0; t->tm_year = 0;
t->tm_isdst = 0; t->tm_isdst = 0;
if (t && t_data)
{
if (t_data_size == 4) // Type F = Compound CP32: Date and Time if (t_data_size == 4) // Type F = Compound CP32: Date and Time
{ {
if ((t_data[0] & 0x80) == 0) // Time valid ? if ((t_data[0] & 0x80) == 0) // Time valid ?
@ -741,6 +748,173 @@ mbus_decode_manufacturer(u_char byte1, u_char byte2)
return m_str; return m_str;
} }
const char *
mbus_data_product_name(mbus_data_variable_header *header)
{
static char buff[128];
unsigned int manufacturer;
if (header)
{
manufacturer = (header->manufacturer[1] << 8) + header->manufacturer[0];
if (manufacturer == MBUS_VARIABLE_DATA_MAN_ACW)
{
switch (header->version)
{
case 0x09:
strcpy(buff,"Itron CF Echo 2");
break;
case 0x0A:
strcpy(buff,"Itron CF 51");
break;
case 0x0B:
strcpy(buff,"Itron CF 55");
break;
case 0x0E:
strcpy(buff,"Itron BM +m");
break;
case 0x0F:
strcpy(buff,"Itron CF 800");
break;
case 0x14:
strcpy(buff,"Itron CYBLE M-Bus 1.4");
break;
}
}
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_SLB)
{
switch (header->version)
{
case 0x02:
strcpy(buff,"Allmess Megacontrol CF-50");
break;
case 0x06:
strcpy(buff,"CF Compact / Integral MK MaXX");
break;
}
}
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_HYD)
{
switch (header->version)
{
case 0x02:
strcpy(buff,"ABB F95 Typ US770");
break;
}
}
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_LUG)
{
switch (header->version)
{
case 0x02:
strcpy(buff,"Landis & Gyr Ultraheat 2WR5");
break;
case 0x03:
strcpy(buff,"Landis & Gyr Ultraheat 2WR6");
break;
case 0x04:
strcpy(buff,"Landis & Gyr Ultraheat UH50");
break;
case 0x07:
strcpy(buff,"Landis & Gyr Ultraheat T230");
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)
{
switch (header->version)
{
case 0x08:
strcpy(buff,"Elster F2");
break;
case 0x09:
strcpy(buff,"Kamstrup SVM F22");
break;
}
}
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_SON)
{
switch (header->version)
{
case 0x0D:
strcpy(buff,"Sontex Supercal 531");
break;
}
}
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_LSE)
{
switch (header->version)
{
case 0x99:
strcpy(buff,"Siemens WFH21");
break;
}
}
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_SPX)
{
switch (header->version)
{
case 0x31:
strcpy(buff,"Sensus PolluTherm");
break;
}
}
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_ELS)
{
switch (header->version)
{
case 0x02:
strcpy(buff,"Elster TMP-A");
break;
}
}
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_NZR)
{
switch (header->version)
{
case 0x01:
strcpy(buff,"NZR DHZ 5/63");
break;
}
}
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_KAM)
{
switch (header->version)
{
case 0x08:
strcpy(buff,"Kamstrup Multical 601");
break;
}
}
else if (manufacturer == MBUS_VARIABLE_DATA_MAN_EMH)
{
switch (header->version)
{
case 0x00:
strcpy(buff,"EMH DIZ");
break;
}
}
return buff;
}
return "";
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// //
// FIXED-LENGTH DATA RECORD FUNCTIONS // FIXED-LENGTH DATA RECORD FUNCTIONS
@ -1748,6 +1922,9 @@ mbus_vib_unit_lookup(mbus_value_information_block *vib)
static char buff[256]; static char buff[256];
int n; int n;
if (vib == NULL)
return "";
if (vib->vif == 0xFD || vib->vif == 0xFB) // first type of VIF extention: see table 8.4.4 if (vib->vif == 0xFD || vib->vif == 0xFB) // first type of VIF extention: see table 8.4.4
{ {
if (vib->nvife == 0) if (vib->nvife == 0)
@ -2162,6 +2339,7 @@ mbus_data_record_function(mbus_data_record *record)
return NULL; return NULL;
} }
/// ///
/// For fixed-length frames, return a string describing the type of value (stored or actual) /// For fixed-length frames, return a string describing the type of value (stored or actual)
/// ///
@ -2965,6 +3143,9 @@ mbus_hex_dump(const char *label, const char *buff, size_t len)
char timestamp[21]; char timestamp[21];
size_t i; size_t i;
if (label == NULL || buff == NULL)
return;
time ( &rawtime ); time ( &rawtime );
timeinfo = gmtime ( &rawtime ); timeinfo = gmtime ( &rawtime );
@ -3006,6 +3187,9 @@ mbus_str_xml_encode(u_char *dst, const u_char *src, size_t max_len)
i = 0; i = 0;
len = 0; len = 0;
if (dst == NULL)
return;
if (src != NULL) if (src != NULL)
{ {
while((len+6) < max_len) while((len+6) < max_len)
@ -3063,6 +3247,10 @@ mbus_data_variable_header_xml(mbus_data_variable_header *header)
mbus_decode_manufacturer(header->manufacturer[0], header->manufacturer[1])); mbus_decode_manufacturer(header->manufacturer[0], header->manufacturer[1]));
len += snprintf(&buff[len], sizeof(buff) - len, " <Version>%d</Version>\n", header->version); len += snprintf(&buff[len], sizeof(buff) - len, " <Version>%d</Version>\n", header->version);
mbus_str_xml_encode(str_encoded, mbus_data_product_name(header), sizeof(str_encoded));
len += snprintf(&buff[len], sizeof(buff) - len, " <ProductName>%s</ProductName>\n", str_encoded);
mbus_str_xml_encode(str_encoded, mbus_data_variable_medium_lookup(header->medium), sizeof(str_encoded)); mbus_str_xml_encode(str_encoded, mbus_data_variable_medium_lookup(header->medium), sizeof(str_encoded));
len += snprintf(&buff[len], sizeof(buff) - len, " <Medium>%s</Medium>\n", str_encoded); len += snprintf(&buff[len], sizeof(buff) - len, " <Medium>%s</Medium>\n", str_encoded);

View File

@ -459,6 +459,25 @@ typedef struct _mbus_data_secondary_address {
#define MBUS_VARIABLE_DATA_MEDIUM_PRESSURE 0x18 #define MBUS_VARIABLE_DATA_MEDIUM_PRESSURE 0x18
#define MBUS_VARIABLE_DATA_MEDIUM_ADC 0x19 #define MBUS_VARIABLE_DATA_MEDIUM_ADC 0x19
#define MBUS_VARIABLE_DATA_MAN_ACW 0x0477
#define MBUS_VARIABLE_DATA_MAN_ABB 0x0442
#define MBUS_VARIABLE_DATA_MAN_AMT 0x05B4
#define MBUS_VARIABLE_DATA_MAN_ELS 0x1593
#define MBUS_VARIABLE_DATA_MAN_EMH 0x15A8
#define MBUS_VARIABLE_DATA_MAN_HYD 0x2324
#define MBUS_VARIABLE_DATA_MAN_KAM 0x2C2D
#define MBUS_VARIABLE_DATA_MAN_LSE 0x3265
#define MBUS_VARIABLE_DATA_MAN_LUG 0x32A7
#define MBUS_VARIABLE_DATA_MAN_NZR 0x3B52
#define MBUS_VARIABLE_DATA_MAN_PAD 0x4024
#define MBUS_VARIABLE_DATA_MAN_QDS 0x4493
#define MBUS_VARIABLE_DATA_MAN_SLB 0x4D82
#define MBUS_VARIABLE_DATA_MAN_SON 0x4DEE
#define MBUS_VARIABLE_DATA_MAN_SPX 0x4E18
#define MBUS_VARIABLE_DATA_MAN_SVM 0x4ECD
#define MBUS_VARIABLE_DATA_MAN_TCM 0x5068
#define MBUS_VARIABLE_DATA_MAN_ZRM 0x6A4D
// //
// Event callback functions // Event callback functions
// //
@ -564,6 +583,7 @@ void mbus_hex_dump(const char *label, const char *buff, size_t len);
// //
int mbus_data_manufacturer_encode(u_char *m_data, u_char *m_code); int mbus_data_manufacturer_encode(u_char *m_data, u_char *m_code);
const char *mbus_decode_manufacturer(u_char byte1, u_char byte2); const char *mbus_decode_manufacturer(u_char byte1, u_char byte2);
const char *mbus_data_product_name(mbus_data_variable_header *header);
int mbus_data_bcd_encode(u_char *bcd_data, size_t bcd_data_size, int value); int mbus_data_bcd_encode(u_char *bcd_data, size_t bcd_data_size, int value);
int mbus_data_int_encode(u_char *int_data, size_t int_data_size, int value); int mbus_data_int_encode(u_char *int_data, size_t int_data_size, int value);

View File

@ -57,7 +57,7 @@ mbus_serial_connect(char *device)
return NULL; return NULL;
} }
bzero(&(handle->t), sizeof(handle->t)); memset(&(handle->t), 0, sizeof(handle->t));
handle->t.c_cflag |= (CS8|CREAD|CLOCAL); handle->t.c_cflag |= (CS8|CREAD|CLOCAL);
handle->t.c_cflag |= PARENB; handle->t.c_cflag |= PARENB;
@ -225,7 +225,13 @@ 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;
bzero((void *)buff, sizeof(buff)); if (handle == NULL || frame == NULL)
{
fprintf(stderr, "%s: Invalid parameter.\n", __PRETTY_FUNCTION__);
return -1;
}
memset((void *)buff, 0, sizeof(buff));
// //
// read data until a packet is received // read data until a packet is received

View File

@ -19,6 +19,7 @@
#include <netdb.h> #include <netdb.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <strings.h> #include <strings.h>
#include <mbus/mbus.h> #include <mbus/mbus.h>
@ -78,7 +79,7 @@ mbus_tcp_connect(char *host, int port)
return NULL; return NULL;
} }
bcopy((void *)(host_addr->h_addr), (void *)(&s.sin_addr), host_addr->h_length); memcpy((void *)(&s.sin_addr), (void *)(host_addr->h_addr), host_addr->h_length);
if (connect(handle->sock, (struct sockaddr *)&s, sizeof(s)) < 0) if (connect(handle->sock, (struct sockaddr *)&s, sizeof(s)) < 0)
{ {
@ -166,7 +167,13 @@ 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;
bzero((void *)buff, sizeof(buff)); if (handle == NULL || frame == NULL)
{
fprintf(stderr, "%s: Invalid parameter.\n", __PRETTY_FUNCTION__);
return -1;
}
memset((void *)buff, 0, sizeof(buff));
// //
// read data until a packet is received // read data until a packet is received

View File

@ -41,13 +41,13 @@ main(int argc, char *argv[])
return 1; return 1;
} }
bzero(buf, sizeof(buf)); memset(buf, 0, sizeof(buf));
len = read(fd, buf, sizeof(buf)); len = read(fd, buf, sizeof(buf));
close(fd); close(fd);
bzero(&reply, sizeof(reply)); memset(&reply, 0, sizeof(reply));
bzero(&frame_data, sizeof(frame_data)); memset(&frame_data, 0, sizeof(frame_data));
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);

View File

@ -41,7 +41,7 @@ main(int argc, char *argv[])
return 1; return 1;
} }
bzero(raw_buff, sizeof(raw_buff)); memset(raw_buff, 0, sizeof(raw_buff));
len = read(fd, raw_buff, sizeof(raw_buff)); len = read(fd, raw_buff, sizeof(raw_buff));
close(fd); close(fd);
@ -60,8 +60,8 @@ main(int argc, char *argv[])
i++; i++;
} }
bzero(&reply, sizeof(reply)); memset(&reply, 0, sizeof(reply));
bzero(&frame_data, sizeof(frame_data)); memset(&frame_data, 0, sizeof(frame_data));
//mbus_parse_set_debug(1); //mbus_parse_set_debug(1);
@ -89,8 +89,7 @@ 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_normalized(&frame_data)); printf("%s", mbus_frame_data_xml(&frame_data));
// printf("%s", mbus_frame_data_xml(&frame_data));
return 0; return 0;
} }