static int cegw_thread_start(void *data);
static int cegw_thread_stop(void);
+static int cegw_thread_recv_udp(void *data);
+static int cegw_thread_recv_can(void *data);
+
enum __cegw_state {
CEGW_RUN,
CEGW_STOP,
static int cegw_state = CEGW_STOP;
static struct socket *can_sock = NULL, *udp_sock = NULL;
+static struct socket *s_can = NULL, *s_eth = NULL;
static struct task_struct *eth_to_can = NULL, *can_to_eth = NULL;
static struct notifier_block notifier;
unsigned short port;
struct cegw_setting* set;
int err = 0;
+ int fd_eth, fd_can;
if (nlmsg_len(nlh) < sizeof(*r))
return -EINVAL;
return err;
}
+ fd_eth = *(int*)nla_data(tb[CEGW_ETH_SOCK]);
+ fd_can = *(int*)nla_data(tb[CEGW_CAN_SOCK]);
+
+ printk( "cegw: sock=%i,%i\n", fd_eth, fd_can );
+
+ s_can = sockfd_lookup( fd_can, &err );
+ s_eth = sockfd_lookup( fd_eth, &err );
+
+ if( s_can == NULL || s_eth == NULL )
+ {
+ printk( "error: socket look-up failed\n" );
+ return 0;
+ }
+
+ struct can_frame greet;
+ greet.can_id = 0;
+ greet.can_dlc = 4;
+ greet.data[0] = 7;
+
+ //cegw_can_send( s_can, &greet, *(int*)nla_data(tb[CEGW_CAN_IFINDEX]) );
+ kthread_run(cegw_thread_recv_udp, NULL, "canethgw");
+ kthread_run(cegw_thread_recv_can, NULL, "canethgw");
+ /*
if (tb[CEGW_CMD_INFO] == NULL) {
pr_devel("canethgw: CEGW_CMD_INFO is missing in rtmsg\n");
return -EINVAL;
}
+ */
+ return 0;
switch (*(int*)nla_data(tb[CEGW_CMD_INFO])) {
case CEGW_LISTEN:
if (!tb[CEGW_ETH_IP] || !tb[CEGW_ETH_PORT]) {
return NOTIFY_DONE;
}
-/**
- * cegw_thread_start - start working threads
- * @data: (struct cegw_setting *) with new listening address
- *
- * Two threads are started. One is serving udp->can routing and the other
- * can->udp.
- */
-static int cegw_thread_start(void *data)
+static int cegw_thread_recv_udp(void *data)
{
- struct sockaddr_in udp_addr;
- struct sockaddr_can can_addr;
- struct cegw_setting *set;
-
- set = (struct cegw_setting *)data;
-
- can_addr.can_family = AF_CAN;
- can_addr.can_ifindex = 0;
+ struct can_frame cf;
+ struct kvec vec;
+ struct msghdr mh;
+ struct sockaddr_in sa;
+ struct hlist_node* pos;
+ int can_ifidx;
+ int recv_size;
- udp_addr.sin_family = AF_INET;
- udp_addr.sin_port = htons(set->eth_port);
- udp_addr.sin_addr = set->eth_ip;
+ memset(&mh, 0, sizeof(mh));
+ mh.msg_name = &sa;
+ mh.msg_namelen = sizeof(sa);
+ mh.msg_control = NULL;
+ mh.msg_controllen = 0;
+ mh.msg_flags = 0;
- kfree(data);
- mutex_lock(&cegw_mutex);
- if (cegw_state == CEGW_EXIT)
- goto out_err;
+ printk( "udp receiving\n" );
- /* stops threads if exist */
- cegw_thread_stop();
+ while( 1 )
+ {
+ vec.iov_base = &cf;
+ vec.iov_len = sizeof(cf);
- /* create and bind sockets */
- if (sock_create_kern(PF_INET, SOCK_DGRAM, IPPROTO_UDP, &udp_sock)
- != 0) {
- printk(KERN_ERR "canethgw: udp socket creation failed\n");
- goto out_err;
+ recv_size = kernel_recvmsg(s_eth, &mh, &vec, 1,
+ sizeof(cf), 0);
+ printk("udp status=%i\n", recv_size);
}
- if (sock_create_kern(PF_CAN, SOCK_RAW, CAN_RAW, &can_sock) != 0) {
- printk(KERN_ERR "canethgw: can socket creation failed\n");
- sock_release(udp_sock);
- goto out_err;
- }
+ return 0;
+}
- if (kernel_bind(udp_sock, (struct sockaddr*)&udp_addr,
- sizeof(udp_addr)) != 0) {
- printk(KERN_ERR "canethgw: udp socket binding failed\n");
- sock_release(udp_sock);
- sock_release(can_sock);
- goto out_err;
- }
+static int cegw_thread_recv_can(void *data)
+{
+ struct can_frame cf;
+ struct kvec vec;
+ struct msghdr mh;
+ struct sockaddr_can ca;
+ struct hlist_node* pos;
+ int can_ifidx;
+ int recv_size;
- if (kernel_bind(can_sock, (struct sockaddr*) &can_addr,
- sizeof(can_addr)) != 0) {
- printk(KERN_ERR "canethgw: can socket binding failed\n");
- kernel_sock_shutdown(udp_sock, SHUT_RDWR);
- sock_release(udp_sock);
- sock_release(can_sock);
- goto out_err;
- }
+ memset(&mh, 0, sizeof(mh));
+ mh.msg_name = &ca;
+ mh.msg_namelen = sizeof(ca);
+ mh.msg_control = NULL;
+ mh.msg_controllen = 0;
+ mh.msg_flags = 0;
- /* start threads */
- cegw_state = CEGW_RUN;
+ printk( "can receiving\n" );
- eth_to_can = kthread_create(cegw_udp2can, NULL, "canethgw");
- if (IS_ERR(eth_to_can)) {
- cegw_state = CEGW_STOP;
- sock_release(udp_sock);
- sock_release(can_sock);
- goto out_err;
- }
- get_task_struct(eth_to_can);
- wake_up_process(eth_to_can);
-
- can_to_eth = kthread_create(cegw_can2udp, NULL, "canethgw");
- if (IS_ERR(can_to_eth)) {
- cegw_state = CEGW_STOP;
- kernel_sock_shutdown(udp_sock, SHUT_RDWR);
- kthread_stop(eth_to_can);
- sock_release(udp_sock);
- sock_release(can_sock);
- goto out_err;
+ while( 1 )
+ {
+ vec.iov_base = &cf;
+ vec.iov_len = sizeof(cf);
+
+ recv_size = kernel_recvmsg(s_can, &mh, &vec, 1,
+ sizeof(cf), 0);
+ printk("can status=%i\n", recv_size);
}
- get_task_struct(can_to_eth);
- wake_up_process(can_to_eth);
- mutex_unlock(&cegw_mutex);
- pr_devel("threads are running\n");
return 0;
-out_err:
- mutex_unlock(&cegw_mutex);
- return -1;
}
/**