sendat.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. #ifndef _UART_H_
  2. #define _UART_H_
  3. #include <stdio.h>
  4. #include <fcntl.h>
  5. #include <termios.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. #include <signal.h>
  9. #include <stdlib.h>
  10. int serial_init(char *device, int speed, int databits, int parity, int stopbits, int RTSCTS, int newline);
  11. int serial_write(int fd, void *src, int len);
  12. int serial_read(int fd, char *buf, int len);
  13. //串口默认初始化接口
  14. #define serial_default(device) serial_init(device, 1500000, 8, 'n', 1, 0, 1)
  15. #endif
  16. /**
  17. *@brief 设置串口数据位,停止位和效验位
  18. *@param fd 类型 int 打开的串口文件句柄
  19. *@param speed 类型 int 波特率
  20. *@param databits 类型 int 数据位 取值为 7 或者8
  21. *@param stopbits 类型 int 停止位 取值为 1 或者2
  22. *@param parity 类型 char 效验类型 取值为N,E,O,S
  23. *@param newline 类型 int 新的一行输出
  24. */
  25. int set_parity(int fd, int speed, int databits, int parity, int stopbits, int RTSCTS, int newline)
  26. {
  27. struct termios options;
  28. if ( tcgetattr(fd, &options) != 0) {
  29. return -1;
  30. }
  31. cfsetispeed(&options, speed);
  32. cfsetospeed(&options, speed);
  33. options.c_cflag &= ~CSIZE;
  34. switch (databits) /*设置数据位数*/
  35. {
  36. case 7:
  37. options.c_cflag |= CS7;
  38. break;
  39. case 8:
  40. options.c_cflag |= CS8;
  41. break;
  42. default:
  43. return -1;
  44. }
  45. options.c_iflag |= INPCK;
  46. cfmakeraw(&options);
  47. //options.c_lflag |= (ICANON | ECHO | ECHOE);
  48. //options.c_lflag &= ~(ICANON | ECHO | ECHOE);
  49. //options.c_iflag &= ~(IXON | IXOFF);
  50. switch (parity)
  51. {
  52. case 'n':
  53. case 'N':
  54. options.c_cflag &= ~PARENB; /* Clear parity enable */
  55. options.c_iflag &= ~INPCK; /* Enable parity checking */
  56. break;
  57. case 'o':
  58. case 'O':
  59. options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/
  60. break;
  61. case 'e':
  62. case 'E':
  63. options.c_cflag |= PARENB; /* Enable parity */
  64. options.c_cflag &= ~PARODD; /* 转换为偶效验*/
  65. break;
  66. case 'S':
  67. case 's': /*as no parity*/
  68. options.c_cflag &= ~PARENB;
  69. options.c_cflag &= ~CSTOPB;
  70. break;
  71. default:
  72. return -1;
  73. }
  74. /* 设置停止位*/
  75. switch (stopbits)
  76. {
  77. case 1:
  78. options.c_cflag &= ~CSTOPB;
  79. break;
  80. case 2:
  81. options.c_cflag |= CSTOPB;
  82. break;
  83. default:
  84. return -1;
  85. }
  86. /* Set rts/cts */
  87. if (RTSCTS)
  88. {
  89. options.c_cflag |= CRTSCTS;
  90. }
  91. if (newline)
  92. {
  93. options.c_lflag |= ICANON;
  94. }
  95. tcflush(fd,TCIFLUSH);
  96. options.c_cc[VTIME] = 150; /* 设置超时15 seconds*/
  97. options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
  98. if (tcsetattr(fd, TCSANOW, &options) != 0)
  99. {
  100. return -1;
  101. }
  102. // printf("set_Parity\n");
  103. return 0;
  104. }
  105. /**
  106. *@brief
  107. *@param device 串口设备
  108. *@param speed 串口速度
  109. *@param databits,parity,stopbits,RTSCTS,分别为数据位,校验位,停止位,rtscts位
  110. *@param newline 接收数据结尾是否加换行符?
  111. */
  112. int serial_init(char *device, int speed, int databits, int parity, int stopbits, int RTSCTS, int newline)
  113. {
  114. int fd, ret;
  115. fd = open(device, O_RDWR|O_NOCTTY);//O_NONBLOCK 非阻塞, O_WRONLY 只读写, O_RDONLY 只读, O_RDWR 读写,O_NOCTTY 阻塞
  116. if (-1 == fd) {
  117. fprintf(stderr, "ERROR: init %s failed\n", device);
  118. return -1;
  119. }
  120. ret = set_parity(fd, speed, databits, parity, stopbits, RTSCTS, newline);
  121. if (ret < 0) {
  122. fprintf(stderr, "ERROR: set parity failed\n");
  123. return -1;
  124. }
  125. return fd;
  126. }
  127. /**
  128. *@brief
  129. *@param fd 串口端口号文件描述符
  130. *@param src 需要通过串口发送的数据
  131. *@param len 需要发送的数据长度
  132. *@param 成功返回0, 否则返回-1
  133. */
  134. int serial_write(int fd, void *src, int len)
  135. {
  136. int ret = write(fd, src, len);
  137. if (len != ret) {
  138. fprintf(stderr, "ERROR: write serial failed!\n");
  139. return -1;
  140. }
  141. return 0;
  142. }
  143. /**
  144. *@brief
  145. *@param fd 串口端口号文件描述符
  146. *@param src 串口接收数据的指针
  147. *@param len 需要接收的数据长度
  148. *@param 成功返回0, 否则返回-1
  149. */
  150. int serial_read(int fd, char *buf, int len)
  151. {
  152. int ret = read(fd, buf, len-1);
  153. if (-1 == ret) {
  154. fprintf(stderr, "ERROR: read serial failed!\n");
  155. return -1;
  156. }
  157. buf[ret] = '\0';
  158. return ret;
  159. }
  160. static void timeout()
  161. {
  162. fprintf(stderr, "No response from modem.\n");
  163. exit(1);
  164. }
  165. /*字符包含判断*/
  166. static int starts_with(const char* prefix, const char* str)
  167. {
  168. while(*prefix)
  169. {
  170. if (*prefix++ != *str++)
  171. {
  172. return 0;
  173. }
  174. }
  175. return 1;
  176. }
  177. /*判断是否存在*/
  178. int file_exist(const char* filename)
  179. {
  180. if (filename && access(filename, F_OK) == 0) {
  181. return 1;
  182. }
  183. return 0;
  184. }
  185. int main(int argc, char **argv)
  186. {
  187. if(argc != 3)
  188. {
  189. fprintf(stderr, "Usage: sendat 2 'ATI'\n");
  190. return 1;
  191. }
  192. char device[16];
  193. sprintf(device, "/dev/ttyUSB%s", argv[1]);
  194. char *message= argv[2];
  195. if (*message=='\0')
  196. {
  197. fprintf(stderr, "ERROR: AT Command Absent.\n");
  198. return 1;
  199. }
  200. if(file_exist(device)==0)
  201. {
  202. fprintf(stderr, "ERROR: AT Device Absent.\n");
  203. return 1;
  204. }
  205. signal(SIGALRM, timeout);
  206. alarm(5);
  207. char *rn= "\r\n";
  208. char buff[1024];
  209. int fd = serial_default(device);
  210. if(fd < 0) return 1;
  211. char *msg= strcat(message, rn);
  212. serial_write(fd, msg, strlen(msg));
  213. int ret=0;
  214. while(1) {
  215. int read = serial_read(fd, buff, sizeof(buff));
  216. printf("%s", buff);
  217. if(starts_with("OK", buff)) {
  218. break;
  219. }
  220. if(starts_with("ERROR", buff)) {
  221. ret=1;
  222. break;
  223. }
  224. if(starts_with("COMMAND NOT SUPPORT", buff)) {
  225. ret=1;
  226. break;
  227. }
  228. if(starts_with("+CME ERROR", buff)) {
  229. ret=1;
  230. break;
  231. }
  232. if(starts_with("+CMS ERROR", buff)) {
  233. ret=1;
  234. break;
  235. }
  236. }
  237. close(fd);
  238. return ret;
  239. }