net: socket: can: Add getsockopt() and setsockopt() support

It is possible to set the filter in user application and that
information is passed to the CANBUS device driver.

Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2019-02-04 16:26:09 +02:00
parent a046a86966
commit df7162331f
2 changed files with 58 additions and 0 deletions

View file

@ -36,6 +36,10 @@ extern "C" {
#define SOL_CAN_BASE 100
#define SOL_CAN_RAW (SOL_CAN_BASE + CAN_RAW)
enum {
CAN_RAW_FILTER = 1,
};
/* Socket CAN MTU size */
#define CAN_MTU (sizeof(struct can_msg))
@ -60,6 +64,14 @@ struct canbus_api {
/** Send a CAN packet by socket */
int (*send)(struct device *dev, struct net_pkt *pkt);
/** Set socket CAN option */
int (*setsockopt)(struct device *dev, void *obj, int level, int optname,
const void *optval, socklen_t optlen);
/** Get socket CAN option */
int (*getsockopt)(struct device *dev, void *obj, int level, int optname,
const void *optval, socklen_t *optlen);
};
/**

View file

@ -329,12 +329,58 @@ static ssize_t can_sock_recvfrom_vmeth(void *obj, void *buf, size_t max_len,
static int can_sock_getsockopt_vmeth(void *obj, int level, int optname,
void *optval, socklen_t *optlen)
{
if (level == SOL_CAN_RAW) {
const struct canbus_api *api;
struct net_if *iface;
struct device *dev;
if (optval == NULL) {
errno = EINVAL;
return -1;
}
iface = net_context_get_iface(obj);
dev = net_if_get_device(iface);
api = dev->driver_api;
if (!api->getsockopt) {
errno = ENOTSUP;
return -1;
}
return api->getsockopt(dev, obj, level, optname, optval,
optlen);
}
return zcan_getsockopt_ctx(obj, level, optname, optval, optlen);
}
static int can_sock_setsockopt_vmeth(void *obj, int level, int optname,
const void *optval, socklen_t optlen)
{
if (level == SOL_CAN_RAW) {
const struct canbus_api *api;
struct net_if *iface;
struct device *dev;
if (optval == NULL) {
errno = EINVAL;
return -1;
}
iface = net_context_get_iface(obj);
dev = net_if_get_device(iface);
api = dev->driver_api;
if (!api->setsockopt) {
errno = ENOTSUP;
return -1;
}
return api->setsockopt(dev, obj, level, optname, optval,
optlen);
}
return zcan_setsockopt_ctx(obj, level, optname, optval, optlen);
}