]> rtime.felk.cvut.cz Git - can-utils.git/commitdiff
Allow SLCAN RTR frames without data length code field.
authorOliver Hartkopp <socketcan@hartkopp.net>
Wed, 4 Feb 2009 16:51:04 +0000 (16:51 +0000)
committerOliver Hartkopp <socketcan@hartkopp.net>
Wed, 4 Feb 2009 16:51:04 +0000 (16:51 +0000)
slcanpty.c

index 7a6075e6492ad16c8eaf59c0967d1b54c0aefbec..fe4e0abd6b194c1243243676923d91bae64cfb5a 100644 (file)
@@ -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)) {