Skip to content

Commit ef3c4bc

Browse files
committed
Reduce memory use of TCP PI backend (closes #621)
- allocate exact memory required to store node and service strings instead of around 1kb of static memory. - accept NULL value of service to use default Modbus port number (502) - unit test updated The new documentation will be updated in another commit.
1 parent 9b679b7 commit ef3c4bc

File tree

3 files changed

+34
-44
lines changed

3 files changed

+34
-44
lines changed

src/modbus-tcp-private.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,15 @@ typedef struct _modbus_tcp {
2727
char ip[16];
2828
} modbus_tcp_t;
2929

30-
#define _MODBUS_TCP_PI_NODE_LENGTH 1025
31-
#define _MODBUS_TCP_PI_SERVICE_LENGTH 32
32-
3330
typedef struct _modbus_tcp_pi {
3431
/* Transaction ID */
3532
uint16_t t_id;
3633
/* TCP port */
3734
int port;
3835
/* Node */
39-
char node[_MODBUS_TCP_PI_NODE_LENGTH];
36+
char *node;
4037
/* Service */
41-
char service[_MODBUS_TCP_PI_SERVICE_LENGTH];
38+
char *service;
4239
} modbus_tcp_pi_t;
4340

4441
#endif /* MODBUS_TCP_PRIVATE_H */

src/modbus-tcp.c

Lines changed: 32 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -740,7 +740,20 @@ static int _modbus_tcp_select(modbus_t *ctx, fd_set *rset, struct timeval *tv, i
740740
}
741741

742742
static void _modbus_tcp_free(modbus_t *ctx) {
743-
free(ctx->backend_data);
743+
if (ctx->backend_data) {
744+
free(ctx->backend_data);
745+
}
746+
free(ctx);
747+
}
748+
749+
static void _modbus_tcp_pi_free(modbus_t *ctx) {
750+
if (ctx->backend_data) {
751+
modbus_tcp_pi_t *ctx_tcp_pi = ctx->backend_data;
752+
free(ctx_tcp_pi->node);
753+
free(ctx_tcp_pi->service);
754+
free(ctx->backend_data);
755+
}
756+
744757
free(ctx);
745758
}
746759

@@ -786,7 +799,7 @@ const modbus_backend_t _modbus_tcp_pi_backend = {
786799
_modbus_tcp_close,
787800
_modbus_tcp_flush,
788801
_modbus_tcp_select,
789-
_modbus_tcp_free
802+
_modbus_tcp_pi_free
790803
};
791804

792805
modbus_t* modbus_new_tcp(const char *ip, int port)
@@ -858,8 +871,6 @@ modbus_t* modbus_new_tcp_pi(const char *node, const char *service)
858871
{
859872
modbus_t *ctx;
860873
modbus_tcp_pi_t *ctx_tcp_pi;
861-
size_t dest_size;
862-
size_t ret_size;
863874

864875
ctx = (modbus_t *)malloc(sizeof(modbus_t));
865876
if (ctx == NULL) {
@@ -879,47 +890,32 @@ modbus_t* modbus_new_tcp_pi(const char *node, const char *service)
879890
return NULL;
880891
}
881892
ctx_tcp_pi = (modbus_tcp_pi_t *)ctx->backend_data;
893+
ctx_tcp_pi->node = NULL;
894+
ctx_tcp_pi->service = NULL;
882895

883-
if (node == NULL) {
884-
/* The node argument can be empty to indicate any hosts */
885-
ctx_tcp_pi->node[0] = 0;
886-
} else {
887-
dest_size = sizeof(char) * _MODBUS_TCP_PI_NODE_LENGTH;
888-
ret_size = strlcpy(ctx_tcp_pi->node, node, dest_size);
889-
if (ret_size == 0) {
890-
fprintf(stderr, "The node string is empty\n");
891-
modbus_free(ctx);
892-
errno = EINVAL;
893-
return NULL;
894-
}
895-
896-
if (ret_size >= dest_size) {
897-
fprintf(stderr, "The node string has been truncated\n");
898-
modbus_free(ctx);
899-
errno = EINVAL;
900-
return NULL;
901-
}
902-
}
903-
904-
if (service != NULL) {
905-
dest_size = sizeof(char) * _MODBUS_TCP_PI_SERVICE_LENGTH;
906-
ret_size = strlcpy(ctx_tcp_pi->service, service, dest_size);
896+
if (node != NULL) {
897+
ctx_tcp_pi->node = strdup(node);
907898
} else {
908-
/* Empty service is not allowed, error caught below. */
909-
ret_size = 0;
899+
/* The node argument can be empty to indicate any hosts */
900+
ctx_tcp_pi->node = strdup("");
910901
}
911902

912-
if (ret_size == 0) {
913-
fprintf(stderr, "The service string is empty\n");
903+
if (ctx_tcp_pi->node == NULL) {
914904
modbus_free(ctx);
915-
errno = EINVAL;
905+
errno = ENOMEM;
916906
return NULL;
917907
}
918908

919-
if (ret_size >= dest_size) {
920-
fprintf(stderr, "The service string has been truncated\n");
909+
if (service != NULL && service[0] != '\0') {
910+
ctx_tcp_pi->service = strdup(service);
911+
} else {
912+
/* Default Modbus port number */
913+
ctx_tcp_pi->service = strdup("502");
914+
}
915+
916+
if (ctx_tcp_pi->service == NULL) {
921917
modbus_free(ctx);
922-
errno = EINVAL;
918+
errno = ENOMEM;
923919
return NULL;
924920
}
925921

tests/unit-test-client.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -681,9 +681,6 @@ int main(int argc, char *argv[])
681681
ctx = modbus_new_rtu("/dev/dummy", 0, 'A', 0, 0);
682682
ASSERT_TRUE(ctx == NULL && errno == EINVAL, "");
683683

684-
ctx = modbus_new_tcp_pi(NULL, NULL);
685-
ASSERT_TRUE(ctx == NULL && errno == EINVAL, "");
686-
687684
printf("\nALL TESTS PASS WITH SUCCESS.\n");
688685
success = TRUE;
689686

0 commit comments

Comments
 (0)