Guest User

Untitled

a guest
Apr 27th, 2018
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.66 KB | None | 0 0
  1. #include <Ethernet.h>
  2. #include <ASocket.h>
  3. #include <EEPROM.h>
  4. #include "Dhcp.h"
  5.  
  6. #ifdef HOST_NAME
  7. #undef HOST_NAME
  8. #endif
  9. #define HOST_NAME "myarduino"
  10. #define DEBUG
  11.  
  12. // where the MAC address starts in EEPROM.
  13. #define MACADDR_START 0
  14. #define BUFFER_LEN 64
  15.  
  16. enum receive_frame_state { COMMAND_READ_WAIT, COMMAND_READ,
  17. HEADER_KEY_READ_WAIT, HEADER_KEY_READ,
  18. HEADER_VAL_READ_WAIT, HEADER_VAL_READ,
  19. BODY_READ_WAIT, BODY_READ,
  20. FRAME_DONE_CLEANUP, FRAME_DONE };
  21.  
  22. enum Cmd { CONNECT, CONNECTED, RECEIPT, MESSAGE, ERROR, UNKNOWN = 900 };
  23.  
  24. struct hash {
  25. char *key;
  26. char *value;
  27. };
  28.  
  29. struct stomp_frame {
  30. Cmd cmd;
  31. char *header;
  32. struct hash **headers;
  33. char *content;
  34. };
  35.  
  36. typedef struct stomp_frame STOMP_FRAME;
  37. /* */
  38. struct stomp_message {
  39. char *header;
  40. char *content;
  41. };
  42. /*
  43. typedef struct stomp_message STOMP_MESSAGE;
  44. */
  45. struct stomp_connection {
  46. unsigned short port;
  47. byte broker_ip[4]; // aaa.bbb.ccc.ddd
  48. char *username;
  49. char *password;
  50. char buffer[BUFFER_LEN];
  51. // Some socket here
  52. };
  53.  
  54. typedef struct stomp_connection STOMP_CONNECTION;
  55.  
  56. unsigned long time;
  57.  
  58. STOMP_CONNECTION conn;
  59.  
  60. byte *mac = (byte *)malloc(sizeof(byte) * 6);
  61. byte my_ip[] = { 192, 168, 2, 4 };
  62. ASocket as;
  63.  
  64. #define SERVER_CONNECT 0
  65. #define SERVER_CONNECTING 1
  66. #define SERVER_RECEIVE 2
  67. #define NET_IDLE 3
  68. #define NET_TIMER 4
  69. uint8 networkState = SERVER_CONNECT;
  70.  
  71. void stomp_login(ASocket *, struct stomp_connection *);
  72. uint8 read_char(ASocket *as);
  73. char * stpcpy(char *, const char *);
  74. void loop_forever(void);
  75.  
  76. void setup() {
  77. Serial.begin(9600);
  78. read_mac_address();
  79. Ethernet.begin(mac, my_ip);
  80. conn.broker_ip[0] = 192;conn.broker_ip[1] = 168;
  81. conn.broker_ip[2] = 2 ;conn.broker_ip[3] = 1;
  82. conn.port = 61613;
  83. conn.username = "";
  84. conn.password = "";
  85.  
  86.  
  87. Serial.println("Done setup");
  88. }
  89. void loop() {
  90. switch(networkState) {
  91. case SERVER_CONNECT:
  92. Serial.println("Connecting...");
  93. if (as.initTCP(0)) {
  94. as.connectTCP(conn.broker_ip,conn.port);
  95. networkState = SERVER_CONNECTING;
  96. }
  97. else {
  98. Serial.println("Failed to init socket");
  99. networkState = NET_IDLE;
  100. }
  101. break;
  102. case SERVER_CONNECTING:
  103. if (as.isConnectedTCP()) {
  104. Serial.println("Connected. Trying to login to STOMP");
  105. stomp_login(&as,&conn);
  106. networkState = SERVER_RECEIVE;
  107. }
  108. break;
  109. case SERVER_RECEIVE:
  110. if (as.isConnectedTCP()) {
  111. // Serial.println("SERVER RECV - is connected");
  112. if (as.available()) {
  113. uint8 c;
  114. as.read(&c,1);
  115. Serial.print(c);
  116. }
  117. }
  118. else {
  119. as.disconnectTCP();
  120. as.close();
  121. networkState = NET_IDLE;
  122. }
  123. break;
  124. case NET_IDLE:
  125. networkState = NET_TIMER;
  126. break;
  127.  
  128. }
  129.  
  130. }
  131.  
  132.  
  133. //////////////////
  134.  
  135. void stomp_login(ASocket *as, struct stomp_connection *conn) {
  136. STOMP_FRAME frame;
  137. char *p;
  138. frame.cmd = CONNECT;
  139. frame.content = (char *)malloc(1 * sizeof(char));
  140. strcpy(frame.content,"");
  141. frame.header = (char *)malloc( sizeof(char) * ( strlen(conn->username) +
  142. strlen(conn->password) +
  143. (2 * strlen("\n")) +
  144. strlen("login:") +
  145. strlen("passcode:") + 1
  146. )
  147. );
  148. p = stpcpy(frame.header,"login:");
  149. p = stpcpy(p,conn->username);
  150. p = stpcpy(p,"\n");
  151. p = stpcpy(p,"passcode:");
  152. p = stpcpy(p,conn->password);
  153. p = stpcpy(p,"\n");
  154.  
  155. send_frame(as,&frame);
  156. receive_frame(as,&frame);
  157. Serial.print("First header: ");
  158. Serial.println(frame.headers[0]->key);
  159. Serial.print("First header value: ");
  160. Serial.println(frame.headers[0]->value);
  161. as->close();
  162. loop_forever();
  163.  
  164. }
  165.  
  166. void send_frame(ASocket *as, struct stomp_frame *frame) {
  167. time = micros();
  168. as->beginPacketTCP();
  169. switch (frame->cmd) {
  170. case CONNECT:
  171. as->write("CONNECT\n");
  172. break;
  173. }
  174. as->write(frame->header);
  175. as->write("\n"); // end of header
  176. as->write(frame->content);
  177. as->write((byte *) "\0",1); // end of content
  178. as->send();
  179. }
  180.  
  181. /*
  182. * Read ONE frame from the STOMP connection by reading character by character
  183. until the entire frame has been read.
  184. 1. Until one of the conditions below is met after reading a character, if
  185. it fails to meet criteria for 2-6 add it to a buffer. Once the character
  186. being read meets the criteria read out of the buffer, assign
  187. appropriately, tack on the single-character buffer, and reset the buffer.
  188. 2. read characters one at a time until a newline is detected; this is the
  189. command. (read_command)
  190. 3. read characters one at a time until two newlines in a row are detected;
  191. this marks the end of headers. Headers are defined by a series of
  192. matches to /(\w+):(\w*)\n/
  193. 4. if one of the headers is 'content-length' read $2 number of characters
  194. following the second newline terminating header block; this is the
  195. content of the frame.
  196. 5. if the 'content-length' header is absent read until a NULL character
  197. following the second newline terminating header block; this is the
  198. content of the frame.
  199. 6. Stop reading after the content of the frame is assembled.
  200. */
  201. void receive_frame(ASocket *as,struct stomp_frame *frame) {
  202. char buffer[BUFFER_LEN];
  203. uint8 i = 0; /* Index to buffer */
  204. uint8 j = 0; /* Generic looping var */
  205. uint8 c; /* One character from the ASocket connection */
  206. int header_idx = -1;
  207. receive_frame_state framestate = COMMAND_READ_WAIT;
  208. signed int content_length = -1;
  209. uint8 l = 0; /* Bytes read of content_length */
  210. bool seen_content_length = false;
  211. frame->headers = NULL;
  212.  
  213. while ( framestate != FRAME_DONE ) {
  214. // Serial.print("framestate = ");
  215. // Serial.println(framestate,DEC);
  216. switch(framestate) {
  217. // Set us up to read the command
  218. case COMMAND_READ_WAIT:
  219. framestate = COMMAND_READ;
  220. break; // COMMAND_READ_WAIT
  221.  
  222. // Read the Command
  223. case COMMAND_READ:
  224. c = read_char(as);
  225. switch (c) {
  226. case 'C':
  227. frame->cmd = CONNECTED;
  228. j = 8; /* Read off 8 characters from the packet CONNECTED\0 - 1 */
  229. break;
  230. case 'R':
  231. frame->cmd = RECEIPT;
  232. j = 5;
  233. break;
  234. case 'M':
  235. frame->cmd = MESSAGE;
  236. j = 5;
  237. break;
  238. case 'E':
  239. frame->cmd = ERROR;
  240. j = 4;
  241. break;
  242. default:
  243. frame->cmd = UNKNOWN;
  244. j = 0;
  245. break;
  246. } /* end switch (c) */
  247.  
  248. j += 1; /* ...and the newline too */
  249. while(j-- > 0)
  250. read_char(as);
  251.  
  252. framestate = HEADER_KEY_READ_WAIT;
  253. break; // COMMAND_READ
  254.  
  255. /* Set us up to read some headers */
  256. case HEADER_KEY_READ_WAIT:
  257. /* Initialize frame->headers with enough space for one header. */
  258. frame->headers = (struct hash **)realloc(frame->headers, ++header_idx *
  259. sizeof(struct hash *)
  260. );
  261. /* Here, we'll initialize these to NULL for our own sanity later on */
  262. frame->headers[header_idx]->key = NULL;
  263. frame->headers[header_idx]->value = NULL;
  264.  
  265. framestate = HEADER_KEY_READ;
  266. break; // HEADER_KEY_READ_WAIT
  267.  
  268. case HEADER_KEY_READ:
  269. c = read_char(as);
  270. switch(c) {
  271. case ':':
  272. /*
  273. Serial.print("HEADER_KEY_READ: encounted : with ");
  274. Serial.print(as->available(),DEC);
  275. Serial.print(" bytes to read");
  276. Serial.print(" i = ");
  277. Serial.print(i,DEC);
  278. Serial.print(" header_idx = ");
  279. Serial.println(header_idx,DEC);
  280. */
  281.  
  282. // Encountered the :, we're done reading value
  283. frame->headers[header_idx]->key = (char *)malloc((1 + i) * sizeof(char));
  284.  
  285. for(j = 0; j < i; j++) {
  286. /*
  287. Serial.print("HEADER_KEY_READ: in (before) loop ");
  288. Serial.print(as->available(),DEC);
  289. Serial.print(" bytes to read");
  290. Serial.print(" i = ");
  291. Serial.print(i,DEC);
  292. Serial.print(" j = ");
  293. Serial.print(j,DEC);
  294. Serial.print(" header_idx = ");
  295. Serial.println(header_idx,DEC);
  296. */
  297. frame->headers[header_idx]->key[j] = buffer[j];
  298. /*
  299. Serial.print("HEADER_KEY_READ: in (after) loop ");
  300. Serial.print(as->available(),DEC);
  301. Serial.print(" bytes to read");
  302. Serial.print(" i = ");
  303. Serial.print(i,DEC);
  304. Serial.print(" j = ");
  305. Serial.print(j,DEC);
  306. Serial.print(" header_idx = ");
  307. Serial.println(header_idx,DEC);
  308. */
  309. }
  310.  
  311.  
  312. frame->headers[header_idx]->key[i] = '\0';
  313.  
  314. i = j = 0;
  315. framestate = HEADER_VAL_READ_WAIT;
  316. break; // :
  317.  
  318. // when reading a \n here we're done reading headers.
  319. case '\n':
  320. if (i == 0)
  321. framestate = BODY_READ_WAIT;
  322.  
  323. break; // \n
  324.  
  325. default:
  326. if (i < BUFFER_LEN)
  327. buffer[i++] = c;
  328. else
  329. loop_forever();
  330. break; //default
  331. }
  332. break; // HEADER_KEY_READ
  333.  
  334. case HEADER_VAL_READ_WAIT:
  335. framestate = HEADER_VAL_READ;
  336. break; // HEADER_VAL_READ_WAIT
  337.  
  338. case HEADER_VAL_READ:
  339. c = read_char(as);
  340. // Serial.print("in HEADER_VAL_READ - read a character: ");
  341. // Serial.println(c);
  342. switch (c) {
  343. case '\n':
  344. frame->headers[header_idx]->value = (char *)malloc((1 + i) * sizeof(char));
  345. for(j = 0; j < i; j++)
  346. frame->headers[header_idx]->value[j] = buffer[j];
  347. frame->headers[header_idx]->value[i] = '\0';
  348. i = j = 0;
  349. framestate = HEADER_KEY_READ_WAIT;
  350.  
  351.  
  352. break; // \n
  353. default:
  354. if (i < BUFFER_LEN)
  355. buffer[i++] = c;
  356. else
  357. loop_forever();
  358. break; //default
  359.  
  360. }
  361. //framestate = HEADER_KEY_READ_WAIT;
  362. break; // HEADER_VAL_READ
  363.  
  364. case BODY_READ_WAIT:
  365. frame->content = NULL; // I'll handle the memory... (* gulp *)
  366. l = 0; /* read 0 bytes of body content */
  367. for(j = header_idx; j > 0; j--) {
  368. if ( (strcmp(frame->headers[j]->key,"content-length") == 0)) {
  369. content_length = atoi(frame->headers[j]->value);
  370. frame->content = (char *)malloc(content_length * sizeof(char));
  371. }
  372. }
  373.  
  374. framestate = BODY_READ;
  375. break; // BODY_READ_WAIT
  376.  
  377. case BODY_READ:
  378. c = read_char(as);
  379. l += 1;
  380. switch(c) {
  381. case '\0':
  382. // if content_length > 0 read that many bytes
  383. if (content_length > 0) {
  384. frame->content[l - 1] = c;
  385. content_length -= 1;
  386.  
  387. /* UGLY - FIXME. I shouldn't need this otherwise I read a byte of the NEXT FRAME!! */
  388. if (content_length == 0)
  389. framestate = FRAME_DONE_CLEANUP;
  390. }
  391. /* End of the body/frame */
  392. else {
  393. for (j = 0; j < i; j++)
  394. frame->content[j] = buffer[i];
  395. frame->content[i + 1] = '\0';
  396.  
  397. framestate = FRAME_DONE_CLEANUP;
  398. }
  399. break; // \0
  400. default:
  401. if (i < BUFFER_LEN - 1)
  402. buffer[i++] = c;
  403. else // FIXME: I should fix this and be smart about BUFFER_LEN and l
  404. loop_forever();
  405.  
  406. break; // default
  407. } // switch(c)
  408.  
  409. framestate = FRAME_DONE_CLEANUP;
  410. break; // BODY_READ
  411.  
  412. case FRAME_DONE_CLEANUP:
  413. /* Check to see if the last-created header has value, else realloc -1
  414. if (frame->headers[header_idx]->key == NULL &&
  415. frame->headers[header_idx]->value == NULL) {
  416.  
  417. frame->headers = (struct hash **)realloc(frame->headers, --header_idx *
  418. sizeof(struct hash *));
  419. } */
  420.  
  421. framestate = FRAME_DONE;
  422. break; // FRAME_DONE_CLEANUP
  423.  
  424. } /* end switch(framestate) */
  425.  
  426. }
  427. }
  428.  
  429. uint8 read_char(ASocket *as) {
  430. uint8 c;
  431. /*
  432. Serial.print("read_char(): isConnectedTCP = ");
  433. Serial.print(as->isConnectedTCP(),HEX);
  434. Serial.print(" available = ");
  435. Serial.print(as->available(),DEC);
  436. Serial.print(" Time = ");
  437. Serial.println(micros() - time);
  438. */
  439. while( ! as->isConnectedTCP() || as->available() <= 0) {
  440. /*
  441. Serial.print("read_char(): isConnectedTCP = ");
  442. Serial.print(as->isConnectedTCP(),HEX);
  443. Serial.print(" available = ");
  444. Serial.print(as->available(),DEC);
  445. Serial.print(" Time = ");
  446. Serial.println(micros() - time);
  447. */
  448. Serial.println("read_char: Waiting for data");
  449. delay(2000);
  450. }
  451. as->read(&c,1);
  452. // Serial.print("Read char: ");
  453. // Serial.println(c);
  454. return c;
  455. }
  456.  
  457. void loop_forever(void) {
  458. for (;;) {
  459. delay(1000);
  460. Serial.println("loop_forever()");
  461. }
  462. }
  463. void read_mac_address() {
  464.  
  465. for (int i = MACADDR_START; i < 6; i++) {
  466. *mac = EEPROM.read(i); // Assign value (pointed to by `mac`) to contents
  467. // of EEPROM.
  468. mac++; // Move to next memory space
  469. }
  470. mac -= 6; // Set pointer location back to the start of
  471. // the allocated memory space.
  472. }
  473. char * stpcpy(char *dst, const char *src) {
  474. const size_t len = strlen (src);
  475. return (char *) memcpy (dst, src, len + 1) + len;
  476. }
  477.  
  478. /*
  479. as->beginPacketTCP();
  480. as->write("CONNECT\n");
  481. as->write("login:");
  482. as->write(conn->username);
  483. as->write("\npasscode:");
  484. as->write(conn->password);
  485. as->write( (byte *) "\n\n\0",3);
  486. // as.write( (byte *) "CONNECT\nlogin:\npasscode:\n\n\0",27);
  487. as->send();
  488. */
Add Comment
Please, Sign In to add comment