]> rtime.felk.cvut.cz Git - can-eth-gw.git/commitdiff
User-space gw
authorRadek Matejka <radek.matejka@gmail.com>
Tue, 10 Jul 2012 16:05:27 +0000 (18:05 +0200)
committerRadek Matejka <radek.matejka@gmail.com>
Tue, 10 Jul 2012 16:05:27 +0000 (18:05 +0200)
First commit.

user/Makefile [new file with mode: 0644]
user/canethgw.c [new file with mode: 0644]

diff --git a/user/Makefile b/user/Makefile
new file mode 100644 (file)
index 0000000..bbab6d0
--- /dev/null
@@ -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 (file)
index 0000000..8048a1f
--- /dev/null
@@ -0,0 +1,146 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <linux/can.h>
+#include <linux/can/raw.h>
+#include <poll.h>
+
+#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;
+}
+