* libsocketcan proposal for upstream (get typekind vcan or can, etc.)
@ 2016-09-23 6:16 aj neu
2016-09-23 6:19 ` aj neu
0 siblings, 1 reply; 4+ messages in thread
From: aj neu @ 2016-09-23 6:16 UTC (permalink / raw)
To: linux-can
Hello,
below, please find a patch which adds the following functions to libsocketcan
device_exists, device_is_up, can_get_typekind
int device_exists(const char *name);
// determine if device is libsocketcan-compatible and exists
int device_is_up(const char *name);
// determine if device is up (also usable for vcan)
int can_get_typekind(const char *name, char *buf, size_t buflen);
// determine if typekind is "can" or "vcan"
The patch can be applied to
https://git.platon.pengutronix.de/cgit/tools/libsocketcan
as follows:
git apply diff.patch
Can this be applied to upstream?
Thanks.
ajneu
diff --git a/include/libsocketcan.h b/include/libsocketcan.h
index dc52053..16fd60a 100644
--- a/include/libsocketcan.h
+++ b/include/libsocketcan.h
@@ -27,11 +27,15 @@
*/
#include <can_netlink.h>
+#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
+int device_exists(const char *name);
+int device_is_up(const char *name);
+
int can_do_restart(const char *name);
int can_do_stop(const char *name);
int can_do_start(const char *name);
@@ -46,6 +50,7 @@ int can_get_restart_ms(const char *name, __u32 *restart_ms);
int can_get_bittiming(const char *name, struct can_bittiming *bt);
int can_get_ctrlmode(const char *name, struct can_ctrlmode *cm);
int can_get_state(const char *name, int *state);
+int can_get_typekind(const char *name, char *buf, size_t buflen);
int can_get_clock(const char *name, struct can_clock *clock);
int can_get_bittiming_const(const char *name, struct can_bittiming_const *btc);
int can_get_berr_counter(const char *name, struct can_berr_counter *bc);
diff --git a/src/libsocketcan.c b/src/libsocketcan.c
index c97a28c..7c7f9bb 100644
--- a/src/libsocketcan.c
+++ b/src/libsocketcan.c
@@ -46,6 +46,10 @@
#define IF_UP 1
#define IF_DOWN 2
+#ifndef IFF_UP
+#define IFF_UP IF_UP
+#endif
+
#define GET_STATE 1
#define GET_RESTART_MS 2
#define GET_BITTIMING 3
@@ -54,6 +58,9 @@
#define GET_BITTIMING_CONST 6
#define GET_BERR_COUNTER 7
#define GET_XSTATS 8
+#define GET_TYPEKIND 9
+#define GET_DEVICEEXISTS 10
+#define GET_DEVICE_UP 11
struct get_req {
struct nlmsghdr n;
@@ -74,6 +81,11 @@ struct req_info {
struct can_bittiming *bittiming;
};
+struct str_buf {
+ char * buf;
+ const size_t capacity; // storage capacity of buf: number of bytes
+};
+
static void
parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta, int len)
{
@@ -389,7 +401,8 @@ static int do_get_nl_link(int fd, __u8 acquire,
const char *name, void *res)
else
continue;
- if (acquire == GET_XSTATS) {
+ switch (acquire) {
+ case GET_XSTATS:
if (!linkinfo[IFLA_INFO_XSTATS])
fprintf(stderr, "no can statistics found\n");
else {
@@ -398,6 +411,30 @@ static int do_get_nl_link(int fd, __u8 acquire,
const char *name, void *res)
ret = 0;
}
continue;
+
+ case GET_TYPEKIND:
+ if (!linkinfo[IFLA_INFO_KIND])
+ fprintf(stderr, "no type-kind found\n");
+ else {
+ const size_t buflen = ((struct str_buf *)res)->capacity;
+ if (buflen) {
+ char * const buf = ((struct str_buf *)res)->buf;
+ *buf = '\0';
+ strncat(buf,
RTA_DATA(linkinfo[IFLA_INFO_KIND]), buflen-1);
+ }
+ ret = 0;
+ }
+ continue;
+
+ case GET_DEVICEEXISTS:
+ ret = 0;
+ continue;
+
+ case GET_DEVICE_UP:
+ if ((ifi->ifi_flags & IFF_UP) == IFF_UP) {
+ ret = 0;
+ }
+ continue;
}
if (!linkinfo[IFLA_INFO_DATA]) {
@@ -652,6 +689,38 @@ static int set_link(const char *name, __u8
if_state, struct req_info *req_info)
/**
* @ingroup extern
+ * device_exists - return non-zero if the device exists
+ *
+ * @param name name of the device. This is the netdev name, as
ifconfig -a shows
+ * in your system. usually it contains prefix "can" and the numer of the can
+ * line. e.g. "can0"
+ *
+ * @return 1 if device exists
+ * @return 0 if device does not exist
+ */
+int device_exists(const char *name)
+{
+ return !get_link(name, GET_DEVICEEXISTS, NULL);
+}
+
+/**
+ * @ingroup extern
+ * device_is_up - return non-zero if the device is up
+ *
+ * @param name name of the device. This is the netdev name, as
ifconfig -a shows
+ * in your system. usually it contains prefix "can" and the numer of the can
+ * line. e.g. "can0"
+ *
+ * @return 1 if device is up
+ * @return 0 if device is not up
+ */
+int device_is_up(const char *name)
+{
+ return !get_link(name, GET_DEVICE_UP, NULL);
+}
+
+/**
+ * @ingroup extern
* can_do_start - start the can interface
* @param name name of the can device. This is the netdev name, as
ifconfig -a shows
* in your system. usually it contains prefix "can" and the numer of the can
@@ -961,6 +1030,25 @@ int can_get_state(const char *name, int *state)
/**
* @ingroup extern
+ * can_get_typekind - get the type (kind) of the netlink, i.e. can or vcan
+ *
+ * @param name name of the can device. This is the netdev name, as
ifconfig -a shows
+ * in your system. usually it contains prefix "can" and the numer of the can
+ * line. e.g. "can0"
+ * @param buf pointer to the first element of a string buffer, to
store the kind
+ * @param buflen length of the string buffer (at most buflen-1 chars
will be written)
+ *
+ * @return 0 if success
+ * @return -1 if failed
+ */
+int can_get_typekind(const char *name, char *buf, size_t buflen)
+{
+ struct str_buf sbuf = { buf, buflen };
+ return get_link(name, GET_TYPEKIND, &sbuf);
+}
+
+/**
+ * @ingroup extern
* can_get_restart_ms - get the current interval of auto restarting.
*
* @param name name of the can device. This is the netdev name, as
ifconfig -a shows
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: libsocketcan proposal for upstream (get typekind vcan or can, etc.)
2016-09-23 6:16 libsocketcan proposal for upstream (get typekind vcan or can, etc.) aj neu
@ 2016-09-23 6:19 ` aj neu
2016-09-23 10:19 ` André Hartmann
2016-09-23 12:15 ` André Hartmann
0 siblings, 2 replies; 4+ messages in thread
From: aj neu @ 2016-09-23 6:19 UTC (permalink / raw)
To: linux-can
[-- Attachment #1: Type: text/plain, Size: 759 bytes --]
On Fri, Sep 23, 2016 at 8:16 AM, aj neu wrote:
> Hello,
>
> below, please find a patch which adds the following functions to libsocketcan
>
> device_exists, device_is_up, can_get_typekind
>
> int device_exists(const char *name);
> // determine if device is libsocketcan-compatible and exists
>
> int device_is_up(const char *name);
> // determine if device is up (also usable for vcan)
>
> int can_get_typekind(const char *name, char *buf, size_t buflen);
> // determine if typekind is "can" or "vcan"
>
>
> The patch can be applied to
> https://git.platon.pengutronix.de/cgit/tools/libsocketcan
> as follows:
> git apply diff.patch
>
>
> Can this be applied to upstream?
>
> Thanks.
> ajneu
Here's the patch as attachment.
[-- Attachment #2: diff.patch --]
[-- Type: text/x-patch, Size: 4994 bytes --]
diff --git a/include/libsocketcan.h b/include/libsocketcan.h
index dc52053..16fd60a 100644
--- a/include/libsocketcan.h
+++ b/include/libsocketcan.h
@@ -27,11 +27,15 @@
*/
#include <can_netlink.h>
+#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
+int device_exists(const char *name);
+int device_is_up(const char *name);
+
int can_do_restart(const char *name);
int can_do_stop(const char *name);
int can_do_start(const char *name);
@@ -46,6 +50,7 @@ int can_get_restart_ms(const char *name, __u32 *restart_ms);
int can_get_bittiming(const char *name, struct can_bittiming *bt);
int can_get_ctrlmode(const char *name, struct can_ctrlmode *cm);
int can_get_state(const char *name, int *state);
+int can_get_typekind(const char *name, char *buf, size_t buflen);
int can_get_clock(const char *name, struct can_clock *clock);
int can_get_bittiming_const(const char *name, struct can_bittiming_const *btc);
int can_get_berr_counter(const char *name, struct can_berr_counter *bc);
diff --git a/src/libsocketcan.c b/src/libsocketcan.c
index c97a28c..7c7f9bb 100644
--- a/src/libsocketcan.c
+++ b/src/libsocketcan.c
@@ -46,6 +46,10 @@
#define IF_UP 1
#define IF_DOWN 2
+#ifndef IFF_UP
+#define IFF_UP IF_UP
+#endif
+
#define GET_STATE 1
#define GET_RESTART_MS 2
#define GET_BITTIMING 3
@@ -54,6 +58,9 @@
#define GET_BITTIMING_CONST 6
#define GET_BERR_COUNTER 7
#define GET_XSTATS 8
+#define GET_TYPEKIND 9
+#define GET_DEVICEEXISTS 10
+#define GET_DEVICE_UP 11
struct get_req {
struct nlmsghdr n;
@@ -74,6 +81,11 @@ struct req_info {
struct can_bittiming *bittiming;
};
+struct str_buf {
+ char * buf;
+ const size_t capacity; // storage capacity of buf: number of bytes
+};
+
static void
parse_rtattr(struct rtattr **tb, int max, struct rtattr *rta, int len)
{
@@ -389,7 +401,8 @@ static int do_get_nl_link(int fd, __u8 acquire, const char *name, void *res)
else
continue;
- if (acquire == GET_XSTATS) {
+ switch (acquire) {
+ case GET_XSTATS:
if (!linkinfo[IFLA_INFO_XSTATS])
fprintf(stderr, "no can statistics found\n");
else {
@@ -398,6 +411,30 @@ static int do_get_nl_link(int fd, __u8 acquire, const char *name, void *res)
ret = 0;
}
continue;
+
+ case GET_TYPEKIND:
+ if (!linkinfo[IFLA_INFO_KIND])
+ fprintf(stderr, "no type-kind found\n");
+ else {
+ const size_t buflen = ((struct str_buf *)res)->capacity;
+ if (buflen) {
+ char * const buf = ((struct str_buf *)res)->buf;
+ *buf = '\0';
+ strncat(buf, RTA_DATA(linkinfo[IFLA_INFO_KIND]), buflen-1);
+ }
+ ret = 0;
+ }
+ continue;
+
+ case GET_DEVICEEXISTS:
+ ret = 0;
+ continue;
+
+ case GET_DEVICE_UP:
+ if ((ifi->ifi_flags & IFF_UP) == IFF_UP) {
+ ret = 0;
+ }
+ continue;
}
if (!linkinfo[IFLA_INFO_DATA]) {
@@ -652,6 +689,38 @@ static int set_link(const char *name, __u8 if_state, struct req_info *req_info)
/**
* @ingroup extern
+ * device_exists - return non-zero if the device exists
+ *
+ * @param name name of the device. This is the netdev name, as ifconfig -a shows
+ * in your system. usually it contains prefix "can" and the numer of the can
+ * line. e.g. "can0"
+ *
+ * @return 1 if device exists
+ * @return 0 if device does not exist
+ */
+int device_exists(const char *name)
+{
+ return !get_link(name, GET_DEVICEEXISTS, NULL);
+}
+
+/**
+ * @ingroup extern
+ * device_is_up - return non-zero if the device is up
+ *
+ * @param name name of the device. This is the netdev name, as ifconfig -a shows
+ * in your system. usually it contains prefix "can" and the numer of the can
+ * line. e.g. "can0"
+ *
+ * @return 1 if device is up
+ * @return 0 if device is not up
+ */
+int device_is_up(const char *name)
+{
+ return !get_link(name, GET_DEVICE_UP, NULL);
+}
+
+/**
+ * @ingroup extern
* can_do_start - start the can interface
* @param name name of the can device. This is the netdev name, as ifconfig -a shows
* in your system. usually it contains prefix "can" and the numer of the can
@@ -961,6 +1030,25 @@ int can_get_state(const char *name, int *state)
/**
* @ingroup extern
+ * can_get_typekind - get the type (kind) of the netlink, i.e. can or vcan
+ *
+ * @param name name of the can device. This is the netdev name, as ifconfig -a shows
+ * in your system. usually it contains prefix "can" and the numer of the can
+ * line. e.g. "can0"
+ * @param buf pointer to the first element of a string buffer, to store the kind
+ * @param buflen length of the string buffer (at most buflen-1 chars will be written)
+ *
+ * @return 0 if success
+ * @return -1 if failed
+ */
+int can_get_typekind(const char *name, char *buf, size_t buflen)
+{
+ struct str_buf sbuf = { buf, buflen };
+ return get_link(name, GET_TYPEKIND, &sbuf);
+}
+
+/**
+ * @ingroup extern
* can_get_restart_ms - get the current interval of auto restarting.
*
* @param name name of the can device. This is the netdev name, as ifconfig -a shows
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: libsocketcan proposal for upstream (get typekind vcan or can, etc.)
2016-09-23 6:19 ` aj neu
@ 2016-09-23 10:19 ` André Hartmann
2016-09-23 12:15 ` André Hartmann
1 sibling, 0 replies; 4+ messages in thread
From: André Hartmann @ 2016-09-23 10:19 UTC (permalink / raw)
To: aj neu, linux-can, mkl
Am 23.09.2016 um 08:19 schrieb aj neu:
> On Fri, Sep 23, 2016 at 8:16 AM, aj neu wrote:
>> Hello,
>>
>> below, please find a patch which adds the following functions to libsocketcan
>>
>> device_exists, device_is_up, can_get_typekind
>>
>> int device_exists(const char *name);
>> // determine if device is libsocketcan-compatible and exists
>>
>> int device_is_up(const char *name);
>> // determine if device is up (also usable for vcan)
>>
>> int can_get_typekind(const char *name, char *buf, size_t buflen);
>> // determine if typekind is "can" or "vcan"
>>
>>
>> The patch can be applied to
>> https://git.platon.pengutronix.de/cgit/tools/libsocketcan
>> as follows:
>> git apply diff.patch
>>
>>
>> Can this be applied to upstream?
>>
>> Thanks.
>> ajneu
>
> Here's the patch as attachment.
>
Hello AJ,
without having a deeper look at your patch, I think it is a quite useful
addition. Please find my comments below.
>> int device_exists(const char *name);
This is good, but even better would be something that enumerates
available interfaces. Looking for available interfaces is a common task,
I guess. Something like Kurt's library [1] does and what I do in
QtSerialBus [2] because I was unable to use [1] because of license
reasons :(
>> int device_is_up(const char *name);
OK, if device_exists returns true for devices that are not up.
>> int can_get_typekind(const char *name, char *buf, size_t buflen);
Can buf contains anything else beside "can" and "vcan"? If not, I
instead propose a more concise function:
int device_is_virtual(const char *name);
Regarding the patch itself:
Marc, what do you say? Will you accept patches to libsocketcan The last
commits are from 2014...
And last, one more comment to the code:
+case GET_TYPEKIND:
+ if (!linkinfo[IFLA_INFO_KIND])
+ fprintf(stderr, "no type-kind found\n");
+ else {
I don't know if there are any rules in libsocketcan, but I really prefer
having curly braces { } around the if also, when there are curly braces
around the else branch.
+ const size_t buflen = ((struct str_buf *)res)->capacity;
+ if (buflen) {
+ char * const buf = ((struct str_buf *)res)->buf;
+ *buf = '\0';
+ strncat(buf, RTA_DATA(linkinfo[IFLA_INFO_KIND]), buflen-1);
First I asked why not using strncpy, but I guess this is a trick to make
sure buf is null-terminated? On the other hand, the following code is
not longer (buflen - 1 is allowed because you checked for zero already):
strncpy(buf, RTA_DATA(linkinfo[IFLA_INFO_KIND]), buflen);
buf[buflen - 1] = '\0';
+ }
+ ret = 0;
+}
Best regards,
André
[1] https://github.com/kurt-vd/enumif
[2]
https://codereview.qt-project.org/#/c/166460/13/src/plugins/canbus/socketcan/socketcanbackend.cpp
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: libsocketcan proposal for upstream (get typekind vcan or can, etc.)
2016-09-23 6:19 ` aj neu
2016-09-23 10:19 ` André Hartmann
@ 2016-09-23 12:15 ` André Hartmann
1 sibling, 0 replies; 4+ messages in thread
From: André Hartmann @ 2016-09-23 12:15 UTC (permalink / raw)
To: aj neu, linux-can
Hi again AJ,
I've now taken a second look at your patch.
As all functions in libsocketcan start with can_*, your new functions
device_exists and device_is_up are not consistent. As all existing
functions already have const char *name as first parameter, I think the
word "device" is superflous. Having all functions starting with can_*
helps including the library in existing projects.
Suggestions:
int can_is_(existing|available|present)(const char *name);
int can_is_up(const char *name);
Best regards,
André
Am 23.09.2016 um 08:19 schrieb aj neu:
> On Fri, Sep 23, 2016 at 8:16 AM, aj neu wrote:
>> Hello,
>>
>> below, please find a patch which adds the following functions to libsocketcan
>>
>> device_exists, device_is_up, can_get_typekind
>>
>> int device_exists(const char *name);
>> // determine if device is libsocketcan-compatible and exists
>>
>> int device_is_up(const char *name);
>> // determine if device is up (also usable for vcan)
>>
>> int can_get_typekind(const char *name, char *buf, size_t buflen);
>> // determine if typekind is "can" or "vcan"
>>
>>
>> The patch can be applied to
>> https://git.platon.pengutronix.de/cgit/tools/libsocketcan
>> as follows:
>> git apply diff.patch
>>
>>
>> Can this be applied to upstream?
>>
>> Thanks.
>> ajneu
>
> Here's the patch as attachment.
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2016-09-23 12:15 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-23 6:16 libsocketcan proposal for upstream (get typekind vcan or can, etc.) aj neu
2016-09-23 6:19 ` aj neu
2016-09-23 10:19 ` André Hartmann
2016-09-23 12:15 ` André Hartmann
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.