uart2tcp-111.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5. #include <termios.h>
  6. #include <string.h>
  7. #include <sys/socket.h>
  8. #include <arpa/inet.h>
  9. #include <sys/ioctl.h>
  10. #include <net/if.h>
  11. #include <time.h>
  12. #define False -1
  13. #define True 0
  14. #define BuffSize 256
  15. typedef struct {
  16. int year, month, day, hour, minute, second;
  17. } Time;
  18. void Now_Time(Time *now) {
  19. time_t currentTime = time(NULL);
  20. struct tm *localTime = localtime(&currentTime);
  21. now->year = localTime->tm_year + 1900;
  22. now->month = localTime->tm_mon + 1;
  23. now->day = localTime->tm_mday;
  24. now->hour = localTime->tm_hour;
  25. now->minute = localTime->tm_min;
  26. now->second = localTime->tm_sec;
  27. }
  28. int Str_Split(char *str, char c, char ***res) {
  29. int count = 1, i = 0, len;
  30. char *temp = str, *start, **arr;
  31. while (*temp != 0) {
  32. if (*temp == c) count++;
  33. temp++;
  34. }
  35. arr = (char **)malloc(count * sizeof(char *));
  36. temp = str;
  37. while (*temp != 0) {
  38. start = temp;
  39. while (*temp != c && *temp != 0) temp++;
  40. len = temp - start;
  41. arr[i] = (char *)malloc((len + 1) * sizeof(char));
  42. strncpy(arr[i], start, len);
  43. arr[i][len] = 0;
  44. if (*temp == c) temp++;
  45. i++;
  46. }
  47. *res = arr;
  48. return count;
  49. }
  50. void Free_Strings(char **list, int count) {
  51. do {
  52. free(list[--count]);
  53. } while (count);
  54. }
  55. int Uart_Open(char *location) {
  56. int fd = open(location, O_RDWR | O_NOCTTY | O_NDELAY);
  57. if (fd == False) return False;
  58. // 恢复串口为阻塞状态
  59. if (fcntl(fd, F_SETFL, 0) < 0) return False;
  60. // 测试是否为终端设备
  61. // if (0 == isatty(STDIN_FILENO)) return False;
  62. return fd;
  63. }
  64. int Uart_Set(int fd, int speed, int flow_ctrl, int data_bits, int stop_bits, int parity) {
  65. int i, status;
  66. int speed_arr[] = {B115200, B19200, B9600, B4800, B2400, B1200, B300};
  67. int name_arr[] = {115200, 19200, 9600, 4800, 2400, 1200, 300};
  68. struct termios options;
  69. if (tcgetattr(fd, &options) != 0) {
  70. printf("Error: SetupSerial 1");
  71. return False;
  72. }
  73. // 设置串口输入波特率和输出波特率
  74. for (i = 0; i < sizeof(speed_arr) / sizeof(int); i++) {
  75. if (speed == name_arr[i]) {
  76. cfsetispeed(&options, speed_arr[i]);
  77. cfsetospeed(&options, speed_arr[i]);
  78. }
  79. }
  80. // 修改控制模式,保证程序不会占用串口
  81. options.c_cflag |= CLOCAL;
  82. // 修改控制模式,使得能够从串口中读取输入数据
  83. options.c_cflag |= CREAD;
  84. // 设置数据流控制
  85. switch (flow_ctrl) {
  86. case 0: // 不使用流控制
  87. options.c_cflag &= ~CRTSCTS;
  88. break;
  89. case 1: // 使用硬件流控制
  90. options.c_cflag |= CRTSCTS;
  91. break;
  92. case 2: // 使用软件流控制
  93. options.c_cflag |= IXON | IXOFF | IXANY;
  94. break;
  95. }
  96. // 设置数据位
  97. // 屏蔽其他标志位
  98. options.c_cflag &= ~CSIZE;
  99. switch (data_bits) {
  100. case 5:
  101. options.c_cflag |= CS5;
  102. break;
  103. case 6:
  104. options.c_cflag |= CS6;
  105. break;
  106. case 7:
  107. options.c_cflag |= CS7;
  108. break;
  109. case 8:
  110. options.c_cflag |= CS8;
  111. break;
  112. default:
  113. printf("Error: Unsupported data size\n");
  114. return False;
  115. }
  116. // 设置校验位
  117. switch (parity) {
  118. case 'n':
  119. case 'N': // 无奇偶校验位。
  120. options.c_cflag &= ~PARENB;
  121. options.c_iflag &= ~INPCK;
  122. break;
  123. case 'o':
  124. case 'O': // 设置为奇校验
  125. options.c_cflag |= (PARODD | PARENB);
  126. options.c_iflag |= INPCK;
  127. break;
  128. case 'e':
  129. case 'E': // 设置为偶校验
  130. options.c_cflag |= PARENB;
  131. options.c_cflag &= ~PARODD;
  132. options.c_iflag |= INPCK;
  133. break;
  134. case 's':
  135. case 'S': // 设置为空格
  136. options.c_cflag &= ~PARENB;
  137. options.c_cflag &= ~CSTOPB;
  138. break;
  139. default:
  140. printf("Error: Unsupported parity\n");
  141. return False;
  142. }
  143. // 设置停止位
  144. switch (stop_bits) {
  145. case 1:
  146. options.c_cflag &= ~CSTOPB;
  147. break;
  148. case 2:
  149. options.c_cflag |= CSTOPB;
  150. break;
  151. default:
  152. printf("Error: Unsupported stop bits\n");
  153. return False;
  154. }
  155. // 修改输出模式,原始数据输出
  156. options.c_oflag &= ~OPOST;
  157. options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
  158. // 设置等待时间和最小接收字符
  159. options.c_cc[VTIME] = 1; /* 读取一个字符等待1*(1/10)s */
  160. options.c_cc[VMIN] = 1; /* 读取字符的最少个数为1 */
  161. // 如果发生数据溢出,接收数据,但是不再读取 刷新收到的数据但是不读
  162. tcflush(fd, TCIFLUSH);
  163. // 激活配置 (将修改后的termios数据设置到串口中)
  164. if (tcsetattr(fd, TCSANOW, &options) != 0) {
  165. printf("Error: com set error!\n");
  166. return False;
  167. }
  168. return True;
  169. }
  170. int Uart_Recv(int fd, char *rcv_buf, int data_len) {
  171. fd_set fs_read;
  172. FD_ZERO(&fs_read);
  173. FD_SET(fd, &fs_read);
  174. return read(fd, rcv_buf, data_len);
  175. }
  176. int Get_Mac(char *mac, int limit) {
  177. struct ifreq ifreq;
  178. int sock;
  179. if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) return False;
  180. strcpy(ifreq.ifr_name, "eth0"); // Current eth0 only
  181. if (ioctl(sock, SIOCGIFHWADDR, &ifreq) < 0) return False;
  182. return snprintf(
  183. mac, limit, "%X%X%X%X%X%X", (unsigned char)ifreq.ifr_hwaddr.sa_data[0],
  184. (unsigned char)ifreq.ifr_hwaddr.sa_data[1], (unsigned char)ifreq.ifr_hwaddr.sa_data[2],
  185. (unsigned char)ifreq.ifr_hwaddr.sa_data[3], (unsigned char)ifreq.ifr_hwaddr.sa_data[4],
  186. (unsigned char)ifreq.ifr_hwaddr.sa_data[5]
  187. );
  188. }
  189. int main() {
  190. Time now;
  191. int ErrNo, UartFd, UartReadSize, SocketFd, SockReadSize, SockSendSize, tmp_;
  192. char MacAddr[18], SockReadBuff[BuffSize], SockSendBuff[BuffSize], UartRecvBuff[BuffSize], **SplitList, DeviceId[32];
  193. // 打开串口Uart
  194. UartFd = Uart_Open("/dev/ttyS0");
  195. if (UartFd == False) {
  196. printf("Error: Failed To Open Uart.\n");
  197. return False;
  198. }
  199. do {
  200. ErrNo = Uart_Set(UartFd, 115200, 0, 8, 1, 'N');
  201. } while (ErrNo == False || UartFd == False);
  202. // 阻塞式连接TCP
  203. struct sockaddr_in sin;
  204. bzero(&sin, sizeof(sin));
  205. sin.sin_family = AF_INET;
  206. inet_pton(AF_INET, "119.3.44.183", &sin.sin_addr);
  207. sin.sin_port = htons(8012);
  208. SocketFd = socket(AF_INET, SOCK_STREAM, 0);
  209. connect(SocketFd, (const struct sockaddr *)&sin, sizeof(sin));
  210. // init message exchange
  211. if (Get_Mac(MacAddr, 18) > 0) printf("Mac Addr: <%s>\n", MacAddr);
  212. else {
  213. printf("Error: Failed To Get Mac Addr.\n");
  214. close(UartFd);
  215. return False;
  216. }
  217. memset(SockSendBuff, 0, BuffSize);
  218. SockSendSize = sprintf(SockSendBuff, "hm+%s+1+7+end", MacAddr);
  219. write(SocketFd, SockSendBuff, SockSendSize);
  220. SockReadSize = read(SocketFd, SockReadBuff, BuffSize);
  221. SockReadBuff[SockReadSize] = 0;
  222. tmp_ = Str_Split(SockReadBuff, '+', &SplitList);
  223. strcpy(DeviceId, SplitList[3]);
  224. Free_Strings(SplitList, tmp_);
  225. printf("Device Id: <%s>\n\n", DeviceId);
  226. // 循环读串口数据
  227. memset(SockSendBuff, 0, BuffSize);
  228. while (1) {
  229. UartReadSize = Uart_Recv(UartFd, UartRecvBuff, BuffSize);
  230. if (UartReadSize > 0) {
  231. UartRecvBuff[UartReadSize] = 0;
  232. strcat(SockSendBuff, UartRecvBuff);
  233. if (strstr(UartRecvBuff, "end")) {
  234. printf("Uart Packet: [%s]\n", SockSendBuff);
  235. tmp_ = Str_Split(SockSendBuff, '+', &SplitList);
  236. Now_Time(&now);
  237. SockSendSize = sprintf(
  238. SockSendBuff, "%s+%s+%s+%s+0+0+%s+%s+%d%02d%02d%02d%02d%02d+1.0#%s#%s+%s+%s",
  239. SplitList[0], DeviceId, SplitList[2], SplitList[4], SplitList[5], SplitList[6],
  240. now.year, now.month, now.day, now.hour, now.minute, now.second,
  241. SplitList[7], SplitList[3], SplitList[8], SplitList[9]
  242. );
  243. SockSendBuff[SockSendSize] = 0;
  244. write(SocketFd, SockSendBuff, SockSendSize);
  245. printf(" |=> Being Send: [%s]\n\n", SockSendBuff);
  246. Free_Strings(SplitList, tmp_);
  247. memset(SockSendBuff, 0, BuffSize);
  248. }
  249. }
  250. }
  251. close(UartFd);
  252. }