modbus-private.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. * Copyright © Stéphane Raimbault <stephane.raimbault@gmail.com>
  3. *
  4. * SPDX-License-Identifier: LGPL-2.1-or-later
  5. */
  6. #ifndef MODBUS_PRIVATE_H
  7. #define MODBUS_PRIVATE_H
  8. // clang-format off
  9. #ifndef _MSC_VER
  10. # include <stdint.h>
  11. # include <sys/time.h>
  12. #else
  13. # include "stdint.h"
  14. # include <time.h>
  15. typedef int ssize_t;
  16. #endif
  17. // clang-format on
  18. #include <config.h>
  19. #include <sys/types.h>
  20. #include "modbus.h"
  21. MODBUS_BEGIN_DECLS
  22. /* It's not really the minimal length (the real one is report slave ID
  23. * in RTU (4 bytes)) but it's a convenient size to use in RTU or TCP
  24. * communications to read many values or write a single one.
  25. * Maximum between :
  26. * - HEADER_LENGTH_TCP (7) + function (1) + address (2) + number (2)
  27. * - HEADER_LENGTH_RTU (1) + function (1) + address (2) + number (2) + CRC (2)
  28. */
  29. #define _MIN_REQ_LENGTH 12
  30. #define _REPORT_SLAVE_ID 180
  31. #define _MODBUS_EXCEPTION_RSP_LENGTH 5
  32. /* Timeouts in microsecond (0.5 s) */
  33. #define _RESPONSE_TIMEOUT 500000
  34. #define _BYTE_TIMEOUT 500000
  35. typedef enum {
  36. _MODBUS_BACKEND_TYPE_RTU = 0,
  37. _MODBUS_BACKEND_TYPE_TCP
  38. } modbus_backend_type_t;
  39. /*
  40. * ---------- Request Indication ----------
  41. * | Client | ---------------------->| Server |
  42. * ---------- Confirmation Response ----------
  43. */
  44. typedef enum {
  45. /* Request message on the server side */
  46. MSG_INDICATION,
  47. /* Request message on the client side */
  48. MSG_CONFIRMATION
  49. } msg_type_t;
  50. /* This structure reduces the number of params in functions and so
  51. * optimizes the speed of execution (~ 37%). */
  52. typedef struct _sft {
  53. int slave;
  54. int function;
  55. int t_id;
  56. } sft_t;
  57. typedef struct _modbus_backend {
  58. unsigned int backend_type;
  59. unsigned int header_length;
  60. unsigned int checksum_length;
  61. unsigned int max_adu_length;
  62. int (*set_slave)(modbus_t *ctx, int slave);
  63. int (*build_request_basis)(
  64. modbus_t *ctx, int function, int addr, int nb, uint8_t *req);
  65. int (*build_response_basis)(sft_t *sft, uint8_t *rsp);
  66. int (*prepare_response_tid)(const uint8_t *req, int *req_length);
  67. int (*send_msg_pre)(uint8_t *req, int req_length);
  68. ssize_t (*send)(modbus_t *ctx, const uint8_t *req, int req_length);
  69. int (*receive)(modbus_t *ctx, uint8_t *req);
  70. ssize_t (*recv)(modbus_t *ctx, uint8_t *rsp, int rsp_length);
  71. int (*check_integrity)(modbus_t *ctx, uint8_t *msg, const int msg_length);
  72. int (*pre_check_confirmation)(modbus_t *ctx,
  73. const uint8_t *req,
  74. const uint8_t *rsp,
  75. int rsp_length);
  76. int (*connect)(modbus_t *ctx);
  77. unsigned int (*is_connected)(modbus_t *ctx);
  78. void (*close)(modbus_t *ctx);
  79. int (*flush)(modbus_t *ctx);
  80. int (*select)(modbus_t *ctx, fd_set *rset, struct timeval *tv, int msg_length);
  81. void (*free)(modbus_t *ctx);
  82. } modbus_backend_t;
  83. struct _modbus {
  84. /* Slave address */
  85. int slave;
  86. /* Socket or file descriptor */
  87. int s;
  88. int debug;
  89. int error_recovery;
  90. int quirks;
  91. struct timeval response_timeout;
  92. struct timeval byte_timeout;
  93. struct timeval indication_timeout;
  94. const modbus_backend_t *backend;
  95. void *backend_data;
  96. };
  97. void _modbus_init_common(modbus_t *ctx);
  98. void _error_print(modbus_t *ctx, const char *context);
  99. int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type);
  100. #ifndef HAVE_STRLCPY
  101. size_t strlcpy(char *dest, const char *src, size_t dest_size);
  102. #endif
  103. MODBUS_END_DECLS
  104. #endif /* MODBUS_PRIVATE_H */