/*------------------------------------------------------------------*/ static u8_t raven_gui_loop(process_event_t ev, process_data_t data) { uint8_t *ptr; int len = 0; if(ev == tcpip_event) { PRINTF("[APP] TCPIP event lport %u rport %u raddress\n",uip_udp_conn->lport, uip_udp_conn->rport); if(uip_udp_conn == node_conn) { PRINTF("[APP] UDP packet\n"); if(uip_newdata()) { ptr = (uint8_t *)uip_appdata; /* Make sure the data is terminated */ ptr[uip_datalen()] = 0; /* Command to this node */ switch(*ptr) { case 'T': send_frame(TEMP_REQUEST, 0, 0); len = snprintf(udp_data, DATA_LEN, "%c%s\r\n", *ptr, last_temp); if(len > 0) { reply_packet(udp_data, len); } break; case 'A': if(ptr[1] > 32) { invert_led = ptr[1] == '1'; send_frame(LED_REQUEST, 1, &invert_led); } len = sprintf(udp_data, "A%u\r\n", invert_led ? 1 : 0); if(len > 0) { reply_packet(udp_data, len); } break; case 'P': PRINTF("[APP] Request for periodic sending of temperatures\n"); if(sscanf((char *)ptr+1,"%d", &periodic_interval)) { PRINTF("[APP] Period %d\n", periodic_interval); if(periodic_interval == 0) { etimer_stop(&periodic_timer); } else { etimer_set(&periodic_timer, periodic_interval * CLOCK_SECOND); } len = snprintf(udp_data, DATA_LEN, "P%d\r\n", periodic_interval); if(len > 0) { reply_packet(udp_data, len); } } break; case 'C': PRINTF("[APP] Command %c\n",ptr[1]); if(sscanf((char *)ptr+2, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x %d", &addr[0],&addr[1],&addr[2],&addr[3],&addr[4], &addr[5],&addr[6],&addr[7],&len) >= 8) { uip_ip6addr(&locaddr, addr[0], addr[1],addr[2], addr[3],addr[4],addr[5],addr[6],addr[7]); if(ptr[1] == 'E') { PRINTF("[APP] Send ping to"); PRINT6ADDR(&locaddr); PRINTF("len %d\n", len); raven_ping6(&locaddr, len); } else if (ptr[1] == 'T') { PRINTF("[APP] Send temperature to"); PRINT6ADDR(&locaddr); PRINTF("\n"); len = snprintf(udp_data, DATA_LEN, "%c\r\n", ptr[1]); if(len > 0) { send_packet(&locaddr, HTONS(0xF0B0), udp_data, len); } } else { PRINTF("[APP] Command unknown\n"); } } break; default: break; } } } } else { switch (ev) { case ICMP6_ECHO_REQUEST: /* We have received a ping request over the air. Send frame back to 3290 */ send_frame(PING_REQUEST, 0, 0); break; case ICMP6_ECHO_REPLY: /* We have received a ping reply over the air. Send frame back to 3290 */ send_frame(PING_REPLY, 1, &seqno); break; case PROCESS_EVENT_TIMER: if(data == &periodic_timer) { PRINTF("[APP] Periodic Timer\n"); /* Send to server if time to send */ len = sprintf(udp_data, "T%s\r\n", last_temp); if(len > 0) { send_packet(&server_addr, SERVER_PORT, udp_data, len); } etimer_reset(&periodic_timer); send_frame(TEMP_REQUEST, 0, 0); } break; case PROCESS_EVENT_POLL: /* Check for command from serial port, execute it. */ if (cmd.done) { /* Execute the waiting command */ switch (cmd.cmd) { case CMD_PING: /* Send ping request over the air */ seqno = cmd.frame[0]; raven_ping6(&server_addr, 0); break; case CMD_TEMP: /* Copy sensor data until white space or end of string. The ATMega3290 sends temperature with both value and type (25 C) */ copy_value(cmd.frame, last_temp, sizeof(last_temp)); PRINTF("[APP] New temp value %s\n", last_temp); break; default: break; } /* Reset command done flag. */ cmd.done = 0; } break; default: break; } } return 0; }
/* * receive and decode packet. * */ static void receive_ping(int afamily, int s, int reply, int natt) { ip_address sender; struct isakmp_hdr ih; char rbuf[256]; char buf[64]; int n, rport; unsigned int sendlen; const char *xchg_name; int xchg; u_int32_t tmp_ic[2], tmp_rc[2]; rport = 500; xchg = 0; sendlen=sizeof(sender); n = recvfrom(s, rbuf, sizeof(rbuf) , 0, (struct sockaddr *)&sender, (socklen_t *)&sendlen); memcpy(&ih, rbuf, sizeof(ih)); if(natt) { /* need to skip 4 bytes! */ if(rbuf[0]!=0x0 || rbuf[1]!=0x0 || rbuf[2]!=0x0 || rbuf[3]!=0x0) { printf("kernel failed to steal ESP packet (SPI=0x%02x%02x%02x%02x) of length %d\n" , rbuf[0], rbuf[1], rbuf[2], rbuf[3] , n); return; } /* otherwise, skip 4 bytes */ memcpy(&ih, rbuf+4, sizeof(ih)); } addrtot(&sender, 0, buf, sizeof(buf)); switch(afamily) { case AF_INET: rport = sender.u.v4.sin_port; break; case AF_INET6: rport = sender.u.v6.sin6_port; break; } if((unsigned int)n < sizeof(ih)) { fprintf(stderr, "read short packet (%d) from %s/%d\n", n, buf, rport); return; } /* translate from network byte order */ ntoh_ping(&ih); if(ih.isa_xchg == ISAKMP_XCHG_ECHOREQUEST || ih.isa_xchg == ISAKMP_XCHG_ECHOREQUEST_PRIVATE || (exchange_number!=0 && ih.isa_xchg == exchange_number)) { xchg_name="echo-request"; xchg=ISAKMP_XCHG_ECHOREQUEST; } else if(ih.isa_xchg == ISAKMP_XCHG_ECHOREPLY || ih.isa_xchg == ISAKMP_XCHG_ECHOREPLY_PRIVATE || (exchange_number!=0 && ih.isa_xchg == exchange_number+1)) { xchg_name="echo-reply"; } else { xchg_name=""; } printf("received %d(%s) packet from %s/%d of len: %d\n", ih.isa_xchg, xchg_name, buf, ntohs(rport), n); /* questionable: printing each cookie as if it were two uint32 values in host order */ memcpy(&tmp_ic, ih.isa_icookie, 2 * sizeof(u_int32_t)); memcpy(&tmp_rc, ih.isa_rcookie, 2 * sizeof(u_int32_t)); printf("\trcookie=%08x_%08x icookie=%08x_%08x msgid=%08x\n", tmp_ic[0], tmp_ic[1], tmp_rc[0], tmp_rc[1], ih.isa_msgid); printf("\tnp=%03d version=%d.%d xchg=%s(%d)\n", ih.isa_np, ih.isa_version >> ISA_MAJ_SHIFT, ih.isa_version & ISA_MIN_MASK, xchg_name, ih.isa_xchg); if(reply && xchg==ISAKMP_XCHG_ECHOREQUEST) { reply_packet(afamily, s, &sender, sendlen, &ih); } }