]> rtime.felk.cvut.cz Git - can-eth-gw.git/commitdiff
PowerPC benchmark
authorRadek Matějka <radek.matejka@gmail.com>
Wed, 28 Nov 2012 21:09:21 +0000 (15:09 -0600)
committerRadek Matějka <radek.matejka@gmail.com>
Wed, 28 Nov 2012 21:09:21 +0000 (15:09 -0600)
ppc folder was added. ppc folder contains files
used for benchmark on PowerPC. (eg. ppc executables, modified
sources, results)

30 files changed:
ppc/bench-kernel [new file with mode: 0755]
ppc/cegw-ppc/Makefile [new file with mode: 0644]
ppc/cegw-ppc/cegw [new file with mode: 0755]
ppc/cegw-ppc/cegw.c [new file with mode: 0644]
ppc/cesend/Makefile [new file with mode: 0644]
ppc/cesend/cesend [new file with mode: 0755]
ppc/cesend/cesend.c [new file with mode: 0644]
ppc/gw-kernel [new file with mode: 0755]
ppc/gw-user [new file with mode: 0755]
ppc/res/ncrcv [new file with mode: 0755]
ppc/res/plotres.m [new file with mode: 0644]
ppc/res/res.tar [new file with mode: 0644]
ppc/res/res1 [new file with mode: 0644]
ppc/res/res2 [new file with mode: 0644]
ppc/res/res3 [new file with mode: 0644]
ppc/res/res_u1 [new file with mode: 0644]
ppc/res/res_u2 [new file with mode: 0644]
ppc/res/res_u3 [new file with mode: 0644]
ppc/res/result/res1.raw [new file with mode: 0644]
ppc/res/result/res2.raw [new file with mode: 0644]
ppc/res/result/res3.raw [new file with mode: 0644]
ppc/res/result/res_k1.raw [new file with mode: 0644]
ppc/res/result/res_u1.raw [new file with mode: 0644]
ppc/res/result/res_u2.raw [new file with mode: 0644]
ppc/res/result/res_u3.raw [new file with mode: 0644]
ppc/shark_home.tar [new file with mode: 0644]
ppc/test [new file with mode: 0755]
ppc/user/Makefile [new file with mode: 0644]
ppc/user/canethgw [new file with mode: 0755]
ppc/user/canethgw.c [new file with mode: 0644]

diff --git a/ppc/bench-kernel b/ppc/bench-kernel
new file mode 100755 (executable)
index 0000000..22180af
--- /dev/null
@@ -0,0 +1,25 @@
+#!/bin/sh
+N=100
+MODE=oneattime
+SLEEP=1
+LOGANDPRINT="tee -a result | cut -c 2-"
+RESULTFILE=/dev/null
+SENDRES=0
+
+if test $# -eq 1; then
+       RESULTFILE=$1
+       SENDRES=1
+fi
+
+#-----------------
+# bench kernel
+#-----------------
+
+sleep $SLEEP
+echo "#kernel udp->can: " | tee -a result | cut -c 2-
+cegwbench -s udp@127.0.0.1:10501 -d can@vcan0 -n $N -m $MODE -t 1 >> $RESULTFILE
+
+sleep $SLEEP
+echo "#kernel can->udp: " | tee -a result | cut -c 2-
+cegwbench -s can@vcan0 -d udp@127.0.0.1:10502 -n $N -m $MODE -t 1 >> $RESULTFILE
+
diff --git a/ppc/cegw-ppc/Makefile b/ppc/cegw-ppc/Makefile
new file mode 100644 (file)
index 0000000..b8214a9
--- /dev/null
@@ -0,0 +1,5 @@
+all:
+       powerpc-linux-gnu-gcc -Wall -ggdb -ocegw -I../../kernel cegw.c
+install: all
+       scp cegw glab:/srv/nfs/root-shark/home/matejra4
+
diff --git a/ppc/cegw-ppc/cegw b/ppc/cegw-ppc/cegw
new file mode 100755 (executable)
index 0000000..5a62abe
Binary files /dev/null and b/ppc/cegw-ppc/cegw differ
diff --git a/ppc/cegw-ppc/cegw.c b/ppc/cegw-ppc/cegw.c
new file mode 100644 (file)
index 0000000..86ac0ee
--- /dev/null
@@ -0,0 +1,559 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <libgen.h>
+#include <string.h>
+#include <getopt.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <net/if.h>
+//#include <libnetlink.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <arpa/inet.h>
+#include <linux/can.h>
+#include <linux/types.h>
+#include <unistd.h>
+#include "canethgw.h"
+
+/**
+ * ToDo:
+ * [ ] print usage, on -h and plain execution
+ * [ ] start/stop listening
+ * [ ] split to files
+ */
+
+#define CEGW_CMD_ADD     1
+#define CEGW_CMD_LIST    2
+#define CEGW_CMD_FLUSH   4
+#define CEGW_CMD_LISTEN  8
+
+/* PowerPC encore */
+#define RTCAN_RTA(r)  ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct rtcanmsg))))
+#define RTCAN_PAYLOAD(n) NLMSG_PAYLOAD(n,sizeof(struct rtcanmsg))
+
+/* some netlink helpers stolen from iproute2 package */
+#define NLMSG_TAIL(nmsg) \
+        ((struct rtattr *)(((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
+#define AF_CAN 29
+
+int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
+              int alen)
+{
+        int len = RTA_LENGTH(alen);
+        struct rtattr *rta;
+
+        if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
+                fprintf(stderr, "addattr_l: message exceeded bound of %d\n",
+                        maxlen);
+                return -1;
+        }
+        rta = NLMSG_TAIL(n);
+        rta->rta_type = type;
+        rta->rta_len = len;
+        memcpy(RTA_DATA(rta), data, alen);
+        n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
+        return 0;
+}
+
+int addattr32(struct nlmsghdr *n, int maxlen, int type, __u32 data)
+{
+        return addattr_l(n, maxlen, type, &data, sizeof(__u32));
+}
+
+enum
+{
+       IF_UNDEF,
+       IF_CAN,
+       IF_ETH_UDP
+};
+
+struct cegw_data
+{
+       int content;
+       int src_if, dst_if;
+       int can_ifidx;
+       struct in_addr eth_addr;
+       unsigned short eth_port;
+       struct in_addr eth_listen_addr;
+       unsigned short eth_listen_port;
+};
+
+struct cegw_nlmsg 
+{
+       struct nlmsghdr nh;
+       struct rtmsg rt;
+       char buf[768]; /* enough? */
+};
+
+struct list_item
+{
+       int type;
+       int can;
+       struct in_addr ip;
+       unsigned short port;
+};
+
+unsigned int cegw_errno = 0;
+
+enum 
+{
+       CEGW_ERR_UNKNOWN,
+       CEGW_ERR_IF_UNSPEC,
+       CEGW_ERR_IF_SAME,
+       CEGW_ERR_IF_TYPE,
+       CEGW_ERR_IF_CAN,
+       CEGW_ERR_IF_ETH,
+       CEGW_ERR_COLON,
+       CEGW_ERR_ATON,
+       CEGW_ERR_PORT
+};
+
+char* cegw_errlist[] =
+{
+       [ CEGW_ERR_UNKNOWN   ] = "",
+       [ CEGW_ERR_IF_UNSPEC ] = "source or destination not specified",
+       [ CEGW_ERR_IF_SAME   ] = "source and destination have same interface type",
+       [ CEGW_ERR_IF_TYPE   ] = "unknown interface type",
+       [ CEGW_ERR_IF_CAN    ] = "invalid can interface",
+       [ CEGW_ERR_IF_ETH    ] = "invalid eth interface",
+       [ CEGW_ERR_COLON     ] = "expected ':' (<ip>:<port>)",
+       [ CEGW_ERR_ATON      ] = "ip address mismatch",
+       [ CEGW_ERR_PORT      ] = "port number"
+};
+
+static void perr( char* s )
+{
+       if( s )
+       {
+               if( cegw_errno == 0 )
+               {
+                       fprintf( stderr, "error: %s\n", s );
+
+               } else
+               {
+                       fprintf( stderr, "error: %s, %s\n", s,
+                                cegw_errlist[ cegw_errno ] );
+               }
+               return;
+       }
+
+       fprintf( stderr, "error: %s\n", cegw_errlist[ cegw_errno ] );
+}
+
+/**
+ * read_addrport - parses @in for eth address. 
+ * Valid input is e.g. udp@127.0.0.1:10502 or can@vcan0.
+ *
+ * @param[in]  in   string to search in
+ * @param[out] addr ip address
+ * @param[out] port transport layer port
+ * @return 0 on success, -1 otherwise
+ */
+int read_addrport( char* in, struct in_addr* addr, unsigned short* port )
+{
+       char* delim = NULL;
+       char addrstr[16];
+       int addrlen;
+       
+       if( (delim = strchr( in, ':' )) == NULL )
+       {
+               cegw_errno = CEGW_ERR_COLON;
+               return -1;
+       }
+
+       /* get address */
+       /* ToDo: overflow */
+       addrlen = delim - in;
+       memcpy( addrstr, in, addrlen );
+       addrstr[addrlen] = '\0';
+       if( inet_aton( addrstr, addr ) == 0 )
+       {
+               cegw_errno = CEGW_ERR_ATON;
+               return -1;
+       }
+
+       /* get port */
+       if( sscanf( delim, ":%hu", port ) != 1 ) /* ToDo: handle overflow */
+       {
+               cegw_errno = CEGW_ERR_PORT;
+               return -1;
+       }
+
+       return 0;
+}
+
+/**
+ * read_iftype - reads @in for iftype
+ * Iftype type is e.g. "can@" or "udp@".
+ *
+ * @param[in] in string to search in
+ * @param[out] iftype iftype detected
+ * @return pointer to @in after iftype on success, NULL otherwise
+ */
+char* read_iftype( char* in, int* iftype )
+{
+       char* ret = in+4;
+       
+       if( strncmp( "udp@", optarg, 4 ) == 0 )
+       {
+               *iftype = IF_ETH_UDP;
+               return ret;
+       }
+       /*
+       if( strncmp( "tcp@", optarg, 4 ) == 0 )
+       {
+               return NULL;
+       }
+       */
+       if( strncmp( "can@", optarg, 4 ) == 0 )
+       {
+               *iftype = IF_CAN;
+               return ret;
+       }
+       
+       cegw_errno = CEGW_ERR_IF_TYPE;
+       return NULL;
+}
+
+/* ToDo: move to common */
+
+/**
+ * read_if - reads interface from @in
+ * Function analyzes @in for interface specification in format
+ * <if>@<ip>:<port>, where <if> is can or udp, <ip> is address in dotted
+ * format
+ *
+ * @param[in]  in string to search in
+ * @param[out] iftype interface type (IF_CAN or IF_ETH_UDP)
+ * @param[out] d ip and port is stored to @d
+ */
+int read_if( char* in, int* iftype, struct cegw_data* d )
+{
+       char* optstr = NULL;
+
+       if( (optstr = read_iftype( in, iftype )) == NULL )
+       {
+               return -1;
+       }
+
+       switch( *iftype )
+       {
+               case IF_CAN:
+                       d->can_ifidx = if_nametoindex( optstr );
+                       if( d->can_ifidx == 0 )
+                       {
+                               cegw_errno = CEGW_ERR_IF_CAN;
+                               return -1;
+                       }
+                       break;
+               case IF_ETH_UDP:
+                       if( read_addrport( optstr, &d->eth_addr, &d->eth_port ) != 0 )
+                       {
+                               return -1;
+                       }
+                       break;
+               default:
+                       return -1;
+                       break;
+       }
+
+       return 0;
+}
+
+inline static int cegw_add( struct cegw_nlmsg* req, struct cegw_data* d )
+{
+       int gwtype = 0;
+
+       req->nh.nlmsg_type  = RTM_NEWROUTE;
+       if( (d->src_if == 0 || d->dst_if == 0) )
+       {
+               cegw_errno = CEGW_ERR_IF_UNSPEC;
+               return -cegw_errno;
+       }
+
+       if( d->src_if == d->dst_if )
+       {
+               cegw_errno = CEGW_ERR_IF_SAME;
+               return -cegw_errno;
+       }
+
+       gwtype = (d->src_if == IF_CAN) ? CEGW_RULE_CAN_ETH : CEGW_RULE_ETH_CAN;
+       addattr_l( &req->nh, sizeof(*req), CEGW_CAN_IFINDEX, &d->can_ifidx, sizeof(d->can_ifidx) );
+       addattr_l( &req->nh, sizeof(*req), CEGW_ETH_IP, &d->eth_addr, sizeof(d->eth_addr) );
+       addattr_l( &req->nh, sizeof(*req), CEGW_ETH_PORT, &d->eth_port, sizeof(d->eth_port) );
+       addattr32( &req->nh, sizeof(*req), CEGW_CMD_INFO, gwtype );
+
+       return 0;
+}
+
+inline static int cegw_listen( struct cegw_nlmsg* req, struct cegw_data* d )
+{
+       req->nh.nlmsg_type = RTM_NEWROUTE;
+       addattr32( &req->nh, sizeof(*req), CEGW_CMD_INFO, CEGW_LISTEN );
+       addattr_l( &req->nh, sizeof(*req), CEGW_ETH_IP, &d->eth_listen_addr, sizeof(d->eth_listen_addr) );
+       addattr_l( &req->nh, sizeof(*req), CEGW_ETH_PORT, &d->eth_listen_port, sizeof(d->eth_listen_port) );
+
+       return 0;
+}
+
+inline static int cegw_list( struct cegw_nlmsg* req, struct cegw_data* d )
+{
+       req->nh.nlmsg_type = RTM_GETROUTE;
+       req->nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
+       
+       return 0;
+}
+
+inline static int cegw_flush( struct cegw_nlmsg* req, struct cegw_data* d )
+{
+       addattr32( &req->nh, sizeof(*req), CEGW_CMD_INFO, CEGW_FLUSH );
+       req->nh.nlmsg_type  = RTM_DELROUTE;
+       return 0;
+}
+
+void print_list_item( struct list_item* li )
+{
+       char ifname[IF_NAMESIZE];
+       const char src_width = 21;
+       char* dotaddr;
+       int tmp;
+
+       if( if_indextoname( li->can, ifname ) == NULL )
+       {
+               strncpy( ifname, "unknown", IF_NAMESIZE );
+       }
+
+       /* ToDo listening at */
+       switch( li->type )
+       {
+               case CEGW_RULE_CAN_ETH:
+                       printf( "can@%-*s -> udp@%s:%hu\n", src_width, ifname, \
+                                inet_ntoa(li->ip), li->port );
+                       break;
+               case CEGW_RULE_ETH_CAN:
+                       dotaddr = inet_ntoa(li->ip);
+                       tmp = src_width - strlen(dotaddr) - 1;
+                       printf( "udp@%s:%-*hu -> can@%s\n", inet_ntoa(li->ip), \
+                                tmp, li->port, ifname );
+                       break;
+       }
+}
+
+int main( int argc, char* argv[] )
+{
+       int s;
+       int tmp = 0;
+       int cmd = 0;
+       char* optstr;
+       char opt;
+       struct sockaddr_nl nladdr;
+       int err = 0;
+       struct cegw_nlmsg req;
+       struct cegw_data d;
+       char rxbuf[8192]; /* ToDo: /linux/netlink.h? */
+       int rsize = 0;
+       struct nlmsghdr* nlh;
+       struct nlmsgerr* rte;
+       struct rtattr* rta;
+       int len;
+       struct list_item li;
+
+       memset( &d, 0, sizeof(d) );
+
+       struct option long_opt[] =
+       {
+               { "add"   , 0, NULL, 'A' },
+               { "flush" , 0, NULL, 'F' },
+               { "list"  , 0, NULL, 'L' },
+               { "listen", 1, NULL, 'l' },
+               { 0, 0, 0, 0 }
+       };
+
+       while( 1 )
+       {
+               opt = getopt_long( argc, argv, "AFLl:s:d:", long_opt, NULL );
+               if( opt == -1 )
+                       break;
+
+               //printf( "optarg=%s\n", optarg );
+               switch( opt )
+               {
+                       case 'A':
+                               cmd |= CEGW_CMD_ADD;
+                               break;
+                       case 'F':
+                               cmd |= CEGW_CMD_FLUSH;
+                               break;
+                       case 'L':
+                               cmd |= CEGW_CMD_LIST;
+                               break;
+                       case 'l':
+                               cmd |= CEGW_CMD_LISTEN;
+                               if( (optstr = read_iftype( optarg, &tmp )) == NULL )
+                               {
+                                       perr( "'--listen'" );
+                                       return -1;
+                               }       
+                               if( tmp != IF_ETH_UDP )
+                               {
+                                       perr( "'--listen' expects udp interface" );
+                                       return -1;
+                               }       
+                               if( read_addrport( optstr, &d.eth_listen_addr, &d.eth_listen_port ) )
+                               {
+                                       perr( "'--listen'" );
+                                       return -1;
+                               }
+                               break;
+                       case 's':
+                               if( read_if( optarg, &d.src_if, &d ) != 0 )
+                               {
+                                       perr( "'-s'" );
+                                       return -1;
+                               }
+                               break;
+                       case 'd':
+                               if( read_if( optarg, &d.dst_if, &d ) != 0 )
+                               {
+                                       perr( "'-d'" );
+                                       return -1;
+                               }
+                               break;
+                       case '?':
+                               return -1;
+                               break;
+                       default:
+                               //fprintf( stderr, "unknown option: %u\n", opt );
+                               goto while_break;
+                               //return -1;
+                               break;
+               }                               
+       }
+
+       while_break:
+
+       /* prepare netlink message */
+       req.nh.nlmsg_len   = NLMSG_LENGTH( sizeof(struct rtmsg) );
+       //req.nh.nlmsg_type;
+       req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+       req.nh.nlmsg_seq   = 0;
+       req.nh.nlmsg_pid   = 0; /* ? */
+
+       memset( &req.rt, 0, sizeof(req.rt) );
+       req.rt.rtm_family = AF_CAN;
+
+       switch( cmd )
+       {
+               case 0:
+                       perr( "command not specified" );
+                       return -1;
+                       break;
+               case CEGW_CMD_ADD:
+                       if( cegw_add( &req, &d ) != 0 )
+                       {
+                               perr( "'--add'" );
+                               return -1;
+                       }
+                       break;
+               case CEGW_CMD_FLUSH:
+                       cegw_flush( &req, &d );
+                       break;
+               case CEGW_CMD_LIST:
+                       cegw_list( &req, &d );
+                       break;
+               case CEGW_CMD_LISTEN:
+                       cegw_listen( &req, &d );
+                       break;
+               default:
+                       perr( "command mismatch" );
+                       break;
+       }
+
+       /* send over netlink socket */
+       s = socket( PF_NETLINK, SOCK_RAW, NETLINK_ROUTE ); /* chck */
+       
+       memset( &nladdr, 0, sizeof(nladdr) );
+       nladdr.nl_family = AF_NETLINK;
+       nladdr.nl_pad = 0;
+       nladdr.nl_pid = 0;
+       nladdr.nl_groups = 0;
+
+       err = sendto( s, &req, req.nh.nlmsg_len, 0, 
+                     (struct sockaddr*)&nladdr, sizeof(nladdr) );
+       if( err < 0 )
+       {
+               perror( "netlink sendto" );
+               return -1;
+       }
+       
+       /* recv */
+       rsize = recv( s, &rxbuf, sizeof(rxbuf), 0 );
+       if( rsize < 0 )
+       {
+               perr( "recv" );
+               return -1;
+       }
+       nlh = (struct nlmsghdr*)rxbuf;
+
+       if( nlh->nlmsg_type == NLMSG_ERROR )
+       {
+               rte = (struct nlmsgerr*)NLMSG_DATA( nlh );
+               err = rte->error;
+
+               if( err == 0  )
+               {
+                       printf( "%s\n", strerror(abs(err)) );
+                       return 0;
+               } else
+               {
+                       printf( "netlink error: %s\n", strerror(abs(err)) );
+                       return -1;
+               }
+       }
+
+       if( cmd & CEGW_CMD_LIST )
+       {
+               /* ToDo recv while */
+               printf( "%10ssource%20sdestination\n", "", "" );
+               while( 1 )
+               {
+                       if( !NLMSG_OK( nlh, rsize ) )
+                       {
+                               break;
+                       }
+                       if( nlh->nlmsg_type == NLMSG_DONE )
+                       {
+                               break;
+                       }
+                       /* ToDo: NLMSG_ERR */
+                       rta = NLMSG_DATA( nlh );
+                       len = NLMSG_PAYLOAD( nlh, 0 );
+                       for( ;RTA_OK(rta, len); rta = RTA_NEXT(rta,len) )
+                       {
+                               switch( rta->rta_type )
+                               {
+                                       case CEGW_TYPE:
+                                               li.type = *(int*)RTA_DATA(rta);
+                                               break;
+                                       case CEGW_CAN_IFINDEX:
+                                               li.can = *(int*)RTA_DATA(rta);
+                                               break;
+                                       case CEGW_ETH_IP:
+                                               li.ip = *(struct in_addr*)RTA_DATA(rta);
+                                               break;
+                                       case CEGW_ETH_PORT:
+                                               li.port = *(unsigned short*)RTA_DATA(rta);
+                                               break;
+                                       /* case CGW_ETH_PROTO */
+                               }
+                       }
+
+                       print_list_item( &li );
+
+                       nlh = NLMSG_NEXT( nlh, rsize );
+               }
+       }
+
+       return 0;
+}
+
diff --git a/ppc/cesend/Makefile b/ppc/cesend/Makefile
new file mode 100644 (file)
index 0000000..4e05b6f
--- /dev/null
@@ -0,0 +1,3 @@
+all:
+       gcc -Wall -ocesend cesend.c
+
diff --git a/ppc/cesend/cesend b/ppc/cesend/cesend
new file mode 100755 (executable)
index 0000000..5480c96
Binary files /dev/null and b/ppc/cesend/cesend differ
diff --git a/ppc/cesend/cesend.c b/ppc/cesend/cesend.c
new file mode 100644 (file)
index 0000000..fb36d92
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * cesend.c - simple command line tool to send CAN-frames via udp
+ * cesend is a fork of cansend from Socket-CAN project.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+
+#include <linux/can.h>
+#include <linux/can/raw.h>
+
+#define CANID_DELIM '#'
+#define DATA_SEPERATOR '.'
+
+unsigned char asc2nibble(char c) {
+
+       if ((c >= '0') && (c <= '9'))
+               return c - '0';
+
+       if ((c >= 'A') && (c <= 'F'))
+               return c - 'A' + 10;
+
+       if ((c >= 'a') && (c <= 'f'))
+               return c - 'a' + 10;
+
+       return 16; /* error */
+}
+
+int parse_canframe(char *cs, struct can_frame *cf) {
+       /* documentation see lib.h */
+
+       int i, idx, dlc, len;
+       unsigned char tmp;
+
+       len = strlen(cs);
+       //printf("'%s' len %d\n", cs, len);
+
+       memset(cf, 0, sizeof(*cf)); /* init CAN frame, e.g. DLC = 0 */
+
+       if (len < 4)
+               return 1;
+
+       if (cs[3] == CANID_DELIM) { /* 3 digits */
+
+               idx = 4;
+               for (i=0; i<3; i++){
+                       if ((tmp = asc2nibble(cs[i])) > 0x0F)
+                               return 1;
+                       cf->can_id |= (tmp << (2-i)*4);
+               }
+
+       } else if (cs[8] == CANID_DELIM) { /* 8 digits */
+
+               idx = 9;
+               for (i=0; i<8; i++){
+                       if ((tmp = asc2nibble(cs[i])) > 0x0F)
+                               return 1;
+                       cf->can_id |= (tmp << (7-i)*4);
+               }
+               if (!(cf->can_id & CAN_ERR_FLAG)) /* 8 digits but no errorframe?  */
+                       cf->can_id |= CAN_EFF_FLAG;   /* then it is an extended frame */
+
+       } else
+               return 1;
+
+       if((cs[idx] == 'R') || (cs[idx] == 'r')){ /* RTR frame */
+               cf->can_id |= CAN_RTR_FLAG;
+               return 0;
+       }
+
+       for (i=0, dlc=0; i<8; i++){
+
+               if(cs[idx] == DATA_SEPERATOR) /* skip (optional) seperator */
+                       idx++;
+
+               if(idx >= len) /* end of string => end of data */
+                       break;
+
+               if ((tmp = asc2nibble(cs[idx++])) > 0x0F)
+                       return 1;
+               cf->data[i] = (tmp << 4);
+               if ((tmp = asc2nibble(cs[idx++])) > 0x0F)
+                       return 1;
+               cf->data[i] |= tmp;
+               dlc++;
+       }
+
+       cf->can_dlc = dlc;
+
+       return 0;
+}
+
+int main(int argc, char **argv)
+{
+       int s; /* can raw socket */ 
+       int nbytes;
+       struct sockaddr_in addr;
+       struct can_frame frame;
+
+       /* check command line options */
+       if (argc != 2) {
+               fprintf(stderr, "Usage: %s <can_frame>.\n", argv[0]);
+               return 1;
+       }
+
+       /* parse CAN frame */
+       if (parse_canframe(argv[1], &frame)){
+               fprintf(stderr, "\nWrong CAN-frame format!\n\n");
+               fprintf(stderr, "Try: <can_id>#{R|data}\n");
+               fprintf(stderr, "can_id can have 3 (SFF) or 8 (EFF) hex chars\n");
+               fprintf(stderr, "data has 0 to 8 hex-values that can (optionally)");
+               fprintf(stderr, " be seperated by '.'\n\n");
+               fprintf(stderr, "e.g. 5A1#11.2233.44556677.88 / 123#DEADBEEF / ");
+               fprintf(stderr, "5AA# /\n     1F334455#1122334455667788 / 123#R ");
+               fprintf(stderr, "for remote transmission request.\n\n");
+               return 1;
+       }
+
+       /* open socket */
+       if(( s = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0 ) {
+               perror("socket");
+               return 1;
+       }
+
+       addr.sin_family = AF_INET;
+       inet_aton( "192.168.2.3", &addr.sin_addr );
+       addr.sin_port = htons( 10501 );
+
+       /* send frame */
+       if ((nbytes = sendto(s, &frame, sizeof(frame), 0, (struct sockaddr*)&addr, sizeof(addr))) != sizeof(frame)) {
+               perror("write");
+               return 1;
+       }
+
+       close(s);
+
+       return 0;
+}
+
diff --git a/ppc/gw-kernel b/ppc/gw-kernel
new file mode 100755 (executable)
index 0000000..96caffe
--- /dev/null
@@ -0,0 +1,8 @@
+# setup kernel canethgw
+
+insmod canethgw.ko
+
+./cegw --listen udp@127.0.0.1:10501
+./cegw --add -s can@can0 -d udp@127.0.0.1:10502
+./cegw --add -s udp@127.0.0.1:10502 -d can@can0
+
diff --git a/ppc/gw-user b/ppc/gw-user
new file mode 100755 (executable)
index 0000000..0d54deb
--- /dev/null
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+# user
+canethgw -s can@can0 -d udp@127.0.0.1:10502 -l udp@127.0.0.1:10501
+
diff --git a/ppc/res/ncrcv b/ppc/res/ncrcv
new file mode 100755 (executable)
index 0000000..f9e39d5
--- /dev/null
@@ -0,0 +1,18 @@
+#!/bin/bash
+PORT=10600
+ID=`ls -1 result | tail -1 | grep -o "[0-9]*\." | sed "s/\.//"`
+echo -n "nc listening on $PORT: "
+nc -l -p $PORT > res
+
+if [ -z $ID ]; then
+       let id=1
+else
+       let id=ID+1
+fi;
+
+FILENAME=result$id
+mv res result/$FILENAME.dat
+cd result
+sed /^#/d $FILENAME.dat > $FILENAME.raw
+echo "done"
+
diff --git a/ppc/res/plotres.m b/ppc/res/plotres.m
new file mode 100644 (file)
index 0000000..e256337
--- /dev/null
@@ -0,0 +1,31 @@
+function [] = plotres( filename )
+% plots canethgw benchmark data
+data = dlmread( ["result/" filename ".raw"] );
+
+figure;
+hold on;
+semilogy( data(1,:), "r" );
+semilogy( data(2,:), "g" );
+semilogy( data(3,:), "b" );
+semilogy( data(4,:), "m" );
+axis tight;
+
+title( 'can-eth-gw performance' );
+legend( "kernel udp->can", "kernel can->udp", "user udp->can",\
+        "user can->udp");
+xlabel( "can frame [id]" );
+ylabel( "transmission duration [ns]" );
+
+kern_udp_can_mean = mean( data(1,:), 2 );
+kern_can_udp_mean = mean( data(2,:), 2 );
+user_udp_can_mean = mean( data(3,:), 2 );
+user_can_udp_mean = mean( data(4,:), 2 );
+printf( "kern_udp_can_mean/user_udp_can_mean=%f\n", kern_udp_can_mean/user_udp_can_mean );
+printf( "kern_can_udp_mean/user_can_udp_mean=%f\n", kern_can_udp_mean/user_can_udp_mean );
+
+kern_mean = mean( [data(1,:) data(2,:)], 2 )
+user_mean = mean( [data(3,:) data(4,:)], 2 )
+printf( "kern_mean/user_mean=%f\n", kern_mean/user_mean );
+
+end
+
diff --git a/ppc/res/res.tar b/ppc/res/res.tar
new file mode 100644 (file)
index 0000000..b01f8ed
Binary files /dev/null and b/ppc/res/res.tar differ
diff --git a/ppc/res/res1 b/ppc/res/res1
new file mode 100644 (file)
index 0000000..ad3a858
--- /dev/null
@@ -0,0 +1,4 @@
+#./cegwbench -s udp@192.168.2.3:10501 -d can@can0 -n 64 -m oneattime -t 1 
+508509.000000  366680.000000   369080.000000   381298.000000   369731.000000   366255.000000   370514.000000   371171.000000   369407.000000   371704.000000   369084.000000   368790.000000   369425.000000   466102.000000   369236.000000   369278.000000   371878.000000   369913.000000   372870.000000   370063.000000   369894.000000   369238.000000   372297.000000   368651.000000   382257.000000   373439.000000   373781.000000   371012.000000   374773.000000   370796.000000   371468.000000   371678.000000   368997.000000   364622.000000   453608.000000   366568.000000   364999.000000   365181.000000   365014.000000   363227.000000   370870.000000   365133.000000   363718.000000   364894.000000   364267.000000   370624.000000   361623.000000   362974.000000   378344.000000   364764.000000   365786.000000   365943.000000   364707.000000   361852.000000   364319.000000   470610.000000   364886.000000   363546.000000   361827.000000   363505.000000   365344.000000   363767.000000   365673.000000   363737.000000   
+#./cegwbench -s can@can0 -d udp@0.0.0.0:10502 -n 64 -m oneattime -t 1 
+472405.000000  382137.000000   383320.000000   381887.000000   442729.000000   378265.000000   383522.000000   382792.000000   382956.000000   382642.000000   383235.000000   382159.000000   383241.000000   383060.000000   415087.000000   384347.000000   381718.000000   382535.000000   383793.000000   382822.000000   383273.000000   383608.000000   395475.000000   378440.000000   414958.000000   383323.000000   382788.000000   393884.000000   378269.000000   383472.000000   383899.000000   382597.000000   383577.000000   382869.000000   699382.000000   405599.000000   383151.000000   383817.000000   384809.000000   382853.000000   383912.000000   382419.000000   384268.000000   383471.000000   298357.000000   377119.000000   385298.000000   385216.000000   385242.000000   385878.000000   386027.000000   385597.000000   386266.000000   384709.000000   416221.000000   383715.000000   382596.000000   382802.000000   384368.000000   382677.000000   383860.000000   383526.000000   383937.000000   383295.000000   
diff --git a/ppc/res/res2 b/ppc/res/res2
new file mode 100644 (file)
index 0000000..7137d49
--- /dev/null
@@ -0,0 +1,4 @@
+#./cegwbench -s udp@192.168.2.3:10501 -d can@can0 -n 64 -m oneattime -t 1 
+500260.000000  365021.000000   372033.000000   387458.000000   368296.000000   365707.000000   386015.000000   483808.000000   344690.000000   343036.000000   340453.000000   338133.000000   339172.000000   385992.000000   373235.000000   365865.000000   369685.000000   367056.000000   398233.000000   368394.000000   370864.000000   370586.000000   370965.000000   374419.000000   372999.000000   370180.000000   371710.000000   369308.000000   459231.000000   370657.000000   376748.000000   368383.000000   367916.000000   367834.000000   365449.000000   363782.000000   363776.000000   363733.000000   364341.000000   402966.000000   360782.000000   367260.000000   365210.000000   364919.000000   363833.000000   363570.000000   364026.000000   362874.000000   364844.000000   363593.000000   339372.000000   367485.000000   366399.000000   363945.000000   365195.000000   362742.000000   364344.000000   365187.000000   364465.000000   375529.000000   453635.000000   364567.000000   371492.000000   365629.000000   
+#./cegwbench -s can@can0 -d udp@0.0.0.0:10502 -n 64 -m oneattime -t 1 
+478155.000000  387482.000000   388466.000000   389489.000000   388966.000000   389578.000000   387678.000000   390322.000000   475484.000000   401216.000000   389009.000000   389742.000000   389658.000000   389767.000000   388703.000000   385375.000000   387442.000000   389856.000000   475104.000000   395687.000000   385354.000000   388908.000000   389711.000000   389453.000000   402621.000000   384565.000000   388038.000000   389544.000000   420445.000000   391400.000000   388940.000000   389805.000000   388660.000000   390145.000000   400934.000000   382027.000000   388426.000000   390410.000000   420732.000000   391938.000000   388925.000000   390831.000000   389303.000000   389658.000000   401676.000000   382205.000000   391506.000000   392286.000000   422484.000000   392848.000000   391315.000000   392313.000000   392428.000000   390653.000000   390728.000000   389022.000000   388530.000000   390065.000000   420130.000000   390541.000000   389121.000000   390083.000000   389024.000000   390111.000000   
diff --git a/ppc/res/res3 b/ppc/res/res3
new file mode 100644 (file)
index 0000000..f8cf2b0
--- /dev/null
@@ -0,0 +1,4 @@
+#./cegwbench -s udp@192.168.2.3:10501 -d can@can0 -n 64 -m oneattime -t 1 
+474596.000000  367429.000000   368155.000000   371446.000000   377213.000000   369393.000000   369757.000000   379663.000000   463456.000000   375854.000000   370329.000000   367949.000000   368000.000000   365562.000000   372220.000000   367093.000000   370200.000000   368279.000000   369815.000000   380477.000000   383617.000000   364807.000000   368976.000000   368178.000000   389906.000000   368600.000000   369475.000000   369867.000000   368989.000000   398289.000000   373103.000000   369835.000000   371471.000000   362925.000000   366396.000000   366023.000000   365509.000000   362832.000000   365325.000000   362404.000000   401411.000000   361977.000000   365241.000000   365943.000000   364765.000000   361749.000000   363387.000000   360916.000000   367526.000000   363239.000000   458649.000000   364484.000000   365791.000000   366359.000000   365432.000000   365579.000000   365552.000000   374369.000000   364921.000000   363723.000000   367383.000000   406038.000000   366299.000000   363605.000000   
+#./cegwbench -s can@can0 -d udp@0.0.0.0:10502 -n 64 -m oneattime -t 1 
+460820.000000  384512.000000   385838.000000   407754.000000   382736.000000   384663.000000   488640.000000   380106.000000   386253.000000   385823.000000   385113.000000   385955.000000   385807.000000   387643.000000   384018.000000   386253.000000   477010.000000   387663.000000   385508.000000   386029.000000   386890.000000   396456.000000   381902.000000   387371.000000   383811.000000   385328.000000   428820.000000   381787.000000   386112.000000   385706.000000   386679.000000   385377.000000   385629.000000   387057.000000   384043.000000   386464.000000   471948.000000   387701.000000   386662.000000   386481.000000   386329.000000   397635.000000   379800.000000   387458.000000   384717.000000   387483.000000   430649.000000   381611.000000   387860.000000   388770.000000   388056.000000   389123.000000   387609.000000   387737.000000   385021.000000   385686.000000   470605.000000   389097.000000   386284.000000   385150.000000   386393.000000   392780.000000   382870.000000   386906.000000   
diff --git a/ppc/res/res_u1 b/ppc/res/res_u1
new file mode 100644 (file)
index 0000000..9bc9004
--- /dev/null
@@ -0,0 +1,4 @@
+#./cegwbench -s udp@192.168.2.3:10501 -d can@can0 -n 64 -m oneattime -t 1 
+569117.000000  445029.000000   406026.000000   450723.000000   412977.000000   403275.000000   404396.000000   398667.000000   405548.000000   404127.000000   529507.000000   534719.000000   421538.000000   405489.000000   404986.000000   402724.000000   404648.000000   400519.000000   403534.000000   496821.000000   414321.000000   404835.000000   401422.000000   404789.000000   407624.000000   407788.000000   404842.000000   404570.000000   420453.000000   453340.000000   417036.000000   411885.000000   404864.000000   401060.000000   402221.000000   397697.000000   404325.000000   401678.000000   495466.000000   404493.000000   403394.000000   398816.000000   399600.000000   401035.000000   405883.000000   403005.000000   403009.000000   398826.000000   430346.000000   397971.000000   403027.000000   396967.000000   404594.000000   417999.000000   400145.000000   397699.000000   401815.000000   403035.000000   400283.000000   413487.000000   412221.000000   403473.000000   399506.000000   402272.000000   
+#./cegwbench -s can@can0 -d udp@0.0.0.0:10502 -n 64 -m oneattime -t 1 
+501823.000000  447632.000000   452955.000000   454020.000000   453817.000000   453735.000000   484704.000000   462224.000000   444710.000000   451900.000000   455313.000000   452260.000000   453549.000000   453692.000000   454835.000000   470707.000000   458149.000000   451630.000000   454100.000000   454887.000000   454681.000000   455154.000000   454050.000000   532459.000000   455581.000000   453478.000000   453077.000000   453833.000000   454764.000000   453515.000000   455714.000000   454427.000000   370950.000000   456705.000000   452922.000000   453302.000000   454434.000000   454039.000000   454081.000000   453643.000000   454800.000000   340729.000000   455031.000000   452959.000000   454275.000000   452304.000000   465016.000000   441042.000000   454640.000000   549677.000000   443658.000000   454118.000000   452257.000000   453022.000000   454409.000000   453581.000000   454850.000000   453386.000000   485272.000000   464241.000000   444426.000000   454427.000000   453272.000000   452758.000000   
diff --git a/ppc/res/res_u2 b/ppc/res/res_u2
new file mode 100644 (file)
index 0000000..079ec40
--- /dev/null
@@ -0,0 +1,4 @@
+#./cegwbench -s udp@192.168.2.3:10501 -d can@can0 -n 64 -m oneattime -t 1 
+529349.000000  451935.000000   405628.000000   413999.000000   417903.000000   401221.000000   407650.000000   401703.000000   405608.000000   407901.000000   493503.000000   422558.000000   418304.000000   413734.000000   411335.000000   410023.000000   410523.000000   403459.000000   423850.000000   412875.000000   437524.000000   406296.000000   404971.000000   404238.000000   405918.000000   405934.000000   407110.000000   401808.000000   403102.000000   499924.000000   406670.000000   415484.000000   414733.000000   400769.000000   402363.000000   397852.000000   402063.000000   414556.000000   411774.000000   425500.000000   397573.000000   401783.000000   401167.000000   399955.000000   401291.000000   399005.000000   403280.000000   400938.000000   401046.000000   367056.000000   404718.000000   402843.000000   402014.000000   401951.000000   402931.000000   402552.000000   403219.000000   401931.000000   493074.000000   406797.000000   418271.000000   405870.000000   399057.000000   406051.000000   
+#./cegwbench -s can@can0 -d udp@0.0.0.0:10502 -n 64 -m oneattime -t 1 
+502779.000000  437088.000000   448443.000000   448987.000000   449350.000000   533099.000000   446495.000000   448844.000000   449794.000000   448188.000000   449629.000000   448719.000000   448765.000000   448591.000000   479926.000000   450402.000000   450717.000000   450216.000000   449044.000000   451006.000000   450339.000000   450598.000000   449161.000000   453954.000000   450456.000000   452221.000000   446443.000000   449961.000000   449182.000000   449337.000000   450482.000000   450570.000000   339469.000000   449061.000000   451426.000000   448661.000000   450207.000000   449550.000000   450506.000000   449415.000000   449233.000000   339977.000000   449856.000000   450870.000000   449059.000000   449188.000000   450571.000000   450107.000000   449731.000000   449766.000000   339663.000000   449004.000000   449874.000000   448032.000000   449933.000000   450289.000000   449109.000000   449821.000000   448899.000000   337417.000000   448688.000000   449713.000000   447722.000000   448302.000000   
diff --git a/ppc/res/res_u3 b/ppc/res/res_u3
new file mode 100644 (file)
index 0000000..04fad78
--- /dev/null
@@ -0,0 +1,4 @@
+#./cegwbench -s udp@192.168.2.3:10501 -d can@can0 -n 64 -m oneattime -t 1 
+695094.000000  423695.000000   405358.000000   418025.000000   414250.000000   400623.000000   405460.000000   400753.000000   403548.000000   498053.000000   406373.000000   405727.000000   405458.000000   400538.000000   407129.000000   399950.000000   417364.000000   413604.000000   408999.000000   433658.000000   404857.000000   402937.000000   405438.000000   401953.000000   403295.000000   402603.000000   404633.000000   400570.000000   496332.000000   384544.000000   383630.000000   398434.000000   378124.000000   387190.000000   378600.000000   377577.000000   377274.000000   377641.000000   376861.000000   436961.000000   398959.000000   400046.000000   401326.000000   413157.000000   413517.000000   397229.000000   403240.000000   400614.000000   493555.000000   380917.000000   380047.000000   380281.000000   380706.000000   377072.000000   375401.000000   375862.000000   375885.000000   376532.000000   533943.000000   404556.000000   411914.000000   409720.000000   401314.000000   400437.000000   
+#./cegwbench -s can@can0 -d udp@0.0.0.0:10502 -n 64 -m oneattime -t 1 
+495020.000000  428264.000000   440632.000000   455448.000000   431200.000000   442588.000000   714755.000000   462081.000000   443047.000000   454305.000000   430635.000000   443390.000000   442610.000000   444052.000000   474234.000000   444617.000000   443340.000000   445032.000000   441325.000000   444522.000000   444167.000000   443013.000000   443401.000000   373511.000000   390381.000000   388182.000000   390410.000000   391070.000000   389230.000000   389655.000000   389333.000000   389567.000000   389306.000000   533271.000000   465790.000000   443877.000000   444340.000000   441586.000000   442002.000000   443691.000000   442513.000000   535594.000000   434522.000000   454517.000000   442867.000000   431694.000000   442458.000000   443362.000000   442284.000000   442940.000000   533714.000000   447634.000000   442829.000000   444551.000000   442213.000000   443303.000000   443418.000000   442979.000000   442876.000000   487455.000000   442772.000000   441957.000000   443595.000000   442114.000000   
diff --git a/ppc/res/result/res1.raw b/ppc/res/result/res1.raw
new file mode 100644 (file)
index 0000000..5d2194b
--- /dev/null
@@ -0,0 +1,4 @@
+508509.000000  366680.000000   369080.000000   381298.000000   369731.000000   366255.000000   370514.000000   371171.000000   369407.000000   371704.000000   369084.000000   368790.000000   369425.000000   466102.000000   369236.000000   369278.000000   371878.000000   369913.000000   372870.000000   370063.000000   369894.000000   369238.000000   372297.000000   368651.000000   382257.000000   373439.000000   373781.000000   371012.000000   374773.000000   370796.000000   371468.000000   371678.000000   368997.000000   364622.000000   453608.000000   366568.000000   364999.000000   365181.000000   365014.000000   363227.000000   370870.000000   365133.000000   363718.000000   364894.000000   364267.000000   370624.000000   361623.000000   362974.000000   378344.000000   364764.000000   365786.000000   365943.000000   364707.000000   361852.000000   364319.000000   470610.000000   364886.000000   363546.000000   361827.000000   363505.000000   365344.000000   363767.000000   365673.000000   363737.000000   
+472405.000000  382137.000000   383320.000000   381887.000000   442729.000000   378265.000000   383522.000000   382792.000000   382956.000000   382642.000000   383235.000000   382159.000000   383241.000000   383060.000000   415087.000000   384347.000000   381718.000000   382535.000000   383793.000000   382822.000000   383273.000000   383608.000000   395475.000000   378440.000000   414958.000000   383323.000000   382788.000000   393884.000000   378269.000000   383472.000000   383899.000000   382597.000000   383577.000000   382869.000000   699382.000000   405599.000000   383151.000000   383817.000000   384809.000000   382853.000000   383912.000000   382419.000000   384268.000000   383471.000000   298357.000000   377119.000000   385298.000000   385216.000000   385242.000000   385878.000000   386027.000000   385597.000000   386266.000000   384709.000000   416221.000000   383715.000000   382596.000000   382802.000000   384368.000000   382677.000000   383860.000000   383526.000000   383937.000000   383295.000000   
+569117.000000  445029.000000   406026.000000   450723.000000   412977.000000   403275.000000   404396.000000   398667.000000   405548.000000   404127.000000   529507.000000   534719.000000   421538.000000   405489.000000   404986.000000   402724.000000   404648.000000   400519.000000   403534.000000   496821.000000   414321.000000   404835.000000   401422.000000   404789.000000   407624.000000   407788.000000   404842.000000   404570.000000   420453.000000   453340.000000   417036.000000   411885.000000   404864.000000   401060.000000   402221.000000   397697.000000   404325.000000   401678.000000   495466.000000   404493.000000   403394.000000   398816.000000   399600.000000   401035.000000   405883.000000   403005.000000   403009.000000   398826.000000   430346.000000   397971.000000   403027.000000   396967.000000   404594.000000   417999.000000   400145.000000   397699.000000   401815.000000   403035.000000   400283.000000   413487.000000   412221.000000   403473.000000   399506.000000   402272.000000   
+501823.000000  447632.000000   452955.000000   454020.000000   453817.000000   453735.000000   484704.000000   462224.000000   444710.000000   451900.000000   455313.000000   452260.000000   453549.000000   453692.000000   454835.000000   470707.000000   458149.000000   451630.000000   454100.000000   454887.000000   454681.000000   455154.000000   454050.000000   532459.000000   455581.000000   453478.000000   453077.000000   453833.000000   454764.000000   453515.000000   455714.000000   454427.000000   370950.000000   456705.000000   452922.000000   453302.000000   454434.000000   454039.000000   454081.000000   453643.000000   454800.000000   340729.000000   455031.000000   452959.000000   454275.000000   452304.000000   465016.000000   441042.000000   454640.000000   549677.000000   443658.000000   454118.000000   452257.000000   453022.000000   454409.000000   453581.000000   454850.000000   453386.000000   485272.000000   464241.000000   444426.000000   454427.000000   453272.000000   452758.000000   
diff --git a/ppc/res/result/res2.raw b/ppc/res/result/res2.raw
new file mode 100644 (file)
index 0000000..2d93827
--- /dev/null
@@ -0,0 +1,2 @@
+500260.000000  365021.000000   372033.000000   387458.000000   368296.000000   365707.000000   386015.000000   483808.000000   344690.000000   343036.000000   340453.000000   338133.000000   339172.000000   385992.000000   373235.000000   365865.000000   369685.000000   367056.000000   398233.000000   368394.000000   370864.000000   370586.000000   370965.000000   374419.000000   372999.000000   370180.000000   371710.000000   369308.000000   459231.000000   370657.000000   376748.000000   368383.000000   367916.000000   367834.000000   365449.000000   363782.000000   363776.000000   363733.000000   364341.000000   402966.000000   360782.000000   367260.000000   365210.000000   364919.000000   363833.000000   363570.000000   364026.000000   362874.000000   364844.000000   363593.000000   339372.000000   367485.000000   366399.000000   363945.000000   365195.000000   362742.000000   364344.000000   365187.000000   364465.000000   375529.000000   453635.000000   364567.000000   371492.000000   365629.000000   
+478155.000000  387482.000000   388466.000000   389489.000000   388966.000000   389578.000000   387678.000000   390322.000000   475484.000000   401216.000000   389009.000000   389742.000000   389658.000000   389767.000000   388703.000000   385375.000000   387442.000000   389856.000000   475104.000000   395687.000000   385354.000000   388908.000000   389711.000000   389453.000000   402621.000000   384565.000000   388038.000000   389544.000000   420445.000000   391400.000000   388940.000000   389805.000000   388660.000000   390145.000000   400934.000000   382027.000000   388426.000000   390410.000000   420732.000000   391938.000000   388925.000000   390831.000000   389303.000000   389658.000000   401676.000000   382205.000000   391506.000000   392286.000000   422484.000000   392848.000000   391315.000000   392313.000000   392428.000000   390653.000000   390728.000000   389022.000000   388530.000000   390065.000000   420130.000000   390541.000000   389121.000000   390083.000000   389024.000000   390111.000000   
diff --git a/ppc/res/result/res3.raw b/ppc/res/result/res3.raw
new file mode 100644 (file)
index 0000000..fc524c0
--- /dev/null
@@ -0,0 +1,2 @@
+474596.000000  367429.000000   368155.000000   371446.000000   377213.000000   369393.000000   369757.000000   379663.000000   463456.000000   375854.000000   370329.000000   367949.000000   368000.000000   365562.000000   372220.000000   367093.000000   370200.000000   368279.000000   369815.000000   380477.000000   383617.000000   364807.000000   368976.000000   368178.000000   389906.000000   368600.000000   369475.000000   369867.000000   368989.000000   398289.000000   373103.000000   369835.000000   371471.000000   362925.000000   366396.000000   366023.000000   365509.000000   362832.000000   365325.000000   362404.000000   401411.000000   361977.000000   365241.000000   365943.000000   364765.000000   361749.000000   363387.000000   360916.000000   367526.000000   363239.000000   458649.000000   364484.000000   365791.000000   366359.000000   365432.000000   365579.000000   365552.000000   374369.000000   364921.000000   363723.000000   367383.000000   406038.000000   366299.000000   363605.000000   
+460820.000000  384512.000000   385838.000000   407754.000000   382736.000000   384663.000000   488640.000000   380106.000000   386253.000000   385823.000000   385113.000000   385955.000000   385807.000000   387643.000000   384018.000000   386253.000000   477010.000000   387663.000000   385508.000000   386029.000000   386890.000000   396456.000000   381902.000000   387371.000000   383811.000000   385328.000000   428820.000000   381787.000000   386112.000000   385706.000000   386679.000000   385377.000000   385629.000000   387057.000000   384043.000000   386464.000000   471948.000000   387701.000000   386662.000000   386481.000000   386329.000000   397635.000000   379800.000000   387458.000000   384717.000000   387483.000000   430649.000000   381611.000000   387860.000000   388770.000000   388056.000000   389123.000000   387609.000000   387737.000000   385021.000000   385686.000000   470605.000000   389097.000000   386284.000000   385150.000000   386393.000000   392780.000000   382870.000000   386906.000000   
diff --git a/ppc/res/result/res_k1.raw b/ppc/res/result/res_k1.raw
new file mode 100644 (file)
index 0000000..bae73b1
--- /dev/null
@@ -0,0 +1,2 @@
+508509.000000  366680.000000   369080.000000   381298.000000   369731.000000   366255.000000   370514.000000   371171.000000   369407.000000   371704.000000   369084.000000   368790.000000   369425.000000   466102.000000   369236.000000   369278.000000   371878.000000   369913.000000   372870.000000   370063.000000   369894.000000   369238.000000   372297.000000   368651.000000   382257.000000   373439.000000   373781.000000   371012.000000   374773.000000   370796.000000   371468.000000   371678.000000   368997.000000   364622.000000   453608.000000   366568.000000   364999.000000   365181.000000   365014.000000   363227.000000   370870.000000   365133.000000   363718.000000   364894.000000   364267.000000   370624.000000   361623.000000   362974.000000   378344.000000   364764.000000   365786.000000   365943.000000   364707.000000   361852.000000   364319.000000   470610.000000   364886.000000   363546.000000   361827.000000   363505.000000   365344.000000   363767.000000   365673.000000   363737.000000   
+472405.000000  382137.000000   383320.000000   381887.000000   442729.000000   378265.000000   383522.000000   382792.000000   382956.000000   382642.000000   383235.000000   382159.000000   383241.000000   383060.000000   415087.000000   384347.000000   381718.000000   382535.000000   383793.000000   382822.000000   383273.000000   383608.000000   395475.000000   378440.000000   414958.000000   383323.000000   382788.000000   393884.000000   378269.000000   383472.000000   383899.000000   382597.000000   383577.000000   382869.000000   699382.000000   405599.000000   383151.000000   383817.000000   384809.000000   382853.000000   383912.000000   382419.000000   384268.000000   383471.000000   298357.000000   377119.000000   385298.000000   385216.000000   385242.000000   385878.000000   386027.000000   385597.000000   386266.000000   384709.000000   416221.000000   383715.000000   382596.000000   382802.000000   384368.000000   382677.000000   383860.000000   383526.000000   383937.000000   383295.000000   
diff --git a/ppc/res/result/res_u1.raw b/ppc/res/result/res_u1.raw
new file mode 100644 (file)
index 0000000..eed9923
--- /dev/null
@@ -0,0 +1,2 @@
+569117.000000  445029.000000   406026.000000   450723.000000   412977.000000   403275.000000   404396.000000   398667.000000   405548.000000   404127.000000   529507.000000   534719.000000   421538.000000   405489.000000   404986.000000   402724.000000   404648.000000   400519.000000   403534.000000   496821.000000   414321.000000   404835.000000   401422.000000   404789.000000   407624.000000   407788.000000   404842.000000   404570.000000   420453.000000   453340.000000   417036.000000   411885.000000   404864.000000   401060.000000   402221.000000   397697.000000   404325.000000   401678.000000   495466.000000   404493.000000   403394.000000   398816.000000   399600.000000   401035.000000   405883.000000   403005.000000   403009.000000   398826.000000   430346.000000   397971.000000   403027.000000   396967.000000   404594.000000   417999.000000   400145.000000   397699.000000   401815.000000   403035.000000   400283.000000   413487.000000   412221.000000   403473.000000   399506.000000   402272.000000   
+501823.000000  447632.000000   452955.000000   454020.000000   453817.000000   453735.000000   484704.000000   462224.000000   444710.000000   451900.000000   455313.000000   452260.000000   453549.000000   453692.000000   454835.000000   470707.000000   458149.000000   451630.000000   454100.000000   454887.000000   454681.000000   455154.000000   454050.000000   532459.000000   455581.000000   453478.000000   453077.000000   453833.000000   454764.000000   453515.000000   455714.000000   454427.000000   370950.000000   456705.000000   452922.000000   453302.000000   454434.000000   454039.000000   454081.000000   453643.000000   454800.000000   340729.000000   455031.000000   452959.000000   454275.000000   452304.000000   465016.000000   441042.000000   454640.000000   549677.000000   443658.000000   454118.000000   452257.000000   453022.000000   454409.000000   453581.000000   454850.000000   453386.000000   485272.000000   464241.000000   444426.000000   454427.000000   453272.000000   452758.000000   
diff --git a/ppc/res/result/res_u2.raw b/ppc/res/result/res_u2.raw
new file mode 100644 (file)
index 0000000..40925cb
--- /dev/null
@@ -0,0 +1,2 @@
+529349.000000  451935.000000   405628.000000   413999.000000   417903.000000   401221.000000   407650.000000   401703.000000   405608.000000   407901.000000   493503.000000   422558.000000   418304.000000   413734.000000   411335.000000   410023.000000   410523.000000   403459.000000   423850.000000   412875.000000   437524.000000   406296.000000   404971.000000   404238.000000   405918.000000   405934.000000   407110.000000   401808.000000   403102.000000   499924.000000   406670.000000   415484.000000   414733.000000   400769.000000   402363.000000   397852.000000   402063.000000   414556.000000   411774.000000   425500.000000   397573.000000   401783.000000   401167.000000   399955.000000   401291.000000   399005.000000   403280.000000   400938.000000   401046.000000   367056.000000   404718.000000   402843.000000   402014.000000   401951.000000   402931.000000   402552.000000   403219.000000   401931.000000   493074.000000   406797.000000   418271.000000   405870.000000   399057.000000   406051.000000   
+502779.000000  437088.000000   448443.000000   448987.000000   449350.000000   533099.000000   446495.000000   448844.000000   449794.000000   448188.000000   449629.000000   448719.000000   448765.000000   448591.000000   479926.000000   450402.000000   450717.000000   450216.000000   449044.000000   451006.000000   450339.000000   450598.000000   449161.000000   453954.000000   450456.000000   452221.000000   446443.000000   449961.000000   449182.000000   449337.000000   450482.000000   450570.000000   339469.000000   449061.000000   451426.000000   448661.000000   450207.000000   449550.000000   450506.000000   449415.000000   449233.000000   339977.000000   449856.000000   450870.000000   449059.000000   449188.000000   450571.000000   450107.000000   449731.000000   449766.000000   339663.000000   449004.000000   449874.000000   448032.000000   449933.000000   450289.000000   449109.000000   449821.000000   448899.000000   337417.000000   448688.000000   449713.000000   447722.000000   448302.000000   
diff --git a/ppc/res/result/res_u3.raw b/ppc/res/result/res_u3.raw
new file mode 100644 (file)
index 0000000..adae3dc
--- /dev/null
@@ -0,0 +1,2 @@
+695094.000000  423695.000000   405358.000000   418025.000000   414250.000000   400623.000000   405460.000000   400753.000000   403548.000000   498053.000000   406373.000000   405727.000000   405458.000000   400538.000000   407129.000000   399950.000000   417364.000000   413604.000000   408999.000000   433658.000000   404857.000000   402937.000000   405438.000000   401953.000000   403295.000000   402603.000000   404633.000000   400570.000000   496332.000000   384544.000000   383630.000000   398434.000000   378124.000000   387190.000000   378600.000000   377577.000000   377274.000000   377641.000000   376861.000000   436961.000000   398959.000000   400046.000000   401326.000000   413157.000000   413517.000000   397229.000000   403240.000000   400614.000000   493555.000000   380917.000000   380047.000000   380281.000000   380706.000000   377072.000000   375401.000000   375862.000000   375885.000000   376532.000000   533943.000000   404556.000000   411914.000000   409720.000000   401314.000000   400437.000000   
+495020.000000  428264.000000   440632.000000   455448.000000   431200.000000   442588.000000   714755.000000   462081.000000   443047.000000   454305.000000   430635.000000   443390.000000   442610.000000   444052.000000   474234.000000   444617.000000   443340.000000   445032.000000   441325.000000   444522.000000   444167.000000   443013.000000   443401.000000   373511.000000   390381.000000   388182.000000   390410.000000   391070.000000   389230.000000   389655.000000   389333.000000   389567.000000   389306.000000   533271.000000   465790.000000   443877.000000   444340.000000   441586.000000   442002.000000   443691.000000   442513.000000   535594.000000   434522.000000   454517.000000   442867.000000   431694.000000   442458.000000   443362.000000   442284.000000   442940.000000   533714.000000   447634.000000   442829.000000   444551.000000   442213.000000   443303.000000   443418.000000   442979.000000   442876.000000   487455.000000   442772.000000   441957.000000   443595.000000   442114.000000   
diff --git a/ppc/shark_home.tar b/ppc/shark_home.tar
new file mode 100644 (file)
index 0000000..9e42605
Binary files /dev/null and b/ppc/shark_home.tar differ
diff --git a/ppc/test b/ppc/test
new file mode 100755 (executable)
index 0000000..ef70399
--- /dev/null
+++ b/ppc/test
@@ -0,0 +1,26 @@
+#!/bin/sh
+N=10
+MODE=oneattime
+
+evalmsg()
+{
+       if test $1 -eq 0; then
+               echo -e "\033[32mOK"
+       else
+               echo -e "\033[31mFAIL"
+       fi;
+               echo -ne "\033[0m"
+}
+
+if test $# -ne 0; then
+       N=$1;
+fi
+
+echo -n "Testing eth->can: "
+cegwbench -s udp@192.168.2.3:10501 -d can@can0 -n $N -m $MODE -t 1 &> /dev/zero
+evalmsg $?
+
+echo -n "Testing can->eth: "
+cegwbench -s can@vcan0 -d udp@127.0.0.1:10502 -n $N -m $MODE -t 1 &> /dev/zero
+evalmsg $?
+
diff --git a/ppc/user/Makefile b/ppc/user/Makefile
new file mode 100644 (file)
index 0000000..4d1b6d2
--- /dev/null
@@ -0,0 +1,5 @@
+PROGRAM=canethgw
+
+all:
+       powerpc-linux-gnu-gcc -Wall -o${PROGRAM} -I../../utils/common/include/ canethgw.c ../../utils/common/cegwerr.c ../../utils/common/readif.c
+
diff --git a/ppc/user/canethgw b/ppc/user/canethgw
new file mode 100755 (executable)
index 0000000..75fe397
Binary files /dev/null and b/ppc/user/canethgw differ
diff --git a/ppc/user/canethgw.c b/ppc/user/canethgw.c
new file mode 100644 (file)
index 0000000..09cae5c
--- /dev/null
@@ -0,0 +1,279 @@
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <signal.h>
+#include <getopt.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <linux/can.h>
+#include <linux/can/raw.h>
+#include <poll.h>
+#include "readif.h"
+#include "cegwerr.h"
+
+/**
+ * ToDo:
+ * [ ] print usage
+ */
+//#define GW_DEBUG
+
+/* powerpc encore */
+#define AF_CAN 29
+#define PF_CAN AF_CAN
+
+#ifdef GW_DEBUG
+#define printdbg(x) printf(x)
+#else
+#define printdbg(x)
+#endif
+
+#define GW_POLL_ETH 0
+#define GW_POLL_CAN 1
+
+#define GW_FLAG_SRC 1
+#define GW_FLAG_DST 2
+#define GW_FLAG_LISTEN 4
+#define GW_FLAG_FILTER 8
+
+unsigned int opt_flag = 0;
+int sock_udp;
+int sock_can;
+struct can_filter flt;
+struct sockaddr_in udp_dest;
+
+/**
+ * filter_check
+ * @return true if frame should be dropped
+ */
+bool filter_check( struct can_frame* cf )
+{
+       if( !(opt_flag & GW_FLAG_FILTER) )
+               return false;
+
+       return ( (cf->can_id & flt.can_mask) == (flt.can_id & flt.can_mask) );
+}
+
+void send_to_can()
+{
+       struct can_frame cf;
+
+       read( sock_udp, &cf, sizeof(cf) );
+
+       if( filter_check( &cf ) )
+       {
+               printdbg( "filter: drop\n" );
+               return;
+       }
+       
+       write( sock_can, &cf, sizeof(cf) );
+       
+       printdbg( "eth -> can\n" );
+}
+
+void send_to_eth()
+{
+       struct can_frame cf;
+
+       read( sock_can, &cf, sizeof(cf) );
+
+       if( filter_check( &cf ) )
+       {
+               printdbg( "filter: drop\n" );
+               return;
+       }
+
+       sendto( sock_udp, &cf, sizeof(cf), 0, (struct sockaddr*) &udp_dest, sizeof(udp_dest) );
+
+       printdbg( "can -> eth\n" );
+}
+
+void signal_exit( int sig )
+{
+       close( sock_udp );
+       close( sock_can );
+       printf( "exiting\n" );
+
+       exit( 0 );
+}
+
+int main( int argc, char* argv[] )
+{
+       struct sockaddr_in udp_addr;
+       struct sockaddr_can can_addr;
+       struct pollfd pfd[2];
+       int polret;
+       int opt;
+       struct cegw_if ceif[2], iflisten;
+       struct cegw_if* ifcan,* ifeth;
+
+       flt.can_id = 0;
+       flt.can_mask = 0;
+
+       struct option longopt[] =
+       {
+               {"listen", 1, NULL, 'l'},
+               { 0, 0, 0, 0 }
+       };
+
+       while( (opt = getopt_long( argc, argv, "s:d:l:f:i:", longopt, NULL )) != -1 )
+       {
+               switch( opt )
+               {
+                       case 's':
+                               if( read_if(optarg, &ceif[0]) != 0 )
+                               {
+                                       perr( "'-s'" );
+                                       return -1;
+                               }
+                               opt_flag |= GW_FLAG_SRC;
+                               break;
+                       case 'd':
+                               if( read_if(optarg, &ceif[1]) != 0 )
+                               {
+                                       perr( "'-d'" );
+                                       return -1;
+                               }
+                               opt_flag |= GW_FLAG_DST;
+                               break;
+                       case 'l':
+                               if( read_if(optarg, &iflisten) != 0 )
+                               {                               
+                                       perr( "'-l'" );
+                                       return -1;
+                               }
+                               if( iflisten.type != IF_ETH_UDP )
+                               {
+                                       perr( "'-l' udp interface expected" );
+                                       return -1;
+                               }
+                               opt_flag |= GW_FLAG_LISTEN;
+                               break;
+                       case 'f':
+                               if( sscanf( optarg, "%x:%x", &flt.can_id,
+                                  &flt.can_mask ) != 2 ) 
+                               {
+                                       perr( "bad filter format");
+                                       return -1;
+                               }
+                               opt_flag |= GW_FLAG_FILTER;
+                               break;
+                       case '?':
+                               return -1;
+                               break;
+               }
+       }
+
+       if( !((opt_flag & GW_FLAG_SRC) && (opt_flag & GW_FLAG_DST) 
+               && (opt_flag & GW_FLAG_LISTEN)) )
+       {
+               perr( "'s', 'd' and 'l' are mandatory" ); 
+               /* ToDo: usage? */
+               return -1;
+       }
+
+       if( !(ceif[0].type == IF_CAN     && ceif[1].type == IF_ETH_UDP) &&
+           !(ceif[0].type == IF_ETH_UDP && ceif[1].type == IF_CAN    )    )
+       {
+               perr( "'-s' and '-d' should be different interface type" );
+               return -1;
+       }
+
+       if( ceif[0].type == IF_CAN )
+       {
+               ifcan = &ceif[0];
+               ifeth = &ceif[1];
+       } else
+       {
+               ifcan = &ceif[1];
+               ifeth = &ceif[0];
+       }
+
+       signal( SIGINT, signal_exit );
+
+       /* prepare udp destination */
+       udp_dest.sin_family = AF_INET;
+       udp_dest.sin_port = htons(ifeth->eth.port);
+       udp_dest.sin_addr = ifeth->eth.ip;
+
+       /* udp socket */
+       sock_udp = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP );
+       if( sock_udp < 0 )
+       {
+               perr( "udp socket creation failed" );
+               return -1;
+       }
+
+       udp_addr.sin_family = AF_INET;
+       udp_addr.sin_port = htons(iflisten.eth.port);
+       udp_addr.sin_addr = iflisten.eth.ip;
+
+       if( bind( sock_udp, (struct sockaddr*) &udp_addr, sizeof(udp_addr) ) < 0 )
+       {
+               perr( "udp socket binding failed" );
+               close( sock_udp );
+               return -1;
+       }
+
+       /* can socket */
+       sock_can = socket( PF_CAN, SOCK_RAW, CAN_RAW );
+       if( sock_can < 0 )
+       {
+               perr( "can socket creation failed");
+               close( sock_can );
+               return -1;
+       }
+
+       can_addr.can_family = AF_CAN;
+       can_addr.can_ifindex = ifcan->can.ifindex;
+
+       if( bind( sock_can, (struct sockaddr*) &can_addr, sizeof(can_addr) ) < 0 )
+       {
+               perr( "can socket binding failed" );
+               return -1;
+       }
+
+       /* poll */
+       pfd[GW_POLL_ETH].fd = sock_udp;
+       pfd[GW_POLL_ETH].events = POLLIN | POLLPRI;
+       pfd[GW_POLL_ETH].revents = 0;
+
+       pfd[GW_POLL_CAN].fd = sock_can;
+       pfd[GW_POLL_CAN].events = POLLIN | POLLPRI;
+       pfd[GW_POLL_CAN].revents = 0;
+
+       printf( "canethgw is running\n" );
+
+       while( 1 )
+       {
+               printdbg( "polling\n" );
+               polret = poll( pfd, 2, -1 );
+               if( polret < 0 )
+               {
+                       perr( "poll(..) failed" );
+                       close( sock_udp );
+                       close( sock_can );
+                       return -1;
+               }
+
+               if( pfd[GW_POLL_ETH].revents != 0 )
+               {
+                       send_to_can();
+               }
+               if( pfd[GW_POLL_CAN].revents != 0 )
+               {
+                       send_to_eth();
+               }
+
+               pfd[GW_POLL_ETH].revents = 0;
+               pfd[GW_POLL_CAN].revents = 0;
+       }
+
+       return 0;
+}
+