From 404ac51055d33a30d7ac1ede01be091c03e404ca Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 18 Jun 2019 15:38:03 +0300 Subject: [PATCH] samples: net: socket: can: Close the socket periodically This is done only for testing purposes, in real life the socket would be closed if it is not used or needed. Signed-off-by: Jukka Rissanen --- samples/net/sockets/can/src/main.c | 126 ++++++++++++++++++++--------- 1 file changed, 86 insertions(+), 40 deletions(-) diff --git a/samples/net/sockets/can/src/main.c b/samples/net/sockets/can/src/main.c index 7719eebf4abba3..f3e6ac466e8f31 100644 --- a/samples/net/sockets/can/src/main.c +++ b/samples/net/sockets/can/src/main.c @@ -12,8 +12,8 @@ LOG_MODULE_REGISTER(net_socket_can_sample, LOG_LEVEL_DBG); #include #include -#define PRIORITY 7 -#define STACKSIZE 750 +#define PRIORITY k_thread_priority_get(k_current_get()) +#define STACKSIZE 1024 #define SLEEP_PERIOD K_SECONDS(1) static k_tid_t tx_tid; @@ -27,6 +27,18 @@ static K_THREAD_STACK_DEFINE(rx_stack, STACKSIZE); static struct k_thread rx_data; #endif +#define CLOSE_PERIOD 15 + +static const struct zcan_filter zfilter = { + .id_type = CAN_STANDARD_IDENTIFIER, + .rtr = CAN_DATAFRAME, + .std_id = 0x1, + .rtr_mask = 1, + .std_id_mask = CAN_STD_ID_MASK +}; + +static struct can_filter filter; + static void tx(int *can_fd) { int fd = POINTER_TO_INT(can_fd); @@ -57,8 +69,38 @@ static void tx(int *can_fd) } } -static void rx(int *can_fd) +static int create_socket(const struct can_filter *filter) { + struct sockaddr_can can_addr; + int fd, ret; + + fd = socket(AF_CAN, SOCK_RAW, CAN_RAW); + if (fd < 0) { + LOG_ERR("Cannot create %s CAN socket (%d)", "2nd", fd); + return fd; + } + + can_addr.can_ifindex = net_if_get_by_iface( + net_if_get_first_by_type(&NET_L2_GET_NAME(CANBUS))); + can_addr.can_family = PF_CAN; + + ret = bind(fd, (struct sockaddr *)&can_addr, sizeof(can_addr)); + if (ret < 0) { + LOG_ERR("Cannot bind %s CAN socket (%d)", "2nd", -errno); + (void)close(fd); + return ret; + } + + (void)setsockopt(fd, SOL_CAN_RAW, CAN_RAW_FILTER, filter, + sizeof(*filter)); + + return fd; +} + +static void rx(int *can_fd, int *do_close_period, + const struct can_filter *filter) +{ + int close_period = POINTER_TO_INT(do_close_period); int fd = POINTER_TO_INT(can_fd); struct sockaddr_can can_addr; socklen_t addr_len; @@ -98,19 +140,29 @@ static void rx(int *can_fd) } else { LOG_INF("[%d] EXT Remote message received", fd); } + + if (POINTER_TO_INT(do_close_period) > 0) { + close_period--; + if (close_period <= 0) { + (void)close(fd); + + k_sleep(K_SECONDS(1)); + + fd = create_socket(filter); + if (fd < 0) { + LOG_ERR("Cannot get socket (%d)", + -errno); + return; + } + + close_period = POINTER_TO_INT(do_close_period); + } + } } } static int setup_socket(void) { - const struct zcan_filter zfilter = { - .id_type = CAN_STANDARD_IDENTIFIER, - .rtr = CAN_DATAFRAME, - .std_id = 0x1, - .rtr_mask = 1, - .std_id_mask = CAN_STD_ID_MASK - }; - struct can_filter filter; struct sockaddr_can can_addr; struct net_if *iface; int fd, rx_fd; @@ -163,38 +215,29 @@ static int setup_socket(void) LOG_DBG("Started socket CAN TX thread"); + LOG_INF("1st RX fd %d", fd); + rx_fd = fd; #if CONFIG_NET_SOCKETS_CAN_RECEIVERS == 2 - fd = socket(AF_CAN, SOCK_RAW, CAN_RAW); - if (fd < 0) { - ret = -errno; - LOG_ERR("Cannot create %s CAN socket (%d)", "2nd", ret); - fd = rx_fd; - goto cleanup; - } - - can_addr.can_ifindex = net_if_get_by_iface(iface); - can_addr.can_family = PF_CAN; - - ret = bind(fd, (struct sockaddr *)&can_addr, sizeof(can_addr)); - if (ret < 0) { - ret = -errno; - LOG_ERR("Cannot bind %s CAN socket (%d)", "2nd", ret); - goto cleanup2; - } - - setsockopt(fd, SOL_CAN_RAW, CAN_RAW_FILTER, &filter, sizeof(filter)); + fd = create_socket(&filter); + if (fd >= 0) { + rx_tid = k_thread_create(&rx_data, rx_stack, + K_THREAD_STACK_SIZEOF(rx_stack), + (k_thread_entry_t)rx, + INT_TO_POINTER(fd), + INT_TO_POINTER(CLOSE_PERIOD), + &filter, PRIORITY, 0, K_NO_WAIT); + if (!rx_tid) { + ret = -ENOENT; + errno = -ret; + LOG_ERR("Cannot create 2nd RX thread!"); + goto cleanup2; + } - rx_tid = k_thread_create(&rx_data, rx_stack, - K_THREAD_STACK_SIZEOF(rx_stack), - (k_thread_entry_t)rx, INT_TO_POINTER(fd), - NULL, NULL, PRIORITY, 0, K_NO_WAIT); - if (!rx_tid) { - ret = -ENOENT; - errno = -ret; - LOG_ERR("Cannot create 2nd RX thread!"); - goto cleanup2; + LOG_INF("2nd RX fd %d", fd); + } else { + LOG_ERR("2nd RX not created (%d)", fd); } #endif @@ -214,11 +257,14 @@ void main(void) { int fd; + /* Let the device start before doing anything */ + k_sleep(K_SECONDS(2)); + fd = setup_socket(); if (fd < 0) { LOG_ERR("Cannot start CAN application (%d)", fd); return; } - rx(INT_TO_POINTER(fd)); + rx(INT_TO_POINTER(fd), NULL, NULL); }