From a740a9e2090d1e5c86749bde03ac0ad33ff049f6 Mon Sep 17 00:00:00 2001 From: Radek Matejka Date: Tue, 10 Jul 2012 18:05:27 +0200 Subject: [PATCH] User-space gw First commit. --- user/Makefile | 2 + user/canethgw.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 user/Makefile create mode 100644 user/canethgw.c diff --git a/user/Makefile b/user/Makefile new file mode 100644 index 0000000..bbab6d0 --- /dev/null +++ b/user/Makefile @@ -0,0 +1,2 @@ +all: + gcc -Wall -o canethgw canethgw.c diff --git a/user/canethgw.c b/user/canethgw.c new file mode 100644 index 0000000..8048a1f --- /dev/null +++ b/user/canethgw.c @@ -0,0 +1,146 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GW_POLL_ETH 0 +#define GW_POLL_CAN 1 + +int sock_udp; +int sock_can; + +void send_to_can() +{ + struct can_frame cf; + read( sock_udp, &cf, sizeof(cf) ); + write( sock_can, &cf, sizeof(cf) ); + + printf( "sending to can\n" ); +} + +void send_to_eth() +{ + struct can_frame cf; + struct sockaddr_in udp_dest; + + udp_dest.sin_family = AF_INET; + udp_dest.sin_addr.s_addr = inet_addr("127.0.0.1"); + udp_dest.sin_port = htons(10502); + + read( sock_can, &cf, sizeof(cf) ); + sendto( sock_udp, &cf, sizeof(cf), 0, (struct sockaddr*) &udp_dest, sizeof(udp_dest) ); + //write( sock_eth, &cf, sizeof(cf) ); + + printf( "sending to eth\n" ); +} + +int main( int argc, char* argv[] ) +{ + struct sockaddr_in udp_addr; + struct sockaddr_can can_addr; + struct ifreq ifr; + struct pollfd pfd[2]; + + if( argc != 2 ) + { + printf( "usage example: %s can1\n", argv[0] ); + return -1; + } + + /* udp socket */ + sock_udp = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP ); + if( sock_udp < 0 ) + { + fprintf( stderr, "error: socket(), udp\n" ); + goto gw_error; + } + + udp_addr.sin_family = AF_INET; + udp_addr.sin_port = htons(10501); + udp_addr.sin_addr.s_addr = INADDR_ANY; + + if( bind( sock_udp, (struct sockaddr*) &udp_addr, sizeof(udp_addr) ) < 0 ) + { + fprintf( stderr, "error: bind(), udp\n" ); + close( sock_udp ); + goto gw_error; + } + + /* can socket*/ + sock_can = socket( PF_CAN, SOCK_RAW, CAN_RAW ); + if( sock_can < 0 ) + { + fprintf( stderr, "error: socket(), can\n"); + close( sock_can ); + goto gw_error; + } + + strcpy( ifr.ifr_name, argv[1] ); + if( ioctl( sock_can, SIOCGIFINDEX, &ifr ) < 0 ) + { + fprintf( stderr, "error: ioctl(), get if index\n" ); + goto gw_error; + } + + can_addr.can_family = AF_CAN; + can_addr.can_ifindex = ifr.ifr_ifindex; +// setsockopt( sock_can, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0 ); /*?!?*/ + + if( bind( sock_can, (struct sockaddr*) &can_addr, sizeof(can_addr) ) < 0 ) + { + fprintf( stderr, "error: bind(), can" ); + goto gw_error; + } + + /* 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; + +/* + unsigned char buf[1]; + struct can_frame cf; + printf( "block\n" ); + read( sock_can, &cf, sizeof(cf) ); again, return 0 + printf( "can read\n" ); +*/ + + while(1) + { + printf( "polling\n" ); + int polret = poll( pfd, 2, -1 ); + if( polret <= 0 ) + { + fprintf( stderr, "error: poll returned 0\n" ); + } + + 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; +gw_error: + return -1; +} + -- 2.39.2