Skip to content

Commit

Permalink
net: socket: can: Add getsockopt() and setsockopt() support
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
jukkar committed Feb 7, 2019
1 parent a046a86 commit df71623
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
12 changes: 12 additions & 0 deletions include/net/socket_can.h
Expand Up @@ -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))

Expand All @@ -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);
};

/**
Expand Down
46 changes: 46 additions & 0 deletions subsys/net/lib/sockets/sockets_can.c
Expand Up @@ -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);
}

Expand Down

0 comments on commit df71623

Please sign in to comment.