modbusd
modbus master daemon
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
mb.h File Reference

modbus daemon API(Interface) More...

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <stdbool.h>
#include <modbus.h>
#include "uthash.h"
#include "log.h"
#include "json.h"
Include dependency graph for mb.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  mbtcp_key_s
 `structure key` for modbus tcp hash table More...
 
struct  mbtcp_handle_s
 hashable mbtcp handle type More...
 

Typedefs

typedef char *(* mbtcp_fc )(uint8_t fc, mbtcp_handle_s *handle, cJSON *req)
 Function pointer of modbus tcp function code. More...
 

Functions

char * set_modbus_success_resp_str_with_data (char *tid, cJSON *json_arr)
 Set modbusd success response string with data (i.e., read func) More...
 
char * set_modbus_success_resp_str (char *tid)
 Set modbusd success response string without data (i.e., write func) More...
 
char * set_modbus_fail_resp_str (char *tid, const char *reason)
 Set modbusd fail response string. More...
 
char * set_modbus_fail_resp_str_with_errno (char *tid, mbtcp_handle_s *handle, int errnum)
 Set modbusd fail response string with error number. More...
 
bool mbtcp_init_handle (mbtcp_handle_s **ptr_handle, char *ip, char *port)
 Init mbtcp handle (to hashtable) and try to connect. More...
 
bool mbtcp_get_handle (mbtcp_handle_s **ptr_handle, char *ip, char *port)
 Get mbtcp handle from hashtable. More...
 
void mbtcp_list_handles ()
 List all handles in mbtcp hash table. More...
 
bool mbtcp_do_connect (mbtcp_handle_s *handle, char **reason)
 Connect to mbtcp slave via mbtcp hashed handle. More...
 
bool mbtcp_get_connection_status (mbtcp_handle_s *handle)
 Get mbtcp handle's connection status. More...
 
char * mbtcp_cmd_hanlder (uint8_t fc, cJSON *req, mbtcp_fc ptr_handler)
 Generic mbtcp command handler. More...
 
char * mbtcp_set_response_timeout (char *tid, long timeout)
 Set mbtcp response timeout in usec. More...
 
char * mbtcp_get_response_timeout (char *tid)
 Get mbtcp response timeout. More...
 
char * mbtcp_read_bit_req_fn (uint8_t fc, mbtcp_handle_s *handle, cJSON *req)
 Help function. More...
 
char * mbtcp_read_reg_req_fn (uint8_t fc, mbtcp_handle_s *handle, cJSON *req)
 Help function. More...
 
char * mbtcp_single_write_req_fn (uint8_t fc, mbtcp_handle_s *handle, cJSON *req)
 Help function. More...
 
char * mbtcp_multi_write_req_fn (uint8_t fc, mbtcp_handle_s *handle, cJSON *req)
 Help function. More...
 

Detailed Description

modbus daemon API(Interface)

Author
Taka Wang

Typedef Documentation

typedef char*(* mbtcp_fc)(uint8_t fc, mbtcp_handle_s *handle, cJSON *req)

Function pointer of modbus tcp function code.

Function pointer to `modbus tcp function code request` for `generic command handle`.

Parameters
fcfunction code
handleMbtcp handle.
reqcJSON request object.
Returns
Modbus response string in JSON format.

Function Documentation

char* mbtcp_cmd_hanlder ( uint8_t  fc,
cJSON req,
mbtcp_fc  ptr_handler 
)

Generic mbtcp command handler.

Parameters
fcfunction code
reqcJSON request object.
ptr_handlerFunction pointer to modbus tcp fc handler.
Returns
Modbus response string in JSON format.

References BEGIN, mbtcp_handle_s::ctx, enable_syslog, json_get_char(), json_get_int(), LOG, and set_modbus_fail_resp_str().

Referenced by main().

221 {
223 
224  char * tid = json_get_char (req, "tid");
225  mbtcp_handle_s *handle = NULL;
226 
227  if (lazy_init_mbtcp_handle (&handle, req))
228  {
229  char * reason = NULL;
230  if (lazy_mbtcp_connect (handle, &reason))
231  {
232  // set slave id
233  int slave = json_get_int (req, "slave");
234  LOG (enable_syslog, "slave id: %d", slave);
235  modbus_set_slave (handle->ctx, slave);
236  return ptr_handler (fc, handle, req);
237  }
238  else
239  {
240  // [enhance]: get reason from modbus response
241  return set_modbus_fail_resp_str (tid, reason);
242  }
243  }
244  else
245  {
246  return set_modbus_fail_resp_str (tid, "Fail to init modbus tcp handle");
247  }
248 }
char * set_modbus_fail_resp_str(char *tid, const char *reason)
Set modbusd fail response string.
Definition: mb.c:41
modbus_t * ctx
is connect to modbus slave?
Definition: mb.h:46
#define BEGIN(flag)
Definition: log.h:48
char * json_get_char(cJSON *inJson, const char *key)
Get char string via key from cJSON object.
Definition: json.c:11
int enable_syslog
Definition: main.c:46
int json_get_int(cJSON *inJson, const char *key)
Get integer value via key from cJSON object.
Definition: json.c:16
hashable mbtcp handle type
Definition: mb.h:42
#define LOG(flag, fmt,...)
Definition: log.h:36

Here is the call graph for this function:

Here is the caller graph for this function:

bool mbtcp_do_connect ( mbtcp_handle_s handle,
char **  reason 
)

Connect to mbtcp slave via mbtcp hashed handle.

Parameters
handleMbtcp handle.
reasonFail reason string.
Returns
Success or not.

References BEGIN, mbtcp_handle_s::connected, mbtcp_handle_s::ctx, enable_syslog, ERR, mbtcp_key_s::ip, mbtcp_handle_s::key, LOG, and mbtcp_key_s::port.

Referenced by mbtcp_init_handle(), and test_init_tcp_handle_and_connect().

175 {
177 
178  if (handle != NULL)
179  {
180  if (modbus_connect (handle->ctx) == -1)
181  {
182  ERR (enable_syslog, "Connection failed: %s", modbus_strerror (errno));
183  handle->connected = false;
184  *reason = (char *) modbus_strerror (errno);
185  return false;
186  }
187  else
188  {
189  LOG (enable_syslog, "%s:%s connected", handle->key.ip, handle->key.port);
190  handle->connected = true;
191  return true;
192  }
193  }
194  else
195  {
196  ERR (enable_syslog, "NULL handle");
197  *reason = "NULL handle";
198  return false;
199  }
200 }
modbus_t * ctx
is connect to modbus slave?
Definition: mb.h:46
#define BEGIN(flag)
Definition: log.h:48
char port[50]
IP v4/v6 address or hostname.
Definition: mb.h:34
char ip[50]
Definition: mb.h:33
mbtcp_key_s key
Definition: mb.h:44
bool connected
key
Definition: mb.h:45
int enable_syslog
Definition: main.c:46
#define ERR(flag, fmt,...)
Definition: log.h:24
#define LOG(flag, fmt,...)
Definition: log.h:36

Here is the caller graph for this function:

bool mbtcp_get_connection_status ( mbtcp_handle_s handle)

Get mbtcp handle's connection status.

Parameters
handleMbtcp handle.
Returns
Success or not.

References BEGIN, mbtcp_handle_s::connected, enable_syslog, ERR, mbtcp_key_s::ip, mbtcp_handle_s::key, LOG, and mbtcp_key_s::port.

Referenced by test_init_tcp_handle_and_connect().

203 {
205 
206  if (handle != NULL)
207  {
208  LOG (enable_syslog, "%s:%s connected: %s", handle->key.ip,
209  handle->key.port,
210  handle->connected ? "true" : "false");
211  return handle->connected;
212  }
213  else
214  {
215  ERR (enable_syslog, "NULL handle");
216  return false;
217  }
218 }
#define BEGIN(flag)
Definition: log.h:48
char port[50]
IP v4/v6 address or hostname.
Definition: mb.h:34
char ip[50]
Definition: mb.h:33
mbtcp_key_s key
Definition: mb.h:44
bool connected
key
Definition: mb.h:45
int enable_syslog
Definition: main.c:46
#define ERR(flag, fmt,...)
Definition: log.h:24
#define LOG(flag, fmt,...)
Definition: log.h:36

Here is the caller graph for this function:

bool mbtcp_get_handle ( mbtcp_handle_s **  ptr_handle,
char *  ip,
char *  port 
)

Get mbtcp handle from hashtable.

Parameters
ptr_handlePointer to mbtcp handle.
ipIP address string.
portModbus TCP server port string or service name.
Returns
Success or not.

References BEGIN, enable_syslog, ERR, HASH_FIND, mbtcp_key_s::ip, mbtcp_handle_s::key, LOG, and mbtcp_key_s::port.

Referenced by test_init_tcp_handle_and_connect().

136 {
138 
139  mbtcp_handle_s query, *hash_ctx;
140  memset (&query, 0, sizeof (mbtcp_handle_s));
141  strcpy (query.key.ip, ip);
142  strcpy (query.key.port, port);
143  // get handle from hash table
144  HASH_FIND (hh, mbtcp_htable, &query.key, sizeof (mbtcp_key_s), hash_ctx);
145 
146  if (hash_ctx != NULL)
147  {
148  LOG (enable_syslog, "tcp server %s:%s found", hash_ctx->key.ip, hash_ctx->key.port);
149  // call by reference to `mbtcp handle address`
150  *ptr_handle = hash_ctx;
151  return true;
152  }
153  else
154  {
155  ERR (enable_syslog, "tcp server %s:%s not found", query.key.ip, query.key.port);
156  *ptr_handle = NULL;
157  return false; // not found
158  }
159 }
#define BEGIN(flag)
Definition: log.h:48
char port[50]
IP v4/v6 address or hostname.
Definition: mb.h:34
char ip[50]
Definition: mb.h:33
`structure key` for modbus tcp hash table
Definition: mb.h:31
mbtcp_key_s key
Definition: mb.h:44
int enable_syslog
Definition: main.c:46
#define ERR(flag, fmt,...)
Definition: log.h:24
#define HASH_FIND(hh, head, keyptr, keylen, out)
Definition: uthash.h:131
hashable mbtcp handle type
Definition: mb.h:42
#define LOG(flag, fmt,...)
Definition: log.h:36

Here is the caller graph for this function:

char* mbtcp_get_response_timeout ( char *  tid)

Get mbtcp response timeout.

Parameters
tidTransaction ID.
Returns
Modbus response string in JSON format.

References BEGIN, cJSON_AddNumberToObject, cJSON_AddStringToObject, cJSON_CreateObject(), cJSON_Delete(), cJSON_PrintUnformatted(), enable_syslog, END, LOG, and tcp_conn_timeout_usec.

Referenced by main().

271 {
273 
274  cJSON *resp_root;
275  resp_root = cJSON_CreateObject();
276  cJSON_AddStringToObject (resp_root, "tid", tid);
277  cJSON_AddNumberToObject (resp_root, "timeout", tcp_conn_timeout_usec);
278  cJSON_AddStringToObject (resp_root, "status", "ok");
279  char * resp_json_string = cJSON_PrintUnformatted (resp_root);
280  LOG (enable_syslog, "resp: %s", resp_json_string);
281 
282  // clean up
283  cJSON_Delete (resp_root);
284  END (enable_syslog);
285  return resp_json_string;
286 }
#define cJSON_AddStringToObject(object, name, s)
Definition: cJSON.h:149
#define BEGIN(flag)
Definition: log.h:48
#define cJSON_AddNumberToObject(object, name, n)
Definition: cJSON.h:148
cJSON * cJSON_CreateObject(void)
Definition: cJSON.c:708
char * cJSON_PrintUnformatted(cJSON *item)
Definition: cJSON.c:347
long tcp_conn_timeout_usec
Definition: mbtcp.c:14
#define END(flag)
Definition: log.h:60
void cJSON_Delete(cJSON *c)
Definition: cJSON.c:81
int enable_syslog
Definition: main.c:46
Definition: cJSON.h:47
#define LOG(flag, fmt,...)
Definition: log.h:36

Here is the call graph for this function:

Here is the caller graph for this function:

bool mbtcp_init_handle ( mbtcp_handle_s **  ptr_handle,
char *  ip,
char *  port 
)

Init mbtcp handle (to hashtable) and try to connect.

Parameters
ptr_handlePointer to mbtcp handle.
ipIP address string.
portModbus TCP server port string.
Returns
Success or not.

References BEGIN, mbtcp_handle_s::connected, mbtcp_handle_s::ctx, enable_syslog, ERR, HASH_ADD, mbtcp_key_s::ip, mbtcp_handle_s::key, LOG, mbtcp_do_connect(), mbtcp_key_s::port, and tcp_conn_timeout_usec.

Referenced by test_init_tcp_handle_and_connect().

90 {
92 
93  // create a mbtcp context
94  modbus_t *ctx = modbus_new_tcp_pi (ip, port);
95 
96  if (ctx == NULL)
97  {
98  ERR (enable_syslog, "Unable to allocate mbtcp context");
99  return false; // fail to allocate context
100  }
101 
102  // set tcp connection timeout
103  modbus_set_response_timeout (ctx, 0, tcp_conn_timeout_usec);
104  LOG (enable_syslog, "set response timeout: %ld", tcp_conn_timeout_usec);
105 
106  // @add context to mbtcp hashtable
107  mbtcp_handle_s *handle = (mbtcp_handle_s*) malloc (sizeof (mbtcp_handle_s));
108  if (handle != NULL)
109  {
110  // let alignment bytes being set to zero-value!!
111  memset (handle, 0, sizeof (mbtcp_handle_s));
112  handle->connected = false;
113  strcpy (handle->key.ip, ip);
114  strcpy (handle->key.port, port);
115  handle->ctx = ctx;
116 
117  HASH_ADD(hh, mbtcp_htable, key, sizeof (mbtcp_key_s), handle);
118  LOG (enable_syslog, "Add %s: %s to mbtcp hashtable", handle->key.ip, mbtcp_htable->key.port);
119 
120  // call by reference to `mbtcp handle address`
121  *ptr_handle = handle;
122 
123  // @connect to server
124  char * reason = NULL;
125  mbtcp_do_connect (handle, &reason);
126  return true;
127  }
128  else
129  {
130  ERR (enable_syslog, "Unable to allocate mbtcp handle");
131  return false;
132  }
133 }
modbus_t * ctx
is connect to modbus slave?
Definition: mb.h:46
bool mbtcp_do_connect(mbtcp_handle_s *handle, char **reason)
Connect to mbtcp slave via mbtcp hashed handle.
Definition: mbtcp.c:174
void * key
Definition: uthash.h:1069
#define BEGIN(flag)
Definition: log.h:48
char port[50]
IP v4/v6 address or hostname.
Definition: mb.h:34
char ip[50]
Definition: mb.h:33
`structure key` for modbus tcp hash table
Definition: mb.h:31
long tcp_conn_timeout_usec
Definition: mbtcp.c:14
mbtcp_key_s key
Definition: mb.h:44
bool connected
key
Definition: mb.h:45
int enable_syslog
Definition: main.c:46
#define ERR(flag, fmt,...)
Definition: log.h:24
#define HASH_ADD(hh, head, fieldname, keylen_in, add)
Definition: uthash.h:317
hashable mbtcp handle type
Definition: mb.h:42
#define LOG(flag, fmt,...)
Definition: log.h:36

Here is the call graph for this function:

Here is the caller graph for this function:

void mbtcp_list_handles ( )

List all handles in mbtcp hash table.

Returns
Void.

References BEGIN, enable_syslog, END, mbtcp_handle_s::hh, mbtcp_key_s::ip, mbtcp_handle_s::key, LOG, UT_hash_handle::next, and mbtcp_key_s::port.

162 {
164 
165  mbtcp_handle_s * handle;
166  for (handle = mbtcp_htable; handle != NULL; handle = handle->hh.next)
167  {
168  LOG (enable_syslog, "ip:%s, port:%s", handle->key.ip, handle->key.port);
169  }
170 
171  END (enable_syslog);
172 }
#define BEGIN(flag)
Definition: log.h:48
char port[50]
IP v4/v6 address or hostname.
Definition: mb.h:34
char ip[50]
Definition: mb.h:33
#define END(flag)
Definition: log.h:60
mbtcp_key_s key
Definition: mb.h:44
int enable_syslog
Definition: main.c:46
void * next
Definition: uthash.h:1066
hashable mbtcp handle type
Definition: mb.h:42
UT_hash_handle hh
modbus context pointer
Definition: mb.h:47
#define LOG(flag, fmt,...)
Definition: log.h:36
char* mbtcp_multi_write_req_fn ( uint8_t  fc,
mbtcp_handle_s handle,
cJSON req 
)

Help function.

FC15, FC16 request handler

Function code 15 and 16 only.

Parameters
handleMbtcp handle.
reqcJSON request object.
Returns
Modbus response string in JSON format.

References BEGIN, cJSON_GetArrayItem(), cJSON_GetArraySize(), cJSON_GetObjectItem(), mbtcp_handle_s::ctx, enable_syslog, json_get_char(), json_get_int(), LOG, set_modbus_fail_resp_str(), set_modbus_fail_resp_str_with_errno(), set_modbus_success_resp_str(), and cJSON::valueint.

Referenced by main().

418 {
420 
421  int addr = json_get_int (req, "addr");
422  int len = json_get_int (req, "len");
423  char * tid = json_get_char (req, "tid");
424  cJSON * data = NULL;
425  int ret = 0;
426  uint8_t bits[len]; // FC15, VLAs
427  uint16_t regs[len]; // FC16, VLAs
428 
429  switch (fc)
430  {
431  case 15:
432  data = cJSON_GetObjectItem (req, "data");
433  for (int i = 0 ; i < cJSON_GetArraySize (data) ; i++)
434  {
435  uint8_t subitem = cJSON_GetArrayItem (data, i)->valueint;
436  bits[i] = subitem;
437  LOG(enable_syslog, "[%d]=%d", i, bits[i]);
438  }
439  ret = modbus_write_bits (handle->ctx, addr, len, bits);
440  break;
441 
442  case 16:
443  data = cJSON_GetObjectItem (req, "data");
444  for (int i = 0 ; i < cJSON_GetArraySize (data) ; i++)
445  {
446  uint16_t subitem = cJSON_GetArrayItem (data, i)->valueint;
447  regs[i] = subitem;
448  LOG(enable_syslog, "[%d]=%d", i, regs[i]);
449  }
450  ret = modbus_write_registers (handle->ctx, addr, len, regs);
451  break;
452 
453  default:
454  return set_modbus_fail_resp_str (tid, "Invalid function code");
455  }
456 
457  if (ret < 0)
458  {
459  return set_modbus_fail_resp_str_with_errno (tid, handle, errno);
460  }
461  else
462  {
463  return set_modbus_success_resp_str (tid);
464  }
465 }
char * set_modbus_fail_resp_str(char *tid, const char *reason)
Set modbusd fail response string.
Definition: mb.c:41
modbus_t * ctx
is connect to modbus slave?
Definition: mb.h:46
cJSON * cJSON_GetObjectItem(cJSON *object, const char *string)
Definition: cJSON.c:666
#define BEGIN(flag)
Definition: log.h:48
int valueint
Definition: cJSON.h:57
char * set_modbus_fail_resp_str_with_errno(char *tid, mbtcp_handle_s *handle, int errnum)
Set modbusd fail response string with error number.
Definition: mb.c:59
char * set_modbus_success_resp_str(char *tid)
Set modbusd success response string without data (i.e., write func)
Definition: mb.c:36
char * json_get_char(cJSON *inJson, const char *key)
Get char string via key from cJSON object.
Definition: json.c:11
int enable_syslog
Definition: main.c:46
cJSON * cJSON_GetArrayItem(cJSON *array, int item)
Definition: cJSON.c:665
int cJSON_GetArraySize(cJSON *array)
Definition: cJSON.c:664
int json_get_int(cJSON *inJson, const char *key)
Get integer value via key from cJSON object.
Definition: json.c:16
unsigned char uint8_t
Definition: uthash.h:78
Definition: cJSON.h:47
#define LOG(flag, fmt,...)
Definition: log.h:36

Here is the call graph for this function:

Here is the caller graph for this function:

char* mbtcp_read_bit_req_fn ( uint8_t  fc,
mbtcp_handle_s handle,
cJSON req 
)

Help function.

FC1, FC2 request handler

Function code 1 and 2 only.

Parameters
handleMbtcp handle.
reqcJSON request object.
Returns
Modbus response string in JSON format.

References BEGIN, cJSON_CreateUInt8Array(), mbtcp_handle_s::ctx, enable_syslog, json_get_char(), json_get_int(), LOG, set_modbus_fail_resp_str(), set_modbus_fail_resp_str_with_errno(), and set_modbus_success_resp_str_with_data().

Referenced by main().

289 {
291 
292  int addr = json_get_int (req, "addr");
293  int len = json_get_int (req, "len");
294  char *tid = json_get_char (req, "tid");
295  uint8_t bits[len];
296  int ret = 0;
297 
298  if (len > MODBUS_MAX_READ_BITS) // 2000
299  {
300  return set_modbus_fail_resp_str (tid, "Too many bits requested");
301  }
302  else
303  {
304  switch (fc)
305  {
306  case 1:
307  ret = modbus_read_bits (handle->ctx, addr, len, bits);
308  break;
309  case 2:
310  ret = modbus_read_input_bits (handle->ctx, addr, len, bits);
311  break;
312  default:
313  return set_modbus_fail_resp_str (tid, "Invalid function code");
314  }
315 
316  if (ret < 0)
317  {
318  return set_modbus_fail_resp_str_with_errno (tid, handle, errno);
319  }
320  else
321  {
322  LOG (enable_syslog, "fc:%d, desired length: %d, read length:%d", fc, len, ret);
323 
324  /* debug only
325  for (int ii = 0; ii < ret; ii++)
326  {
327  LOG (enable_syslog, "[%d]=%d", ii, bits[ii]);
328  }
329  */
330 
331  // uint8_t array
333  }
334  }
335 }
char * set_modbus_fail_resp_str(char *tid, const char *reason)
Set modbusd fail response string.
Definition: mb.c:41
modbus_t * ctx
is connect to modbus slave?
Definition: mb.h:46
#define BEGIN(flag)
Definition: log.h:48
char * set_modbus_fail_resp_str_with_errno(char *tid, mbtcp_handle_s *handle, int errnum)
Set modbusd fail response string with error number.
Definition: mb.c:59
char * json_get_char(cJSON *inJson, const char *key)
Get char string via key from cJSON object.
Definition: json.c:11
char * set_modbus_success_resp_str_with_data(char *tid, cJSON *json_arr)
Set modbusd success response string with data (i.e., read func)
Definition: mb.c:15
cJSON * cJSON_CreateUInt8Array(const uint8_t *numbers, int count)
Definition: cJSON.c:712
int enable_syslog
Definition: main.c:46
int json_get_int(cJSON *inJson, const char *key)
Get integer value via key from cJSON object.
Definition: json.c:16
unsigned char uint8_t
Definition: uthash.h:78
#define LOG(flag, fmt,...)
Definition: log.h:36

Here is the call graph for this function:

Here is the caller graph for this function:

char* mbtcp_read_reg_req_fn ( uint8_t  fc,
mbtcp_handle_s handle,
cJSON req 
)

Help function.

FC3, FC4 request handler

Function code 3 and 4 only.

Parameters
handleMbtcp handle.
reqcJSON request object.
Returns
Modbus response string in JSON format.

References BEGIN, cJSON_CreateUInt16Array(), mbtcp_handle_s::ctx, enable_syslog, json_get_char(), json_get_int(), LOG, set_modbus_fail_resp_str(), set_modbus_fail_resp_str_with_errno(), and set_modbus_success_resp_str_with_data().

Referenced by main().

338 {
340 
341  int addr = json_get_int (req, "addr");
342  int len = json_get_int (req, "len");
343  char * tid = json_get_char (req, "tid");
344  uint16_t regs[len];
345  int ret = 0;
346 
347  if (len > MODBUS_MAX_READ_REGISTERS) // 125
348  {
349  return set_modbus_fail_resp_str (tid, "Too many registers requested");
350  }
351  else
352  {
353  switch (fc)
354  {
355  case 3:
356  ret = modbus_read_registers (handle->ctx, addr, len, regs);
357  break;
358  case 4:
359  ret = modbus_read_input_registers (handle->ctx, addr, len, regs);
360  break;
361  default:
362  return set_modbus_fail_resp_str (tid, "Invalid function code");
363  }
364 
365  if (ret < 0)
366  {
367  return set_modbus_fail_resp_str_with_errno (tid, handle, errno);
368  }
369  else
370  {
371  LOG (enable_syslog, "fc:%d, desired length: %d, read length:%d", fc, len, ret);
372 
373  /* debug only
374  for (int ii = 0; ii < ret; ii++)
375  {
376  LOG (enable_syslog, "[%d]=%d", ii, regs[ii]);
377  }
378  */
379 
380  // uint16_t array
382  }
383  }
384 }
char * set_modbus_fail_resp_str(char *tid, const char *reason)
Set modbusd fail response string.
Definition: mb.c:41
modbus_t * ctx
is connect to modbus slave?
Definition: mb.h:46
#define BEGIN(flag)
Definition: log.h:48
char * set_modbus_fail_resp_str_with_errno(char *tid, mbtcp_handle_s *handle, int errnum)
Set modbusd fail response string with error number.
Definition: mb.c:59
char * json_get_char(cJSON *inJson, const char *key)
Get char string via key from cJSON object.
Definition: json.c:11
char * set_modbus_success_resp_str_with_data(char *tid, cJSON *json_arr)
Set modbusd success response string with data (i.e., read func)
Definition: mb.c:15
cJSON * cJSON_CreateUInt16Array(const uint16_t *numbers, int count)
Definition: cJSON.c:713
int enable_syslog
Definition: main.c:46
int json_get_int(cJSON *inJson, const char *key)
Get integer value via key from cJSON object.
Definition: json.c:16
#define LOG(flag, fmt,...)
Definition: log.h:36

Here is the call graph for this function:

Here is the caller graph for this function:

char* mbtcp_set_response_timeout ( char *  tid,
long  timeout 
)

Set mbtcp response timeout in usec.

Parameters
tidTransaction ID.
timeoutTimeout in usec.
Returns
Modbus response string in JSON format.

References BEGIN, cJSON_AddStringToObject, cJSON_CreateObject(), cJSON_Delete(), cJSON_PrintUnformatted(), enable_syslog, END, LOG, and tcp_conn_timeout_usec.

Referenced by main().

251 {
253 
254  // set timeout
255  tcp_conn_timeout_usec = timeout;
256 
257  cJSON *resp_root;
258  resp_root = cJSON_CreateObject ();
259  cJSON_AddStringToObject (resp_root, "tid", tid);
260  cJSON_AddStringToObject (resp_root, "status", "ok");
261  char * resp_json_string = cJSON_PrintUnformatted (resp_root);
262  LOG (enable_syslog, "resp: %s", resp_json_string);
263 
264  // clean up
265  cJSON_Delete (resp_root);
266  END (enable_syslog);
267  return resp_json_string;
268 }
#define cJSON_AddStringToObject(object, name, s)
Definition: cJSON.h:149
#define BEGIN(flag)
Definition: log.h:48
cJSON * cJSON_CreateObject(void)
Definition: cJSON.c:708
char * cJSON_PrintUnformatted(cJSON *item)
Definition: cJSON.c:347
long tcp_conn_timeout_usec
Definition: mbtcp.c:14
#define END(flag)
Definition: log.h:60
void cJSON_Delete(cJSON *c)
Definition: cJSON.c:81
int enable_syslog
Definition: main.c:46
Definition: cJSON.h:47
#define LOG(flag, fmt,...)
Definition: log.h:36

Here is the call graph for this function:

Here is the caller graph for this function:

char* mbtcp_single_write_req_fn ( uint8_t  fc,
mbtcp_handle_s handle,
cJSON req 
)

Help function.

FC5, FC6 request handler

Function code 5 and 6 only.

Parameters
handleMbtcp handle.
reqcJSON request object.
Returns
Modbus response string in JSON format.

References BEGIN, mbtcp_handle_s::ctx, enable_syslog, json_get_char(), json_get_int(), set_modbus_fail_resp_str(), set_modbus_fail_resp_str_with_errno(), and set_modbus_success_resp_str().

Referenced by main().

387 {
389 
390  int addr = json_get_int (req, "addr");
391  char * tid = json_get_char (req, "tid");
392  int data = json_get_int (req, "data");
393  int ret = 0;
394 
395  switch (fc)
396  {
397  case 5:
398  ret = modbus_write_bit (handle->ctx, addr, data);
399  break;
400  case 6:
401  ret = modbus_write_register (handle->ctx, addr, data);
402  break;
403  default:
404  return set_modbus_fail_resp_str (tid, "Invalid function code");
405  }
406 
407  if (ret < 0)
408  {
409  return set_modbus_fail_resp_str_with_errno (tid, handle, errno);
410  }
411  else
412  {
413  return set_modbus_success_resp_str (tid);
414  }
415 }
char * set_modbus_fail_resp_str(char *tid, const char *reason)
Set modbusd fail response string.
Definition: mb.c:41
modbus_t * ctx
is connect to modbus slave?
Definition: mb.h:46
#define BEGIN(flag)
Definition: log.h:48
char * set_modbus_fail_resp_str_with_errno(char *tid, mbtcp_handle_s *handle, int errnum)
Set modbusd fail response string with error number.
Definition: mb.c:59
char * set_modbus_success_resp_str(char *tid)
Set modbusd success response string without data (i.e., write func)
Definition: mb.c:36
char * json_get_char(cJSON *inJson, const char *key)
Get char string via key from cJSON object.
Definition: json.c:11
int enable_syslog
Definition: main.c:46
int json_get_int(cJSON *inJson, const char *key)
Get integer value via key from cJSON object.
Definition: json.c:16

Here is the call graph for this function:

Here is the caller graph for this function:

char* set_modbus_fail_resp_str ( char *  tid,
const char *  reason 
)

Set modbusd fail response string.

Parameters
tidTransaction ID.
reasonFail reason string.
Returns
Modbus response string in JSON format.

References BEGIN, cJSON_AddStringToObject, cJSON_CreateObject(), cJSON_Delete(), cJSON_PrintUnformatted(), enable_syslog, ERR, and LOG.

Referenced by main(), mbtcp_cmd_hanlder(), mbtcp_multi_write_req_fn(), mbtcp_read_bit_req_fn(), mbtcp_read_reg_req_fn(), mbtcp_single_write_req_fn(), and set_modbus_fail_resp_str_with_errno().

42 {
44 
45  ERR (enable_syslog, "Fail: %s", reason);
46 
47  cJSON *resp_root;
48  resp_root = cJSON_CreateObject ();
49  cJSON_AddStringToObject (resp_root, "tid", tid);
50  cJSON_AddStringToObject (resp_root, "status", reason);
51 
52  char * resp_json_string = cJSON_PrintUnformatted (resp_root);
53  LOG(enable_syslog, "resp: %s", resp_json_string);
54  // clean up
55  cJSON_Delete (resp_root);
56  return resp_json_string;
57 }
#define cJSON_AddStringToObject(object, name, s)
Definition: cJSON.h:149
#define BEGIN(flag)
Definition: log.h:48
cJSON * cJSON_CreateObject(void)
Definition: cJSON.c:708
char * cJSON_PrintUnformatted(cJSON *item)
Definition: cJSON.c:347
int enable_syslog
Definition: main.c:46
void cJSON_Delete(cJSON *c)
Definition: cJSON.c:81
#define ERR(flag, fmt,...)
Definition: log.h:24
Definition: cJSON.h:47
#define LOG(flag, fmt,...)
Definition: log.h:36

Here is the call graph for this function:

Here is the caller graph for this function:

char* set_modbus_fail_resp_str_with_errno ( char *  tid,
mbtcp_handle_s handle,
int  errnum 
)

Set modbusd fail response string with error number.

Parameters
tidTransaction ID.
handleMbtcp handle.
errnumError number from modbus tcp handle.
Returns
Modbus error response string in JSON format.

References BEGIN, mbtcp_handle_s::connected, enable_syslog, ERR, and set_modbus_fail_resp_str().

Referenced by mbtcp_multi_write_req_fn(), mbtcp_read_bit_req_fn(), mbtcp_read_reg_req_fn(), and mbtcp_single_write_req_fn().

60 {
62 
63  // [TODO][enhance] reconnect proactively?
64  // ... if the request interval is very large,
65  // we should try to reconnect automatically
66 
67  if (errnum == 104) // Connection reset by peer (i.e, tcp connection timeout)
68  {
69  handle->connected = false;
70  }
71 
72  ERR (enable_syslog, "%s:%d", modbus_strerror (errnum), errnum);
73  return set_modbus_fail_resp_str (tid, modbus_strerror (errnum));
74 }
char * set_modbus_fail_resp_str(char *tid, const char *reason)
Set modbusd fail response string.
Definition: mb.c:41
#define BEGIN(flag)
Definition: log.h:48
int enable_syslog
Definition: main.c:46
bool connected
key
Definition: mb.h:45
#define ERR(flag, fmt,...)
Definition: log.h:24

Here is the call graph for this function:

Here is the caller graph for this function:

char* set_modbus_success_resp_str ( char *  tid)

Set modbusd success response string without data (i.e., write func)

Parameters
tidTransaction ID.
Returns
Modbus ok response string in JSON format.

References set_modbus_success_resp_str_with_data().

Referenced by mbtcp_multi_write_req_fn(), and mbtcp_single_write_req_fn().

37 {
38  return set_modbus_success_resp_str_with_data (tid, NULL);
39 }
char * set_modbus_success_resp_str_with_data(char *tid, cJSON *json_arr)
Set modbusd success response string with data (i.e., read func)
Definition: mb.c:15

Here is the call graph for this function:

Here is the caller graph for this function:

char* set_modbus_success_resp_str_with_data ( char *  tid,
cJSON json_arr 
)

Set modbusd success response string with data (i.e., read func)

Parameters
tidTransaction ID.
json_arrcJSON pointer to data array
Returns
Modbus ok response string in JSON format.

References BEGIN, cJSON_AddItemToObject(), cJSON_AddStringToObject, cJSON_CreateObject(), cJSON_Delete(), cJSON_PrintUnformatted(), enable_syslog, and LOG.

Referenced by mbtcp_read_bit_req_fn(), mbtcp_read_reg_req_fn(), and set_modbus_success_resp_str().

16 {
18 
19  cJSON *resp_root;
20  resp_root = cJSON_CreateObject ();
21  cJSON_AddStringToObject (resp_root, "tid", tid);
22 
23  if (json_arr != NULL)
24  {
25  cJSON_AddItemToObject (resp_root, "data", json_arr);
26  }
27  cJSON_AddStringToObject (resp_root, "status", "ok");
28 
29  char * resp_json_str = cJSON_PrintUnformatted (resp_root);
30  LOG (enable_syslog, "resp: %s", resp_json_str);
31  // clean up
32  cJSON_Delete (resp_root);
33  return resp_json_str;
34 }
#define cJSON_AddStringToObject(object, name, s)
Definition: cJSON.h:149
void cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item)
Definition: cJSON.c:676
#define BEGIN(flag)
Definition: log.h:48
cJSON * cJSON_CreateObject(void)
Definition: cJSON.c:708
char * cJSON_PrintUnformatted(cJSON *item)
Definition: cJSON.c:347
int enable_syslog
Definition: main.c:46
void cJSON_Delete(cJSON *c)
Definition: cJSON.c:81
Definition: cJSON.h:47
#define LOG(flag, fmt,...)
Definition: log.h:36

Here is the call graph for this function:

Here is the caller graph for this function: