fork download
  1. #include <string>
  2. #include <iostream>
  3. #include <stdlib.h>
  4. #include <stdio.h>
  5. #include <unistd.h>
  6. #include <fcntl.h>
  7. #include <termios.h>
  8. #include <sys/types.h>
  9. #include <sys/socket.h>
  10. #include <netinet/in.h>
  11. #include "zmq.h"
  12. #include "zmq_utils.h"
  13.  
  14. //#define __DEBUG__
  15.  
  16. const ssize_t data_size = 1024;
  17. char buffer[data_size];
  18. char unlock = 17;
  19. char starter = 29;
  20. char terminator = 30;
  21.  
  22. class Arduino
  23. {
  24. struct termios tio;
  25. struct termios stdio;
  26. struct termios old_stdio;
  27. int tty_fd;
  28. ssize_t read;
  29. public:
  30. Arduino()
  31. {
  32. tcgetattr(STDOUT_FILENO, &old_stdio);
  33.  
  34. memset(&stdio, 0, sizeof(stdio));
  35. stdio.c_iflag = 0;
  36. stdio.c_oflag = 0;
  37. stdio.c_cflag = 0;
  38. stdio.c_lflag = 0;
  39. stdio.c_cc[VMIN] = 1;
  40. stdio.c_cc[VTIME] = 0;
  41. tcsetattr(STDOUT_FILENO, TCSANOW, &stdio);
  42. tcsetattr(STDOUT_FILENO, TCSAFLUSH, &stdio);
  43. fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);       // make the reads non-blocking
  44.  
  45. memset(&tio, 0, sizeof(tio));
  46. tio.c_iflag = 0;
  47. tio.c_oflag = 0;
  48. tio.c_cflag = CS8 | CREAD | CLOCAL;           // 8n1, see termios.h for more information
  49. tio.c_lflag = 0;
  50. tio.c_cc[VMIN] = 1;
  51. tio.c_cc[VTIME] = 5;
  52. }
  53. ~Arduino()
  54. {
  55. close(tty_fd);
  56. tcsetattr(STDOUT_FILENO, TCSANOW, &old_stdio);
  57. }
  58. void Connect(std::string device = "/dev/ttyACM0")
  59. {
  60.  
  61. tty_fd = open(device.c_str(), O_RDWR | O_NONBLOCK);
  62. cfsetospeed(&tio, B115200);            // 115200 baud
  63. cfsetispeed(&tio, B115200);            // 115200 baud
  64.  
  65. tcsetattr(tty_fd, TCSANOW, &tio);
  66. }
  67. ssize_t Recv(bool old = false)
  68. {
  69. if (old)
  70. {
  71. ssize_t c = ::read(tty_fd, &buffer[0], data_size);
  72. if (c > 0)
  73. {
  74. return c;
  75. }
  76. return 0;
  77. }
  78. else
  79. {
  80. ssize_t c = ::read(tty_fd, &buffer[0], 1);
  81. if (c == 1 && buffer[0] == starter)
  82. {
  83. ssize_t c = ::read(tty_fd, &buffer[1], data_size - 1);
  84. if (c > 0)
  85. {
  86. return c + 1;
  87. }
  88. return 0;
  89. }
  90. return 0;
  91. }
  92. }
  93. ssize_t Send(ssize_t write_size)
  94. {
  95. return ::write(tty_fd, &buffer[0], write_size);
  96. }
  97. };
  98.  
  99. class Server
  100. {
  101. void *context;
  102. void *responder;
  103. int rc;
  104. ssize_t count;
  105. public:
  106. Server()
  107. {
  108.  
  109. }
  110. bool Start(std::string port = "5000")
  111. {
  112. context = zmq_ctx_new();
  113. responder = zmq_socket(context, ZMQ_DEALER);
  114. rc = zmq_bind(responder, (std::string("tcp://*:") + port).c_str());
  115. return rc == 0;
  116. }
  117. ssize_t Recv()
  118. {
  119. std::cout << "Trying ZMQ_RECV...\r\n" << std::flush;
  120. if (zmq_recv(responder, &buffer[0], 1, ZMQ_DONTWAIT) != -1)
  121. {
  122. std::cout << "checking buffer[0] == starter\r\n" << std::flush;
  123. if (buffer[0] == starter)
  124. {
  125. std::cout << "yes, receiving other data...\r\n" << std::flush;
  126. count = zmq_recv(responder, &buffer[0], data_size, ZMQ_DONTWAIT);
  127. if (count == -1)
  128. {
  129. std::cout << "ZMQ RECV error: ";
  130. int err =
  131. zmq_errno();
  132. switch (err)
  133. {
  134. case EAGAIN:
  135. std::cout << "EAGAIN";
  136. break;
  137. case ENOTSUP:
  138. std::cout << "ENOTSUP";
  139. break;
  140. case EFSM:
  141. std::cout << "EFSM";
  142. break;
  143. case ETERM:
  144. std::cout << "ETERM";
  145. break;
  146. case ENOTSOCK:
  147. std::cout << "ENOTSOCK";
  148. break;
  149. case EINTR:
  150. std::cout << "EINTR";
  151. break;
  152. case EFAULT:
  153. std::cout << "EFAULT";
  154. break;
  155. }
  156. std::cout << "\r\n" << std::flush;
  157. return 0;
  158. }else
  159. if (count > 0)
  160. {
  161. std::cout << "...OK\r\n" << std::flush;
  162. return count + 1;
  163. }
  164. else
  165. {
  166. std::cout << "FAIL 1\r\n" << std::flush;
  167. return 0;
  168. }
  169. }
  170. std::cout << "FAIL 2\r\n" << std::flush;
  171. return 0;
  172. }
  173. return 0;
  174. }
  175. bool Send(ssize_t size)
  176. {
  177. if (zmq_send(responder, &buffer[0], size, ZMQ_DONTWAIT) == -1)
  178. {
  179. //std::cout << "ZMQ SEND error: ";
  180. //int err =
  181. //zmq_errno();
  182. /*switch (err)
  183. {
  184. case EAGAIN:
  185. std::cout << "EAGAIN";
  186. break;
  187. case ENOTSUP:
  188. std::cout << "ENOTSUP";
  189. break;
  190. case EFSM:
  191. std::cout << "EFSM";
  192. break;
  193. case ETERM:
  194. std::cout << "ETERM";
  195. break;
  196. case ENOTSOCK:
  197. std::cout << "ENOTSOCK";
  198. break;
  199. case EINTR:
  200. std::cout << "EINTR";
  201. break;
  202. case EFAULT:
  203. std::cout << "EFAULT";
  204. break;
  205. }
  206. std::cout << "\r\n" << std::flush;*/
  207. return false;
  208. }
  209. return true;
  210. }
  211. };
  212.  
  213. void SleepMs(int ms)
  214. {
  215. usleep(ms * 1000); //convert to microseconds
  216. }
  217.  
  218. void UnlockArduino(Arduino& ACM0)
  219. {
  220. buffer[0] = starter;
  221. buffer[1] = 0;
  222. buffer[2] = unlock;
  223. buffer[3] = unlock;
  224. buffer[4] = unlock;
  225. buffer[5] = unlock;
  226. buffer[6] = terminator;
  227. ACM0.Send(7);
  228. }
  229.  
  230. int main()
  231. {
  232. memset(&buffer[0], 0, sizeof(buffer));
  233. ssize_t count = 0;
  234.  
  235. //setup arduino and server
  236. Arduino ACM0;
  237. Server Svr;
  238.  
  239. //connect to arduino and start server
  240. ACM0.Connect();
  241.  
  242. //send startup code
  243. UnlockArduino(ACM0);
  244. SleepMs(35);
  245. bool status = true;
  246. char CODE_OK[16] = { 'U', 'N', 'L', 'O', 'C', 'K', 'O', 'K', '-', '5', 'A', 'E', '3', 'C', '2' };
  247.  
  248. while (status)
  249. {
  250. //std::cout << "Trying Recv...\r\n" << std::flush;
  251. count = ACM0.Recv(true);
  252. if (count >= 15)
  253. {
  254. //std::cout << "Received...\r\n" << std::flush;
  255. status = false;
  256. if (std::string(buffer,15).compare(std::string(CODE_OK,15)) == 0)
  257. {
  258.  
  259. }
  260. else
  261. {
  262. status = true;
  263. }
  264. std::cout << buffer << std::flush;
  265. //std::cout << "\r\nStatus:" << status << "\r\n" << std::flush;
  266. }
  267. SleepMs(75);
  268. if (status)
  269. {
  270. UnlockArduino(ACM0);
  271. }
  272. SleepMs(75);
  273. }
  274. //std::cout << "Received UNLOCK == OK Signal\r\n" << std::flush;
  275. if (Svr.Start("5000"))
  276. {
  277. //infinite loop
  278. while (true)
  279. {
  280. //check if arduino has data to send
  281. count = ACM0.Recv();
  282. if (count > 0)
  283. {
  284. std::cout << "SENDING: [" << std::hex << (int)buffer[0] << "|"
  285. << std::hex << (int)buffer[1] << "|"
  286. << std::hex << (int)buffer[2] << "|"
  287. << std::hex << (int)buffer[3] << "|"
  288. << std::hex << (int)buffer[4] << "|"
  289. << std::hex << (int)buffer[5] << "|"
  290. << std::hex << (int)buffer[6] << "]" << "\r\n" << std::flush;
  291. //if yes send to laptop
  292. Svr.Send(count);
  293. }
  294.  
  295. //check if laptop has data to send to arduino
  296. count = Svr.Recv();
  297. if (count > 0)
  298. {
  299. std::cout << "RECEIVED: [" << std::hex << (int)buffer[0] << "|"
  300. << std::hex << (int)buffer[1] << "|"
  301. << std::hex << (int)buffer[2] << "|"
  302. << std::hex << (int)buffer[3] << "|"
  303. << std::hex << (int)buffer[4] << "|"
  304. << std::hex << (int)buffer[5] << "|"
  305. << std::hex << (int)buffer[6] << "]" << "\r\n" << std::flush;
  306. //if yes do it
  307. ACM0.Send(count);
  308. }
  309.  
  310. SleepMs(250);
  311. }
  312. }
  313.  
  314.    return EXIT_SUCCESS;
  315. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:11:17: fatal error: zmq.h: No such file or directory
 #include "zmq.h"
                 ^
compilation terminated.
stdout
Standard output is empty