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:
parent
a046a86966
commit
df7162331f
|
@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue