Added new socketoptions to force the isotp protocol to intentionally

misbehave for regression tests.

CAN_ISOTP_TX_STMIN:
Set a value in nano secs that's used as minimum CF gap by the sender.
This value is used instead of the value provided by the receiver inside the FC.

CAN_ISOTP_RX_STMIN:
Ignores received CF frames which timestamps differ less than this value in nano
secs. This is used to test the receivers misbehaviour when the receiver
provides a lower stmin value that he's able to cope with. Received CF frames
are silently dropped when they come faster than specified by this value.
pull/7/head
Oliver Hartkopp 2010-11-14 08:55:06 +00:00
parent d3468d907f
commit 6aeb7d1faa
2 changed files with 23 additions and 3 deletions

View File

@ -71,6 +71,7 @@ void print_usage(char *prg)
fprintf(stderr, " -P <mode> (check padding in SF/CF. (l)ength (c)ontent (a)ll)\n"); fprintf(stderr, " -P <mode> (check padding in SF/CF. (l)ength (c)ontent (a)ll)\n");
fprintf(stderr, " -b <bs> (blocksize. 0 = off)\n"); fprintf(stderr, " -b <bs> (blocksize. 0 = off)\n");
fprintf(stderr, " -m <val> (STmin in ms/ns. See spec.)\n"); fprintf(stderr, " -m <val> (STmin in ms/ns. See spec.)\n");
fprintf(stderr, " -f <time ns> (force rx stmin value in nanosecs)\n");
fprintf(stderr, " -w <num> (max. wait frame transmissions.)\n"); fprintf(stderr, " -w <num> (max. wait frame transmissions.)\n");
fprintf(stderr, " -l (loop: do not exit after pdu receiption.)\n"); fprintf(stderr, " -l (loop: do not exit after pdu receiption.)\n");
fprintf(stderr, "\nCAN IDs and addresses are given and expected in hexadecimal values.\n"); fprintf(stderr, "\nCAN IDs and addresses are given and expected in hexadecimal values.\n");
@ -87,6 +88,7 @@ int main(int argc, char **argv)
static struct can_isotp_fc_options fcopts; static struct can_isotp_fc_options fcopts;
int opt, i; int opt, i;
extern int optind, opterr, optopt; extern int optind, opterr, optopt;
__u32 force_rx_stmin = 0;
int loop = 0; int loop = 0;
unsigned char msg[4096]; unsigned char msg[4096];
@ -94,7 +96,7 @@ int main(int argc, char **argv)
addr.can_addr.tp.tx_id = addr.can_addr.tp.rx_id = NO_CAN_ID; addr.can_addr.tp.tx_id = addr.can_addr.tp.rx_id = NO_CAN_ID;
while ((opt = getopt(argc, argv, "s:d:x:p:P:b:m:w:l?")) != -1) { while ((opt = getopt(argc, argv, "s:d:x:p:P:b:m:w:f:l?")) != -1) {
switch (opt) { switch (opt) {
case 's': case 's':
addr.can_addr.tp.tx_id = strtoul(optarg, (char **)NULL, 16); addr.can_addr.tp.tx_id = strtoul(optarg, (char **)NULL, 16);
@ -144,6 +146,11 @@ int main(int argc, char **argv)
fcopts.wftmax = strtoul(optarg, (char **)NULL, 16) & 0xFF; fcopts.wftmax = strtoul(optarg, (char **)NULL, 16) & 0xFF;
break; break;
case 'f':
opts.flags |= CAN_ISOTP_FORCE_RXSTMIN;
force_rx_stmin = strtoul(optarg, (char **)NULL, 10);
break;
case 'l': case 'l':
loop = 1; loop = 1;
break; break;
@ -176,6 +183,9 @@ int main(int argc, char **argv)
setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_OPTS, &opts, sizeof(opts)); setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_OPTS, &opts, sizeof(opts));
setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_RECV_FC, &fcopts, sizeof(fcopts)); setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_RECV_FC, &fcopts, sizeof(fcopts));
if (opts.flags & CAN_ISOTP_FORCE_RXSTMIN)
setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_RX_STMIN, &force_rx_stmin, sizeof(force_rx_stmin));
addr.can_family = AF_CAN; addr.can_family = AF_CAN;
strcpy(ifr.ifr_name, argv[optind]); strcpy(ifr.ifr_name, argv[optind]);
ioctl(s, SIOCGIFINDEX, &ifr); ioctl(s, SIOCGIFINDEX, &ifr);

View File

@ -69,7 +69,8 @@ void print_usage(char *prg)
fprintf(stderr, " -x <addr> (extended addressing mode. Use 'any' for all addresses)\n"); fprintf(stderr, " -x <addr> (extended addressing mode. Use 'any' for all addresses)\n");
fprintf(stderr, " -p <byte> (set and enable padding byte)\n"); fprintf(stderr, " -p <byte> (set and enable padding byte)\n");
fprintf(stderr, " -P <mode> (check padding in FC. (l)ength (c)ontent (a)ll)\n"); fprintf(stderr, " -P <mode> (check padding in FC. (l)ength (c)ontent (a)ll)\n");
fprintf(stderr, " -t <time ns> (transmit time in nanosecs)\n"); fprintf(stderr, " -t <time ns> (frame transmit time (N_As) in nanosecs)\n");
fprintf(stderr, " -f <time ns> (ignore FC and force local tx stmin value in nanosecs)\n");
fprintf(stderr, "\nCAN IDs and addresses are given and expected in hexadecimal values.\n"); fprintf(stderr, "\nCAN IDs and addresses are given and expected in hexadecimal values.\n");
fprintf(stderr, "The pdu data is expected on STDIN in space separated ASCII hex values.\n"); fprintf(stderr, "The pdu data is expected on STDIN in space separated ASCII hex values.\n");
fprintf(stderr, "\n"); fprintf(stderr, "\n");
@ -83,12 +84,13 @@ int main(int argc, char **argv)
static struct can_isotp_options opts; static struct can_isotp_options opts;
int opt; int opt;
extern int optind, opterr, optopt; extern int optind, opterr, optopt;
__u32 force_tx_stmin = 0;
unsigned char buf[4096]; unsigned char buf[4096];
int buflen = 0; int buflen = 0;
addr.can_addr.tp.tx_id = addr.can_addr.tp.rx_id = NO_CAN_ID; addr.can_addr.tp.tx_id = addr.can_addr.tp.rx_id = NO_CAN_ID;
while ((opt = getopt(argc, argv, "s:d:x:p:P:t:?")) != -1) { while ((opt = getopt(argc, argv, "s:d:x:p:P:t:f:?")) != -1) {
switch (opt) { switch (opt) {
case 's': case 's':
addr.can_addr.tp.tx_id = strtoul(optarg, (char **)NULL, 16); addr.can_addr.tp.tx_id = strtoul(optarg, (char **)NULL, 16);
@ -130,6 +132,11 @@ int main(int argc, char **argv)
opts.frame_txtime = strtoul(optarg, (char **)NULL, 10); opts.frame_txtime = strtoul(optarg, (char **)NULL, 10);
break; break;
case 'f':
opts.flags |= CAN_ISOTP_FORCE_TXSTMIN;
force_tx_stmin = strtoul(optarg, (char **)NULL, 10);
break;
case '?': case '?':
print_usage(basename(argv[0])); print_usage(basename(argv[0]));
exit(0); exit(0);
@ -157,6 +164,9 @@ int main(int argc, char **argv)
setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_OPTS, &opts, sizeof(opts)); setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_OPTS, &opts, sizeof(opts));
if (opts.flags & CAN_ISOTP_FORCE_TXSTMIN)
setsockopt(s, SOL_CAN_ISOTP, CAN_ISOTP_TX_STMIN, &force_tx_stmin, sizeof(force_tx_stmin));
addr.can_family = AF_CAN; addr.can_family = AF_CAN;
strcpy(ifr.ifr_name, argv[optind]); strcpy(ifr.ifr_name, argv[optind]);
ioctl(s, SIOCGIFINDEX, &ifr); ioctl(s, SIOCGIFINDEX, &ifr);