Merge pull request #10 from lategoodbye/master
A lot of bugfixes especially for serial connections
This commit is contained in:
		| @@ -35,7 +35,7 @@ POST_UNINSTALL = : | |||||||
| build_triplet = @build@ | build_triplet = @build@ | ||||||
| host_triplet = @host@ | host_triplet = @host@ | ||||||
| subdir = . | subdir = . | ||||||
| DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \ | DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ | ||||||
| 	$(srcdir)/Makefile.in $(srcdir)/config.h.in \ | 	$(srcdir)/Makefile.in $(srcdir)/config.h.in \ | ||||||
| 	$(srcdir)/libmbus.pc.in $(top_srcdir)/configure COPYING \ | 	$(srcdir)/libmbus.pc.in $(top_srcdir)/configure COPYING \ | ||||||
| 	INSTALL config.guess config.sub depcomp install-sh ltmain.sh \ | 	INSTALL config.guess config.sub depcomp install-sh ltmain.sh \ | ||||||
|   | |||||||
| @@ -25,11 +25,11 @@ static int debug = 0; | |||||||
| int | int | ||||||
| main(int argc, char **argv) | main(int argc, char **argv) | ||||||
| { | { | ||||||
|     mbus_frame reply; |     mbus_frame *frame, reply; | ||||||
|     mbus_frame_data reply_data; |     mbus_frame_data reply_data; | ||||||
|     mbus_handle *handle = NULL; |     mbus_handle *handle = NULL; | ||||||
|  |  | ||||||
|     char *device, *addr_str, matching_addr[16], *xml_result; |     char *device, *addr_str, *xml_result; | ||||||
|     int address, baudrate = 9600; |     int address, baudrate = 9600; | ||||||
|   |   | ||||||
|     memset((void *)&reply, 0, sizeof(mbus_frame)); |     memset((void *)&reply, 0, sizeof(mbus_frame)); | ||||||
| @@ -85,28 +85,54 @@ main(int argc, char **argv) | |||||||
|         return 1; |         return 1; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |     // | ||||||
|  |     // init slave to get really the beginning of the records | ||||||
|  |     // | ||||||
|  |      | ||||||
|  |     frame = mbus_frame_new(MBUS_FRAME_TYPE_SHORT); | ||||||
|  |      | ||||||
|  |     if (frame == NULL) | ||||||
|  |     { | ||||||
|  |         fprintf(stderr, "Failed to allocate mbus frame.\n"); | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     frame->control = MBUS_CONTROL_MASK_SND_NKE | MBUS_CONTROL_MASK_DIR_M2S; | ||||||
|  |     frame->address = MBUS_ADDRESS_BROADCAST_NOREPLY; | ||||||
|  |      | ||||||
|  |     if (debug) | ||||||
|  |         printf("%s: debug: sending init frame\n", __PRETTY_FUNCTION__); | ||||||
|  |      | ||||||
|  |     if (mbus_send_frame(handle, frame) == -1) | ||||||
|  |     { | ||||||
|  |         fprintf(stderr, "Failed to send mbus frame.\n"); | ||||||
|  |         mbus_frame_free(frame); | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     mbus_recv_frame(handle, &reply); | ||||||
|      |      | ||||||
|     if (strlen(addr_str) == 16) |     if (strlen(addr_str) == 16) | ||||||
|     { |     { | ||||||
|         // secondary addressing |         // secondary addressing | ||||||
|  |  | ||||||
|         int probe_ret; |         int ret; | ||||||
|  |  | ||||||
|         probe_ret = mbus_probe_secondary_address(handle, addr_str, matching_addr); |         ret = mbus_select_secondary_address(handle, addr_str); | ||||||
|  |  | ||||||
|         if (probe_ret == MBUS_PROBE_COLLISION) |         if (ret == MBUS_PROBE_COLLISION) | ||||||
|         { |         { | ||||||
|             fprintf(stderr, "%s: Error: The address mask [%s] matches more than one device.\n", __PRETTY_FUNCTION__, addr_str); |             fprintf(stderr, "%s: Error: The address mask [%s] matches more than one device.\n", __PRETTY_FUNCTION__, addr_str); | ||||||
|             return 1; |             return 1; | ||||||
|         } |         } | ||||||
|         else if (probe_ret == MBUS_PROBE_NOTHING) |         else if (ret == MBUS_PROBE_NOTHING) | ||||||
|         { |         { | ||||||
|             fprintf(stderr, "%s: Error: The selected secondary address does not match any device [%s].\n", __PRETTY_FUNCTION__, addr_str); |             fprintf(stderr, "%s: Error: The selected secondary address does not match any device [%s].\n", __PRETTY_FUNCTION__, addr_str); | ||||||
|             return 1; |             return 1; | ||||||
|         } |         } | ||||||
|         else if (probe_ret == MBUS_PROBE_ERROR) |         else if (ret == MBUS_PROBE_ERROR) | ||||||
|         { |         { | ||||||
|             fprintf(stderr, "%s: Error: Failed to probe secondary address [%s].\n", __PRETTY_FUNCTION__, addr_str); |             fprintf(stderr, "%s: Error: Failed to select secondary address [%s].\n", __PRETTY_FUNCTION__, addr_str); | ||||||
|             return 1;     |             return 1;     | ||||||
|         } |         } | ||||||
|         // else MBUS_PROBE_SINGLE |         // else MBUS_PROBE_SINGLE | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ main(int argc, char **argv) | |||||||
|     mbus_frame_data reply_data; |     mbus_frame_data reply_data; | ||||||
|     mbus_handle *handle = NULL; |     mbus_handle *handle = NULL; | ||||||
|  |  | ||||||
|     char *device, *addr_str, matching_addr[16]; |     char *device, *addr_str; | ||||||
|     int address, baudrate = 9600; |     int address, baudrate = 9600; | ||||||
|  |  | ||||||
|     if (argc == 3) |     if (argc == 3) | ||||||
| @@ -87,23 +87,23 @@ main(int argc, char **argv) | |||||||
|     { |     { | ||||||
|         // secondary addressing |         // secondary addressing | ||||||
|  |  | ||||||
|         int probe_ret; |         int ret; | ||||||
|  |  | ||||||
|         probe_ret = mbus_probe_secondary_address(handle, addr_str, matching_addr); |         ret = mbus_select_secondary_address(handle, addr_str); | ||||||
|  |  | ||||||
|         if (probe_ret == MBUS_PROBE_COLLISION) |         if (ret == MBUS_PROBE_COLLISION) | ||||||
|         { |         { | ||||||
|             fprintf(stderr, "%s: Error: The address mask [%s] matches more than one device.\n", __PRETTY_FUNCTION__, addr_str); |             fprintf(stderr, "%s: Error: The address mask [%s] matches more than one device.\n", __PRETTY_FUNCTION__, addr_str); | ||||||
|             return 1; |             return 1; | ||||||
|         } |         } | ||||||
|         else if (probe_ret == MBUS_PROBE_NOTHING) |         else if (ret == MBUS_PROBE_NOTHING) | ||||||
|         { |         { | ||||||
|             fprintf(stderr, "%s: Error: The selected secondary address does not match any device [%s].\n", __PRETTY_FUNCTION__, addr_str); |             fprintf(stderr, "%s: Error: The selected secondary address does not match any device [%s].\n", __PRETTY_FUNCTION__, addr_str); | ||||||
|             return 1; |             return 1; | ||||||
|         } |         } | ||||||
|         else if (probe_ret == MBUS_PROBE_ERROR) |         else if (ret == MBUS_PROBE_ERROR) | ||||||
|         { |         { | ||||||
|             fprintf(stderr, "%s: Error: Failed to probe secondary address [%s].\n", __PRETTY_FUNCTION__, addr_str); |             fprintf(stderr, "%s: Error: Failed to select secondary address [%s].\n", __PRETTY_FUNCTION__, addr_str); | ||||||
|             return 1;     |             return 1;     | ||||||
|         } |         } | ||||||
|         // else MBUS_PROBE_SINGLE |         // else MBUS_PROBE_SINGLE | ||||||
|   | |||||||
| @@ -28,7 +28,9 @@ main(int argc, char **argv) | |||||||
|     char *device, *addr_mask; |     char *device, *addr_mask; | ||||||
|     int baudrate = 9600; |     int baudrate = 9600; | ||||||
|     mbus_handle *handle = NULL; |     mbus_handle *handle = NULL; | ||||||
|     mbus_frame *frame = NULL, *reply = NULL; |     mbus_frame *frame = NULL, reply; | ||||||
|  |      | ||||||
|  |     memset((void *)&reply, 0, sizeof(mbus_frame)); | ||||||
|  |  | ||||||
|     if (argc == 2) |     if (argc == 2) | ||||||
|     { |     { | ||||||
| @@ -108,7 +110,7 @@ main(int argc, char **argv) | |||||||
|  |  | ||||||
|     if (mbus_serial_set_baudrate(handle->m_serial_handle, baudrate) == -1) |     if (mbus_serial_set_baudrate(handle->m_serial_handle, baudrate) == -1) | ||||||
|     { |     { | ||||||
|         printf("Failed to set baud rate.\n"); |         fprintf(stderr, "Failed to set baud rate.\n"); | ||||||
|         return 1; |         return 1; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -134,7 +136,7 @@ main(int argc, char **argv) | |||||||
|         return 1; |         return 1; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     (void) mbus_recv_frame(handle, reply); |     (void) mbus_recv_frame(handle, &reply); | ||||||
|  |  | ||||||
|     frame->control = MBUS_CONTROL_MASK_SND_NKE | MBUS_CONTROL_MASK_DIR_M2S; |     frame->control = MBUS_CONTROL_MASK_SND_NKE | MBUS_CONTROL_MASK_DIR_M2S; | ||||||
|     frame->address = 0xFF; |     frame->address = 0xFF; | ||||||
| @@ -146,7 +148,7 @@ main(int argc, char **argv) | |||||||
|         return 1; |         return 1; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     (void) mbus_recv_frame(handle, reply); |     (void) mbus_recv_frame(handle, &reply); | ||||||
|  |  | ||||||
|     mbus_scan_2nd_address_range(handle, 0, addr_mask); |     mbus_scan_2nd_address_range(handle, 0, addr_mask); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -28,6 +28,7 @@ main(int argc, char **argv) | |||||||
|     mbus_handle *handle; |     mbus_handle *handle; | ||||||
|     char *device; |     char *device; | ||||||
|     int address, baudrate = 9600; |     int address, baudrate = 9600; | ||||||
|  |     int ret; | ||||||
|  |  | ||||||
|     if (argc == 2) |     if (argc == 2) | ||||||
|     { |     { | ||||||
| @@ -76,7 +77,7 @@ main(int argc, char **argv) | |||||||
|     if (debug) |     if (debug) | ||||||
|         printf("Scanning primary addresses:\n"); |         printf("Scanning primary addresses:\n"); | ||||||
|  |  | ||||||
|     for (address = 0; address < 254; address++) |     for (address = 0; address <= 250; address++) | ||||||
|     { |     { | ||||||
|         mbus_frame reply; |         mbus_frame reply; | ||||||
|  |  | ||||||
| @@ -94,15 +95,40 @@ main(int argc, char **argv) | |||||||
|             return 1; |             return 1; | ||||||
|         }  |         }  | ||||||
|          |          | ||||||
|         if (mbus_recv_frame(handle, &reply) == -1) |         ret = mbus_recv_frame(handle, &reply); | ||||||
|  |  | ||||||
|  |         if (ret == -1) | ||||||
|         { |         { | ||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
|          |          | ||||||
|  |         if (debug) | ||||||
|  |             printf("\n"); | ||||||
|  |          | ||||||
|  |         if (ret == -2) | ||||||
|  |         { | ||||||
|  |             /* check for more data (collision) */ | ||||||
|  |             while (mbus_recv_frame(handle, &reply) != -1); | ||||||
|  |              | ||||||
|  |             printf("Collision at address %d\n", address); | ||||||
|  |              | ||||||
|  |             continue; | ||||||
|  |         }  | ||||||
|  |  | ||||||
|         if (mbus_frame_type(&reply) == MBUS_FRAME_TYPE_ACK) |         if (mbus_frame_type(&reply) == MBUS_FRAME_TYPE_ACK) | ||||||
|         { |         { | ||||||
|             if (debug) |             /* check for more data (collision) */ | ||||||
|                 printf("\n"); |             while (mbus_recv_frame(handle, &reply) != -1) | ||||||
|  |             { | ||||||
|  |                 ret = -2; | ||||||
|  |             } | ||||||
|  |      | ||||||
|  |             if (ret == -2) | ||||||
|  |             { | ||||||
|  |                 printf("Collision at address %d\n", address); | ||||||
|  |                  | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|                  |                  | ||||||
|             printf("Found a M-Bus device at address %d\n", address); |             printf("Found a M-Bus device at address %d\n", address); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -77,12 +77,15 @@ main(int argc, char **argv) | |||||||
|         printf("No reply from device\n"); |         printf("No reply from device\n"); | ||||||
|         return 1; |         return 1; | ||||||
|     } |     } | ||||||
|  |     else if (mbus_frame_type(&reply) != MBUS_FRAME_TYPE_ACK) | ||||||
|     if (mbus_frame_type(&reply) != MBUS_FRAME_TYPE_ACK) |  | ||||||
|     { |     { | ||||||
|         printf("Unknown reply:\n"); |         printf("Unknown reply:\n"); | ||||||
|         mbus_frame_print(&reply); |         mbus_frame_print(&reply); | ||||||
|     } |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         printf("Switched baud rate of device to %d\n", target_baudrate); | ||||||
|  |     } | ||||||
|      |      | ||||||
|     mbus_disconnect(handle); |     mbus_disconnect(handle); | ||||||
|     return 0; |     return 0; | ||||||
|   | |||||||
| @@ -72,23 +72,23 @@ main(int argc, char **argv) | |||||||
|     { |     { | ||||||
|         // secondary addressing |         // secondary addressing | ||||||
|  |  | ||||||
|         int probe_ret; |         int ret; | ||||||
|  |  | ||||||
|         probe_ret = mbus_probe_secondary_address(handle, addr_str, matching_addr); |         ret = mbus_select_secondary_address(handle, addr_str); | ||||||
|  |  | ||||||
|         if (probe_ret == MBUS_PROBE_COLLISION) |         if (ret == MBUS_PROBE_COLLISION) | ||||||
|         { |         { | ||||||
|             fprintf(stderr, "%s: Error: The address mask [%s] matches more than one device.\n", __PRETTY_FUNCTION__, addr_str); |             fprintf(stderr, "%s: Error: The address mask [%s] matches more than one device.\n", __PRETTY_FUNCTION__, addr_str); | ||||||
|             return 1; |             return 1; | ||||||
|         } |         } | ||||||
|         else if (probe_ret == MBUS_PROBE_NOTHING) |         else if (ret == MBUS_PROBE_NOTHING) | ||||||
|         { |         { | ||||||
|             fprintf(stderr, "%s: Error: The selected secondary address does not match any device [%s].\n", __PRETTY_FUNCTION__, addr_str); |             fprintf(stderr, "%s: Error: The selected secondary address does not match any device [%s].\n", __PRETTY_FUNCTION__, addr_str); | ||||||
|             return 1; |             return 1; | ||||||
|         } |         } | ||||||
|         else if (probe_ret == MBUS_PROBE_ERROR) |         else if (ret == MBUS_PROBE_ERROR) | ||||||
|         { |         { | ||||||
|             fprintf(stderr, "%s: Error: Failed to probe secondary address [%s].\n", __PRETTY_FUNCTION__, addr_str); |             fprintf(stderr, "%s: Error: Failed to select secondary address [%s].\n", __PRETTY_FUNCTION__, addr_str); | ||||||
|             return 1;     |             return 1;     | ||||||
|         } |         } | ||||||
|         // else MBUS_PROBE_SINGLE |         // else MBUS_PROBE_SINGLE | ||||||
|   | |||||||
| @@ -72,23 +72,23 @@ main(int argc, char **argv) | |||||||
|     { |     { | ||||||
|         // secondary addressing |         // secondary addressing | ||||||
|  |  | ||||||
|         int probe_ret; |         int ret; | ||||||
|  |  | ||||||
|         probe_ret = mbus_probe_secondary_address(handle, addr_str, matching_addr); |         ret = mbus_select_secondary_address(handle, addr_str); | ||||||
|  |  | ||||||
|         if (probe_ret == MBUS_PROBE_COLLISION) |         if (ret == MBUS_PROBE_COLLISION) | ||||||
|         { |         { | ||||||
|             fprintf(stderr, "%s: Error: The address mask [%s] matches more than one device.\n", __PRETTY_FUNCTION__, addr_str); |             fprintf(stderr, "%s: Error: The address mask [%s] matches more than one device.\n", __PRETTY_FUNCTION__, addr_str); | ||||||
|             return 1; |             return 1; | ||||||
|         } |         } | ||||||
|         else if (probe_ret == MBUS_PROBE_NOTHING) |         else if (ret == MBUS_PROBE_NOTHING) | ||||||
|         { |         { | ||||||
|             fprintf(stderr, "%s: Error: The selected secondary address does not match any device [%s].\n", __PRETTY_FUNCTION__, addr_str); |             fprintf(stderr, "%s: Error: The selected secondary address does not match any device [%s].\n", __PRETTY_FUNCTION__, addr_str); | ||||||
|             return 1; |             return 1; | ||||||
|         } |         } | ||||||
|         else if (probe_ret == MBUS_PROBE_ERROR) |         else if (ret == MBUS_PROBE_ERROR) | ||||||
|         { |         { | ||||||
|             fprintf(stderr, "%s: Error: Failed to probe secondary address [%s].\n", __PRETTY_FUNCTION__, addr_str); |             fprintf(stderr, "%s: Error: Failed to select secondary address [%s].\n", __PRETTY_FUNCTION__, addr_str); | ||||||
|             return 1;     |             return 1;     | ||||||
|         } |         } | ||||||
|         // else MBUS_PROBE_SINGLE |         // else MBUS_PROBE_SINGLE | ||||||
|   | |||||||
| @@ -701,6 +701,26 @@ mbus_variable_vif fixed_table[] = { | |||||||
|     { 0xFFFF, 0.0, "", "" }, |     { 0xFFFF, 0.0, "", "" }, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | void (*_mbus_scan_progress)(mbus_handle * handle, const char *mask) = NULL; | ||||||
|  | void (*_mbus_found_event)(mbus_handle * handle, mbus_frame *frame) = NULL; | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | /// Register a function for the scan progress. | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | void | ||||||
|  | mbus_register_scan_progress(void (*event)(mbus_handle * handle, const char *mask)) | ||||||
|  | { | ||||||
|  |     _mbus_scan_progress = event; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | /// Register a function for the found events. | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | void | ||||||
|  | mbus_register_found_event(void (*event)(mbus_handle * handle, mbus_frame *frame)) | ||||||
|  | { | ||||||
|  |     _mbus_found_event = event; | ||||||
|  | } | ||||||
|  |  | ||||||
| int mbus_fixed_normalize(int medium_unit, long medium_value, char **unit_out, double *value_out, char **quantity_out) | int mbus_fixed_normalize(int medium_unit, long medium_value, char **unit_out, double *value_out, char **quantity_out) | ||||||
| { | { | ||||||
| @@ -708,6 +728,12 @@ int mbus_fixed_normalize(int medium_unit, long medium_value, char **unit_out, do | |||||||
|     int i; |     int i; | ||||||
|     medium_unit = medium_unit & 0x3F; |     medium_unit = medium_unit & 0x3F; | ||||||
|      |      | ||||||
|  |     if (unit_out == NULL || value_out == NULL || quantity_out == NULL) | ||||||
|  |     { | ||||||
|  |         MBUS_ERROR("%s: Invalid parameter.\n", __PRETTY_FUNCTION__); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     switch (medium_unit) |     switch (medium_unit) | ||||||
|     { |     { | ||||||
|         case 0x00:     |         case 0x00:     | ||||||
| @@ -909,6 +935,12 @@ mbus_vif_unit_normalize(int vif, double value, char **unit_out, double *value_ou | |||||||
|  |  | ||||||
|     int i; |     int i; | ||||||
|      |      | ||||||
|  |     if (unit_out == NULL || value_out == NULL || quantity_out == NULL) | ||||||
|  |     { | ||||||
|  |         MBUS_ERROR("%s: Invalid parameter.\n", __PRETTY_FUNCTION__); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  |      | ||||||
|     for(i=0; vif_table[i].vif < 0xfff; ++i) |     for(i=0; vif_table[i].vif < 0xfff; ++i) | ||||||
|     { |     { | ||||||
|         if (vif_table[i].vif == newVif) |         if (vif_table[i].vif == newVif) | ||||||
| @@ -931,7 +963,14 @@ mbus_vif_unit_normalize(int vif, double value, char **unit_out, double *value_ou | |||||||
| int | int | ||||||
| mbus_vib_unit_normalize(mbus_value_information_block *vib, double value, char **unit_out, double *value_out, char **quantity_out) | mbus_vib_unit_normalize(mbus_value_information_block *vib, double value, char **unit_out, double *value_out, char **quantity_out) | ||||||
| {    | {    | ||||||
|  |     if (vib == NULL || unit_out == NULL || value_out == NULL || quantity_out == NULL) | ||||||
|  |     { | ||||||
|  |         MBUS_ERROR("%s: Invalid parameter.\n", __PRETTY_FUNCTION__); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  |      | ||||||
|     MBUS_DEBUG("%s: vib_unit_normalize - VIF=0x%02X\n", __PRETTY_FUNCTION__, vib->vif); |     MBUS_DEBUG("%s: vib_unit_normalize - VIF=0x%02X\n", __PRETTY_FUNCTION__, vib->vif); | ||||||
|  |      | ||||||
|     if (vib->vif == 0xFD) /* first type of VIF extention: see table 8.4.4 a */ |     if (vib->vif == 0xFD) /* first type of VIF extention: see table 8.4.4 a */ | ||||||
|     { |     { | ||||||
|         if (vib->nvife == 0) |         if (vib->nvife == 0) | ||||||
| @@ -1007,6 +1046,8 @@ mbus_record_new() | |||||||
| void | void | ||||||
| mbus_record_free(mbus_record * rec) | mbus_record_free(mbus_record * rec) | ||||||
| { | { | ||||||
|  |     if (rec) | ||||||
|  |     { | ||||||
|         if (! rec->is_numeric) |         if (! rec->is_numeric) | ||||||
|         { |         { | ||||||
|             free((rec->value).str_val.value); |             free((rec->value).str_val.value); | ||||||
| @@ -1031,6 +1072,7 @@ mbus_record_free(mbus_record * rec) | |||||||
|             rec->quantity = NULL; |             rec->quantity = NULL; | ||||||
|         } |         } | ||||||
|         free(rec); |         free(rec); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -1080,6 +1122,12 @@ mbus_parse_variable_record(mbus_data_record *data) | |||||||
|     int    value_out_str_size = 0; |     int    value_out_str_size = 0; | ||||||
|     double real_val         = 0.0;  /**< normalized value */ |     double real_val         = 0.0;  /**< normalized value */ | ||||||
|      |      | ||||||
|  |     if (data == NULL) | ||||||
|  |     { | ||||||
|  |         MBUS_ERROR("%s: Invalid record.\n", __PRETTY_FUNCTION__); | ||||||
|  |         return NULL; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (!(record = mbus_record_new())) |     if (!(record = mbus_record_new())) | ||||||
|     { |     { | ||||||
|         MBUS_ERROR("%s: memory allocation error\n", __PRETTY_FUNCTION__); |         MBUS_ERROR("%s: memory allocation error\n", __PRETTY_FUNCTION__); | ||||||
| @@ -1500,37 +1548,6 @@ mbus_sendrecv_request(mbus_handle *handle, int address, mbus_frame *reply, int m | |||||||
|         return -1; |         return -1; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     // |  | ||||||
|     // init slave to get really the beginning of the records |  | ||||||
|     // |  | ||||||
|      |  | ||||||
|     frame->control = MBUS_CONTROL_MASK_SND_NKE | MBUS_CONTROL_MASK_DIR_M2S; |  | ||||||
|     frame->address = address; |  | ||||||
|      |  | ||||||
|     if (debug) |  | ||||||
|         printf("%s: debug: sending init frame\n", __PRETTY_FUNCTION__); |  | ||||||
|      |  | ||||||
|     if (mbus_send_frame(handle, frame) == -1) |  | ||||||
|     { |  | ||||||
|         MBUS_ERROR("%s: failed to send mbus frame.\n", __PRETTY_FUNCTION__); |  | ||||||
|         mbus_frame_free(frame); |  | ||||||
|         return -1; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     if (mbus_recv_frame(handle, reply) == -1) |  | ||||||
|     { |  | ||||||
|         MBUS_ERROR("%s: Failed to receive M-Bus response frame.\n", __PRETTY_FUNCTION__); |  | ||||||
|         mbus_frame_free(frame); |  | ||||||
|         return -1; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     if (mbus_frame_type(reply) != MBUS_FRAME_TYPE_ACK) |  | ||||||
|     { |  | ||||||
|         MBUS_ERROR("%s: Unknown reply.\n", __PRETTY_FUNCTION__); |  | ||||||
|         mbus_frame_free(frame); |  | ||||||
|         return -1; |  | ||||||
|     } |  | ||||||
|      |  | ||||||
|     frame->control = MBUS_CONTROL_MASK_REQ_UD2 |  |     frame->control = MBUS_CONTROL_MASK_REQ_UD2 |  | ||||||
|                      MBUS_CONTROL_MASK_DIR_M2S |  |                      MBUS_CONTROL_MASK_DIR_M2S |  | ||||||
|                      MBUS_CONTROL_MASK_FCV     |  |                      MBUS_CONTROL_MASK_FCV     |  | ||||||
| @@ -1678,16 +1695,15 @@ mbus_send_ping_frame(mbus_handle *handle, int address) | |||||||
| } | } | ||||||
|  |  | ||||||
| //------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||||
| // Prove for the presence of a device(s) using the supplied secondary address  | // Select a device using the supplied secondary address  (mask). | ||||||
| // (mask). |  | ||||||
| //------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||||
| int | int | ||||||
| mbus_probe_secondary_address(mbus_handle * handle, const char *mask, char *matching_addr) | mbus_select_secondary_address(mbus_handle * handle, const char *mask) | ||||||
| { | { | ||||||
|     int ret; |     int ret; | ||||||
|     mbus_frame reply; |     mbus_frame reply; | ||||||
|  |  | ||||||
|     if (mask == NULL || matching_addr == NULL || strlen(mask) != 16) |     if (mask == NULL || strlen(mask) != 16) | ||||||
|     { |     { | ||||||
|         MBUS_ERROR("%s: Invalid address masks.\n", __PRETTY_FUNCTION__); |         MBUS_ERROR("%s: Invalid address masks.\n", __PRETTY_FUNCTION__); | ||||||
|         return MBUS_PROBE_ERROR; |         return MBUS_PROBE_ERROR; | ||||||
| @@ -1730,6 +1746,34 @@ mbus_probe_secondary_address(mbus_handle * handle, const char *mask, char *match | |||||||
|             return MBUS_PROBE_COLLISION; |             return MBUS_PROBE_COLLISION; | ||||||
|         } |         } | ||||||
|          |          | ||||||
|  |         return MBUS_PROBE_SINGLE; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     MBUS_ERROR("%s: Unexpected reply for address [%s].\n", __PRETTY_FUNCTION__, mask); | ||||||
|  |  | ||||||
|  |     return MBUS_PROBE_NOTHING; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | // Prove for the presence of a device(s) using the supplied secondary address  | ||||||
|  | // (mask). | ||||||
|  | //------------------------------------------------------------------------------ | ||||||
|  | int  | ||||||
|  | mbus_probe_secondary_address(mbus_handle * handle, const char *mask, char *matching_addr) | ||||||
|  | { | ||||||
|  |     int ret; | ||||||
|  |     mbus_frame reply; | ||||||
|  |  | ||||||
|  |     if (mask == NULL || matching_addr == NULL || strlen(mask) != 16) | ||||||
|  |     { | ||||||
|  |         MBUS_ERROR("%s: Invalid address masks.\n", __PRETTY_FUNCTION__); | ||||||
|  |         return MBUS_PROBE_ERROR; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     ret = mbus_select_secondary_address(handle, mask); | ||||||
|  |      | ||||||
|  |     if (ret == MBUS_PROBE_SINGLE) | ||||||
|  |     { | ||||||
|         /* send a data request command to find out the full address */ |         /* send a data request command to find out the full address */ | ||||||
|         if (mbus_send_request_frame(handle, 253) == -1) |         if (mbus_send_request_frame(handle, 253) == -1) | ||||||
|         { |         { | ||||||
| @@ -1755,6 +1799,12 @@ mbus_probe_secondary_address(mbus_handle * handle, const char *mask, char *match | |||||||
|         if (mbus_frame_type(&reply) != MBUS_FRAME_TYPE_ACK) |         if (mbus_frame_type(&reply) != MBUS_FRAME_TYPE_ACK) | ||||||
|         { |         { | ||||||
|             snprintf(matching_addr, 17, "%s", mbus_frame_get_secondary_address(&reply)); |             snprintf(matching_addr, 17, "%s", mbus_frame_get_secondary_address(&reply)); | ||||||
|  |  | ||||||
|  |             if (_mbus_found_event) | ||||||
|  |             { | ||||||
|  |                 _mbus_found_event(handle,&reply); | ||||||
|  |             } | ||||||
|  |  | ||||||
|             return MBUS_PROBE_SINGLE; |             return MBUS_PROBE_SINGLE; | ||||||
|         } |         } | ||||||
|         else |         else | ||||||
| @@ -1765,14 +1815,18 @@ mbus_probe_secondary_address(mbus_handle * handle, const char *mask, char *match | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|      |      | ||||||
|     MBUS_ERROR("%s: Unexpected reply for address [%s].\n", __PRETTY_FUNCTION__, mask); |     return ret; | ||||||
|  |  | ||||||
|     return MBUS_PROBE_NOTHING; |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| int mbus_read_slave(mbus_handle * handle, mbus_address *address, mbus_frame * reply) | int mbus_read_slave(mbus_handle * handle, mbus_address *address, mbus_frame * reply) | ||||||
| { | { | ||||||
|  |     if (handle == NULL || address == NULL) | ||||||
|  |     { | ||||||
|  |         MBUS_ERROR("%s: Invalid handle or address.\n", __PRETTY_FUNCTION__); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (address->is_primary) |     if (address->is_primary) | ||||||
|     { |     { | ||||||
|         if (mbus_send_request_frame(handle, address->primary) == -1) |         if (mbus_send_request_frame(handle, address->primary) == -1) | ||||||
| @@ -1847,6 +1901,12 @@ mbus_scan_2nd_address_range(mbus_handle * handle, int pos, char *addr_mask) | |||||||
|     int i, i_start, i_end, probe_ret; |     int i, i_start, i_end, probe_ret; | ||||||
|     char *mask, matching_mask[17]; |     char *mask, matching_mask[17]; | ||||||
|      |      | ||||||
|  |     if (handle == NULL || addr_mask == NULL) | ||||||
|  |     { | ||||||
|  |         MBUS_ERROR("%s: Invalid handle or address mask.\n", __PRETTY_FUNCTION__); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if (strlen(addr_mask) != 16) |     if (strlen(addr_mask) != 16) | ||||||
|     { |     { | ||||||
|         fprintf(stderr, "%s: Illegal address mask [%s]. Not 16 characters long.\n", __PRETTY_FUNCTION__, addr_mask); |         fprintf(stderr, "%s: Illegal address mask [%s]. Not 16 characters long.\n", __PRETTY_FUNCTION__, addr_mask); | ||||||
| @@ -1886,12 +1946,18 @@ mbus_scan_2nd_address_range(mbus_handle * handle, int pos, char *addr_mask) | |||||||
|     { |     { | ||||||
|         mask[pos] = '0'+i; |         mask[pos] = '0'+i; | ||||||
|  |  | ||||||
|  |         if (_mbus_scan_progress) | ||||||
|  |             _mbus_scan_progress(handle,mask); | ||||||
|  |      | ||||||
|         probe_ret = mbus_probe_secondary_address(handle, mask, matching_mask); |         probe_ret = mbus_probe_secondary_address(handle, mask, matching_mask); | ||||||
|  |  | ||||||
|         if (probe_ret == MBUS_PROBE_SINGLE) |         if (probe_ret == MBUS_PROBE_SINGLE) | ||||||
|  |         { | ||||||
|  |             if (!_mbus_found_event) | ||||||
|             { |             { | ||||||
|                 printf("Found a device on secondary address %s [using address mask %s]\n", matching_mask, mask); |                 printf("Found a device on secondary address %s [using address mask %s]\n", matching_mask, mask); | ||||||
|             } |             } | ||||||
|  |         } | ||||||
|         else if (probe_ret == MBUS_PROBE_COLLISION) |         else if (probe_ret == MBUS_PROBE_COLLISION) | ||||||
|         { |         { | ||||||
|             // collision, more than one device matching, restrict the search mask further |             // collision, more than one device matching, restrict the search mask further | ||||||
|   | |||||||
| @@ -128,6 +128,18 @@ typedef struct _mbus_record { | |||||||
| } mbus_record; | } mbus_record; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Event callback functions | ||||||
|  |  */ | ||||||
|  | extern void (*_mbus_scan_progress)(mbus_handle * handle, const char *mask); | ||||||
|  | extern void (*_mbus_found_event)(mbus_handle * handle, mbus_frame *frame); | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Event register functions | ||||||
|  |  */ | ||||||
|  | void mbus_register_scan_progress(void (*event)(mbus_handle * handle, const char *mask)); | ||||||
|  | void mbus_register_found_event(void (*event)(mbus_handle * handle, mbus_frame *frame)); | ||||||
|  |  | ||||||
| /**  | /**  | ||||||
|  * Connects to serial gateway and initializes MBus handle |  * Connects to serial gateway and initializes MBus handle | ||||||
|  *  |  *  | ||||||
| @@ -230,6 +242,16 @@ int mbus_sendrecv_request(mbus_handle *handle, int address, mbus_frame *reply, i | |||||||
|  */ |  */ | ||||||
| int mbus_send_ping_frame(mbus_handle *handle, int address); | int mbus_send_ping_frame(mbus_handle *handle, int address); | ||||||
|  |  | ||||||
|  | /**  | ||||||
|  |  * Select slave by secondary address using "unified" handle | ||||||
|  |  *  | ||||||
|  |  * @param handle        Initialized handle | ||||||
|  |  * @param mask          Address/mask to select | ||||||
|  |  *  | ||||||
|  |  * @return See MBUS_PROBE_* constants | ||||||
|  |  */ | ||||||
|  | int mbus_select_secondary_address(mbus_handle * handle, const char *mask); | ||||||
|  |  | ||||||
| /**  | /**  | ||||||
|  * Probe/address slave by secondary address using "unified" handle |  * Probe/address slave by secondary address using "unified" handle | ||||||
|  *  |  *  | ||||||
|   | |||||||
| @@ -620,10 +620,14 @@ mbus_data_str_decode(u_char *dst, const u_char *src, size_t len) | |||||||
|     size_t i; |     size_t i; | ||||||
|  |  | ||||||
|     i = 0; |     i = 0; | ||||||
|  |      | ||||||
|  |     if (src && dst) | ||||||
|  |     { | ||||||
|         dst[len] = '\0'; |         dst[len] = '\0'; | ||||||
|         while(len > 0) { |         while(len > 0) { | ||||||
|             dst[i++] = src[--len]; |             dst[i++] = src[--len]; | ||||||
|         } |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| //------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||||
| @@ -639,6 +643,8 @@ mbus_data_bin_decode(u_char *dst, const u_char *src, size_t len, size_t max_len) | |||||||
|     i = 0; |     i = 0; | ||||||
|     pos = 0; |     pos = 0; | ||||||
|      |      | ||||||
|  |     if (src && dst) | ||||||
|  |     { | ||||||
|         while((i < len) && ((pos+3) < max_len)) { |         while((i < len) && ((pos+3) < max_len)) { | ||||||
|             pos += snprintf(&dst[pos], max_len - pos, "%.2X ", src[i]); |             pos += snprintf(&dst[pos], max_len - pos, "%.2X ", src[i]); | ||||||
|             i++; |             i++; | ||||||
| @@ -651,6 +657,7 @@ mbus_data_bin_decode(u_char *dst, const u_char *src, size_t len, size_t max_len) | |||||||
|         } |         } | ||||||
|          |          | ||||||
|         dst[pos] = '\0'; |         dst[pos] = '\0'; | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| //------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||||
| @@ -661,6 +668,8 @@ mbus_data_bin_decode(u_char *dst, const u_char *src, size_t len, size_t max_len) | |||||||
| void | void | ||||||
| mbus_data_tm_decode(struct tm *t, u_char *t_data, size_t t_data_size) | mbus_data_tm_decode(struct tm *t, u_char *t_data, size_t t_data_size) | ||||||
| { | { | ||||||
|  |     if (t && t_data) | ||||||
|  |     { | ||||||
|         t->tm_sec   = 0; |         t->tm_sec   = 0; | ||||||
|         t->tm_min   = 0; |         t->tm_min   = 0; | ||||||
|         t->tm_hour  = 0; |         t->tm_hour  = 0; | ||||||
| @@ -669,8 +678,6 @@ mbus_data_tm_decode(struct tm *t, u_char *t_data, size_t t_data_size) | |||||||
|         t->tm_year  = 0;  |         t->tm_year  = 0;  | ||||||
|         t->tm_isdst = 0; |         t->tm_isdst = 0; | ||||||
|     |     | ||||||
|     if (t && t_data) |  | ||||||
|     { |  | ||||||
|         if (t_data_size == 4)                // Type F = Compound CP32: Date and Time |         if (t_data_size == 4)                // Type F = Compound CP32: Date and Time | ||||||
|         {      |         {      | ||||||
|             if ((t_data[0] & 0x80) == 0)     // Time valid ? |             if ((t_data[0] & 0x80) == 0)     // Time valid ? | ||||||
| @@ -741,6 +748,173 @@ mbus_decode_manufacturer(u_char byte1, u_char byte2) | |||||||
|     return m_str; |     return m_str; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | const char * | ||||||
|  | mbus_data_product_name(mbus_data_variable_header *header) | ||||||
|  | { | ||||||
|  |     static char buff[128]; | ||||||
|  |     unsigned int manufacturer; | ||||||
|  |  | ||||||
|  |     if (header) | ||||||
|  |     { | ||||||
|  |         manufacturer = (header->manufacturer[1] << 8) + header->manufacturer[0]; | ||||||
|  |  | ||||||
|  |         if (manufacturer == MBUS_VARIABLE_DATA_MAN_ACW)  | ||||||
|  |         { | ||||||
|  |             switch (header->version) | ||||||
|  |             { | ||||||
|  |                 case 0x09: | ||||||
|  |                     strcpy(buff,"Itron CF Echo 2"); | ||||||
|  |                     break; | ||||||
|  |                 case 0x0A: | ||||||
|  |                     strcpy(buff,"Itron CF 51"); | ||||||
|  |                     break; | ||||||
|  |                 case 0x0B: | ||||||
|  |                     strcpy(buff,"Itron CF 55"); | ||||||
|  |                     break; | ||||||
|  |                 case 0x0E: | ||||||
|  |                     strcpy(buff,"Itron BM +m"); | ||||||
|  |                     break; | ||||||
|  |                 case 0x0F: | ||||||
|  |                     strcpy(buff,"Itron CF 800"); | ||||||
|  |                     break; | ||||||
|  |                 case 0x14: | ||||||
|  |                     strcpy(buff,"Itron CYBLE M-Bus 1.4"); | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else if (manufacturer == MBUS_VARIABLE_DATA_MAN_SLB)  | ||||||
|  |         { | ||||||
|  |             switch (header->version) | ||||||
|  |             { | ||||||
|  |                 case 0x02: | ||||||
|  |                     strcpy(buff,"Allmess Megacontrol CF-50"); | ||||||
|  |                     break; | ||||||
|  |                 case 0x06: | ||||||
|  |                     strcpy(buff,"CF Compact / Integral MK MaXX"); | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else if (manufacturer == MBUS_VARIABLE_DATA_MAN_HYD)  | ||||||
|  |         { | ||||||
|  |             switch (header->version) | ||||||
|  |             { | ||||||
|  |                 case 0x02: | ||||||
|  |                     strcpy(buff,"ABB F95 Typ US770"); | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else if (manufacturer == MBUS_VARIABLE_DATA_MAN_LUG)  | ||||||
|  |         { | ||||||
|  |             switch (header->version) | ||||||
|  |             { | ||||||
|  |                 case 0x02: | ||||||
|  |                     strcpy(buff,"Landis & Gyr Ultraheat 2WR5"); | ||||||
|  |                     break; | ||||||
|  |                 case 0x03: | ||||||
|  |                     strcpy(buff,"Landis & Gyr Ultraheat 2WR6"); | ||||||
|  |                     break; | ||||||
|  |                 case 0x04: | ||||||
|  |                     strcpy(buff,"Landis & Gyr Ultraheat UH50"); | ||||||
|  |                     break; | ||||||
|  |                 case 0x07: | ||||||
|  |                     strcpy(buff,"Landis & Gyr Ultraheat T230"); | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else if (manufacturer == MBUS_VARIABLE_DATA_MAN_ZRM) | ||||||
|  |         { | ||||||
|  |             switch (header->version) | ||||||
|  |             { | ||||||
|  |                 case 0x81: | ||||||
|  |                     strcpy(buff,"Minol Minocal C2"); | ||||||
|  |                     break; | ||||||
|  |                 case 0x82: | ||||||
|  |                     strcpy(buff,"Minol Minocal WR3"); | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else if (manufacturer == MBUS_VARIABLE_DATA_MAN_SVM)  | ||||||
|  |         { | ||||||
|  |             switch (header->version) | ||||||
|  |             { | ||||||
|  |                 case 0x08: | ||||||
|  |                     strcpy(buff,"Elster F2"); | ||||||
|  |                     break; | ||||||
|  |                 case 0x09: | ||||||
|  |                     strcpy(buff,"Kamstrup SVM F22"); | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else if (manufacturer == MBUS_VARIABLE_DATA_MAN_SON)  | ||||||
|  |         { | ||||||
|  |             switch (header->version) | ||||||
|  |             { | ||||||
|  |                 case 0x0D: | ||||||
|  |                     strcpy(buff,"Sontex Supercal 531"); | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else if (manufacturer == MBUS_VARIABLE_DATA_MAN_LSE) | ||||||
|  |         { | ||||||
|  |             switch (header->version) | ||||||
|  |             { | ||||||
|  |                 case 0x99: | ||||||
|  |                     strcpy(buff,"Siemens WFH21"); | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else if (manufacturer == MBUS_VARIABLE_DATA_MAN_SPX)  | ||||||
|  |         { | ||||||
|  |             switch (header->version) | ||||||
|  |             { | ||||||
|  |                 case 0x31: | ||||||
|  |                     strcpy(buff,"Sensus PolluTherm"); | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else if (manufacturer == MBUS_VARIABLE_DATA_MAN_ELS) | ||||||
|  |         { | ||||||
|  |             switch (header->version) | ||||||
|  |             { | ||||||
|  |                 case 0x02: | ||||||
|  |                     strcpy(buff,"Elster TMP-A"); | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else if (manufacturer == MBUS_VARIABLE_DATA_MAN_NZR) | ||||||
|  |         { | ||||||
|  |             switch (header->version) | ||||||
|  |             { | ||||||
|  |                 case 0x01: | ||||||
|  |                     strcpy(buff,"NZR DHZ 5/63"); | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else if (manufacturer == MBUS_VARIABLE_DATA_MAN_KAM) | ||||||
|  |         { | ||||||
|  |             switch (header->version) | ||||||
|  |             { | ||||||
|  |                 case 0x08: | ||||||
|  |                     strcpy(buff,"Kamstrup Multical 601"); | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         else if (manufacturer == MBUS_VARIABLE_DATA_MAN_EMH) | ||||||
|  |         { | ||||||
|  |             switch (header->version) | ||||||
|  |             { | ||||||
|  |                 case 0x00: | ||||||
|  |                     strcpy(buff,"EMH DIZ"); | ||||||
|  |                     break; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return buff; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return ""; | ||||||
|  | } | ||||||
|  |  | ||||||
| //------------------------------------------------------------------------------ | //------------------------------------------------------------------------------ | ||||||
| // | // | ||||||
| // FIXED-LENGTH DATA RECORD FUNCTIONS | // FIXED-LENGTH DATA RECORD FUNCTIONS | ||||||
| @@ -1748,6 +1922,9 @@ mbus_vib_unit_lookup(mbus_value_information_block *vib) | |||||||
|     static char buff[256]; |     static char buff[256]; | ||||||
|     int n; |     int n; | ||||||
|      |      | ||||||
|  |     if (vib == NULL) | ||||||
|  |         return ""; | ||||||
|  |  | ||||||
|     if (vib->vif == 0xFD || vib->vif == 0xFB) // first type of VIF extention: see table 8.4.4  |     if (vib->vif == 0xFD || vib->vif == 0xFB) // first type of VIF extention: see table 8.4.4  | ||||||
|     { |     { | ||||||
|         if (vib->nvife == 0) |         if (vib->nvife == 0) | ||||||
| @@ -2162,6 +2339,7 @@ mbus_data_record_function(mbus_data_record *record) | |||||||
|     return NULL; |     return NULL; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| /// | /// | ||||||
| /// For fixed-length frames, return a string describing the type of value (stored or actual) | /// For fixed-length frames, return a string describing the type of value (stored or actual) | ||||||
| /// | /// | ||||||
| @@ -2965,6 +3143,9 @@ mbus_hex_dump(const char *label, const char *buff, size_t len) | |||||||
|     char timestamp[21]; |     char timestamp[21]; | ||||||
|     size_t i; |     size_t i; | ||||||
|      |      | ||||||
|  |     if (label == NULL || buff == NULL) | ||||||
|  |         return; | ||||||
|  |      | ||||||
|     time ( &rawtime ); |     time ( &rawtime ); | ||||||
|     timeinfo = gmtime ( &rawtime ); |     timeinfo = gmtime ( &rawtime ); | ||||||
|      |      | ||||||
| @@ -3006,6 +3187,9 @@ mbus_str_xml_encode(u_char *dst, const u_char *src, size_t max_len) | |||||||
|     i = 0; |     i = 0; | ||||||
|     len = 0; |     len = 0; | ||||||
|      |      | ||||||
|  |     if (dst == NULL) | ||||||
|  |         return; | ||||||
|  |      | ||||||
|     if (src != NULL) |     if (src != NULL) | ||||||
|     { |     { | ||||||
|         while((len+6) < max_len)  |         while((len+6) < max_len)  | ||||||
| @@ -3063,6 +3247,10 @@ mbus_data_variable_header_xml(mbus_data_variable_header *header) | |||||||
|                 mbus_decode_manufacturer(header->manufacturer[0], header->manufacturer[1]));                |                 mbus_decode_manufacturer(header->manufacturer[0], header->manufacturer[1]));                | ||||||
|         len += snprintf(&buff[len], sizeof(buff) - len, "        <Version>%d</Version>\n", header->version); |         len += snprintf(&buff[len], sizeof(buff) - len, "        <Version>%d</Version>\n", header->version); | ||||||
|          |          | ||||||
|  |         mbus_str_xml_encode(str_encoded, mbus_data_product_name(header), sizeof(str_encoded)); | ||||||
|  |          | ||||||
|  |         len += snprintf(&buff[len], sizeof(buff) - len, "        <ProductName>%s</ProductName>\n", str_encoded); | ||||||
|  |          | ||||||
|         mbus_str_xml_encode(str_encoded, mbus_data_variable_medium_lookup(header->medium), sizeof(str_encoded));  |         mbus_str_xml_encode(str_encoded, mbus_data_variable_medium_lookup(header->medium), sizeof(str_encoded));  | ||||||
|          |          | ||||||
|         len += snprintf(&buff[len], sizeof(buff) - len, "        <Medium>%s</Medium>\n", str_encoded); |         len += snprintf(&buff[len], sizeof(buff) - len, "        <Medium>%s</Medium>\n", str_encoded); | ||||||
|   | |||||||
| @@ -459,6 +459,25 @@ typedef struct _mbus_data_secondary_address { | |||||||
| #define MBUS_VARIABLE_DATA_MEDIUM_PRESSURE      0x18 | #define MBUS_VARIABLE_DATA_MEDIUM_PRESSURE      0x18 | ||||||
| #define MBUS_VARIABLE_DATA_MEDIUM_ADC           0x19 | #define MBUS_VARIABLE_DATA_MEDIUM_ADC           0x19 | ||||||
|  |  | ||||||
|  | #define MBUS_VARIABLE_DATA_MAN_ACW              0x0477 | ||||||
|  | #define MBUS_VARIABLE_DATA_MAN_ABB              0x0442 | ||||||
|  | #define MBUS_VARIABLE_DATA_MAN_AMT              0x05B4 | ||||||
|  | #define MBUS_VARIABLE_DATA_MAN_ELS              0x1593 | ||||||
|  | #define MBUS_VARIABLE_DATA_MAN_EMH              0x15A8 | ||||||
|  | #define MBUS_VARIABLE_DATA_MAN_HYD              0x2324 | ||||||
|  | #define MBUS_VARIABLE_DATA_MAN_KAM              0x2C2D | ||||||
|  | #define MBUS_VARIABLE_DATA_MAN_LSE              0x3265 | ||||||
|  | #define MBUS_VARIABLE_DATA_MAN_LUG              0x32A7 | ||||||
|  | #define MBUS_VARIABLE_DATA_MAN_NZR              0x3B52 | ||||||
|  | #define MBUS_VARIABLE_DATA_MAN_PAD              0x4024 | ||||||
|  | #define MBUS_VARIABLE_DATA_MAN_QDS              0x4493 | ||||||
|  | #define MBUS_VARIABLE_DATA_MAN_SLB              0x4D82 | ||||||
|  | #define MBUS_VARIABLE_DATA_MAN_SON              0x4DEE | ||||||
|  | #define MBUS_VARIABLE_DATA_MAN_SPX              0x4E18 | ||||||
|  | #define MBUS_VARIABLE_DATA_MAN_SVM              0x4ECD | ||||||
|  | #define MBUS_VARIABLE_DATA_MAN_TCM              0x5068 | ||||||
|  | #define MBUS_VARIABLE_DATA_MAN_ZRM              0x6A4D | ||||||
|  |  | ||||||
| // | // | ||||||
| // Event callback functions | // Event callback functions | ||||||
| // | // | ||||||
| @@ -564,6 +583,7 @@ void  mbus_hex_dump(const char *label, const char *buff, size_t len); | |||||||
| // | // | ||||||
| int mbus_data_manufacturer_encode(u_char *m_data, u_char *m_code); | int mbus_data_manufacturer_encode(u_char *m_data, u_char *m_code); | ||||||
| const char *mbus_decode_manufacturer(u_char byte1, u_char byte2); | const char *mbus_decode_manufacturer(u_char byte1, u_char byte2); | ||||||
|  | const char *mbus_data_product_name(mbus_data_variable_header *header); | ||||||
|   |   | ||||||
| int mbus_data_bcd_encode(u_char *bcd_data, size_t bcd_data_size, int value); | int mbus_data_bcd_encode(u_char *bcd_data, size_t bcd_data_size, int value); | ||||||
| int mbus_data_int_encode(u_char *int_data, size_t int_data_size, int value); | int mbus_data_int_encode(u_char *int_data, size_t int_data_size, int value); | ||||||
|   | |||||||
| @@ -57,7 +57,7 @@ mbus_serial_connect(char *device) | |||||||
|         return NULL; |         return NULL; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     bzero(&(handle->t), sizeof(handle->t)); |     memset(&(handle->t), 0, sizeof(handle->t)); | ||||||
|     handle->t.c_cflag |= (CS8|CREAD|CLOCAL); |     handle->t.c_cflag |= (CS8|CREAD|CLOCAL); | ||||||
|     handle->t.c_cflag |= PARENB; |     handle->t.c_cflag |= PARENB; | ||||||
|  |  | ||||||
| @@ -225,7 +225,13 @@ mbus_serial_recv_frame(mbus_serial_handle *handle, mbus_frame *frame) | |||||||
|     char buff[PACKET_BUFF_SIZE]; |     char buff[PACKET_BUFF_SIZE]; | ||||||
|     int len, remaining, nread; |     int len, remaining, nread; | ||||||
|      |      | ||||||
|     bzero((void *)buff, sizeof(buff)); |     if (handle == NULL || frame == NULL) | ||||||
|  |     { | ||||||
|  |         fprintf(stderr, "%s: Invalid parameter.\n", __PRETTY_FUNCTION__); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     memset((void *)buff, 0, sizeof(buff)); | ||||||
|  |  | ||||||
|     // |     // | ||||||
|     // read data until a packet is received |     // read data until a packet is received | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ | |||||||
| #include <netdb.h> | #include <netdb.h> | ||||||
|  |  | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  | #include <string.h> | ||||||
| #include <strings.h> | #include <strings.h> | ||||||
|  |  | ||||||
| #include <mbus/mbus.h> | #include <mbus/mbus.h> | ||||||
| @@ -78,7 +79,7 @@ mbus_tcp_connect(char *host, int port) | |||||||
|         return NULL; |         return NULL; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     bcopy((void *)(host_addr->h_addr), (void *)(&s.sin_addr), host_addr->h_length); |     memcpy((void *)(&s.sin_addr), (void *)(host_addr->h_addr), host_addr->h_length); | ||||||
|  |  | ||||||
|     if (connect(handle->sock, (struct sockaddr *)&s, sizeof(s)) < 0) |     if (connect(handle->sock, (struct sockaddr *)&s, sizeof(s)) < 0) | ||||||
|     { |     { | ||||||
| @@ -166,7 +167,13 @@ mbus_tcp_recv_frame(mbus_tcp_handle *handle, mbus_frame *frame) | |||||||
|     char buff[PACKET_BUFF_SIZE]; |     char buff[PACKET_BUFF_SIZE]; | ||||||
|     int len, remaining, nread; |     int len, remaining, nread; | ||||||
|      |      | ||||||
|     bzero((void *)buff, sizeof(buff)); |     if (handle == NULL || frame == NULL) | ||||||
|  |     { | ||||||
|  |         fprintf(stderr, "%s: Invalid parameter.\n", __PRETTY_FUNCTION__); | ||||||
|  |         return -1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     memset((void *)buff, 0, sizeof(buff)); | ||||||
|  |  | ||||||
|     // |     // | ||||||
|     // read data until a packet is received |     // read data until a packet is received | ||||||
|   | |||||||
| @@ -41,13 +41,13 @@ main(int argc, char *argv[]) | |||||||
|         return 1; |         return 1; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	bzero(buf, sizeof(buf)); | 	memset(buf, 0, sizeof(buf)); | ||||||
| 	len = read(fd, buf, sizeof(buf)); | 	len = read(fd, buf, sizeof(buf)); | ||||||
|  |  | ||||||
| 	close(fd); | 	close(fd); | ||||||
|  |  | ||||||
| 	bzero(&reply, sizeof(reply)); | 	memset(&reply, 0, sizeof(reply)); | ||||||
| 	bzero(&frame_data, sizeof(frame_data)); | 	memset(&frame_data, 0, sizeof(frame_data)); | ||||||
| 	mbus_parse(&reply, buf, len); | 	mbus_parse(&reply, buf, len); | ||||||
| 	mbus_frame_data_parse(&reply, &frame_data); | 	mbus_frame_data_parse(&reply, &frame_data); | ||||||
| 	mbus_frame_print(&reply); | 	mbus_frame_print(&reply); | ||||||
|   | |||||||
| @@ -41,7 +41,7 @@ main(int argc, char *argv[]) | |||||||
|         return 1; |         return 1; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	bzero(raw_buff, sizeof(raw_buff)); | 	memset(raw_buff, 0, sizeof(raw_buff)); | ||||||
| 	len = read(fd, raw_buff, sizeof(raw_buff)); | 	len = read(fd, raw_buff, sizeof(raw_buff)); | ||||||
| 	close(fd); | 	close(fd); | ||||||
|  |  | ||||||
| @@ -60,8 +60,8 @@ main(int argc, char *argv[]) | |||||||
|         i++; |         i++; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	bzero(&reply, sizeof(reply)); | 	memset(&reply, 0, sizeof(reply)); | ||||||
| 	bzero(&frame_data, sizeof(frame_data)); | 	memset(&frame_data, 0, sizeof(frame_data)); | ||||||
| 	 | 	 | ||||||
| 	//mbus_parse_set_debug(1); | 	//mbus_parse_set_debug(1); | ||||||
| 	 | 	 | ||||||
| @@ -89,8 +89,7 @@ main(int argc, char *argv[]) | |||||||
|      |      | ||||||
|     //mbus_frame_print(&reply); |     //mbus_frame_print(&reply); | ||||||
|     //mbus_frame_data_print(&frame_data); |     //mbus_frame_data_print(&frame_data); | ||||||
| 	printf("%s", mbus_frame_data_xml_normalized(&frame_data)); | 	printf("%s", mbus_frame_data_xml(&frame_data)); | ||||||
| 	// printf("%s", mbus_frame_data_xml(&frame_data)); |  | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Robert Johansson
					Robert Johansson