Added automatic extended frame format recognition.

Most SocketCAN userspace tools (like cansend) recognize the EFF by the 
stringlength of the given CAN-ID: 3 -> SFF , 8 -> EFF.
This was missing in the candump filter definition and therefore the 
values had to be specified with the CAN_EFF_FLAG set in the value, e.g.
92345678 for the extended CAN-ID 12345678 - this was not really nice.

Now the filtersets for extended frames can be specified as expected:
12345678:1FFFFFFF to filter for only 12345678 extended CAN-ID
000000AA:1FFFFFFF to filter for only AA extended CAN-ID.
pull/7/head
Oliver Hartkopp 2008-07-02 04:05:11 +00:00
parent 6410c22fd5
commit f1c095d801
1 changed files with 28 additions and 2 deletions

View File

@ -116,12 +116,16 @@ void print_usage(char *prg)
fprintf(stderr, " <can_id>:<can_mask> (matches when <received_can_id> & mask == can_id & mask)\n");
fprintf(stderr, " <can_id>~<can_mask> (matches when <received_can_id> & mask != can_id & mask)\n");
fprintf(stderr, " #<error_mask> (set error frame filter, see include/linux/can/error.h)\n");
fprintf(stderr, "\nCAN IDs, masks and data content are given and expected in hexadecimal values.\n");
fprintf(stderr, "When can_id and can_mask are both 8 digits, they are assumed to be 29 bit EFF.\n");
fprintf(stderr, "Without any given filter all data frames are received ('0:0' default filter).\n");
fprintf(stderr, "\nUse interface name '%s' to receive from all CAN interfaces.\n", ANYDEV);
fprintf(stderr, "CAN IDs, masks and data content are given and expected in hexadecimal values.\n");
fprintf(stderr, "\nExamples:\n");
fprintf(stderr, "%s -c -c -ta can0,123:7FF,400:700,#000000FF can2,400~7F0 can3 can8\n", prg);
fprintf(stderr, "%s -l any,0~0,#FFFFFFFF (log only error frames but no(!) data frames)\n", prg);
fprintf(stderr, "%s -l any,0:0,#FFFFFFFF (log error frames and also all data frames)\n", prg);
fprintf(stderr, "%s vcan2,92345678:9FFFFFFF (match only for extended CAN ID 12345678)\n", prg);
fprintf(stderr, "%s vcan2,12345678:1FFFFFFF (analog to above due to 8 digit value length)\n", prg);
fprintf(stderr, "\n");
}
@ -179,6 +183,21 @@ int idx2dindex(int ifidx, int socket) {
return i;
}
canid_t checkeff(char *ptr, char *nptr)
{
int len;
if (nptr)
len = nptr - ptr;
else
len = strlen(ptr);
if (len == 17 && (ptr[8] == ':' || ptr[8] == '~'))
return CAN_EFF_FLAG;
else
return 0;
}
int main(int argc, char **argv)
{
fd_set rdfs;
@ -194,6 +213,7 @@ int main(int argc, char **argv)
int opt, ret;
int currmax, numfilter;
char *ptr, *nptr;
canid_t eff;
struct sockaddr_can addr;
struct can_filter rfilter[MAXFILTER];
can_err_mask_t err_mask;
@ -364,13 +384,19 @@ int main(int argc, char **argv)
&rfilter[numfilter].can_id,
(long unsigned int *)
&rfilter[numfilter].can_mask) == 2) {
eff = checkeff(ptr, nptr);
rfilter[numfilter].can_id |= eff;
rfilter[numfilter].can_mask |= eff;
numfilter++;
} else if (sscanf(ptr, "%lx~%lx",
(long unsigned int *)
&rfilter[numfilter].can_id,
(long unsigned int *)
&rfilter[numfilter].can_mask) == 2) {
rfilter[numfilter].can_id |= CAN_INV_FILTER;
rfilter[numfilter].can_id |= CAN_INV_FILTER;
eff = checkeff(ptr, nptr);
rfilter[numfilter].can_id |= eff;
rfilter[numfilter].can_mask |= eff;
numfilter++;
} else if (sscanf(ptr, "#%lx",
(long unsigned int *)&err_mask) != 1) {