diff --git a/bin/mbus-serial-request-data-multi-reply.c b/bin/mbus-serial-request-data-multi-reply.c index bb9e793..e044c09 100755 --- a/bin/mbus-serial-request-data-multi-reply.c +++ b/bin/mbus-serial-request-data-multi-reply.c @@ -103,18 +103,17 @@ main(int argc, char **argv) device = argv[c]; addr_str = argv[c+1]; - - if (debug) - { - mbus_register_send_event(&mbus_dump_send_event); - mbus_register_recv_event(&mbus_dump_recv_event); - } - if ((handle = mbus_context_serial(device)) == NULL) { fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str()); return 1; } + + if (debug) + { + mbus_register_send_event(handle, &mbus_dump_send_event); + mbus_register_recv_event(handle, &mbus_dump_recv_event); + } if (mbus_connect(handle) == -1) { diff --git a/bin/mbus-serial-request-data.c b/bin/mbus-serial-request-data.c index 9b94c83..1152a04 100755 --- a/bin/mbus-serial-request-data.c +++ b/bin/mbus-serial-request-data.c @@ -64,17 +64,17 @@ main(int argc, char **argv) return 0; } - if (debug) - { - mbus_register_send_event(&mbus_dump_send_event); - mbus_register_recv_event(&mbus_dump_recv_event); - } - if ((handle = mbus_context_serial(device)) == NULL) { fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str()); return 1; } + + if (debug) + { + mbus_register_send_event(handle, &mbus_dump_send_event); + mbus_register_recv_event(handle, &mbus_dump_recv_event); + } if (mbus_connect(handle) == -1) { diff --git a/bin/mbus-serial-scan-secondary.c b/bin/mbus-serial-scan-secondary.c index 28e1dbe..894ccf2 100755 --- a/bin/mbus-serial-scan-secondary.c +++ b/bin/mbus-serial-scan-secondary.c @@ -116,12 +116,6 @@ main(int argc, char **argv) return 0; } - if (debug) - { - mbus_register_send_event(&mbus_dump_send_event); - mbus_register_recv_event(&mbus_dump_recv_event); - } - if (addr_mask == NULL) { fprintf(stderr, "Failed to allocate address mask.\n"); @@ -141,6 +135,12 @@ main(int argc, char **argv) free(addr_mask); return 1; } + + if (debug) + { + mbus_register_send_event(handle, &mbus_dump_send_event); + mbus_register_recv_event(handle, &mbus_dump_recv_event); + } if (mbus_connect(handle) == -1) { diff --git a/bin/mbus-serial-scan.c b/bin/mbus-serial-scan.c index 8a16538..8a935c9 100755 --- a/bin/mbus-serial-scan.c +++ b/bin/mbus-serial-scan.c @@ -108,17 +108,17 @@ main(int argc, char **argv) return 0; } - if (debug) - { - mbus_register_send_event(&mbus_dump_send_event); - mbus_register_recv_event(&mbus_dump_recv_event); - } - if ((handle = mbus_context_serial(device)) == NULL) { fprintf(stderr,"Scan failed: Could not initialize M-Bus context: %s\n", mbus_error_str()); return 1; } + + if (debug) + { + mbus_register_send_event(handle, &mbus_dump_send_event); + mbus_register_recv_event(handle, &mbus_dump_recv_event); + } if (mbus_connect(handle) == -1) { diff --git a/bin/mbus-tcp-application-reset.c b/bin/mbus-tcp-application-reset.c index 106efab..54ca46c 100755 --- a/bin/mbus-tcp-application-reset.c +++ b/bin/mbus-tcp-application-reset.c @@ -68,17 +68,17 @@ main(int argc, char **argv) return 1; } - if (debug) - { - mbus_register_send_event(&mbus_dump_send_event); - mbus_register_recv_event(&mbus_dump_recv_event); - } - if ((handle = mbus_context_tcp(host, port)) == NULL) { fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str()); return 1; } + + if (debug) + { + mbus_register_send_event(handle, &mbus_dump_send_event); + mbus_register_recv_event(handle, &mbus_dump_recv_event); + } if (mbus_connect(handle) == -1) { diff --git a/bin/mbus-tcp-raw-send.c b/bin/mbus-tcp-raw-send.c index fc9ad65..a324378 100644 --- a/bin/mbus-tcp-raw-send.c +++ b/bin/mbus-tcp-raw-send.c @@ -79,17 +79,17 @@ main(int argc, char **argv) return 1; } - if (debug) - { - mbus_register_send_event(&mbus_dump_send_event); - mbus_register_recv_event(&mbus_dump_recv_event); - } - if ((handle = mbus_context_tcp(host, port)) == NULL) { fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str()); return 1; } + + if (debug) + { + mbus_register_send_event(handle, &mbus_dump_send_event); + mbus_register_recv_event(handle, &mbus_dump_recv_event); + } if (mbus_connect(handle) == -1) { diff --git a/bin/mbus-tcp-request-data-multi-reply.c b/bin/mbus-tcp-request-data-multi-reply.c index fa38a35..8cc1d2e 100755 --- a/bin/mbus-tcp-request-data-multi-reply.c +++ b/bin/mbus-tcp-request-data-multi-reply.c @@ -105,17 +105,17 @@ main(int argc, char **argv) return 1; } - if (debug) - { - mbus_register_send_event(&mbus_dump_send_event); - mbus_register_recv_event(&mbus_dump_recv_event); - } - if ((handle = mbus_context_tcp(host, port)) == NULL) { fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str()); return 1; } + + if (debug) + { + mbus_register_send_event(handle, &mbus_dump_send_event); + mbus_register_recv_event(handle, &mbus_dump_recv_event); + } if (mbus_connect(handle) == -1) { diff --git a/bin/mbus-tcp-request-data.c b/bin/mbus-tcp-request-data.c index c0093f8..91ff0c0 100755 --- a/bin/mbus-tcp-request-data.c +++ b/bin/mbus-tcp-request-data.c @@ -59,17 +59,17 @@ main(int argc, char **argv) return 1; } - if (debug) - { - mbus_register_send_event(&mbus_dump_send_event); - mbus_register_recv_event(&mbus_dump_recv_event); - } - if ((handle = mbus_context_tcp(host, port)) == NULL) { fprintf(stderr, "Could not initialize M-Bus context: %s\n", mbus_error_str()); return 1; } + + if (debug) + { + mbus_register_send_event(handle, &mbus_dump_send_event); + mbus_register_recv_event(handle, &mbus_dump_recv_event); + } if (mbus_connect(handle) == -1) { diff --git a/bin/mbus-tcp-scan.c b/bin/mbus-tcp-scan.c index a7ea01e..70ed102 100755 --- a/bin/mbus-tcp-scan.c +++ b/bin/mbus-tcp-scan.c @@ -94,17 +94,17 @@ main(int argc, char **argv) return 1; } - if (debug) - { - mbus_register_send_event(&mbus_dump_send_event); - mbus_register_recv_event(&mbus_dump_recv_event); - } - if ((handle = mbus_context_tcp(host, port)) == NULL) { fprintf(stderr,"Scan failed: Could not initialize M-Bus context: %s\n", mbus_error_str()); return 1; } + + if (debug) + { + mbus_register_send_event(handle, &mbus_dump_send_event); + mbus_register_recv_event(handle, &mbus_dump_recv_event); + } if (mbus_connect(handle) == -1) { diff --git a/mbus/mbus-protocol-aux.c b/mbus/mbus-protocol-aux.c index 6f96d87..be7312d 100755 --- a/mbus/mbus-protocol-aux.c +++ b/mbus/mbus-protocol-aux.c @@ -707,25 +707,40 @@ 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 receive events. +//------------------------------------------------------------------------------ +void +mbus_register_recv_event(mbus_handle * handle, void (*event)(unsigned char src_type, const char *buff, size_t len)) +{ + handle->recv_event = event; +} + +//------------------------------------------------------------------------------ +/// Register a function for send events. +//------------------------------------------------------------------------------ +void +mbus_register_send_event(mbus_handle * handle, void (*event)(unsigned char src_type, const char *buff, size_t len)) +{ + handle->send_event = event; +} //------------------------------------------------------------------------------ /// Register a function for the scan progress. //------------------------------------------------------------------------------ void -mbus_register_scan_progress(void (*event)(mbus_handle * handle, const char *mask)) +mbus_register_scan_progress(mbus_handle * handle, void (*event)(mbus_handle * handle, const char *mask)) { - _mbus_scan_progress = event; + handle->scan_progress = event; } //------------------------------------------------------------------------------ /// Register a function for the found events. //------------------------------------------------------------------------------ void -mbus_register_found_event(void (*event)(mbus_handle * handle, mbus_frame *frame)) +mbus_register_found_event(mbus_handle * handle, void (*event)(mbus_handle * handle, mbus_frame *frame)) { - _mbus_found_event = event; + handle->found_event = event; } int mbus_fixed_normalize(int medium_unit, long medium_value, char **unit_out, double *value_out, char **quantity_out) @@ -1424,6 +1439,10 @@ mbus_context_serial(const char *device) handle->recv = mbus_serial_recv_frame; handle->send = mbus_serial_send_frame; handle->free_auxdata = mbus_serial_data_free; + handle->recv_event = NULL; + handle->send_event = NULL; + handle->scan_progress = NULL; + handle->found_event = NULL; if ((serial_data->device = strdup(device)) == NULL) { @@ -1467,6 +1486,10 @@ mbus_context_tcp(const char *host, uint16_t port) handle->recv = mbus_tcp_recv_frame; handle->send = mbus_tcp_send_frame; handle->free_auxdata = mbus_tcp_data_free; + handle->recv_event = NULL; + handle->send_event = NULL; + handle->scan_progress = NULL; + handle->found_event = NULL; tcp_data->port = port; if ((tcp_data->host = strdup(host)) == NULL) @@ -1811,6 +1834,57 @@ mbus_send_request_frame(mbus_handle * handle, int address) return retval; } +//------------------------------------------------------------------------------ +// send a user data packet from master to slave +//------------------------------------------------------------------------------ +int +mbus_send_user_data_frame(mbus_handle * handle, int address, const unsigned char *data, size_t data_size) +{ + int retval = 0; + mbus_frame *frame; + + if (mbus_is_primary_address(address) == 0) + { + MBUS_ERROR("%s: invalid address %d\n", __PRETTY_FUNCTION__, address); + return -1; + } + + if (data == NULL) + { + MBUS_ERROR("%s: Invalid data\n", __PRETTY_FUNCTION__); + return -1; + } + + if ((data_size > MBUS_FRAME_DATA_LENGTH) || (data_size == 0)) + { + MBUS_ERROR("%s: illegal data_size %d\n", __PRETTY_FUNCTION__, data_size); + return -1; + } + + frame = mbus_frame_new(MBUS_FRAME_TYPE_LONG); + + if (frame == NULL) + { + MBUS_ERROR("%s: failed to allocate mbus frame.\n", __PRETTY_FUNCTION__); + return -1; + } + + frame->control = MBUS_CONTROL_MASK_SND_UD | MBUS_CONTROL_MASK_DIR_M2S; + frame->address = address; + frame->control_information = MBUS_CONTROL_INFO_DATA_SEND; + frame->data_size = data_size; + memcpy(frame->data, data, data_size); + + if (mbus_send_frame(handle, frame) == -1) + { + MBUS_ERROR("%s: failed to send mbus frame.\n", __PRETTY_FUNCTION__); + retval = -1; + } + + mbus_frame_free(frame); + return retval; +} + //------------------------------------------------------------------------------ // send a request from master to slave and collect the reply (replies) // from the slave. @@ -2138,9 +2212,9 @@ mbus_probe_secondary_address(mbus_handle *handle, const char *mask, char *matchi snprintf(matching_addr, 17, "%s", addr); - if (_mbus_found_event) + if (handle->found_event) { - _mbus_found_event(handle,&reply); + handle->found_event(handle,&reply); } return MBUS_PROBE_SINGLE; @@ -2284,14 +2358,14 @@ mbus_scan_2nd_address_range(mbus_handle * handle, int pos, char *addr_mask) { mask[pos] = '0'+i; - if (_mbus_scan_progress) - _mbus_scan_progress(handle,mask); + if (handle->scan_progress) + handle->scan_progress(handle,mask); probe_ret = mbus_probe_secondary_address(handle, mask, matching_mask); if (probe_ret == MBUS_PROBE_SINGLE) { - if (!_mbus_found_event) + if (!handle->found_event) { printf("Found a device on secondary address %s [using address mask %s]\n", matching_mask, mask); } diff --git a/mbus/mbus-protocol-aux.h b/mbus/mbus-protocol-aux.h index c2a255a..2cb61ec 100755 --- a/mbus/mbus-protocol-aux.h +++ b/mbus/mbus-protocol-aux.h @@ -93,6 +93,10 @@ typedef struct _mbus_handle { int (*send) (struct _mbus_handle *handle, mbus_frame *frame); int (*recv) (struct _mbus_handle *handle, mbus_frame *frame); void (*free_auxdata) (struct _mbus_handle *handle); + void (*recv_event) (unsigned char src_type, const char *buff, size_t len); + void (*send_event) (unsigned char src_type, const char *buff, size_t len); + void (*scan_progress) (struct _mbus_handle *handle, const char *mask); + void (*found_event) (struct _mbus_handle *handle, mbus_frame *frame); void *auxdata; } mbus_handle; @@ -148,17 +152,16 @@ typedef enum _mbus_context_option { MBUS_OPTION_PURGE_FIRST_FRAME /**< option controls the echo cancelation for mbus_recv_frame */ } mbus_context_option; -/** - * 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)); +// +// Event register functions +// +void mbus_register_recv_event(mbus_handle *handle, void (*event)(unsigned char src_type, const char *buff, size_t len)); +void mbus_register_send_event(mbus_handle *handle, void (*event)(unsigned char src_type, const char *buff, size_t len)); +void mbus_register_scan_progress(mbus_handle *handle, void (*event)(mbus_handle *handle, const char *mask)); +void mbus_register_found_event(mbus_handle *handle, void (*event)(mbus_handle *handle, mbus_frame *frame)); /** * Allocate and initialize M-Bus serial context. @@ -287,6 +290,18 @@ int mbus_send_switch_baudrate_frame(mbus_handle * handle, int address, long baud */ int mbus_send_request_frame(mbus_handle * handle, int address); +/** + * Sends user data frame (SND_UD) to given slave using "unified" handle + * + * @param handle Initialized handle + * @param address Address (0-255) + * @param data User data + * @param data_size Byte count of user data + * + * @return Zero when successful. + */ +int mbus_send_user_data_frame(mbus_handle * handle, int address, const unsigned char *data, size_t data_size); + /** * Sends a request and read replies until no more records available * or limit is reached. diff --git a/mbus/mbus-protocol.c b/mbus/mbus-protocol.c index ab85a0f..8ec3130 100755 --- a/mbus/mbus-protocol.c +++ b/mbus/mbus-protocol.c @@ -26,12 +26,6 @@ static char error_str[512]; //------------------------------------------------------------------------------ static mbus_slave_data slave_data[MBUS_MAX_PRIMARY_SLAVES]; -// -// init event callback -// -void (*_mbus_recv_event)(unsigned char src_type, const char *buff, size_t len) = NULL; -void (*_mbus_send_event)(unsigned char src_type, const char *buff, size_t len) = NULL; - // // trace callbacks // @@ -47,24 +41,6 @@ mbus_dump_send_event(unsigned char src_type, const char *buff, size_t len) mbus_hex_dump("SEND", buff, len); } -//------------------------------------------------------------------------------ -/// Register a function for receive events. -//------------------------------------------------------------------------------ -void -mbus_register_recv_event(void (*event)(unsigned char src_type, const char *buff, size_t len)) -{ - _mbus_recv_event = event; -} - -//------------------------------------------------------------------------------ -/// Register a function for send events. -//------------------------------------------------------------------------------ -void -mbus_register_send_event(void (*event)(unsigned char src_type, const char *buff, size_t len)) -{ - _mbus_send_event = event; -} - //------------------------------------------------------------------------------ /// Return a string that contains an the latest error message. //------------------------------------------------------------------------------ diff --git a/mbus/mbus-protocol.h b/mbus/mbus-protocol.h index cbc5c7b..8c8edde 100755 --- a/mbus/mbus-protocol.h +++ b/mbus/mbus-protocol.h @@ -70,6 +70,8 @@ extern "C" { // // +#define MBUS_FRAME_DATA_LENGTH 252 + typedef struct _mbus_frame { unsigned char start1; @@ -83,7 +85,7 @@ typedef struct _mbus_frame { unsigned char checksum; unsigned char stop; - unsigned char data[252]; + unsigned char data[MBUS_FRAME_DATA_LENGTH]; size_t data_size; int type; @@ -511,18 +513,9 @@ typedef struct _mbus_data_secondary_address { // // Event callback functions // -extern void (*_mbus_recv_event)(unsigned char src_type, const char *buff, size_t len); -extern void (*_mbus_send_event)(unsigned char src_type, const char *buff, size_t len); - void mbus_dump_recv_event(unsigned char src_type, const char *buff, size_t len); void mbus_dump_send_event(unsigned char src_type, const char *buff, size_t len); -// -// Event register functions -// -void mbus_register_recv_event(void (*event)(unsigned char src_type, const char *buff, size_t len)); -void mbus_register_send_event(void (*event)(unsigned char src_type, const char *buff, size_t len)); - // // variable length records // diff --git a/mbus/mbus-serial.c b/mbus/mbus-serial.c index d120f8b..8949d02 100755 --- a/mbus/mbus-serial.c +++ b/mbus/mbus-serial.c @@ -255,8 +255,8 @@ mbus_serial_send_frame(mbus_handle *handle, mbus_frame *frame) // // call the send event function, if the callback function is registered // - if (_mbus_send_event) - _mbus_send_event(MBUS_HANDLE_TYPE_SERIAL, buff, len); + if (handle->send_event) + handle->send_event(MBUS_HANDLE_TYPE_SERIAL, buff, len); } else { @@ -353,8 +353,8 @@ mbus_serial_recv_frame(mbus_handle *handle, mbus_frame *frame) // // call the receive event function, if the callback function is registered // - if (_mbus_recv_event) - _mbus_recv_event(MBUS_HANDLE_TYPE_SERIAL, buff, len); + if (handle->recv_event) + handle->recv_event(MBUS_HANDLE_TYPE_SERIAL, buff, len); if (remaining != 0) { diff --git a/mbus/mbus-tcp.c b/mbus/mbus-tcp.c index ebf0c65..81043db 100755 --- a/mbus/mbus-tcp.c +++ b/mbus/mbus-tcp.c @@ -159,8 +159,8 @@ mbus_tcp_send_frame(mbus_handle *handle, mbus_frame *frame) // // call the send event function, if the callback function is registered // - if (_mbus_send_event) - _mbus_send_event(MBUS_HANDLE_TYPE_TCP, buff, len); + if (handle->send_event) + handle->send_event(MBUS_HANDLE_TYPE_TCP, buff, len); } else { @@ -232,8 +232,8 @@ retry: // // call the receive event function, if the callback function is registered // - if (_mbus_recv_event) - _mbus_recv_event(MBUS_HANDLE_TYPE_TCP, buff, len); + if (handle->recv_event) + handle->recv_event(MBUS_HANDLE_TYPE_TCP, buff, len); if (remaining < 0) { mbus_error_str_set("M-Bus layer failed to parse data.");