cascade_slave_tcp.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. #include "cascade_slave_tcp.h"
  2. #include "stdlib.h"
  3. #include "cascade.h"
  4. #include "thread.h"
  5. Modbus_Manger_Tcp* tcp_modbus_init(const char* ip, uint16_t port,uint8_t addr,int power_type)
  6. {
  7. Modbus_Manger_Tcp* tcp = NULL;
  8. tcp = (Modbus_Manger_Tcp*)malloc(sizeof(Modbus_Manger_Tcp));
  9. if(!tcp)
  10. {
  11. log_d("malloc modubus manger faield!!!\n");
  12. goto err1;
  13. }
  14. memset(tcp, 0, sizeof(Modbus_Manger_Tcp));
  15. tcp->ctx = modbus_new_tcp(ip, port);
  16. if(!tcp->ctx)
  17. {
  18. log_d("malloc modbus_tcp ctx faield!!!\n");
  19. goto err2;
  20. }
  21. struct timeval response_timeout;
  22. response_timeout.tv_sec = 1;
  23. response_timeout.tv_usec = 0;
  24. modbus_set_response_timeout(tcp->ctx, 0,800000);
  25. modbus_set_byte_timeout(tcp->ctx,0,50000);
  26. modbus_set_error_recovery(tcp->ctx,MODBUS_ERROR_RECOVERY_PROTOCOL);
  27. modbus_set_slave(tcp->ctx,addr);
  28. strcpy(tcp->ip,ip);
  29. tcp->port = port;
  30. tcp->slave_id = addr;
  31. tcp->power_type = power_type;
  32. return tcp;
  33. err2:
  34. free(tcp);
  35. err1:
  36. return tcp;
  37. }
  38. void tcp_modbus_deinit(Modbus_Manger_Tcp **tcp)
  39. {
  40. Modbus_Manger_Tcp** tmp = tcp;
  41. if(tmp)
  42. {
  43. if(*tmp)
  44. {
  45. modbus_free((*tmp)->ctx);
  46. modbus_close((*tmp)->ctx);
  47. free(*tmp);
  48. *tmp = 0;
  49. }
  50. }
  51. }
  52. static void memswap(uint8_t *buf, int len)
  53. {
  54. int i;
  55. uint8_t tmp;
  56. for(i=0; i<len; i+=2) {
  57. tmp = buf[i];
  58. buf[i] = buf[i+1];
  59. buf[i+1] = tmp;
  60. }
  61. }
  62. static int _mb_hdr(uint8_t *data, int datalen, mb_hdr_t *h)
  63. {
  64. h->addr = data[0];
  65. h->func = data[1];
  66. h->reg = data[2]<<8 | data[3];
  67. h->regcnt = data[4]<<8 | data[5];
  68. h->dlen = 0;
  69. h->data = NULL;
  70. if(datalen>8) {
  71. h->dlen = data[6];
  72. h->data = data+7;
  73. memswap(h->data, h->dlen+h->dlen%2);
  74. }
  75. //print_hdr("sss", h);
  76. return 0;
  77. }
  78. static inline GlobalDeviceManager* get_dm(void)
  79. {
  80. return &__globalDeviceManage;
  81. }
  82. static void *pthread_handle_tcp(void *arg)
  83. {
  84. uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH] = {0};
  85. int ret = 0;
  86. //Modbus_Manger_Tcp *tcp = (Modbus_Manger_Tcp *)(arg);
  87. int fd = *(int*)(arg);
  88. Modbus_Manger_Tcp *mb =tcp_modbus_init("0.0.0.0",CASCADE_SLAVE_PORT,1,0);
  89. struct timeval response_timeout;
  90. response_timeout.tv_sec = 1;
  91. response_timeout.tv_usec = 0;
  92. modbus_set_response_timeout(mb->ctx, 0,800000);
  93. modbus_set_byte_timeout(mb->ctx,0,50000);
  94. modbus_set_error_recovery(mb->ctx,MODBUS_ERROR_RECOVERY_PROTOCOL);
  95. //mb->ctx->s = fd;
  96. //mdbus_tcp_setfd(mb->ctx,fd);
  97. mb->ctx->s = fd;
  98. int rc = 0;
  99. mb_hdr_t h;
  100. while(1)
  101. {
  102. rc = modbus_receive(mb->ctx,query);
  103. log_d("recive modbus rc=%d\n",rc);
  104. if(rc > 0)
  105. {
  106. _mb_hdr(&query[6],rc,&h);
  107. if(h.func==MODBUS_FC_READ_HOLDING_REGISTERS) {
  108. cascade_slave_read(h.reg, h.regcnt);
  109. modbus_reply(mb->ctx,query,rc,cascade_slave_map());
  110. }
  111. else if(h.func==MODBUS_FC_WRITE_SINGLE_REGISTER) {
  112. cascade_slave_write(h.reg, h.regcnt);
  113. modbus_reply(mb->ctx,query,rc,cascade_slave_map());
  114. }
  115. }else if(rc < 0)
  116. {
  117. log_d("thread out!!!!!\n");
  118. break;
  119. }else
  120. {
  121. continue;
  122. }
  123. }
  124. modbus_close(mb->ctx);
  125. modbus_free(mb->ctx);
  126. mb->ctx = 0;
  127. free(mb);
  128. mb = NULL;
  129. pthread_exit(NULL);
  130. }
  131. void* tcp_modbus_thread(void *arg)
  132. {
  133. //GlobalDeviceManager *mgr = (GlobalDeviceManager *)(arg);
  134. GlobalDeviceManager *mgr = get_dm();
  135. Modbus_Manger_Tcp *tcp = mgr->md_tcp;
  136. tcp->connection = modbus_tcp_listen(tcp->ctx,CASCADE_SLAVE_CONNECTION);
  137. modbus_tcp_accept(tcp->ctx,&tcp->connection);
  138. uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH] = {0};
  139. mb_hdr_t h;
  140. log_d("start tcp modbus thread!!!\n");
  141. int rc = 0;
  142. pthread_t thread_id = 0;
  143. int recive_fd = 0;
  144. while(1)
  145. {
  146. if(tcp->ctx){
  147. struct sockaddr_in addr;
  148. socklen_t addrlen;
  149. addrlen = sizeof(addr);
  150. #ifdef HAVE_ACCEPT4
  151. /* Inherit socket flags and use accept4 call */
  152. recive_fd = accept4(tcp->connection, (struct sockaddr *)&addr, &addrlen, SOCK_CLOEXEC);
  153. #else
  154. recive_fd = accept(tcp->connection, (struct sockaddr *)&addr, &addrlen);
  155. #endif
  156. if(recive_fd > 0)
  157. {
  158. pthread_create(&thread_id,NULL,pthread_handle_tcp,(void*)(&recive_fd));
  159. pthread_detach(thread_id);
  160. }
  161. }
  162. }
  163. pthread_exit(NULL);
  164. }