Merge pull request #10 from lategoodbye/master
A lot of bugfixes especially for serial connections
This commit is contained in:
commit
198a0df8f0
@ -35,7 +35,7 @@ POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
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)/libmbus.pc.in $(top_srcdir)/configure COPYING \
|
||||
INSTALL config.guess config.sub depcomp install-sh ltmain.sh \
|
||||
|
@ -25,11 +25,11 @@ static int debug = 0;
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
mbus_frame reply;
|
||||
mbus_frame *frame, reply;
|
||||
mbus_frame_data reply_data;
|
||||
mbus_handle *handle = NULL;
|
||||
|
||||
char *device, *addr_str, matching_addr[16], *xml_result;
|
||||
char *device, *addr_str, *xml_result;
|
||||
int address, baudrate = 9600;
|
||||
|
||||
memset((void *)&reply, 0, sizeof(mbus_frame));
|
||||
@ -84,29 +84,55 @@ main(int argc, char **argv)
|
||||
printf("Failed to set baud rate.\n");
|
||||
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)
|
||||
{
|
||||
// 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);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
// else MBUS_PROBE_SINGLE
|
||||
|
@ -29,7 +29,7 @@ main(int argc, char **argv)
|
||||
mbus_frame_data reply_data;
|
||||
mbus_handle *handle = NULL;
|
||||
|
||||
char *device, *addr_str, matching_addr[16];
|
||||
char *device, *addr_str;
|
||||
int address, baudrate = 9600;
|
||||
|
||||
if (argc == 3)
|
||||
@ -87,23 +87,23 @@ main(int argc, char **argv)
|
||||
{
|
||||
// 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);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
// else MBUS_PROBE_SINGLE
|
||||
|
@ -28,7 +28,9 @@ main(int argc, char **argv)
|
||||
char *device, *addr_mask;
|
||||
int baudrate = 9600;
|
||||
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)
|
||||
{
|
||||
@ -108,7 +110,7 @@ main(int argc, char **argv)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -134,7 +136,7 @@ main(int argc, char **argv)
|
||||
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->address = 0xFF;
|
||||
@ -146,7 +148,7 @@ main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
(void) mbus_recv_frame(handle, reply);
|
||||
(void) mbus_recv_frame(handle, &reply);
|
||||
|
||||
mbus_scan_2nd_address_range(handle, 0, addr_mask);
|
||||
|
||||
|
@ -28,6 +28,7 @@ main(int argc, char **argv)
|
||||
mbus_handle *handle;
|
||||
char *device;
|
||||
int address, baudrate = 9600;
|
||||
int ret;
|
||||
|
||||
if (argc == 2)
|
||||
{
|
||||
@ -76,7 +77,7 @@ main(int argc, char **argv)
|
||||
if (debug)
|
||||
printf("Scanning primary addresses:\n");
|
||||
|
||||
for (address = 0; address < 254; address++)
|
||||
for (address = 0; address <= 250; address++)
|
||||
{
|
||||
mbus_frame reply;
|
||||
|
||||
@ -93,16 +94,41 @@ main(int argc, char **argv)
|
||||
printf("Scan failed. Could not send ping frame: %s\n", mbus_error_str());
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = mbus_recv_frame(handle, &reply);
|
||||
|
||||
if (mbus_recv_frame(handle, &reply) == -1)
|
||||
if (ret == -1)
|
||||
{
|
||||
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 (debug)
|
||||
printf("\n");
|
||||
/* check for more data (collision) */
|
||||
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);
|
||||
}
|
||||
|
@ -77,12 +77,15 @@ main(int argc, char **argv)
|
||||
printf("No reply from device\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (mbus_frame_type(&reply) != MBUS_FRAME_TYPE_ACK)
|
||||
else if (mbus_frame_type(&reply) != MBUS_FRAME_TYPE_ACK)
|
||||
{
|
||||
printf("Unknown reply:\n");
|
||||
mbus_frame_print(&reply);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Switched baud rate of device to %d\n", target_baudrate);
|
||||
}
|
||||
|
||||
mbus_disconnect(handle);
|
||||
return 0;
|
||||
|
@ -72,23 +72,23 @@ main(int argc, char **argv)
|
||||
{
|
||||
// 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);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
// else MBUS_PROBE_SINGLE
|
||||
|
@ -72,23 +72,23 @@ main(int argc, char **argv)
|
||||
{
|
||||
// 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);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
// else MBUS_PROBE_SINGLE
|
||||
|
@ -701,12 +701,38 @@ mbus_variable_vif fixed_table[] = {
|
||||
{ 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)
|
||||
{
|
||||
double exponent = 0.0;
|
||||
int i;
|
||||
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)
|
||||
{
|
||||
@ -909,6 +935,12 @@ mbus_vif_unit_normalize(int vif, double value, char **unit_out, double *value_ou
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
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);
|
||||
|
||||
if (vib->vif == 0xFD) /* first type of VIF extention: see table 8.4.4 a */
|
||||
{
|
||||
if (vib->nvife == 0)
|
||||
@ -1007,30 +1046,33 @@ mbus_record_new()
|
||||
void
|
||||
mbus_record_free(mbus_record * rec)
|
||||
{
|
||||
if (! rec->is_numeric)
|
||||
if (rec)
|
||||
{
|
||||
free((rec->value).str_val.value);
|
||||
(rec->value).str_val.value = NULL;
|
||||
if (! rec->is_numeric)
|
||||
{
|
||||
free((rec->value).str_val.value);
|
||||
(rec->value).str_val.value = NULL;
|
||||
}
|
||||
|
||||
if (rec->unit)
|
||||
{
|
||||
free(rec->unit);
|
||||
rec->unit = NULL;
|
||||
}
|
||||
|
||||
if (rec->function_medium)
|
||||
{
|
||||
free(rec->function_medium);
|
||||
rec->function_medium = NULL;
|
||||
}
|
||||
|
||||
if (rec->quantity)
|
||||
{
|
||||
free(rec->quantity);
|
||||
rec->quantity = NULL;
|
||||
}
|
||||
free(rec);
|
||||
}
|
||||
|
||||
if (rec->unit)
|
||||
{
|
||||
free(rec->unit);
|
||||
rec->unit = NULL;
|
||||
}
|
||||
|
||||
if (rec->function_medium)
|
||||
{
|
||||
free(rec->function_medium);
|
||||
rec->function_medium = NULL;
|
||||
}
|
||||
|
||||
if (rec->quantity)
|
||||
{
|
||||
free(rec->quantity);
|
||||
rec->quantity = NULL;
|
||||
}
|
||||
free(rec);
|
||||
}
|
||||
|
||||
|
||||
@ -1079,6 +1121,12 @@ mbus_parse_variable_record(mbus_data_record *data)
|
||||
char * value_out_str = NULL;
|
||||
int value_out_str_size = 0;
|
||||
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()))
|
||||
{
|
||||
@ -1500,37 +1548,6 @@ mbus_sendrecv_request(mbus_handle *handle, int address, mbus_frame *reply, int m
|
||||
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 |
|
||||
MBUS_CONTROL_MASK_DIR_M2S |
|
||||
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
|
||||
// (mask).
|
||||
// Select a device using the supplied secondary address (mask).
|
||||
//------------------------------------------------------------------------------
|
||||
int
|
||||
mbus_probe_secondary_address(mbus_handle * handle, const char *mask, char *matching_addr)
|
||||
int
|
||||
mbus_select_secondary_address(mbus_handle * handle, const char *mask)
|
||||
{
|
||||
int ret;
|
||||
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__);
|
||||
return MBUS_PROBE_ERROR;
|
||||
@ -1729,10 +1745,38 @@ mbus_probe_secondary_address(mbus_handle * handle, const char *mask, char *match
|
||||
{
|
||||
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 */
|
||||
if (mbus_send_request_frame(handle, 253) == -1)
|
||||
{
|
||||
{
|
||||
MBUS_ERROR("%s: Failed to send request to selected secondary device [mask %s]: %s.\n",
|
||||
__PRETTY_FUNCTION__,
|
||||
mask,
|
||||
@ -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)
|
||||
{
|
||||
snprintf(matching_addr, 17, "%s", mbus_frame_get_secondary_address(&reply));
|
||||
|
||||
if (_mbus_found_event)
|
||||
{
|
||||
_mbus_found_event(handle,&reply);
|
||||
}
|
||||
|
||||
return MBUS_PROBE_SINGLE;
|
||||
}
|
||||
else
|
||||
@ -1764,15 +1814,19 @@ mbus_probe_secondary_address(mbus_handle * handle, const char *mask, char *match
|
||||
return MBUS_PROBE_NOTHING;
|
||||
}
|
||||
}
|
||||
|
||||
MBUS_ERROR("%s: Unexpected reply for address [%s].\n", __PRETTY_FUNCTION__, mask);
|
||||
|
||||
return MBUS_PROBE_NOTHING;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
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 (mbus_send_request_frame(handle, address->primary) == -1)
|
||||
@ -1846,6 +1900,12 @@ mbus_scan_2nd_address_range(mbus_handle * handle, int pos, char *addr_mask)
|
||||
{
|
||||
int i, i_start, i_end, probe_ret;
|
||||
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)
|
||||
{
|
||||
@ -1885,12 +1945,18 @@ mbus_scan_2nd_address_range(mbus_handle * handle, int pos, char *addr_mask)
|
||||
for (i = 0; i <= 9; i++)
|
||||
{
|
||||
mask[pos] = '0'+i;
|
||||
|
||||
if (_mbus_scan_progress)
|
||||
_mbus_scan_progress(handle,mask);
|
||||
|
||||
probe_ret = mbus_probe_secondary_address(handle, mask, matching_mask);
|
||||
|
||||
if (probe_ret == MBUS_PROBE_SINGLE)
|
||||
{
|
||||
printf("Found a device on secondary address %s [using address mask %s]\n", matching_mask, mask);
|
||||
if (!_mbus_found_event)
|
||||
{
|
||||
printf("Found a device on secondary address %s [using address mask %s]\n", matching_mask, mask);
|
||||
}
|
||||
}
|
||||
else if (probe_ret == MBUS_PROBE_COLLISION)
|
||||
{
|
||||
|
@ -128,6 +128,18 @@ typedef struct _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
|
||||
*
|
||||
@ -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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*
|
||||
|
@ -620,9 +620,13 @@ mbus_data_str_decode(u_char *dst, const u_char *src, size_t len)
|
||||
size_t i;
|
||||
|
||||
i = 0;
|
||||
dst[len] = '\0';
|
||||
while(len > 0) {
|
||||
dst[i++] = src[--len];
|
||||
|
||||
if (src && dst)
|
||||
{
|
||||
dst[len] = '\0';
|
||||
while(len > 0) {
|
||||
dst[i++] = src[--len];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -639,18 +643,21 @@ mbus_data_bin_decode(u_char *dst, const u_char *src, size_t len, size_t max_len)
|
||||
i = 0;
|
||||
pos = 0;
|
||||
|
||||
while((i < len) && ((pos+3) < max_len)) {
|
||||
pos += snprintf(&dst[pos], max_len - pos, "%.2X ", src[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (pos > 0)
|
||||
if (src && dst)
|
||||
{
|
||||
// remove last space
|
||||
pos--;
|
||||
while((i < len) && ((pos+3) < max_len)) {
|
||||
pos += snprintf(&dst[pos], max_len - pos, "%.2X ", src[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (pos > 0)
|
||||
{
|
||||
// remove last space
|
||||
pos--;
|
||||
}
|
||||
|
||||
dst[pos] = '\0';
|
||||
}
|
||||
|
||||
dst[pos] = '\0';
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -661,16 +668,16 @@ mbus_data_bin_decode(u_char *dst, const u_char *src, size_t len, size_t max_len)
|
||||
void
|
||||
mbus_data_tm_decode(struct tm *t, u_char *t_data, size_t t_data_size)
|
||||
{
|
||||
t->tm_sec = 0;
|
||||
t->tm_min = 0;
|
||||
t->tm_hour = 0;
|
||||
t->tm_mday = 0;
|
||||
t->tm_mon = 0;
|
||||
t->tm_year = 0;
|
||||
t->tm_isdst = 0;
|
||||
|
||||
if (t && t_data)
|
||||
{
|
||||
t->tm_sec = 0;
|
||||
t->tm_min = 0;
|
||||
t->tm_hour = 0;
|
||||
t->tm_mday = 0;
|
||||
t->tm_mon = 0;
|
||||
t->tm_year = 0;
|
||||
t->tm_isdst = 0;
|
||||
|
||||
if (t_data_size == 4) // Type F = Compound CP32: Date and Time
|
||||
{
|
||||
if ((t_data[0] & 0x80) == 0) // Time valid ?
|
||||
@ -741,6 +748,173 @@ mbus_decode_manufacturer(u_char byte1, u_char byte2)
|
||||
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
|
||||
@ -1747,6 +1921,9 @@ mbus_vib_unit_lookup(mbus_value_information_block *vib)
|
||||
{
|
||||
static char buff[256];
|
||||
int n;
|
||||
|
||||
if (vib == NULL)
|
||||
return "";
|
||||
|
||||
if (vib->vif == 0xFD || vib->vif == 0xFB) // first type of VIF extention: see table 8.4.4
|
||||
{
|
||||
@ -2162,6 +2339,7 @@ mbus_data_record_function(mbus_data_record *record)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// 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];
|
||||
size_t i;
|
||||
|
||||
if (label == NULL || buff == NULL)
|
||||
return;
|
||||
|
||||
time ( &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;
|
||||
len = 0;
|
||||
|
||||
if (dst == NULL)
|
||||
return;
|
||||
|
||||
if (src != NULL)
|
||||
{
|
||||
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]));
|
||||
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));
|
||||
|
||||
len += snprintf(&buff[len], sizeof(buff) - len, " <Medium>%s</Medium>\n", str_encoded);
|
||||
|
@ -459,6 +459,25 @@ typedef struct _mbus_data_secondary_address {
|
||||
#define MBUS_VARIABLE_DATA_MEDIUM_PRESSURE 0x18
|
||||
#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
|
||||
//
|
||||
@ -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);
|
||||
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_int_encode(u_char *int_data, size_t int_data_size, int value);
|
||||
|
@ -57,7 +57,7 @@ mbus_serial_connect(char *device)
|
||||
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 |= PARENB;
|
||||
|
||||
@ -224,8 +224,14 @@ mbus_serial_recv_frame(mbus_serial_handle *handle, mbus_frame *frame)
|
||||
{
|
||||
char buff[PACKET_BUFF_SIZE];
|
||||
int len, remaining, nread;
|
||||
|
||||
if (handle == NULL || frame == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: Invalid parameter.\n", __PRETTY_FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bzero((void *)buff, sizeof(buff));
|
||||
memset((void *)buff, 0, sizeof(buff));
|
||||
|
||||
//
|
||||
// read data until a packet is received
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <netdb.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include <mbus/mbus.h>
|
||||
@ -78,7 +79,7 @@ mbus_tcp_connect(char *host, int port)
|
||||
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)
|
||||
{
|
||||
@ -165,8 +166,14 @@ mbus_tcp_recv_frame(mbus_tcp_handle *handle, mbus_frame *frame)
|
||||
{
|
||||
char buff[PACKET_BUFF_SIZE];
|
||||
int len, remaining, nread;
|
||||
|
||||
if (handle == NULL || frame == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s: Invalid parameter.\n", __PRETTY_FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bzero((void *)buff, sizeof(buff));
|
||||
memset((void *)buff, 0, sizeof(buff));
|
||||
|
||||
//
|
||||
// read data until a packet is received
|
||||
|
@ -41,13 +41,13 @@ main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
bzero(buf, sizeof(buf));
|
||||
memset(buf, 0, sizeof(buf));
|
||||
len = read(fd, buf, sizeof(buf));
|
||||
|
||||
close(fd);
|
||||
|
||||
bzero(&reply, sizeof(reply));
|
||||
bzero(&frame_data, sizeof(frame_data));
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
memset(&frame_data, 0, sizeof(frame_data));
|
||||
mbus_parse(&reply, buf, len);
|
||||
mbus_frame_data_parse(&reply, &frame_data);
|
||||
mbus_frame_print(&reply);
|
||||
|
@ -41,7 +41,7 @@ main(int argc, char *argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
bzero(raw_buff, sizeof(raw_buff));
|
||||
memset(raw_buff, 0, sizeof(raw_buff));
|
||||
len = read(fd, raw_buff, sizeof(raw_buff));
|
||||
close(fd);
|
||||
|
||||
@ -60,8 +60,8 @@ main(int argc, char *argv[])
|
||||
i++;
|
||||
}
|
||||
|
||||
bzero(&reply, sizeof(reply));
|
||||
bzero(&frame_data, sizeof(frame_data));
|
||||
memset(&reply, 0, sizeof(reply));
|
||||
memset(&frame_data, 0, sizeof(frame_data));
|
||||
|
||||
//mbus_parse_set_debug(1);
|
||||
|
||||
@ -89,8 +89,7 @@ main(int argc, char *argv[])
|
||||
|
||||
//mbus_frame_print(&reply);
|
||||
//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;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user