diff --git a/arch/sim/src/sim/posix/sim_hostcan.c b/arch/sim/src/sim/posix/sim_hostcan.c index e5e50a9c23f..bf453333f52 100644 --- a/arch/sim/src/sim/posix/sim_hostcan.c +++ b/arch/sim/src/sim/posix/sim_hostcan.c @@ -184,3 +184,35 @@ bool host_can_avail(struct sim_can_s *can) return select(can->fd + 1, &fdset, NULL, NULL, &tv) > 0; } + +/**************************************************************************** + * Name: host_can_loopback + ****************************************************************************/ + +int host_can_loopback(struct sim_can_s *can, bool enable) +{ + int ret; + int tmp; + + /* Receive own messages */ + + tmp = 1; + ret = setsockopt(can->fd, SOL_CAN_RAW, CAN_RAW_RECV_OWN_MSGS, + &tmp, sizeof(tmp)); + if (ret < 0) + { + return -errno; + } + + /* Set loopback mode */ + + tmp = 1; + ret = setsockopt(can->fd, SOL_CAN_RAW, CAN_RAW_LOOPBACK, &tmp, + sizeof(tmp)); + if (ret < 0) + { + return -errno; + } + + return 0; +} diff --git a/arch/sim/src/sim/sim_canchar.c b/arch/sim/src/sim/sim_canchar.c index 5101a91dddb..5a1843c9a95 100644 --- a/arch/sim/src/sim/sim_canchar.c +++ b/arch/sim/src/sim/sim_canchar.c @@ -361,10 +361,18 @@ int sim_canchar_initialize(int devidx, int devno) if (ret < 0) { canerr("host_can_init failed %d\n", ret); - kmm_free(priv); - return ret; + goto errout; } +#ifdef CONFIG_CAN_LOOPBACK + ret = host_can_loopback(&priv->host, true); + if (ret < 0) + { + canerr("host_can_loopback failed %d\n", ret); + goto errout; + } +#endif + /* Initialzie CAN character driver */ priv->dev.cd_ops = &g_sim_can_ops; @@ -377,9 +385,12 @@ int sim_canchar_initialize(int devidx, int devno) if (ret < 0) { canerr("can_register failed %d\n", ret); - kmm_free(priv); - return ret; + goto errout; } return OK; + +errout: + kmm_free(priv); + return ret; } diff --git a/arch/sim/src/sim/sim_hostcan.h b/arch/sim/src/sim/sim_hostcan.h index dcb427a0087..d18891e8bc1 100644 --- a/arch/sim/src/sim/sim_hostcan.h +++ b/arch/sim/src/sim/sim_hostcan.h @@ -62,5 +62,6 @@ int host_can_send(struct sim_can_s *can, void *frame, size_t len); int host_can_ifup(struct sim_can_s *can); int host_can_ifdown(struct sim_can_s *can); bool host_can_avail(struct sim_can_s *can); +int host_can_loopback(struct sim_can_s *can, bool enable); #endif /* __ARCH_SIM_SRC_SIM_CAN_H */