#include <ip_malloc.h>
#include <in_cksum.h>
+#include <Statistics.h>
module UdpP {
provides interface UDP[uint8_t clnt];
provides interface Init;
+ provides interface Statistics<udp_statistics_t>;
uses interface IP;
uses interface IPAddress;
} implementation {
+#ifdef PRINTFUART_ENABLED
+#undef dbg
+#define dbg(X,fmt, args...) printfUART(fmt, ##args)
+#endif
+
enum {
N_CLIENTS = uniqueCount("UDP_CLIENT"),
};
+ udp_statistics_t stats;
uint16_t local_ports[N_CLIENTS];
enum {
}
command error_t Init.init() {
+ call Statistics.clear();
ip_memclr((uint8_t *)local_ports, sizeof(uint16_t) * N_CLIENTS);
return SUCCESS;
}
return SUCCESS;
}
-
event void IP.recv(struct ip6_hdr *iph,
void *payload,
struct ip_metadata *meta) {
ip_memcpy(&addr.sin6_addr, &iph->ip6_src, 16);
addr.sin6_port = udph->srcport;
+
+ {
+ uint16_t rx_cksum = ntohs(udph->chksum), my_cksum;
+ vec_t cksum_vec[4];
+ uint32_t hdr[2];
+
+ udph->chksum = 0;
+
+ cksum_vec[0].ptr = (uint8_t *)(iph->ip6_src.s6_addr);
+ cksum_vec[0].len = 16;
+ cksum_vec[1].ptr = (uint8_t *)(iph->ip6_dst.s6_addr);
+ cksum_vec[1].len = 16;
+ cksum_vec[2].ptr = (uint8_t *)hdr;
+ cksum_vec[2].len = 8;
+ hdr[0] = iph->plen;
+ hdr[1] = htonl(IANA_UDP);
+ cksum_vec[3].ptr = payload;
+ cksum_vec[3].len = ntohs(iph->plen);
+
+ my_cksum = in_cksum(cksum_vec, 4);
+ printfUART("rx cksum: %x calc: %x\n", rx_cksum, my_cksum);
+ if (rx_cksum != my_cksum) {
+ BLIP_STATS_INCR(cksum);
+ return;
+ }
+ }
+
+ BLIP_STATS_INCR(rcvd);
signal UDP.recvfrom[i](&addr, (void *)(udph + 1), ntohs(iph->plen) - sizeof(struct udp_hdr), meta);
}
g_udp = (struct generic_header *)(udp + 1);
// fill in all the packet fields
- ip_memclr((uint8_t *)&msg->hdr, sizeof(struct ip6_hdr));
+ ip_memclr((uint8_t *)msg, sizeof(struct split_ip_msg));
ip_memclr((uint8_t *)udp, sizeof(struct udp_hdr));
setSrcAddr(msg);
memcpy(&msg->hdr.ip6_dst, dest->sin6_addr.s6_addr, 16);
- if (local_ports[clnt] == 0 && alloc_lport(clnt) == 0) return FAIL;
+ if (local_ports[clnt] == 0 && (local_ports[clnt] = alloc_lport(clnt)) == 0) {
+ ip_free(msg);
+ return FAIL;
+ }
udp->srcport = local_ports[clnt];
udp->dstport = dest->sin6_port;
udp->len = htons(len + sizeof(struct udp_hdr));
udp->chksum = htons(msg_cksum(msg, IANA_UDP));
rc = call IP.send(msg);
+ BLIP_STATS_INCR(sent);
ip_free(msg);
return rc;
}
+ command void Statistics.clear() {
+#ifdef BLIP_STATS
+ ip_memclr((uint8_t *)&stats, sizeof(udp_statistics_t));
+#endif
+ }
+
+ command void Statistics.get(udp_statistics_t *buf) {
+#ifdef BLIP_STATS
+ ip_memcpy(buf, &stats, sizeof(udp_statistics_t));
+#endif
+ }
+
default event void UDP.recvfrom[uint8_t clnt](struct sockaddr_in6 *from, void *payload,
uint16_t len, struct ip_metadata *meta) {