Merge pull request #14 from jakubovsky/master

Few improvements
This commit is contained in:
Robert Johansson
2012-07-09 08:03:41 -07:00
19 changed files with 425 additions and 292 deletions

17
bin/mbus-serial-request-data-multi-reply.c Normal file → Executable file
View File

@ -73,13 +73,19 @@ main(int argc, char **argv)
mbus_register_recv_event(&mbus_dump_recv_event); mbus_register_recv_event(&mbus_dump_recv_event);
} }
if ((handle = mbus_connect_serial(device)) == NULL) if ((handle = mbus_context_serial(device)) == NULL)
{ {
fprintf(stderr, "Failed to setup connection to M-bus gateway\n"); fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str());
return 1; return 1;
} }
if (mbus_serial_set_baudrate(handle->m_serial_handle, baudrate) == -1) if (!mbus_connect(handle))
{
printf("Failed to setup connection to M-bus gateway\n");
return 1;
}
if (mbus_serial_set_baudrate(handle, baudrate) == -1)
{ {
printf("Failed to set baud rate.\n"); printf("Failed to set baud rate.\n");
return 1; return 1;
@ -110,7 +116,7 @@ main(int argc, char **argv)
return 1; return 1;
} }
while (mbus_recv_frame(handle, &reply) != -1); mbus_purge_frames(handle);
// //
// resend SND_NKE, maybe the first get lost // resend SND_NKE, maybe the first get lost
@ -129,7 +135,7 @@ main(int argc, char **argv)
return 1; return 1;
} }
while (mbus_recv_frame(handle, &reply) != -1); mbus_purge_frames(handle);
if (strlen(addr_str) == 16) if (strlen(addr_str) == 16)
{ {
@ -193,6 +199,7 @@ main(int argc, char **argv)
free(xml_result); free(xml_result);
mbus_disconnect(handle); mbus_disconnect(handle);
mbus_context_free(handle);
return 0; return 0;
} }

13
bin/mbus-serial-request-data.c Normal file → Executable file
View File

@ -70,13 +70,19 @@ main(int argc, char **argv)
mbus_register_recv_event(&mbus_dump_recv_event); mbus_register_recv_event(&mbus_dump_recv_event);
} }
if ((handle = mbus_connect_serial(device)) == NULL) if ((handle = mbus_context_serial(device)) == NULL)
{ {
fprintf(stderr, "Failed to setup connection to M-bus gateway\n"); fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str());
return 1; return 1;
} }
if (mbus_serial_set_baudrate(handle->m_serial_handle, baudrate) == -1) if (mbus_connect(handle) == -1)
{
printf("Failed to setup connection to M-bus gateway\n");
return 1;
}
if (mbus_serial_set_baudrate(handle, baudrate) == -1)
{ {
printf("Failed to set baud rate.\n"); printf("Failed to set baud rate.\n");
return 1; return 1;
@ -162,6 +168,7 @@ main(int argc, char **argv)
} }
mbus_disconnect(handle); mbus_disconnect(handle);
mbus_context_free(handle);
return 0; return 0;
} }

14
bin/mbus-serial-scan-secondary.c Normal file → Executable file
View File

@ -102,13 +102,19 @@ main(int argc, char **argv)
return 1; return 1;
} }
if ((handle = mbus_connect_serial(device)) == NULL) if ((handle = mbus_context_serial(device)) == NULL)
{ {
fprintf(stderr, "Failed to setup connection to M-bus gateway: %s\n", mbus_error_str()); fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str());
return 1; return 1;
} }
if (mbus_serial_set_baudrate(handle->m_serial_handle, baudrate) == -1) if (!mbus_connect(handle))
{
printf("Failed to setup connection to M-bus gateway\n");
return 1;
}
if (mbus_serial_set_baudrate(handle, baudrate) == -1)
{ {
fprintf(stderr, "Failed to set baud rate.\n"); fprintf(stderr, "Failed to set baud rate.\n");
return 1; return 1;
@ -153,7 +159,7 @@ main(int argc, char **argv)
mbus_scan_2nd_address_range(handle, 0, addr_mask); mbus_scan_2nd_address_range(handle, 0, addr_mask);
mbus_disconnect(handle); mbus_disconnect(handle);
mbus_context_free(handle);
//printf("Summary: Tried %ld address masks and found %d devices.\n", probe_count, match_count); //printf("Summary: Tried %ld address masks and found %d devices.\n", probe_count, match_count);
free(addr_mask); free(addr_mask);

24
bin/mbus-serial-scan.c Normal file → Executable file
View File

@ -62,13 +62,19 @@ main(int argc, char **argv)
mbus_register_recv_event(&mbus_dump_recv_event); mbus_register_recv_event(&mbus_dump_recv_event);
} }
if ((handle = mbus_connect_serial(device)) == NULL) if ((handle = mbus_context_serial(device)) == NULL)
{
fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str());
return 1;
}
if (mbus_connect(handle) == -1)
{ {
printf("Failed to setup connection to M-bus gateway\n"); printf("Failed to setup connection to M-bus gateway\n");
return 1; return 1;
} }
if (mbus_serial_set_baudrate(handle->m_serial_handle, baudrate) == -1) if (mbus_serial_set_baudrate(handle, baudrate) == -1)
{ {
printf("Failed to set baud rate.\n"); printf("Failed to set baud rate.\n");
return 1; return 1;
@ -97,7 +103,7 @@ main(int argc, char **argv)
ret = mbus_recv_frame(handle, &reply); ret = mbus_recv_frame(handle, &reply);
if (ret == -1) if (ret == -3)
{ {
continue; continue;
} }
@ -108,22 +114,15 @@ main(int argc, char **argv)
if (ret == -2) if (ret == -2)
{ {
/* check for more data (collision) */ /* check for more data (collision) */
while (mbus_recv_frame(handle, &reply) != -1); mbus_purge_frames(handle);
printf("Collision at address %d\n", address); printf("Collision at address %d\n", address);
continue; continue;
} }
if (mbus_frame_type(&reply) == MBUS_FRAME_TYPE_ACK) if (mbus_frame_type(&reply) == MBUS_FRAME_TYPE_ACK)
{ {
/* check for more data (collision) */ /* check for more data (collision) */
while (mbus_recv_frame(handle, &reply) != -1) if (mbus_purge_frames(handle))
{
ret = -2;
}
if (ret == -2)
{ {
printf("Collision at address %d\n", address); printf("Collision at address %d\n", address);
@ -135,6 +134,7 @@ main(int argc, char **argv)
} }
mbus_disconnect(handle); mbus_disconnect(handle);
mbus_context_free(handle);
return 0; return 0;
} }

17
bin/mbus-serial-select-secondary.c Normal file → Executable file
View File

@ -53,13 +53,19 @@ main(int argc, char **argv)
return 1; return 1;
} }
if ((handle = mbus_connect_serial(device)) == NULL) if ((handle = mbus_context_serial(device)) == NULL)
{ {
printf("Failed to setup connection to M-bus device: %s\n", mbus_error_str()); fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str());
return 1; return 1;
} }
if (mbus_serial_set_baudrate(handle->m_serial_handle, baudrate) == -1) if (mbus_connect(handle) == -1)
{
printf("Failed to setup connection to M-bus gateway\n");
return 1;
}
if (mbus_serial_set_baudrate(handle, baudrate) == -1)
{ {
printf("Failed to set baud rate.\n"); printf("Failed to set baud rate.\n");
return 1; return 1;
@ -73,7 +79,7 @@ main(int argc, char **argv)
ret = mbus_recv_frame(handle, &reply); ret = mbus_recv_frame(handle, &reply);
if (ret == -1) if (ret == -3)
{ {
printf("No reply from device with secondary address %s: %s\n", argv[2], mbus_error_str()); printf("No reply from device with secondary address %s: %s\n", argv[2], mbus_error_str());
return 1; return 1;
@ -93,7 +99,7 @@ main(int argc, char **argv)
return 1; return 1;
} }
if (mbus_recv_frame(handle, &reply) == -1) if (mbus_recv_frame(handle, &reply) != 0)
{ {
printf("Failed to recieve reply from selected secondary device: %s\n", mbus_error_str()); printf("Failed to recieve reply from selected secondary device: %s\n", mbus_error_str());
return 1; return 1;
@ -113,6 +119,7 @@ main(int argc, char **argv)
free(addr); free(addr);
mbus_disconnect(handle); mbus_disconnect(handle);
mbus_context_free(handle);
return 0; return 0;
} }

15
bin/mbus-serial-switch-baudrate.c Normal file → Executable file
View File

@ -52,13 +52,19 @@ main(int argc, char **argv)
return 0; return 0;
} }
if ((handle = mbus_connect_serial(device)) == NULL) if ((handle = mbus_context_serial(device)) == NULL)
{ {
printf("Failed to setup connection to M-bus device: %s\n", mbus_error_str()); fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str());
return 1; return 1;
} }
if (mbus_serial_set_baudrate(handle->m_serial_handle, source_baudrate) == -1) if (mbus_connect(handle) == -1)
{
printf("Failed to setup connection to M-bus gateway\n");
return 1;
}
if (mbus_serial_set_baudrate(handle, source_baudrate) == -1)
{ {
printf("Failed to set baud rate.\n"); printf("Failed to set baud rate.\n");
return 1; return 1;
@ -72,7 +78,7 @@ main(int argc, char **argv)
ret = mbus_recv_frame(handle, &reply); ret = mbus_recv_frame(handle, &reply);
if (ret == -1) if (ret == -3)
{ {
printf("No reply from device\n"); printf("No reply from device\n");
return 1; return 1;
@ -88,6 +94,7 @@ main(int argc, char **argv)
} }
mbus_disconnect(handle); mbus_disconnect(handle);
mbus_context_free(handle);
return 0; return 0;
} }

9
bin/mbus-tcp-request-data-multi-reply.c Normal file → Executable file
View File

@ -62,7 +62,13 @@ main(int argc, char **argv)
mbus_register_recv_event(&mbus_dump_recv_event); mbus_register_recv_event(&mbus_dump_recv_event);
} }
if ((handle = mbus_connect_tcp(host, port)) == NULL) if ((handle = mbus_context_tcp(host, port)) == NULL)
{
fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str());
return 1;
}
if (mbus_connect(handle) == -1)
{ {
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;
@ -157,6 +163,7 @@ main(int argc, char **argv)
free(xml_result); free(xml_result);
mbus_disconnect(handle); mbus_disconnect(handle);
mbus_context_free(handle);
return 0; return 0;
} }

11
bin/mbus-tcp-request-data.c Normal file → Executable file
View File

@ -62,7 +62,13 @@ main(int argc, char **argv)
mbus_register_recv_event(&mbus_dump_recv_event); mbus_register_recv_event(&mbus_dump_recv_event);
} }
if ((handle = mbus_connect_tcp(host, port)) == NULL) if ((handle = mbus_context_tcp(host, port)) == NULL)
{
fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str());
return 1;
}
if (mbus_connect(handle) == -1)
{ {
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;
@ -113,7 +119,7 @@ main(int argc, char **argv)
if (mbus_recv_frame(handle, &reply) != 0) if (mbus_recv_frame(handle, &reply) != 0)
{ {
fprintf(stderr, "Failed to receive M-Bus response frame.\n"); fprintf(stderr, "Failed to receive M-Bus response frame: %s\n", mbus_error_str());
return 1; return 1;
} }
@ -147,6 +153,7 @@ main(int argc, char **argv)
} }
mbus_disconnect(handle); mbus_disconnect(handle);
mbus_context_free(handle);
return 0; return 0;
} }

11
bin/mbus-tcp-scan-secondary.c Normal file → Executable file
View File

@ -57,9 +57,15 @@ main(int argc, char **argv)
return 1; return 1;
} }
if ((handle = mbus_connect_tcp(host, port)) == NULL) if ((handle = mbus_context_tcp(host, port)) == NULL)
{ {
fprintf(stderr, "Failed to setup connection to M-bus gateway: %s\n", mbus_error_str()); fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str());
return 1;
}
if (mbus_connect(handle) == -1)
{
fprintf(stderr, "Failed to setup connection to M-bus gateway\n");
return 1; return 1;
} }
@ -103,6 +109,7 @@ main(int argc, char **argv)
mbus_scan_2nd_address_range(handle, 0, addr_mask); mbus_scan_2nd_address_range(handle, 0, addr_mask);
mbus_disconnect(handle); mbus_disconnect(handle);
mbus_context_free(handle);
//printf("Summary: Tried %ld address masks and found %d devices.\n", probe_count, match_count); //printf("Summary: Tried %ld address masks and found %d devices.\n", probe_count, match_count);

24
bin/mbus-tcp-scan.c Normal file → Executable file
View File

@ -17,7 +17,6 @@
#include <stdio.h> #include <stdio.h>
#include <mbus/mbus.h> #include <mbus/mbus.h>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Execution starts here: // Execution starts here:
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -52,7 +51,13 @@ main(int argc, char **argv)
mbus_register_recv_event(&mbus_dump_recv_event); mbus_register_recv_event(&mbus_dump_recv_event);
} }
if ((handle = mbus_connect_tcp(host, port)) == NULL) if ((handle = mbus_context_tcp(host, port)) == NULL)
{
printf("Scan failed: Could not initialize M-Bus context: %s\n", mbus_error_str());
return 1;
}
if (mbus_connect(handle) == -1)
{ {
printf("Scan failed: Could not setup connection to M-bus gateway: %s\n", mbus_error_str()); printf("Scan failed: Could not setup connection to M-bus gateway: %s\n", mbus_error_str());
return 1; return 1;
@ -81,7 +86,7 @@ main(int argc, char **argv)
ret = mbus_recv_frame(handle, &reply); ret = mbus_recv_frame(handle, &reply);
if (ret == -1) if (ret == -3)
{ {
continue; continue;
} }
@ -92,25 +97,17 @@ main(int argc, char **argv)
if (ret == -2) if (ret == -2)
{ {
/* check for more data (collision) */ /* check for more data (collision) */
while (mbus_recv_frame(handle, &reply) != -1); mbus_purge_frames(handle);
printf("Collision at address %d\n", address); printf("Collision at address %d\n", address);
continue; continue;
} }
if (mbus_frame_type(&reply) == MBUS_FRAME_TYPE_ACK) if (mbus_frame_type(&reply) == MBUS_FRAME_TYPE_ACK)
{ {
/* check for more data (collision) */ /* check for more data (collision) */
while (mbus_recv_frame(handle, &reply) != -1) if (mbus_purge_frames(handle))
{
ret = -2;
}
if (ret == -2)
{ {
printf("Collision at address %d\n", address); printf("Collision at address %d\n", address);
continue; continue;
} }
@ -119,6 +116,7 @@ main(int argc, char **argv)
} }
mbus_disconnect(handle); mbus_disconnect(handle);
mbus_context_free(handle);
return 0; return 0;
} }

15
bin/mbus-tcp-select-secondary.c Normal file → Executable file
View File

@ -45,9 +45,15 @@ main(int argc, char **argv)
return 1; return 1;
} }
if ((handle = mbus_connect_tcp(host, port)) == NULL) if ((handle = mbus_context_tcp(host, port)) == NULL)
{ {
printf("Failed to setup connection to M-bus gateway: %s\n", mbus_error_str()); fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str());
return 1;
}
if (mbus_connect(handle) == -1)
{
fprintf(stderr, "Failed to setup connection to M-bus gateway\n");
return 1; return 1;
} }
@ -59,7 +65,7 @@ main(int argc, char **argv)
ret = mbus_recv_frame(handle, &reply); ret = mbus_recv_frame(handle, &reply);
if (ret == -1) if (ret == -3)
{ {
printf("No reply from device with secondary address %s: %s\n", argv[3], mbus_error_str()); printf("No reply from device with secondary address %s: %s\n", argv[3], mbus_error_str());
return 1; return 1;
@ -79,7 +85,7 @@ main(int argc, char **argv)
return 1; return 1;
} }
if (mbus_recv_frame(handle, &reply) == -1) if (mbus_recv_frame(handle, &reply) != 0)
{ {
printf("Failed to recieve reply from selected secondary device: %s\n", mbus_error_str()); printf("Failed to recieve reply from selected secondary device: %s\n", mbus_error_str());
return 1; return 1;
@ -99,6 +105,7 @@ main(int argc, char **argv)
free(addr); free(addr);
mbus_disconnect(handle); mbus_disconnect(handle);
mbus_context_free(handle);
return 0; return 0;
} }

181
mbus/mbus-protocol-aux.c Normal file → Executable file
View File

@ -12,6 +12,8 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#include "mbus-protocol-aux.h" #include "mbus-protocol-aux.h"
#include "mbus-serial.h"
#include "mbus-tcp.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -1308,74 +1310,120 @@ mbus_frame_data_xml_normalized(mbus_frame_data *data)
} }
mbus_handle * mbus_handle *
mbus_connect_serial(const char * device) mbus_context_serial(const char *device)
{ {
mbus_serial_handle * serial_handle; mbus_handle *handle;
if ((serial_handle = mbus_serial_connect((char*)device)) == NULL) mbus_serial_data *serial_data;
{ char error_str[128];
MBUS_ERROR("%s: Failed to setup serial connection to M-bus gateway on %s.\n",
__PRETTY_FUNCTION__,
device);
return NULL;
}
mbus_handle * handle; if ((handle = (mbus_handle *) malloc(sizeof(mbus_handle))) == NULL)
if ((handle = (mbus_handle * ) malloc(sizeof(mbus_handle))) == NULL)
{ {
MBUS_ERROR("%s: Failed to allocate handle.\n", __PRETTY_FUNCTION__); MBUS_ERROR("%s: Failed to allocate handle.\n", __PRETTY_FUNCTION__);
return NULL; return NULL;
} }
if ((serial_data = (mbus_serial_data *)malloc(sizeof(mbus_serial_data))) == NULL)
{
snprintf(error_str, sizeof(error_str), "%s: failed to allocate memory for handle\n", __PRETTY_FUNCTION__);
mbus_error_str_set(error_str);
free(handle);
return NULL;
}
handle->is_serial = 1; handle->is_serial = 1;
handle->m_serial_handle = serial_handle; handle->auxdata = serial_data;
handle->open = mbus_serial_connect;
handle->close = mbus_serial_disconnect;
handle->recv = mbus_serial_recv_frame;
handle->send = mbus_serial_send_frame;
handle->free_auxdata = mbus_serial_data_free;
if ((serial_data->device = strdup(device)) == NULL)
{
snprintf(error_str, sizeof(error_str), "%s: failed to allocate memory for device\n", __PRETTY_FUNCTION__);
mbus_error_str_set(error_str);
free(serial_data);
free(handle);
return NULL;
}
return handle; return handle;
} }
mbus_handle * mbus_handle *
mbus_connect_tcp(const char * host, int port) mbus_context_tcp(const char *host, int port)
{ {
mbus_tcp_handle * tcp_handle; mbus_handle *handle;
if ((tcp_handle = mbus_tcp_connect((char*)host, port)) == NULL) mbus_tcp_data *tcp_data;
{ char error_str[128];
MBUS_ERROR("%s: Failed to setup tcp connection to M-bus gateway on %s, port %d.\n",
__PRETTY_FUNCTION__,
host,
port);
return NULL;
}
mbus_handle * handle; if ((handle = (mbus_handle *) malloc(sizeof(mbus_handle))) == NULL)
if ((handle = (mbus_handle * ) malloc(sizeof(mbus_handle))) == NULL)
{ {
MBUS_ERROR("%s: Failed to allocate handle.\n", __PRETTY_FUNCTION__); MBUS_ERROR("%s: Failed to allocate handle.\n", __PRETTY_FUNCTION__);
return NULL; return NULL;
} }
if ((tcp_data = (mbus_tcp_data *)malloc(sizeof(mbus_tcp_data))) == NULL)
{
snprintf(error_str, sizeof(error_str), "%s: failed to allocate memory for handle\n", __PRETTY_FUNCTION__);
mbus_error_str_set(error_str);
free(handle);
return NULL;
}
handle->is_serial = 0; handle->is_serial = 0;
handle->m_tcp_handle = tcp_handle; handle->auxdata = tcp_data;
handle->open = mbus_tcp_connect;
handle->close = mbus_tcp_disconnect;
handle->recv = mbus_tcp_recv_frame;
handle->send = mbus_tcp_send_frame;
handle->free_auxdata = mbus_tcp_data_free;
tcp_data->port = port;
if ((tcp_data->host = strdup(host)) == NULL)
{
snprintf(error_str, sizeof(error_str), "%s: failed to allocate memory for host\n", __PRETTY_FUNCTION__);
mbus_error_str_set(error_str);
free(tcp_data);
free(handle);
return NULL;
}
return handle; return handle;
} }
void
mbus_context_free(mbus_handle * handle)
{
if (handle)
{
handle->free_auxdata(handle);
free(handle);
}
}
int
mbus_connect(mbus_handle * handle)
{
if (handle == NULL)
{
MBUS_ERROR("%s: Invalid M-Bus handle for disconnect.\n", __PRETTY_FUNCTION__);
return -1;
}
return handle->open(handle);
}
int int
mbus_disconnect(mbus_handle * handle) mbus_disconnect(mbus_handle * handle)
{ {
if (handle == NULL) if (handle == NULL)
{ {
MBUS_ERROR("%s: Invalid M-Bus handle for disconnect.\n", __PRETTY_FUNCTION__); MBUS_ERROR("%s: Invalid M-Bus handle for disconnect.\n", __PRETTY_FUNCTION__);
return 0; return -1;
} }
if (handle->is_serial) return handle->close(handle);
{
mbus_serial_disconnect(handle->m_serial_handle);
handle->m_serial_handle = NULL;
}
else
{
mbus_tcp_disconnect(handle->m_tcp_handle);
handle->m_tcp_handle = NULL;
}
free(handle);
return 0;
} }
int int
@ -1386,23 +1434,16 @@ mbus_recv_frame(mbus_handle * handle, mbus_frame *frame)
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__);
return 0; return -1;
} }
if (frame == NULL) if (frame == NULL)
{ {
MBUS_ERROR("%s: Invalid frame.\n", __PRETTY_FUNCTION__); MBUS_ERROR("%s: Invalid frame.\n", __PRETTY_FUNCTION__);
return 0; return -1;
} }
if (handle->is_serial) result = handle->recv(handle, frame);
{
result = mbus_serial_recv_frame(handle->m_serial_handle, frame);
}
else
{
result = mbus_tcp_recv_frame(handle->m_tcp_handle, frame);
}
if (frame != NULL) if (frame != NULL)
{ {
@ -1413,6 +1454,24 @@ mbus_recv_frame(mbus_handle * handle, mbus_frame *frame)
return result; return result;
} }
int mbus_purge_frames(mbus_handle *handle)
{
int err, received;
mbus_frame reply;
received = 0;
while (1)
{
err = mbus_recv_frame(handle, &reply);
if (err != -2 && err != 0)
break;
received = 1;
}
return received;
}
int int
mbus_send_frame(mbus_handle * handle, mbus_frame *frame) mbus_send_frame(mbus_handle * handle, mbus_frame *frame)
{ {
@ -1422,15 +1481,7 @@ mbus_send_frame(mbus_handle * handle, mbus_frame *frame)
return 0; return 0;
} }
if (handle->is_serial) return handle->send(handle, frame);
{
return mbus_serial_send_frame(handle->m_serial_handle, frame);
}
else
{
return mbus_tcp_send_frame(handle->m_tcp_handle, frame);
}
return 0;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -1751,7 +1802,7 @@ mbus_select_secondary_address(mbus_handle * handle, const char *mask)
ret = mbus_recv_frame(handle, &reply); ret = mbus_recv_frame(handle, &reply);
if (ret == -1) if (ret == -3)
{ {
return MBUS_PROBE_NOTHING; return MBUS_PROBE_NOTHING;
} }
@ -1759,20 +1810,14 @@ mbus_select_secondary_address(mbus_handle * handle, const char *mask)
if (ret == -2) if (ret == -2)
{ {
/* check for more data (collision) */ /* check for more data (collision) */
while (mbus_recv_frame(handle, &reply) != -1); mbus_purge_frames(handle);
return MBUS_PROBE_COLLISION; return MBUS_PROBE_COLLISION;
} }
if (mbus_frame_type(&reply) == MBUS_FRAME_TYPE_ACK) if (mbus_frame_type(&reply) == MBUS_FRAME_TYPE_ACK)
{ {
/* check for more data (collision) */ /* check for more data (collision) */
while (mbus_recv_frame(handle, &reply) != -1) if (mbus_purge_frames(handle))
{
ret = -2;
}
if (ret == -2)
{ {
return MBUS_PROBE_COLLISION; return MBUS_PROBE_COLLISION;
} }
@ -1817,7 +1862,7 @@ mbus_probe_secondary_address(mbus_handle * handle, const char *mask, char *match
ret = mbus_recv_frame(handle, &reply); ret = mbus_recv_frame(handle, &reply);
if (ret == -1) if (ret == -3)
{ {
return MBUS_PROBE_NOTHING; return MBUS_PROBE_NOTHING;
} }

63
mbus/mbus-protocol-aux.h Normal file → Executable file
View File

@ -20,9 +20,11 @@
* the data processing. * the data processing.
* Typical use might be (in oversimplified "pseudocode"): * Typical use might be (in oversimplified "pseudocode"):
* \verbatim * \verbatim
* mbus_handle = mbus_connect_serial(device); * mbus_handle = mbus_context_serial(device);
* or * or
* mbus_handle = mbus_connect_tcp(host, port); * mbus_handle = mbus_context_tcp(host, port);
*
* mbus_connect(mbus_handle);
* *
* ... * ...
* *
@ -45,6 +47,7 @@
* ... * ...
* *
* mbus_disconnect(mbus_handle); * mbus_disconnect(mbus_handle);
* mbus_context_free(mbus_handle);
* \endverbatim * \endverbatim
* *
* Note that the quantity values are partially "normalized". For example energy * Note that the quantity values are partially "normalized". For example energy
@ -60,28 +63,28 @@
#ifndef __MBUS_PROTOCOL_AUX_H__ #ifndef __MBUS_PROTOCOL_AUX_H__
#define __MBUS_PROTOCOL_AUX_H__ #define __MBUS_PROTOCOL_AUX_H__
#include <mbus/mbus.h> #include "mbus-protocol.h"
#include <mbus/mbus-protocol.h>
#include <mbus/mbus-serial.h>
#include <mbus/mbus-tcp.h>
#define MBUS_PROBE_NOTHING 0 #define MBUS_PROBE_NOTHING 0
#define MBUS_PROBE_SINGLE 1 #define MBUS_PROBE_SINGLE 1
#define MBUS_PROBE_COLLISION 2 #define MBUS_PROBE_COLLISION 2
#define MBUS_PROBE_ERROR -1 #define MBUS_PROBE_ERROR -1
/** /**
* Unified MBus handle type encapsulating either Serial or TCP gateway. * Unified MBus handle type encapsulating either Serial or TCP gateway.
*/ */
typedef struct _mbus_handle { struct _mbus_handle {
int fd;
char is_serial; /**< _handle type (non zero for serial) */ char is_serial; /**< _handle type (non zero for serial) */
union { int (*open) (struct _mbus_handle *handle);
mbus_tcp_handle * m_tcp_handle; /**< TCP gateway handle */ int (*close) (struct _mbus_handle *handle);
mbus_serial_handle * m_serial_handle; /**< Serial gateway handle */ int (*send) (struct _mbus_handle *handle, mbus_frame *frame);
}; int (*recv) (struct _mbus_handle *handle, mbus_frame *frame);
} mbus_handle; void (*free_auxdata) (struct _mbus_handle *handle);
void *auxdata;
};
typedef struct _mbus_handle mbus_handle;
/** /**
* MBus slave address type (primary/secodary address) * MBus slave address type (primary/secodary address)
@ -141,23 +144,40 @@ void mbus_register_scan_progress(void (*event)(mbus_handle * handle, const char
void mbus_register_found_event(void (*event)(mbus_handle * handle, mbus_frame *frame)); void mbus_register_found_event(void (*event)(mbus_handle * handle, mbus_frame *frame));
/** /**
* Connects to serial gateway and initializes MBus handle * Allocate and initialize M-Bus serial context.
* *
* @param device Serial device (like /dev/ttyUSB0 or /dev/ttyS0) * @param device Serial device (like /dev/ttyUSB0 or /dev/ttyS0)
* *
* @return Initialized "unified" handler when successful, NULL otherwise; * @return Initialized "unified" handler when successful, NULL otherwise;
*/ */
mbus_handle * mbus_connect_serial(const char * device); mbus_handle * mbus_context_serial(const char *device);
/** /**
* Connects to TCP gateway and initializes MBus handle * Allocate and initialize M-Bus TCP context.
* *
* @param host Gateway host * @param host Gateway host
* @param port Gateway port * @param port Gateway port
* *
* @return Initialized "unified" handler when successful, NULL otherwise; * @return Initialized "unified" handler when successful, NULL otherwise;
*/ */
mbus_handle * mbus_connect_tcp(const char *host, int port); mbus_handle * mbus_context_tcp(const char *host, int port);
/**
* Deallocate memory used by M-Bus context.
*
* @param handle Initialized handle
*
*/
void mbus_context_free(mbus_handle * handle);
/**
* Connect to serial bus or TCP gateway depending on context.
*
* @param handle Initialized handle
*
* @return Zero when successful.
*/
int mbus_connect(mbus_handle * handle);
/** /**
* Disconnects the "unified" handle. * Disconnects the "unified" handle.
@ -178,6 +198,15 @@ int mbus_disconnect(mbus_handle * handle);
*/ */
int mbus_recv_frame(mbus_handle * handle, mbus_frame *frame); int mbus_recv_frame(mbus_handle * handle, mbus_frame *frame);
/**
* Used for handling collisions. Blocks as long as receiving frames or corrupted data.
*
* @param handle Initialized handle
*
* @return Zero when nothing received, one otherwise.
*/
int mbus_purge_frames(mbus_handle * handle);
/** /**
* Sends frame using "unified" handle * Sends frame using "unified" handle
* *

2
mbus/mbus-protocol.c Normal file → Executable file
View File

@ -13,7 +13,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <mbus/mbus-protocol.h> #include "mbus-protocol.h"
static int parse_debug = 0, debug = 0; static int parse_debug = 0, debug = 0;
static char error_str[512]; static char error_str[512];

0
mbus/mbus-protocol.h Normal file → Executable file
View File

100
mbus/mbus-serial.c Normal file → Executable file
View File

@ -20,49 +20,48 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <mbus/mbus.h> #include "mbus-serial.h"
#include <mbus/mbus-serial.h> #include "mbus-protocol-aux.h"
#include "mbus-protocol.h"
#define PACKET_BUFF_SIZE 2048 #define PACKET_BUFF_SIZE 2048
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/// Set up a serial connection handle. /// Set up a serial connection handle.
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
mbus_serial_handle * int
mbus_serial_connect(char *device) mbus_serial_connect(mbus_handle *handle)
{ {
mbus_serial_handle *handle; mbus_serial_data *serial_data;
const char *device;
struct termios *term;
if (device == NULL) if (handle == NULL)
{ return -1;
return NULL;
}
if ((handle = (mbus_serial_handle *)malloc(sizeof(mbus_serial_handle))) == NULL) serial_data = (mbus_serial_data *) handle->auxdata;
{ if (serial_data == NULL || serial_data->device == NULL)
fprintf(stderr, "%s: failed to allocate memory for handle\n", __PRETTY_FUNCTION__); return -1;
return NULL;
}
handle->device = device; // strdup?
device = serial_data->device;
term = &(serial_data->t);
// //
// create the SERIAL connection // create the SERIAL connection
// //
// Use blocking read and handle it by serial port VMIN/VTIME setting // Use blocking read and handle it by serial port VMIN/VTIME setting
if ((handle->fd = open(handle->device, O_RDWR | O_NOCTTY)) < 0) if ((handle->fd = open(device, O_RDWR | O_NOCTTY)) < 0)
{ {
fprintf(stderr, "%s: failed to open tty.", __PRETTY_FUNCTION__); fprintf(stderr, "%s: failed to open tty.", __PRETTY_FUNCTION__);
return NULL; return -1;
} }
memset(&(handle->t), 0, sizeof(handle->t)); memset(term, 0, sizeof(*term));
handle->t.c_cflag |= (CS8|CREAD|CLOCAL); term->c_cflag |= (CS8|CREAD|CLOCAL);
handle->t.c_cflag |= PARENB; term->c_cflag |= PARENB;
// No received data still OK // No received data still OK
handle->t.c_cc[VMIN] = 0; term->c_cc[VMIN] = 0;
// Wait at most 0.2 sec.Note that it starts after first received byte!! // Wait at most 0.2 sec.Note that it starts after first received byte!!
// I.e. if CMIN>0 and there are no data we would still wait forever... // I.e. if CMIN>0 and there are no data we would still wait forever...
@ -75,54 +74,56 @@ mbus_serial_connect(char *device)
// For 2400Bd this means (330 + 11) / 2400 + 0.05 = 188.75 ms (added 11 bit periods to receive first byte). // For 2400Bd this means (330 + 11) / 2400 + 0.05 = 188.75 ms (added 11 bit periods to receive first byte).
// I.e. timeout of 0.2s seems appropriate for 2400Bd. // I.e. timeout of 0.2s seems appropriate for 2400Bd.
handle->t.c_cc[VTIME] = 2; // Timeout in 1/10 sec term->c_cc[VTIME] = 2; // Timeout in 1/10 sec
cfsetispeed(&(handle->t), B2400); cfsetispeed(term, B2400);
cfsetospeed(&(handle->t), B2400); cfsetospeed(term, B2400);
#ifdef MBUS_SERIAL_DEBUG #ifdef MBUS_SERIAL_DEBUG
printf("%s: t.c_cflag = %x\n", __PRETTY_FUNCTION__, handle->t.c_cflag); printf("%s: t.c_cflag = %x\n", __PRETTY_FUNCTION__, term->c_cflag);
printf("%s: t.c_oflag = %x\n", __PRETTY_FUNCTION__, handle->t.c_oflag); printf("%s: t.c_oflag = %x\n", __PRETTY_FUNCTION__, term->c_oflag);
printf("%s: t.c_iflag = %x\n", __PRETTY_FUNCTION__, handle->t.c_iflag); printf("%s: t.c_iflag = %x\n", __PRETTY_FUNCTION__, term->c_iflag);
printf("%s: t.c_lflag = %x\n", __PRETTY_FUNCTION__, handle->t.c_lflag); printf("%s: t.c_lflag = %x\n", __PRETTY_FUNCTION__, term->c_lflag);
#endif #endif
tcsetattr(handle->fd, TCSANOW, &(handle->t)); tcsetattr(handle->fd, TCSANOW, term);
return handle; return 0;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Set baud rate for serial connection // Set baud rate for serial connection
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int int
mbus_serial_set_baudrate(mbus_serial_handle *handle, int baudrate) mbus_serial_set_baudrate(mbus_handle *handle, int baudrate)
{ {
speed_t speed; speed_t speed;
if (handle == NULL) if (handle == NULL)
return -1; return -1;
mbus_serial_data *serial_data = (mbus_serial_data *) handle->auxdata;
switch (baudrate) switch (baudrate)
{ {
case 300: case 300:
speed = B300; speed = B300;
handle->t.c_cc[VTIME] = 12; // Timeout in 1/10 sec serial_data->t.c_cc[VTIME] = 12; // Timeout in 1/10 sec
break; break;
case 1200: case 1200:
speed = B1200; speed = B1200;
handle->t.c_cc[VTIME] = 4; // Timeout in 1/10 sec serial_data->t.c_cc[VTIME] = 4; // Timeout in 1/10 sec
break; break;
case 2400: case 2400:
speed = B2400; speed = B2400;
handle->t.c_cc[VTIME] = 2; // Timeout in 1/10 sec serial_data->t.c_cc[VTIME] = 2; // Timeout in 1/10 sec
break; break;
case 9600: case 9600:
speed = B9600; speed = B9600;
handle->t.c_cc[VTIME] = 1; // Timeout in 1/10 sec serial_data->t.c_cc[VTIME] = 1; // Timeout in 1/10 sec
break; break;
default: default:
@ -130,19 +131,19 @@ mbus_serial_set_baudrate(mbus_serial_handle *handle, int baudrate)
} }
// Set input baud rate // Set input baud rate
if (cfsetispeed(&(handle->t), speed) != 0) if (cfsetispeed(&(serial_data->t), speed) != 0)
{ {
return -1; return -1;
} }
// Set output baud rate // Set output baud rate
if (cfsetospeed(&(handle->t), speed) != 0) if (cfsetospeed(&(serial_data->t), speed) != 0)
{ {
return -1; return -1;
} }
// Change baud rate immediately // Change baud rate immediately
if (tcsetattr(handle->fd, TCSANOW, &(handle->t)) != 0) if (tcsetattr(handle->fd, TCSANOW, &(serial_data->t)) != 0)
{ {
return -1; return -1;
} }
@ -155,7 +156,7 @@ mbus_serial_set_baudrate(mbus_serial_handle *handle, int baudrate)
// //
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int int
mbus_serial_disconnect(mbus_serial_handle *handle) mbus_serial_disconnect(mbus_handle *handle)
{ {
if (handle == NULL) if (handle == NULL)
{ {
@ -164,16 +165,27 @@ mbus_serial_disconnect(mbus_serial_handle *handle)
close(handle->fd); close(handle->fd);
free(handle);
return 0; return 0;
} }
void
mbus_serial_data_free(mbus_handle *handle)
{
mbus_serial_data *serial_data;
if (handle)
{
serial_data = (mbus_serial_data *) handle->auxdata;
free(serial_data->device);
free(serial_data);
}
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// //
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int int
mbus_serial_send_frame(mbus_serial_handle *handle, mbus_frame *frame) mbus_serial_send_frame(mbus_handle *handle, mbus_frame *frame)
{ {
u_char buff[PACKET_BUFF_SIZE]; u_char buff[PACKET_BUFF_SIZE];
int len, ret; int len, ret;
@ -225,7 +237,7 @@ mbus_serial_send_frame(mbus_serial_handle *handle, mbus_frame *frame)
// //
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int int
mbus_serial_recv_frame(mbus_serial_handle *handle, mbus_frame *frame) mbus_serial_recv_frame(mbus_handle *handle, mbus_frame *frame)
{ {
char buff[PACKET_BUFF_SIZE]; char buff[PACKET_BUFF_SIZE];
int len, remaining, nread, timeouts; int len, remaining, nread, timeouts;

24
mbus/mbus-serial.h Normal file → Executable file
View File

@ -19,23 +19,21 @@
#define MBUS_SERIAL_H #define MBUS_SERIAL_H
#include <termios.h> #include <termios.h>
#include <mbus/mbus.h> #include "mbus-protocol-aux.h"
#include "mbus-protocol.h"
typedef struct _mbus_serial_handle {
typedef struct _mbus_serial_data
{
char *device; char *device;
int fd;
struct termios t; struct termios t;
} mbus_serial_data;
} mbus_serial_handle; int mbus_serial_connect(mbus_handle *handle);
int mbus_serial_disconnect(mbus_handle *handle);
int mbus_serial_send_frame(mbus_handle *handle, mbus_frame *frame);
mbus_serial_handle *mbus_serial_connect(char *device); int mbus_serial_recv_frame(mbus_handle *handle, mbus_frame *frame);
int mbus_serial_disconnect(mbus_serial_handle *handle); int mbus_serial_set_baudrate(mbus_handle *handle, int baudrate);
int mbus_serial_send_frame(mbus_serial_handle *handle, mbus_frame *frame); void mbus_serial_data_free(mbus_handle *handle);
int mbus_serial_recv_frame(mbus_serial_handle *handle, mbus_frame *frame);
int mbus_serial_set_baudrate(mbus_serial_handle *handle, int baudrate);
#endif /* MBUS_SERIAL_H */ #endif /* MBUS_SERIAL_H */

131
mbus/mbus-tcp.c Normal file → Executable file
View File

@ -21,49 +21,43 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <strings.h> #include <strings.h>
#include <errno.h>
#include <mbus/mbus.h> #include "mbus-tcp.h"
#include <mbus/mbus-tcp.h>
#define PACKET_BUFF_SIZE 2048 #define PACKET_BUFF_SIZE 2048
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
/// Setup a TCP/IP handle. /// Setup a TCP/IP handle.
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
mbus_tcp_handle * int
mbus_tcp_connect(char *host, int port) mbus_tcp_connect(mbus_handle *handle)
{ {
mbus_tcp_handle *handle; char error_str[128], *host;
struct hostent *host_addr; struct hostent *host_addr;
struct sockaddr_in s; struct sockaddr_in s;
struct timeval time_out; struct timeval time_out;
mbus_tcp_data *tcp_data;
int port;
if (host == NULL) if (handle == NULL)
{ return -1;
return NULL;
}
if ((handle = (mbus_tcp_handle *)malloc(sizeof(mbus_tcp_handle))) == NULL) tcp_data = (mbus_tcp_data *) handle->auxdata;
{ if (tcp_data == NULL || tcp_data->host == NULL)
char error_str[128]; return -1;
snprintf(error_str, sizeof(error_str), "%s: failed to allocate memory for handle\n", __PRETTY_FUNCTION__);
mbus_error_str_set(error_str);
return NULL;
}
handle->host = host; // strdup ? host = tcp_data->host;
handle->port = port; port = tcp_data->port;
// //
// create the TCP connection // create the TCP connection
// //
if ((handle->sock = socket(AF_INET,SOCK_STREAM, 0)) < 0) if ((handle->fd = socket(AF_INET,SOCK_STREAM, 0)) < 0)
{ {
char error_str[128];
snprintf(error_str, sizeof(error_str), "%s: failed to setup a socket.", __PRETTY_FUNCTION__); snprintf(error_str, sizeof(error_str), "%s: failed to setup a socket.", __PRETTY_FUNCTION__);
mbus_error_str_set(error_str); mbus_error_str_set(error_str);
return NULL; return -1;
} }
s.sin_family = AF_INET; s.sin_family = AF_INET;
@ -72,47 +66,54 @@ mbus_tcp_connect(char *host, int port)
/* resolve hostname */ /* resolve hostname */
if ((host_addr = gethostbyname(host)) == NULL) if ((host_addr = gethostbyname(host)) == NULL)
{ {
char error_str[128];
snprintf(error_str, sizeof(error_str), "%s: unknown host: %s", __PRETTY_FUNCTION__, host); snprintf(error_str, sizeof(error_str), "%s: unknown host: %s", __PRETTY_FUNCTION__, host);
mbus_error_str_set(error_str); mbus_error_str_set(error_str);
free(handle); return -1;
return NULL;
} }
memcpy((void *)(&s.sin_addr), (void *)(host_addr->h_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->fd, (struct sockaddr *)&s, sizeof(s)) < 0)
{ {
char error_str[128];
snprintf(error_str, sizeof(error_str), "%s: Failed to establish connection to %s:%d", __PRETTY_FUNCTION__, host, port); snprintf(error_str, sizeof(error_str), "%s: Failed to establish connection to %s:%d", __PRETTY_FUNCTION__, host, port);
mbus_error_str_set(error_str); mbus_error_str_set(error_str);
free(handle); return -1;
return NULL;
} }
// Set a timeout // Set a timeout
time_out.tv_sec = 4; //seconds time_out.tv_sec = 4; //seconds
time_out.tv_usec = 0; time_out.tv_usec = 0;
setsockopt(handle->sock, SOL_SOCKET, SO_SNDTIMEO, &time_out, sizeof(time_out)); setsockopt(handle->fd, SOL_SOCKET, SO_SNDTIMEO, &time_out, sizeof(time_out));
setsockopt(handle->sock, SOL_SOCKET, SO_RCVTIMEO, &time_out, sizeof(time_out)); setsockopt(handle->fd, SOL_SOCKET, SO_RCVTIMEO, &time_out, sizeof(time_out));
return handle; return 0;
}
void
mbus_tcp_data_free(mbus_handle *handle)
{
mbus_tcp_data *tcp_data;
if (handle)
{
tcp_data = (mbus_tcp_data *) handle->auxdata;
free(tcp_data->host);
free(tcp_data);
}
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// //
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int int
mbus_tcp_disconnect(mbus_tcp_handle *handle) mbus_tcp_disconnect(mbus_handle *handle)
{ {
if (handle == NULL) if (handle == NULL)
{ {
return -1; return -1;
} }
close(handle->sock); close(handle->fd);
free(handle);
return 0; return 0;
} }
@ -121,7 +122,7 @@ mbus_tcp_disconnect(mbus_tcp_handle *handle)
// //
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int int
mbus_tcp_send_frame(mbus_tcp_handle *handle, mbus_frame *frame) mbus_tcp_send_frame(mbus_handle *handle, mbus_frame *frame)
{ {
u_char buff[PACKET_BUFF_SIZE]; u_char buff[PACKET_BUFF_SIZE];
int len, ret; int len, ret;
@ -139,7 +140,7 @@ mbus_tcp_send_frame(mbus_tcp_handle *handle, mbus_frame *frame)
return -1; return -1;
} }
if ((ret = write(handle->sock, buff, len)) == len) if ((ret = write(handle->fd, buff, len)) == len)
{ {
// //
// call the send event function, if the callback function is registered // call the send event function, if the callback function is registered
@ -161,56 +162,46 @@ mbus_tcp_send_frame(mbus_tcp_handle *handle, mbus_frame *frame)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// //
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
int int mbus_tcp_recv_frame(mbus_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, timeouts; int len, remaining, nread;
if (handle == NULL || frame == NULL) if (handle == NULL || frame == NULL) {
{
fprintf(stderr, "%s: Invalid parameter.\n", __PRETTY_FUNCTION__); fprintf(stderr, "%s: Invalid parameter.\n", __PRETTY_FUNCTION__);
return -1; return -1;
} }
memset((void *)buff, 0, sizeof(buff)); memset((void *) buff, 0, sizeof(buff));
// //
// read data until a packet is received // read data until a packet is received
// //
remaining = 1; // start by reading 1 byte remaining = 1; // start by reading 1 byte
len = 0; len = 0;
timeouts = 0;
do { do {
retry:
nread = read(handle->fd, &buff[len], remaining);
switch (nread) {
case -1:
if (errno == EINTR)
goto retry;
if (errno == EAGAIN || errno == EWOULDBLOCK) {
mbus_error_str_set("M-Bus tcp transport layer response timeout has been reached.");
return -3;
}
if ((nread = read(handle->sock, &buff[len], remaining)) == -1)
{
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;
} case 0:
mbus_error_str_set("M-Bus tcp transport layer connection closed by remote host.");
if (nread == 0) return -4;
{ default:
timeouts++;
if (timeouts >= 3)
{
// abort to avoid endless loop
fprintf(stderr, "%s: Timeout\n", __PRETTY_FUNCTION__);
break;
}
}
len += nread; len += nread;
} while ((remaining = mbus_parse(frame, buff, len)) > 0);
if (len == 0)
{
// No data received
return -1;
} }
} while ((remaining = mbus_parse(frame, buff, len)) > 0);
// //
// call the receive event function, if the callback function is registered // call the receive event function, if the callback function is registered
@ -218,8 +209,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;
} }
@ -227,3 +217,4 @@ mbus_tcp_recv_frame(mbus_tcp_handle *handle, mbus_frame *frame)
return 0; return 0;
} }

22
mbus/mbus-tcp.h Normal file → Executable file
View File

@ -18,22 +18,20 @@
#ifndef MBUS_TCP_H #ifndef MBUS_TCP_H
#define MBUS_TCP_H #define MBUS_TCP_H
#include <mbus/mbus.h> #include "mbus-protocol.h"
#include "mbus-protocol-aux.h"
typedef struct _mbus_tcp_handle {
typedef struct _mbus_tcp_data
{
char *host; char *host;
int port; int port;
int sock; } mbus_tcp_data;
} mbus_tcp_handle; int mbus_tcp_connect(mbus_handle *handle);
int mbus_tcp_disconnect(mbus_handle *handle);
int mbus_tcp_send_frame(mbus_handle *handle, mbus_frame *frame);
mbus_tcp_handle *mbus_tcp_connect(char *host, int port); int mbus_tcp_recv_frame(mbus_handle *handle, mbus_frame *frame);
int mbus_tcp_disconnect(mbus_tcp_handle *handle); void mbus_tcp_data_free(mbus_handle *handle);
int mbus_tcp_send_frame(mbus_tcp_handle *handle, mbus_frame *frame);
int mbus_tcp_recv_frame(mbus_tcp_handle *handle, mbus_frame *frame);
#endif /* MBUS_TCP_H */ #endif /* MBUS_TCP_H */