unit-test-client.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  1. /*
  2. * Copyright © 2008-2010 Stéphane Raimbault <stephane.raimbault@gmail.com>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include <stdio.h>
  18. #include <unistd.h>
  19. #include <string.h>
  20. #include <stdlib.h>
  21. #include <errno.h>
  22. #include <modbus.h>
  23. #include "unit-test.h"
  24. enum {
  25. TCP,
  26. TCP_PI,
  27. RTU
  28. };
  29. int main(int argc, char *argv[])
  30. {
  31. uint8_t *tab_rp_bits;
  32. uint16_t *tab_rp_registers;
  33. uint16_t *tab_rp_registers_bad;
  34. modbus_t *ctx;
  35. int i;
  36. uint8_t value;
  37. int address;
  38. int nb_points;
  39. int rc;
  40. float real;
  41. struct timeval timeout_begin_old;
  42. struct timeval timeout_begin_new;
  43. int use_backend;
  44. if (argc > 1) {
  45. if (strcmp(argv[1], "tcp") == 0) {
  46. use_backend = TCP;
  47. } else if (strcmp(argv[1], "tcppi") == 0) {
  48. use_backend = TCP_PI;
  49. } else if (strcmp(argv[1], "rtu") == 0) {
  50. use_backend = RTU;
  51. } else {
  52. printf("Usage:\n %s [tcp|tcppi|rtu] - Modbus client for unit testing\n\n", argv[0]);
  53. exit(1);
  54. }
  55. } else {
  56. /* By default */
  57. use_backend = TCP;
  58. }
  59. if (use_backend == TCP) {
  60. ctx = modbus_new_tcp("127.0.0.1", 1502);
  61. } else if (use_backend == TCP_PI) {
  62. ctx = modbus_new_tcp_pi("::1", "1502");
  63. } else {
  64. ctx = modbus_new_rtu("/dev/ttyUSB1", 115200, 'N', 8, 1);
  65. }
  66. if (ctx == NULL) {
  67. fprintf(stderr, "Unable to allocate libmodbus context\n");
  68. return -1;
  69. }
  70. modbus_set_debug(ctx, TRUE);
  71. if (use_backend == RTU) {
  72. modbus_set_slave(ctx, SERVER_ID);
  73. }
  74. if (modbus_connect(ctx) == -1) {
  75. fprintf(stderr, "Connection failed: %s\n",
  76. modbus_strerror(errno));
  77. modbus_free(ctx);
  78. return -1;
  79. }
  80. /* Allocate and initialize the memory to store the bits */
  81. nb_points = (UT_BITS_NB_POINTS > UT_INPUT_BITS_NB_POINTS) ?
  82. UT_BITS_NB_POINTS : UT_INPUT_BITS_NB_POINTS;
  83. tab_rp_bits = (uint8_t *) malloc(nb_points * sizeof(uint8_t));
  84. memset(tab_rp_bits, 0, nb_points * sizeof(uint8_t));
  85. /* Allocate and initialize the memory to store the registers */
  86. nb_points = (UT_REGISTERS_NB_POINTS >
  87. UT_INPUT_REGISTERS_NB_POINTS) ?
  88. UT_REGISTERS_NB_POINTS : UT_INPUT_REGISTERS_NB_POINTS;
  89. tab_rp_registers = (uint16_t *) malloc(nb_points * sizeof(uint16_t));
  90. memset(tab_rp_registers, 0, nb_points * sizeof(uint16_t));
  91. printf("** UNIT TESTING **\n");
  92. printf("\nTEST WRITE/READ:\n");
  93. /** COIL BITS **/
  94. /* Single */
  95. rc = modbus_write_bit(ctx, UT_BITS_ADDRESS, ON);
  96. printf("1/2 modbus_write_bit: ");
  97. if (rc == 1) {
  98. printf("OK\n");
  99. } else {
  100. printf("FAILED\n");
  101. goto close;
  102. }
  103. rc = modbus_read_bits(ctx, UT_BITS_ADDRESS, 1, tab_rp_bits);
  104. printf("2/2 modbus_read_bits: ");
  105. if (rc != 1) {
  106. printf("FAILED (nb points %d)\n", rc);
  107. goto close;
  108. }
  109. if (tab_rp_bits[0] != ON) {
  110. printf("FAILED (%0X = != %0X)\n", tab_rp_bits[0], ON);
  111. goto close;
  112. }
  113. printf("OK\n");
  114. /* End single */
  115. /* Multiple bits */
  116. {
  117. uint8_t tab_value[UT_BITS_NB_POINTS];
  118. modbus_set_bits_from_bytes(tab_value, 0, UT_BITS_NB_POINTS,
  119. UT_BITS_TAB);
  120. rc = modbus_write_bits(ctx, UT_BITS_ADDRESS,
  121. UT_BITS_NB_POINTS, tab_value);
  122. printf("1/2 modbus_write_bits: ");
  123. if (rc == UT_BITS_NB_POINTS) {
  124. printf("OK\n");
  125. } else {
  126. printf("FAILED\n");
  127. goto close;
  128. }
  129. }
  130. rc = modbus_read_bits(ctx, UT_BITS_ADDRESS,
  131. UT_BITS_NB_POINTS, tab_rp_bits);
  132. printf("2/2 modbus_read_bits: ");
  133. if (rc != UT_BITS_NB_POINTS) {
  134. printf("FAILED (nb points %d)\n", rc);
  135. goto close;
  136. }
  137. i = 0;
  138. address = UT_BITS_ADDRESS;
  139. nb_points = UT_BITS_NB_POINTS;
  140. while (nb_points > 0) {
  141. int nb_bits = (nb_points > 8) ? 8 : nb_points;
  142. value = modbus_get_byte_from_bits(tab_rp_bits, i*8, nb_bits);
  143. if (value != UT_BITS_TAB[i]) {
  144. printf("FAILED (%0X != %0X)\n",
  145. value, UT_BITS_TAB[i]);
  146. goto close;
  147. }
  148. nb_points -= nb_bits;
  149. i++;
  150. }
  151. printf("OK\n");
  152. /* End of multiple bits */
  153. /** DISCRETE INPUTS **/
  154. rc = modbus_read_input_bits(ctx, UT_INPUT_BITS_ADDRESS,
  155. UT_INPUT_BITS_NB_POINTS, tab_rp_bits);
  156. printf("1/1 modbus_read_input_bits: ");
  157. if (rc != UT_INPUT_BITS_NB_POINTS) {
  158. printf("FAILED (nb points %d)\n", rc);
  159. goto close;
  160. }
  161. i = 0;
  162. address = UT_INPUT_BITS_ADDRESS;
  163. nb_points = UT_INPUT_BITS_NB_POINTS;
  164. while (nb_points > 0) {
  165. int nb_bits = (nb_points > 8) ? 8 : nb_points;
  166. value = modbus_get_byte_from_bits(tab_rp_bits, i*8, nb_bits);
  167. if (value != UT_INPUT_BITS_TAB[i]) {
  168. printf("FAILED (%0X != %0X)\n",
  169. value, UT_INPUT_BITS_TAB[i]);
  170. goto close;
  171. }
  172. nb_points -= nb_bits;
  173. i++;
  174. }
  175. printf("OK\n");
  176. /** HOLDING REGISTERS **/
  177. /* Single register */
  178. rc = modbus_write_register(ctx, UT_REGISTERS_ADDRESS, 0x1234);
  179. printf("1/2 modbus_write_register: ");
  180. if (rc == 1) {
  181. printf("OK\n");
  182. } else {
  183. printf("FAILED\n");
  184. goto close;
  185. }
  186. rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS,
  187. 1, tab_rp_registers);
  188. printf("2/2 modbus_read_registers: ");
  189. if (rc != 1) {
  190. printf("FAILED (nb points %d)\n", rc);
  191. goto close;
  192. }
  193. if (tab_rp_registers[0] != 0x1234) {
  194. printf("FAILED (%0X != %0X)\n",
  195. tab_rp_registers[0], 0x1234);
  196. goto close;
  197. }
  198. printf("OK\n");
  199. /* End of single register */
  200. /* Many registers */
  201. rc = modbus_write_registers(ctx, UT_REGISTERS_ADDRESS,
  202. UT_REGISTERS_NB_POINTS,
  203. UT_REGISTERS_TAB);
  204. printf("1/5 modbus_write_registers: ");
  205. if (rc == UT_REGISTERS_NB_POINTS) {
  206. printf("OK\n");
  207. } else {
  208. printf("FAILED\n");
  209. goto close;
  210. }
  211. rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS,
  212. UT_REGISTERS_NB_POINTS,
  213. tab_rp_registers);
  214. printf("2/5 modbus_read_registers: ");
  215. if (rc != UT_REGISTERS_NB_POINTS) {
  216. printf("FAILED (nb points %d)\n", rc);
  217. goto close;
  218. }
  219. for (i=0; i < UT_REGISTERS_NB_POINTS; i++) {
  220. if (tab_rp_registers[i] != UT_REGISTERS_TAB[i]) {
  221. printf("FAILED (%0X != %0X)\n",
  222. tab_rp_registers[i],
  223. UT_REGISTERS_TAB[i]);
  224. goto close;
  225. }
  226. }
  227. printf("OK\n");
  228. rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS,
  229. 0, tab_rp_registers);
  230. printf("3/5 modbus_read_registers (0): ");
  231. if (rc != 0) {
  232. printf("FAILED (nb points %d)\n", rc);
  233. goto close;
  234. }
  235. printf("OK\n");
  236. nb_points = (UT_REGISTERS_NB_POINTS >
  237. UT_INPUT_REGISTERS_NB_POINTS) ?
  238. UT_REGISTERS_NB_POINTS : UT_INPUT_REGISTERS_NB_POINTS;
  239. memset(tab_rp_registers, 0, nb_points * sizeof(uint16_t));
  240. /* Write registers to zero from tab_rp_registers and store read registers
  241. into tab_rp_registers. So the read registers must set to 0, except the
  242. first one because there is an offset of 1 register on write. */
  243. rc = modbus_read_and_write_registers(ctx,
  244. UT_REGISTERS_ADDRESS,
  245. UT_REGISTERS_NB_POINTS,
  246. tab_rp_registers,
  247. UT_REGISTERS_ADDRESS + 1,
  248. UT_REGISTERS_NB_POINTS - 1,
  249. tab_rp_registers);
  250. printf("4/5 modbus_read_and_write_registers: ");
  251. if (rc != UT_REGISTERS_NB_POINTS) {
  252. printf("FAILED (nb points %d != %d)\n", rc, UT_REGISTERS_NB_POINTS);
  253. goto close;
  254. }
  255. if (tab_rp_registers[0] != UT_REGISTERS_TAB[0]) {
  256. printf("FAILED (%0X != %0X)\n",
  257. tab_rp_registers[0], UT_REGISTERS_TAB[0]);
  258. }
  259. for (i=1; i < UT_REGISTERS_NB_POINTS; i++) {
  260. if (tab_rp_registers[i] != 0) {
  261. printf("FAILED (%0X != %0X)\n",
  262. tab_rp_registers[i], 0);
  263. goto close;
  264. }
  265. }
  266. printf("OK\n");
  267. /* End of many registers */
  268. /** INPUT REGISTERS **/
  269. rc = modbus_read_input_registers(ctx, UT_INPUT_REGISTERS_ADDRESS,
  270. UT_INPUT_REGISTERS_NB_POINTS,
  271. tab_rp_registers);
  272. printf("1/1 modbus_read_input_registers: ");
  273. if (rc != UT_INPUT_REGISTERS_NB_POINTS) {
  274. printf("FAILED (nb points %d)\n", rc);
  275. goto close;
  276. }
  277. for (i=0; i < UT_INPUT_REGISTERS_NB_POINTS; i++) {
  278. if (tab_rp_registers[i] != UT_INPUT_REGISTERS_TAB[i]) {
  279. printf("FAILED (%0X != %0X)\n",
  280. tab_rp_registers[i], UT_INPUT_REGISTERS_TAB[i]);
  281. goto close;
  282. }
  283. }
  284. printf("OK\n");
  285. printf("\nTEST FLOATS\n");
  286. /** FLOAT **/
  287. printf("1/2 Set float: ");
  288. modbus_set_float(UT_REAL, tab_rp_registers);
  289. if (tab_rp_registers[1] == (UT_IREAL >> 16) &&
  290. tab_rp_registers[0] == (UT_IREAL & 0xFFFF)) {
  291. printf("OK\n");
  292. } else {
  293. printf("FAILED (%x != %x)\n",
  294. *((uint32_t *)tab_rp_registers), UT_IREAL);
  295. goto close;
  296. }
  297. printf("2/2 Get float: ");
  298. real = modbus_get_float(tab_rp_registers);
  299. if (real == UT_REAL) {
  300. printf("OK\n");
  301. } else {
  302. printf("FAILED (%f != %f)\n", real, UT_REAL);
  303. goto close;
  304. }
  305. printf("\nAt this point, error messages doesn't mean the test has failed\n");
  306. /** ILLEGAL DATA ADDRESS **/
  307. printf("\nTEST ILLEGAL DATA ADDRESS:\n");
  308. /* The mapping begins at 0 and ends at address + nb_points so
  309. * the addresses are not valid. */
  310. rc = modbus_read_bits(ctx, UT_BITS_ADDRESS,
  311. UT_BITS_NB_POINTS + 1,
  312. tab_rp_bits);
  313. printf("* modbus_read_bits: ");
  314. if (rc == -1 && errno == EMBXILADD) {
  315. printf("OK\n");
  316. } else {
  317. printf("FAILED\n");
  318. goto close;
  319. }
  320. rc = modbus_read_input_bits(ctx, UT_INPUT_BITS_ADDRESS,
  321. UT_INPUT_BITS_NB_POINTS + 1,
  322. tab_rp_bits);
  323. printf("* modbus_read_input_bits: ");
  324. if (rc == -1 && errno == EMBXILADD)
  325. printf("OK\n");
  326. else {
  327. printf("FAILED\n");
  328. goto close;
  329. }
  330. rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS,
  331. UT_REGISTERS_NB_POINTS + 1,
  332. tab_rp_registers);
  333. printf("* modbus_read_registers: ");
  334. if (rc == -1 && errno == EMBXILADD)
  335. printf("OK\n");
  336. else {
  337. printf("FAILED\n");
  338. goto close;
  339. }
  340. rc = modbus_read_input_registers(ctx, UT_INPUT_REGISTERS_ADDRESS,
  341. UT_INPUT_REGISTERS_NB_POINTS + 1,
  342. tab_rp_registers);
  343. printf("* modbus_read_input_registers: ");
  344. if (rc == -1 && errno == EMBXILADD)
  345. printf("OK\n");
  346. else {
  347. printf("FAILED\n");
  348. goto close;
  349. }
  350. rc = modbus_write_bit(ctx, UT_BITS_ADDRESS + UT_BITS_NB_POINTS, ON);
  351. printf("* modbus_write_bit: ");
  352. if (rc == -1 && errno == EMBXILADD) {
  353. printf("OK\n");
  354. } else {
  355. printf("FAILED\n");
  356. goto close;
  357. }
  358. rc = modbus_write_bits(ctx, UT_BITS_ADDRESS + UT_BITS_NB_POINTS,
  359. UT_BITS_NB_POINTS,
  360. tab_rp_bits);
  361. printf("* modbus_write_coils: ");
  362. if (rc == -1 && errno == EMBXILADD) {
  363. printf("OK\n");
  364. } else {
  365. printf("FAILED\n");
  366. goto close;
  367. }
  368. rc = modbus_write_registers(ctx, UT_REGISTERS_ADDRESS +
  369. UT_REGISTERS_NB_POINTS,
  370. UT_REGISTERS_NB_POINTS,
  371. tab_rp_registers);
  372. printf("* modbus_write_registers: ");
  373. if (rc == -1 && errno == EMBXILADD) {
  374. printf("OK\n");
  375. } else {
  376. printf("FAILED\n");
  377. goto close;
  378. }
  379. /** TOO MANY DATA **/
  380. printf("\nTEST TOO MANY DATA ERROR:\n");
  381. rc = modbus_read_bits(ctx, UT_BITS_ADDRESS, MODBUS_MAX_READ_BITS + 1,
  382. tab_rp_bits);
  383. printf("* modbus_read_bits: ");
  384. if (rc == -1 && errno == EMBMDATA) {
  385. printf("OK\n");
  386. } else {
  387. printf("FAILED\n");
  388. goto close;
  389. }
  390. rc = modbus_read_input_bits(ctx, UT_INPUT_BITS_ADDRESS,
  391. MODBUS_MAX_READ_BITS + 1,
  392. tab_rp_bits);
  393. printf("* modbus_read_input_bits: ");
  394. if (rc == -1 && errno == EMBMDATA) {
  395. printf("OK\n");
  396. } else {
  397. printf("FAILED\n");
  398. goto close;
  399. }
  400. rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS,
  401. MODBUS_MAX_READ_REGISTERS + 1,
  402. tab_rp_registers);
  403. printf("* modbus_read_registers: ");
  404. if (rc == -1 && errno == EMBMDATA) {
  405. printf("OK\n");
  406. } else {
  407. printf("FAILED\n");
  408. goto close;
  409. }
  410. rc = modbus_read_input_registers(ctx, UT_INPUT_REGISTERS_ADDRESS,
  411. MODBUS_MAX_READ_REGISTERS + 1,
  412. tab_rp_registers);
  413. printf("* modbus_read_input_registers: ");
  414. if (rc == -1 && errno == EMBMDATA) {
  415. printf("OK\n");
  416. } else {
  417. printf("FAILED\n");
  418. goto close;
  419. }
  420. rc = modbus_write_bits(ctx, UT_BITS_ADDRESS,
  421. MODBUS_MAX_WRITE_BITS + 1,
  422. tab_rp_bits);
  423. printf("* modbus_write_bits: ");
  424. if (rc == -1 && errno == EMBMDATA) {
  425. printf("OK\n");
  426. } else {
  427. goto close;
  428. printf("FAILED\n");
  429. }
  430. rc = modbus_write_registers(ctx, UT_REGISTERS_ADDRESS,
  431. MODBUS_MAX_WRITE_REGISTERS + 1,
  432. tab_rp_registers);
  433. printf("* modbus_write_registers: ");
  434. if (rc == -1 && errno == EMBMDATA) {
  435. printf("OK\n");
  436. } else {
  437. printf("FAILED\n");
  438. goto close;
  439. }
  440. /** SLAVE REPLY **/
  441. printf("\nTEST SLAVE REPLY:\n");
  442. modbus_set_slave(ctx, 18);
  443. rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS,
  444. UT_REGISTERS_NB_POINTS,
  445. tab_rp_registers);
  446. if (use_backend == RTU) {
  447. /* No response in RTU mode */
  448. printf("1/4 No response from slave %d: ", 18);
  449. if (rc == -1 && errno == ETIMEDOUT) {
  450. printf("OK\n");
  451. } else {
  452. printf("FAILED\n");
  453. goto close;
  454. }
  455. } else {
  456. /* Response in TCP mode */
  457. printf("1/4 Response from slave %d: ", 18);
  458. if (rc == UT_REGISTERS_NB_POINTS) {
  459. printf("OK\n");
  460. } else {
  461. printf("FAILED\n");
  462. goto close;
  463. }
  464. }
  465. rc = modbus_set_slave(ctx, MODBUS_BROADCAST_ADDRESS);
  466. if (rc == -1) {
  467. printf("Invalid broacast address\n");
  468. goto close;
  469. }
  470. rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS,
  471. UT_REGISTERS_NB_POINTS,
  472. tab_rp_registers);
  473. printf("2/4 Reply after a broadcast query: ");
  474. if (rc == UT_REGISTERS_NB_POINTS) {
  475. printf("OK\n");
  476. } else {
  477. printf("FAILED\n");
  478. goto close;
  479. }
  480. /* Restore slave */
  481. if (use_backend == RTU) {
  482. modbus_set_slave(ctx, SERVER_ID);
  483. } else {
  484. modbus_set_slave(ctx, MODBUS_TCP_SLAVE);
  485. }
  486. printf("3/4 Report slave ID: \n");
  487. /* tab_rp_bits is used to store bytes */
  488. rc = modbus_report_slave_id(ctx, tab_rp_bits);
  489. if (rc == -1) {
  490. printf("FAILED\n");
  491. goto close;
  492. }
  493. if (((use_backend == RTU) && (tab_rp_bits[0] == SERVER_ID))
  494. || tab_rp_bits[0] == 0xFF) {
  495. printf("OK\n");
  496. } else {
  497. printf("FAILED\n");
  498. goto close;
  499. }
  500. /* Save original timeout */
  501. modbus_get_timeout_begin(ctx, &timeout_begin_old);
  502. /* Define a new and too short timeout */
  503. timeout_begin_new.tv_sec = 0;
  504. timeout_begin_new.tv_usec = 0;
  505. modbus_set_timeout_begin(ctx, &timeout_begin_new);
  506. rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS,
  507. UT_REGISTERS_NB_POINTS,
  508. tab_rp_registers);
  509. printf("4/4 Too short timeout: ");
  510. if (rc == -1 && errno == ETIMEDOUT) {
  511. printf("OK\n");
  512. } else {
  513. printf("FAILED\n");
  514. goto close;
  515. }
  516. /* Restore original timeout */
  517. modbus_set_timeout_begin(ctx, &timeout_begin_old);
  518. /* Wait for data before flushing */
  519. usleep(100);
  520. modbus_flush(ctx);
  521. /** BAD RESPONSE **/
  522. printf("\nTEST BAD RESPONSE ERROR:\n");
  523. /* Allocate only the required space */
  524. tab_rp_registers_bad = (uint16_t *) malloc(
  525. UT_REGISTERS_NB_POINTS_SPECIAL * sizeof(uint16_t));
  526. rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS,
  527. UT_REGISTERS_NB_POINTS_SPECIAL,
  528. tab_rp_registers_bad);
  529. printf("* modbus_read_registers: ");
  530. if (rc == -1 && errno == EMBBADDATA) {
  531. printf("OK\n");
  532. } else {
  533. printf("FAILED\n");
  534. goto close;
  535. }
  536. free(tab_rp_registers_bad);
  537. /** MANUAL EXCEPTION **/
  538. printf("\nTEST MANUAL EXCEPTION:\n");
  539. rc = modbus_read_registers(ctx, UT_REGISTERS_ADDRESS_SPECIAL,
  540. UT_REGISTERS_NB_POINTS,
  541. tab_rp_registers);
  542. printf("* modbus_read_registers at special address: ");
  543. if (rc == -1 && errno == EMBXSBUSY) {
  544. printf("OK\n");
  545. } else {
  546. printf("FAILED\n");
  547. goto close;
  548. }
  549. /** RAW REQUEST */
  550. printf("\nTEST RAW REQUEST:\n");
  551. {
  552. const int RAW_REQ_LENGTH = 6;
  553. uint8_t raw_req[] = { (use_backend == RTU) ? SERVER_ID : 0xFF,
  554. 0x03, 0x00, 0x01, 0x0, 0x05 };
  555. int req_length;
  556. uint8_t rsp[MODBUS_TCP_MAX_ADU_LENGTH];
  557. req_length = modbus_send_raw_request(ctx, raw_req,
  558. RAW_REQ_LENGTH * sizeof(uint8_t));
  559. if ((use_backend == RTU && req_length == (RAW_REQ_LENGTH + 2)) ||
  560. ((use_backend == TCP || use_backend == TCP_PI) &&
  561. req_length == (RAW_REQ_LENGTH + 6))) {
  562. printf("OK\n");
  563. } else {
  564. printf("FAILED (%d)\n", req_length);
  565. goto close;
  566. }
  567. printf("* modbus_receive: ");
  568. rc = modbus_receive(ctx, -1, rsp);
  569. if ((use_backend == RTU && rc == 15) ||
  570. ((use_backend == TCP || use_backend == TCP_PI) &&
  571. rc == 19)) {
  572. printf("OK\n");
  573. } else {
  574. printf("FAILED (%d)\n", rc);
  575. goto close;
  576. }
  577. }
  578. printf("\nALL TESTS PASS WITH SUCCESS.\n");
  579. close:
  580. /* Free the memory */
  581. free(tab_rp_bits);
  582. free(tab_rp_registers);
  583. /* Close the connection */
  584. modbus_close(ctx);
  585. modbus_free(ctx);
  586. return 0;
  587. }