#include <arpa/inet.h>
#include <fcntl.h>
#include <errno.h>
+#include <signal.h>
#ifndef SO_BUSY_POLL
#define SO_BUSY_POLL 46
#endif
-#define FRAME_SIZE 256
+#define FRAME_SIZE 128
#define BLOCK_SIZE 4096
#define BLOCK_NR 2
#define FRAME_NR (BLOCK_NR*(BLOCK_SIZE/FRAME_SIZE))
int (*out_fn)(struct out_ctx *ctx, struct can_frame *cf);
};
+struct stats {
+ int store;
+ int send;
+} stats;
+
+void sigint(int v)
+{
+ printf("store:%d\nsend:%d\ntotal:%d\n",
+ stats.store, stats.send, stats.store + stats.send);
+ exit(0);
+}
+
enum in2out in_read(struct in_ctx *ctx, struct can_frame *cf)
{
int ret = read(ctx->s, cf, sizeof(*cf));
perror("read");
exit(1);
}
- return SEND;
+ return STORE_ONLY;
}
void init_read(struct in_ctx *ctx)
s = CHECK(socket(PF_CAN, SOCK_RAW, CAN_RAW));
+ int rcvbuf = 25000; /* Limit rcvbuf to not have so big queueing latencies */
+ CHECK(setsockopt(s, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)));
+
if (nonblocking) {
int flags = CHECK(fcntl(s, F_GETFL, 0));
CHECK(fcntl(s, F_SETFL, flags | O_NONBLOCK));
//struct sockaddr_ll *addr = (void*)hdr + TPACKET_ALIGN(ctx->hdrlen);
(void)ret;
struct can_frame *cf_mmap = (void*)hdr + hdr->tp_mac;
- //printf("ret:%d st:%#08x m:%d RX in frame %2d, CAN ID %#3x\n", ret, hdr->tp_status, hdr->tp_mac, ctx->current, cf_mmap->can_id);
*cf = *cf_mmap;
hdr->tp_status = 0;
ctx->current = (ctx->current + 1) % FRAME_NR;
int out_packet_tx(struct out_ctx *ctx, struct can_frame *cf)
{
volatile struct tpacket2_hdr *hdr = ctx->ptr + ctx->current*FRAME_SIZE;
- int ret = -1;
- if (ctx->from_in == NOP)
+ if (ctx->from_in == NOP) {
+ CHECK(send(ctx->s, NULL, 0, 0));
return 0;
-
+ }
while (hdr->tp_status != TP_STATUS_AVAILABLE) {
- struct pollfd pfd = {.fd = ctx->s, .revents = 0,
- .events = POLLIN|POLLRDNORM|POLLERR };
- ret = CHECK(poll(&pfd, 1, -1));
+ CHECK(send(ctx->s, NULL, 0, 0));
}
- (void)ret;
+
//struct sockaddr_ll *addr = (void*)hdr + TPACKET_HDRLEN - sizeof(struct sockaddr_ll);
struct can_frame *cf_mmap = (void*)hdr + TPACKET_HDRLEN - sizeof(struct sockaddr_ll);
*cf_mmap = *cf;
ctx->current = (ctx->current + 1) % FRAME_NR;
if (ctx->from_in == SEND){
- ret = CHECK(send(ctx->s, NULL, 0, 0));
+ CHECK(send(ctx->s, NULL, 0, 0));
return 0;
}
return 0;
if (optind+1 < argc)
devout = argv[optind+1];
+ signal(SIGINT, sigint);
gw();
return 0;