-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] Add PF_CAN protocol for socket CAN #11454
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
/* | ||
* Copyright (c) 2018 Intel Corporation. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#ifndef _SOCKET_CAN_H_ | ||
#define _SOCKET_CAN_H_ | ||
|
||
#include <device.h> | ||
#include <net/net_ip.h> | ||
#include <can.h> | ||
#include <zephyr/types.h> | ||
|
||
/** Max length of socket packet */ | ||
#define CAN_NET_MTU (72) | ||
|
||
/** Protocol family of socket can connection */ | ||
#define CAN_CONTEXT_FAMILY BIT(8) | ||
|
||
/** Context type of socket can connection */ | ||
#define CAN_CONTEXT_TYPE BIT(9) | ||
|
||
/** Context proto for socket can connection */ | ||
#define CAN_CONTEXT_PROTO BIT(10) | ||
|
||
/** | ||
* @brief socket addr structure for AF_CAN protocol | ||
* | ||
* Socket address structure for AF_CAN protocol family | ||
* | ||
*/ | ||
struct sockaddr_can { | ||
/** protocol family for socket can */ | ||
sa_family_t can_family; | ||
/** net_if interface associated with socket */ | ||
u8_t can_ifindex; | ||
}; | ||
|
||
/** | ||
* @brief check matched CAN filter for incoming CAN message. | ||
* | ||
* This routine matches id with configured filters id and return true or false. | ||
* * | ||
* @param dev Pointer to the device structure for the driver instance. | ||
* @param pkt incoming net_pkt | ||
* | ||
* @retval 1 if filter matched otherwise 0. | ||
*/ | ||
typedef int (*socket_can_check_filter_matched_t)(struct device *dev, | ||
struct net_pkt *pkt); | ||
|
||
/** | ||
* @brief configure filter for accpetance filter. | ||
* | ||
* This routine configure can filter and register rx callback. | ||
* * | ||
* @param dev Pointer to the device structure for the driver instance. | ||
* @param filter can_filter structure | ||
* | ||
* @retval return < 0 in case of error and 0 for success. | ||
*/ | ||
typedef int (*socket_can_config_filter_t)(struct device *dev, | ||
struct can_filter *filter); | ||
|
||
int socket_can_get_opt(struct net_context *context, int optname, | ||
void *optval, socklen_t *optlen); | ||
int socket_can_set_opt(struct net_context *context, int optname, | ||
const void *optval, socklen_t optlen); | ||
|
||
|
||
|
||
/** | ||
* @brief socket can driver api structure | ||
* Socket CAN driver apis for iface interface functions and ioctl call. | ||
* | ||
*/ | ||
struct socket_can_driver_api_t { | ||
/** iface interface for socket apis to send and init function*/ | ||
struct net_if_api iface_api; | ||
/** check matching filter for loopback messages */ | ||
socket_can_check_filter_matched_t check_matched_filter; | ||
/** configure filter with rx callback */ | ||
socket_can_config_filter_t config_filter; | ||
}; | ||
|
||
/** | ||
* @brief socket can context structure | ||
* | ||
* socket can driver specific structure. | ||
* | ||
*/ | ||
struct socket_can_context { | ||
/** id of CAN instance */ | ||
u32_t id; | ||
/** iface interface reference structure*/ | ||
struct net_if *iface; | ||
/** can device structure reference */ | ||
struct device *can_dev; | ||
}; | ||
|
||
/** | ||
* @brief socket can mode structure | ||
* | ||
* This structure will be passed via setSocketOpt and configure can controller | ||
* operation mode as well as baud rate | ||
*/ | ||
struct socket_can_mode { | ||
enum can_mode op_mode; | ||
u32_t baud_rate; | ||
}; | ||
|
||
__syscall int socket_can_check_filter_matched(struct device *dev, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar comment to the above - no socket_can_check_filter_matched() function in POSIX. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @pfalcon: What if we get this patch in as-is and update it as soon as you'll be ready with setsockopt code? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @laperie that's not a good idea actually There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you actually need a function like socket_can_check_filter_matched? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @alexanderwachter This function implements local loopback functionality mentioned in section 3.2 of https://www.kernel.org/doc/Documentation/networking/can.txt. And in https://www.can-cia.org/fileadmin/resources/documents/proceedings/2012_kleine-budde.pdf document it is mentioned to implement it via software filtering. So this function checks if sent CAN packet Id is matched with any of configured filter id on sender node then socket application will receive this locally loopbacked packet. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Be aware that the loopback mode bit does not only check the filter and send the message back if it matches. It also set the ACK bit while sending. Basically it acknowledges its own package. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This loopback is not via can controller. It will check the matched filter in SW layer only and if matched then connection callback will be trigger with this pkt and socket recv call will get the packet. So for every sent packet this check will happen and if current mode of CAN is loopback mode then same mode will receive two packets. One from CAN controller and another from sw filtering. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed ioctl calls and implemented getsockopt and setsockopt APIs for configuring can mode, bit rate and filters. |
||
struct net_pkt *pkt); | ||
|
||
static inline int _impl_socket_can_check_filter_matched(struct device *dev, | ||
struct net_pkt *pkt) | ||
{ | ||
const struct socket_can_driver_api_t *api = NULL; | ||
int result = 0; | ||
|
||
if (pkt == NULL) { | ||
goto err; | ||
} | ||
|
||
api = dev->driver_api; | ||
if (api && api->check_matched_filter) { | ||
result = api->check_matched_filter(dev, pkt); | ||
} | ||
err: | ||
return result; | ||
} | ||
|
||
__syscall int socket_can_config_filter(struct device *dev, | ||
struct can_filter *filter); | ||
|
||
static inline int _impl_socket_can_config_filter(struct device *dev, | ||
struct can_filter *filter) | ||
{ | ||
const struct socket_can_driver_api_t *api = NULL; | ||
int res = 0; | ||
|
||
if (filter == NULL) { | ||
res = -EBADF; | ||
goto err; | ||
} | ||
|
||
api = dev->driver_api; | ||
if (api && api->config_filter) { | ||
res = api->config_filter(dev, filter); | ||
} | ||
err: | ||
return res; | ||
} | ||
|
||
#include <syscalls/socket_can.h> | ||
|
||
#endif /*_SOCKET_CAN_H_ */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How CAN (and raw even), can be part of IP protocol? Is it transported through IP? Just asking, I don't know CAN.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"The SocketCAN concept extends the Berkeley sockets API in Linux by introducing a new protocol family, PF_CAN, that coexists with other protocol families like PF_INET for the Internet Protocol. The communication with the CAN bus is therefore done analogously to the use of the Internet Protocol via sockets."
Source: https://en.wikipedia.org/wiki/SocketCAN
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few comments here:
struct can_frame
. This is very, very different from normal TCP or UDP sockets.