static void udp_packet_finish(struct proto_hdr *hdr) { struct packet *pkt = current_packet(); uint16_t total_len; total_len = pkt->len - hdr->pkt_offset; proto_hdr_field_set_default_be16(hdr, UDP_LEN, total_len); udp_csum_update(hdr); }
static void tcp_csum_update(struct proto_hdr *hdr) { struct proto_hdr *lower = proto_lower_header(hdr); struct packet *pkt = current_packet(); uint16_t total_len; uint16_t csum; if (hdr->is_csum_valid) return; if (proto_hdr_field_is_set(hdr, TCP_CSUM)) return; if (!lower) return; total_len = pkt->len - hdr->pkt_offset; proto_hdr_field_set_default_be16(hdr, TCP_CSUM, 0); switch (lower->ops->id) { case PROTO_IP4: csum = p4_csum((void *) proto_header_ptr(lower), proto_header_ptr(hdr), total_len, IPPROTO_TCP); break; case PROTO_IP6: csum = p6_csum((void *) proto_header_ptr(lower), proto_header_ptr(hdr), total_len, IPPROTO_TCP); break; default: csum = 0; break; } proto_hdr_field_set_default_be16(hdr, TCP_CSUM, bswap_16(csum)); hdr->is_csum_valid = true; }
int main(int argc, char *argv[]) { /* Disable driver enable for RS485 ASAP */ //DDRC |= (1 << PC2); //PORTC &= ~(1 << PC2); /* init serial line debugging */ UBRR0H = UBRRH_VALUE; UBRR0L = UBRRL_VALUE; UCSR0B = (1 << RXCIE1) | (1 << RXEN1) | (1 << TXEN0); UCSR0C = (1<<UCSZ00) | (1<<UCSZ01); /* Initialize UART */ net_init(); DBG("READY!\r\n"); DBG("Initializing SPI...\r\n"); spi_init(); DBG("Initializing ENC28J60...\r\n"); init_enc28j60(); DBG("Initialized ENC28J60\r\n"); char obuf[64]; snprintf(obuf, sizeof(obuf), "enc28j60 rev 0x%x\n", read_control_register(REG_EREVID)); DBG(obuf); char buf[16] = "serial: X\n"; int cnt = 0; while (1) { if (eth_to_rs_cnt > 0 && eth_to_rs[eth_to_rs_cnt-1] == '$') { eth_to_rs[eth_to_rs_cnt-1] = '\0'; int dest = 0; int pktlen = 0; char minibuf[16]; minibuf[0] = eth_to_rs[1]; minibuf[1] = eth_to_rs[2]; minibuf[2] = '\0'; if (sscanf(minibuf, "%d", &dest) != 1) { DBG("Could not parse dest\r\n"); eth_to_rs_cnt = 0; continue; } minibuf[0] = eth_to_rs[3]; minibuf[1] = eth_to_rs[4]; if (sscanf(minibuf, "%d", &pktlen) != 1) { DBG("Could not parse len\r\n"); eth_to_rs_cnt = 0; continue; } if (pktlen != (eth_to_rs_cnt - 6)) { DBG("lens are not the same\r\n"); minibuf[2] = '\r'; minibuf[3] = '\n'; minibuf[4] = '\0'; DBG(minibuf); snprintf(minibuf, sizeof(minibuf), "e: %d\r\n", eth_to_rs_cnt-6); DBG(minibuf); snprintf(minibuf, sizeof(minibuf), "p: %d\r\n", pktlen); DBG(minibuf); eth_to_rs_cnt = 0; continue; } fmt_packet(lbuffer, dest, 0xFF, eth_to_rs + 5, pktlen); struct buspkt *packet = (struct buspkt*)lbuffer; send_packet(packet); syslog_send("sent packet", strlen("sent packet")); _delay_ms(25); sendit = 0; eth_to_rs_cnt = 0; } #if 0 network_process(); if (uip_recvlen > 0) { syslog_send("handling ethernet packet", strlen("handling ethernet packet")); DBG("Handling packet\r\n"); handle_icmpv6(); if (uip_recvbuf[20] == 0x11) { syslog_send("handling udp packet", strlen("handling udp packet")); /* UDP */ uint8_t *udp = uip_recvbuf + 14 + 40; uint8_t len = udp[5] - 8; /* TODO: sanity check */ uint8_t *recvpayload = udp + 8 /* udp */; fmt_packet(lbuffer, uip_recvbuf[53], 0xFF, recvpayload, len); struct buspkt *packet = (struct buspkt*)lbuffer; //syslog_send("sending packet", strlen("sending packet")); send_packet(packet); _delay_ms(25); cnt = 85; syslog_send("ethernet to rs485 done", strlen("ethernet to rs485 done")); } //syslog_send("received a packet", strlen("received a packet")); buf[14] = uip_recvlen; //syslog_send(uip_recvbuf, uip_recvlen); uip_recvlen = 0; } #endif _delay_ms(10); if (cnt++ == 100) { fmt_packet(lbuffer, 1, 0, "ping", 4); struct buspkt *packet = (struct buspkt*)lbuffer; syslog_send("ping sent", strlen("ping sent")); send_packet(packet); cnt = 0; snprintf(obuf, sizeof(obuf), "cnt = %d, rem = %d\r\n", eth_to_rs_cnt, eth_to_rs_rem); syslog_send(obuf, strlen(obuf)); } uint8_t status = bus_status(); if (status == BUS_STATUS_IDLE) continue; if (status == BUS_STATUS_MESSAGE) { /* get a copy of the current packet */ struct buspkt *packet = current_packet(); uint8_t *walk = packet; uint8_t *payload = (uint8_t*)packet; payload += sizeof(struct buspkt); /* check for ping replies */ if (packet->destination == 0x00 && memcmp(payload, "pong", strlen("pong")) == 0) { syslog_send("pong received", strlen("pong received")); /* TODO: store that this controller is reachable */ /* check if the controller has any waiting messages */ if (payload[4] > 0) { /* request the message */ fmt_packet(lbuffer, packet->source, 0, "send", 4); struct buspkt *reply = (struct buspkt*)lbuffer; //syslog_send("sending packet", strlen("sending packet")); _delay_ms(25); send_packet(reply); syslog_send("sendreq sent", strlen("sendreq sent")); //syslog_send(reply, reply->length_lo + sizeof(struct buspkt)); _delay_ms(25); cnt = 0; } } #if 0 /* copy packet->destination into the MAC and IPv6 address */ uip_buf[5] = packet->destination; /* MAC */ uip_buf[53] = packet->destination; /* IPv6 */ /* copy packet->source into the MAC and IPv6 address */ uip_buf[11] = packet->source; /* MAC */ uip_buf[37] = packet->source; /* IPv6 */ raw_send(payload, packet->length_lo); #endif char minibuf[16]; snprintf(minibuf, sizeof(minibuf), "^%02d%02d", 0, packet->length_lo); uart_puts(minibuf); uint8_t c; for (c = 0; c < sizeof(struct buspkt); c++) { while ( !( UCSR0A & (1<<UDRE0)) ); UDR0 = walk[c]; } for (c = 0; c < packet->length_lo; c++) { while ( !( UCSR0A & (1<<UDRE0)) ); UDR0 = payload[c]; } while ( !( UCSR0A & (1<<UDRE0)) ); UDR0 = '$'; /* discard the packet from serial buffer */ packet_done(); continue; } if (status == BUS_STATUS_WRONG_CRC) { syslog_send("broken", strlen("broken")); struct buspkt *packet = current_packet(); raw_send(packet, 16); skip_byte(); continue; } } }