From c588f0d0b27eeea12decedd0f511103a87dbbfa9 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Wed, 4 Feb 2009 16:51:04 +0000 Subject: [PATCH] Allow SLCAN RTR frames without data length code field. --- slcanpty.c | 65 +++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/slcanpty.c b/slcanpty.c index 7a6075e..fe4e0ab 100644 --- a/slcanpty.c +++ b/slcanpty.c @@ -174,10 +174,11 @@ rx_restart: nbytes--; } - if (nbytes < 2) + if (!nbytes) continue; rxcmd = rxbuf[0]; + rxbuf[nbytes] = 0; #ifdef DEBUG for (tmp = 0; tmp < nbytes; tmp++) @@ -302,37 +303,57 @@ rx_restart: else rxp = 9; /* dlc position Tiiiiiiiid */ - if (!((rxbuf[rxp] >= '0') && (rxbuf[rxp] < '9'))) - goto rx_out_nack; - - rxf.can_dlc = rxbuf[rxp] & 0x0F; /* get can_dlc */ + *(unsigned long long *) (&rxf.data) = 0ULL; /* clear */ - rxbuf[rxp] = 0; /* terminate can_id string */ + if ((rxcmd | 0x20) == 'r' && rxbuf[rxp] != '0') { + /* RTR frame without dlc information */ - rxf.can_id = strtoul(rxbuf+1, NULL, 16); + rxf.can_dlc = rxbuf[rxp]; /* save */ - if (!(rxcmd & 0x20)) /* NO tiny chars => EFF */ - rxf.can_id |= CAN_EFF_FLAG; + rxbuf[rxp] = 0; /* terminate can_id string */ - if ((rxcmd | 0x20) == 'r') /* RTR frame */ + rxf.can_id = strtoul(rxbuf+1, NULL, 16); rxf.can_id |= CAN_RTR_FLAG; - *(unsigned long long *) (&rxf.data) = 0ULL; /* clear */ + if (!(rxcmd & 0x20)) /* NO tiny chars => EFF */ + rxf.can_id |= CAN_EFF_FLAG; - for (i = 0, rxp++; i < rxf.can_dlc; i++) { + rxbuf[rxp] = rxf.can_dlc; /* restore */ + rxf.can_dlc = 0; + rxp--; /* we have no dlc component here */ - tmp = asc2nibble(rxbuf[rxp++]); - if (tmp > 0x0F) - goto rx_out_nack; - rxf.data[i] = (tmp << 4); - tmp = asc2nibble(rxbuf[rxp++]); - if (tmp > 0x0F) + } else { + + if (!(rxbuf[rxp] >= '0' && rxbuf[rxp] < '9')) goto rx_out_nack; - rxf.data[i] |= tmp; + + rxf.can_dlc = rxbuf[rxp] & 0x0F; /* get dlc */ + + rxbuf[rxp] = 0; /* terminate can_id string */ + + rxf.can_id = strtoul(rxbuf+1, NULL, 16); + + if (!(rxcmd & 0x20)) /* NO tiny chars => EFF */ + rxf.can_id |= CAN_EFF_FLAG; + + if ((rxcmd | 0x20) == 'r') /* RTR frame */ + rxf.can_id |= CAN_RTR_FLAG; + + for (i = 0, rxp++; i < rxf.can_dlc; i++) { + + tmp = asc2nibble(rxbuf[rxp++]); + if (tmp > 0x0F) + goto rx_out_nack; + rxf.data[i] = (tmp << 4); + tmp = asc2nibble(rxbuf[rxp++]); + if (tmp > 0x0F) + goto rx_out_nack; + rxf.data[i] |= tmp; + } + /* point to last real data */ + if (rxf.can_dlc) + rxp--; } - /* point to last real data */ - if (rxf.can_dlc) - rxp--; nbytes = write(s, &rxf, sizeof(rxf)); if (nbytes != sizeof(rxf)) { -- 2.7.4