[Cryptech-Commits] [sw/libhal] 02/04: Refactor serial and slip.

git at cryptech.is git at cryptech.is
Fri Jun 3 08:54:30 UTC 2016


This is an automated email from the git hooks/post-receive script.

paul at psgd.org pushed a commit to branch master
in repository sw/libhal.

commit 63fd94a724893152592b5f318e7d98f2be0ede74
Author: Paul Selkirk <paul at psgd.org>
AuthorDate: Thu Jun 2 12:37:33 2016 -0400

    Refactor serial and slip.
---
 rpc_client_serial.c                  |  56 +---------
 rpc_client_serial.c => rpc_serial.c  |  51 ++++-----
 rpc_server_serial.c                  |  26 +----
 slip_internal.h => serial_internal.h |  28 ++---
 slip.c                               | 208 ++++++++++++++++++-----------------
 slip_internal.h                      |  22 ++--
 6 files changed, 163 insertions(+), 228 deletions(-)

diff --git a/rpc_client_serial.c b/rpc_client_serial.c
index 5194793..ec53e05 100644
--- a/rpc_client_serial.c
+++ b/rpc_client_serial.c
@@ -47,70 +47,22 @@
 #define DEVICE "/dev/ttyUSB0"
 #define SPEED B115200
 
-static int fd = -1;
-
 hal_error_t hal_rpc_client_transport_init(void)
 {
-    struct termios tty;
-
-    fd = open(DEVICE, O_RDWR | O_NOCTTY | O_SYNC);
-    if (fd == -1)
-	return perror("open"), HAL_ERROR_RPC_TRANSPORT;
-
-    if (tcgetattr (fd, &tty) != 0)
-	return perror("tcgetattr"), HAL_ERROR_RPC_TRANSPORT;
-
-    cfsetospeed (&tty, SPEED);
-    cfsetispeed (&tty, SPEED);
-
-    tty.c_cflag &= ~CSIZE;
-    tty.c_cflag |= (CS8 | CLOCAL | CREAD);
-
-    tty.c_iflag = 0;
-    tty.c_oflag = 0;
-    tty.c_lflag = 0;
-
-    tty.c_cc[VMIN] = 1;
-    tty.c_cc[VTIME] = 0;
-
-    if (tcsetattr (fd, TCSANOW, &tty) != 0)
-	return perror("tcsetattr"), HAL_ERROR_RPC_TRANSPORT;
-
-    return HAL_OK;
+    return hal_serial_init(DEVICE, SPEED);
 }
 
 hal_error_t hal_rpc_client_transport_close(void)
 {
-    int ret = close(fd);
-    fd = -1;
-    if (ret != 0)
-        return perror("close"), HAL_ERROR_RPC_TRANSPORT;
-    return HAL_OK;
+    return hal_serial_close();
 }
 
 hal_error_t hal_rpc_send(const uint8_t * const buf, const size_t len)
 {
-    if (hal_slip_send(buf, len) == -1)
-        return HAL_ERROR_RPC_TRANSPORT;
-    return HAL_OK;
+    return hal_slip_send(buf, len);
 }
 
 hal_error_t hal_rpc_recv(uint8_t * const buf, size_t * const len)
 {
-    int ret;
-
-    if ((ret = hal_slip_recv(buf, *len)) == -1)
-        return HAL_ERROR_RPC_TRANSPORT;
-    *len = ret;
-    return HAL_OK;
-}
-
-int hal_slip_send_char(const uint8_t c)
-{
-    return write(fd, &c, 1);
-}
-
-int hal_slip_recv_char(uint8_t * const c)
-{
-    return read(fd, c, 1);
+    return hal_slip_recv(buf, *len);
 }
diff --git a/rpc_client_serial.c b/rpc_serial.c
similarity index 74%
copy from rpc_client_serial.c
copy to rpc_serial.c
index 5194793..dc5821f 100644
--- a/rpc_client_serial.c
+++ b/rpc_serial.c
@@ -1,6 +1,6 @@
 /*
- * rpc_client_serial.c
- * -------------------
+ * rpc_serial.c
+ * ------------
  * Remote procedure call transport over serial line with SLIP framing.
  *
  * Copyright (c) 2016, NORDUnet A/S All rights reserved.
@@ -44,24 +44,23 @@
 #include "hal_internal.h"
 #include "slip_internal.h"
 
-#define DEVICE "/dev/ttyUSB0"
-#define SPEED B115200
-
 static int fd = -1;
 
-hal_error_t hal_rpc_client_transport_init(void)
+hal_error_t hal_serial_init(const char * const device, const speed_t speed)
 {
     struct termios tty;
-
-    fd = open(DEVICE, O_RDWR | O_NOCTTY | O_SYNC);
-    if (fd == -1)
-	return perror("open"), HAL_ERROR_RPC_TRANSPORT;
+    
+    fd = open(device, O_RDWR | O_NOCTTY | O_SYNC);
+    if (fd == -1) {
+        fprintf(stderr, "open %s: ", device);
+	return perror(""), HAL_ERROR_RPC_TRANSPORT;
+    }
 
     if (tcgetattr (fd, &tty) != 0)
 	return perror("tcgetattr"), HAL_ERROR_RPC_TRANSPORT;
 
-    cfsetospeed (&tty, SPEED);
-    cfsetispeed (&tty, SPEED);
+    cfsetospeed (&tty, speed);
+    cfsetispeed (&tty, speed);
 
     tty.c_cflag &= ~CSIZE;
     tty.c_cflag |= (CS8 | CLOCAL | CREAD);
@@ -79,7 +78,7 @@ hal_error_t hal_rpc_client_transport_init(void)
     return HAL_OK;
 }
 
-hal_error_t hal_rpc_client_transport_close(void)
+hal_error_t hal_serial_close(void)
 {
     int ret = close(fd);
     fd = -1;
@@ -88,29 +87,23 @@ hal_error_t hal_rpc_client_transport_close(void)
     return HAL_OK;
 }
 
-hal_error_t hal_rpc_send(const uint8_t * const buf, const size_t len)
+hal_error_t hal_serial_send_char(const uint8_t c)
 {
-    if (hal_slip_send(buf, len) == -1)
-        return HAL_ERROR_RPC_TRANSPORT;
+    if (write(fd, &c, 1) != 1)
+	return perror("write"), HAL_ERROR_RPC_TRANSPORT;
     return HAL_OK;
 }
 
-hal_error_t hal_rpc_recv(uint8_t * const buf, size_t * const len)
+hal_error_t hal_serial_recv_char(uint8_t * const c)
 {
-    int ret;
-
-    if ((ret = hal_slip_recv(buf, *len)) == -1)
-        return HAL_ERROR_RPC_TRANSPORT;
-    *len = ret;
+    if (read(fd, c, 1) != 1)
+	return perror("read"), HAL_ERROR_RPC_TRANSPORT;
     return HAL_OK;
 }
 
-int hal_slip_send_char(const uint8_t c)
-{
-    return write(fd, &c, 1);
-}
-
-int hal_slip_recv_char(uint8_t * const c)
+/* Access routine for the file descriptor, so daemon can poll on it.
+ */
+int hal_serial_get_fd(void)
 {
-    return read(fd, c, 1);
+    return fd;
 }
diff --git a/rpc_server_serial.c b/rpc_server_serial.c
index 8844f3c..f09fdc2 100644
--- a/rpc_server_serial.c
+++ b/rpc_server_serial.c
@@ -36,11 +36,6 @@
 #include "hal_internal.h"
 #include "slip_internal.h"
 
-/* Don't include stm-uart.h to avoid conflicting definitions of HAL_OK.
- */
-extern int uart_send_char(uint8_t ch);
-extern int uart_recv_char(uint8_t *cp);
-
 hal_error_t hal_rpc_server_transport_init(void)
 {
     return HAL_OK;
@@ -53,27 +48,10 @@ hal_error_t hal_rpc_server_transport_close(void)
 
 hal_error_t hal_rpc_sendto(const uint8_t * const buf, const size_t len, void *opaque)
 {
-    if (hal_slip_send(buf, len) == -1)
-        return HAL_ERROR_RPC_TRANSPORT;
-    return HAL_OK;
+    return hal_slip_send(buf, len);
 }
 
 hal_error_t hal_rpc_recvfrom(uint8_t * const buf, size_t * const len, void **opaque)
 {
-    int ret;
-
-    if ((ret = hal_slip_recv(buf, *len)) == -1)
-        return HAL_ERROR_RPC_TRANSPORT;
-    *len = ret;
-    return HAL_OK;
-}
-
-int hal_slip_send_char(uint8_t c)
-{
-    return (uart_send_char(c) == 0) ? 0 : -1;
-}
-
-int hal_slip_recv_char(uint8_t *c)
-{
-    return (uart_recv_char(c) == 0) ? 0 : -1;
+    return hal_slip_recv(buf, len, *len);
 }
diff --git a/slip_internal.h b/serial_internal.h
similarity index 71%
copy from slip_internal.h
copy to serial_internal.h
index 103f72d..abf2259 100644
--- a/slip_internal.h
+++ b/serial_internal.h
@@ -1,7 +1,7 @@
 /*
- * slip_internal.h
- * ---------------
- * Send/recv data over a serial connection with SLIP framing
+ * serial_internal.c
+ * -----------------
+ * Low-level serial transport functions.
  *
  * Copyright (c) 2016, NORDUnet A/S All rights reserved.
  *
@@ -32,20 +32,12 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef _HAL_SLIP_INTERNAL_H
-#define _HAL_SLIP_INTERNAL_H
+#ifndef _HAL_SERIAL_INTERNAL_H
+#define _HAL_SERIAL_INTERNAL_H
 
-#include "hal_internal.h"
+hal_error_t hal_serial_init(const char * const device, const speed_t speed, int * const fdp);
+hal_error_t hal_serial_close(void);
+int hal_serial_send_char(const uint8_t c);
+int hal_serial_recv_char(uint8_t * const c);
 
-/* Defined in slip.c - send/recv a block of data with SLIP framing.
- */
-extern int hal_slip_send(const uint8_t * const p, const size_t len);
-extern int hal_slip_recv(uint8_t * const p, const size_t len);
-
-/* Defined in rpc_[client|server]_serial.c - send/recv one byte over a
- * serial connection.
- */
-extern int hal_slip_send_char(const uint8_t c);
-extern int hal_slip_recv_char(uint8_t * const c);
-
-#endif /* _HAL_SLIP_INTERNAL_H */
+#endif /* _HAL_SERIAL_INTERNAL_H */
diff --git a/slip.c b/slip.c
index 3b448f4..889663a 100644
--- a/slip.c
+++ b/slip.c
@@ -1,4 +1,37 @@
-/* SLIP send/recv code, from RFC 1055 */
+/*
+ * slip.c
+ * ------
+ * SLIP send/recv code, based on RFC 1055
+ *
+ * Copyright (c) 2016, NORDUnet A/S All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * - Redistributions of source code must retain the above copyright notice,
+ *   this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of the NORDUnet nor the names of its contributors may
+ *   be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
 
 #include <stdio.h>      /* perror */
 
@@ -11,16 +44,34 @@
 #define ESC_END         0334    /* ESC ESC_END means END data byte */
 #define ESC_ESC         0335    /* ESC ESC_ESC means ESC data byte */
 
-/* SLIP_SEND: sends a packet of length "len", starting at
- * location "p".
+#define check_send_char(c) \
+    if (hal_serial_send_char(c) != HAL_OK) \
+        return perror("hal_serial_send_char"), HAL_ERROR_RPC_TRANSPORT;
+
+/* Send a single character with SLIP escaping.
  */
-int hal_slip_send(const uint8_t * const ptr, const size_t len)
+hal_error_t hal_slip_send_char(const uint8_t c)
 {
-    int i;
-    uint8_t *p = (uint8_t *)ptr;
+    switch (c) {
+    case END:
+        check_send_char(ESC);
+        check_send_char(ESC_END);
+        break;
+    case ESC:
+        check_send_char(ESC);
+        check_send_char(ESC_ESC);
+        break;
+    default:
+        check_send_char(c);
+    }
 
-#define check_send_char(c) if (hal_slip_send_char(c) == -1) return perror("write"), -1;
+    return HAL_OK;
+}
 
+/* Send a message with SLIP framing.
+ */
+hal_error_t hal_slip_send(const uint8_t * const buf, const size_t len)
+{
     /* send an initial END character to flush out any data that may
      * have accumulated in the receiver due to line noise
      */
@@ -29,113 +80,74 @@ int hal_slip_send(const uint8_t * const ptr, const size_t len)
     /* for each byte in the packet, send the appropriate character
      * sequence
      */
-    for (i = 0; i < len; ++i) {
-        switch (*p) {
-            /* if it's the same code as an END character, we send a
-             * special two character code so as not to make the
-             * receiver think we sent an END
-             */
-        case END:
-            check_send_char(ESC);
-            check_send_char(ESC_END);
-            break;
-
-            /* if it's the same code as an ESC character,
-             * we send a special two character code so as not
-             * to make the receiver think we sent an ESC
-             */
-        case ESC:
-            check_send_char(ESC);
-            check_send_char(ESC_ESC);
-            break;
-
-            /* otherwise, we just send the character
-             */
-        default:
-            check_send_char(*p);
-        }
-
-        p++;
+    for (int i = 0; i < len; ++i) {
+        hal_error_t ret;
+        if ((ret = hal_slip_send_char(buf[i])) != HAL_OK)
+            return ret;
     }
 
     /* tell the receiver that we're done sending the packet
      */
     check_send_char(END);
 
-    return 0;
-#undef check_send_char
+    return HAL_OK;
 }
 
-/* SLIP_RECV: receives a packet into the buffer located at "p".
- *      If more than len bytes are received, the packet will
- *      be truncated.
- *      Returns the number of bytes stored in the buffer.
+#define check_recv_char(c) \
+    if (hal_serial_recv_char(c) != HAL_OK) \
+        return perror("hal_serial_recv_char"), HAL_ERROR_RPC_TRANSPORT;
+
+/* Receive a single character into a buffer, with SLIP un-escaping
  */
-int hal_slip_recv(uint8_t * const p, const size_t len)
+hal_error_t hal_slip_recv_char(uint8_t * const buf, size_t * const len, const size_t maxlen, int * const complete)
 {
+#define buf_push(c) do { if (*len < maxlen) buf[(*len)++] = c; } while (0)
+    static int esc_flag = 0;
     uint8_t c;
-    size_t received = 0;
-
-#define check_recv_char(c) if (hal_slip_recv_char(&c) == -1) return perror("read"), -1;
-
-    /* sit in a loop reading bytes until we put together
-     * a whole packet.
-     * Make sure not to copy them into the packet if we
-     * run out of room.
-     */
-    while (1) {
-        /* get a character to process
-         */
-        check_recv_char(c);
-
-        /* handle bytestuffing if necessary
-         */
-        switch (c) {
-
-            /* if it's an END character then we're done with
-             * the packet
-             */
-        case END:
-            /* a minor optimization: if there is no
-             * data in the packet, ignore it. This is
-             * meant to avoid bothering IP with all
-             * the empty packets generated by the
-             * duplicate END characters which are in
-             * turn sent to try to detect line noise.
-             */
-            if (received)
-                return received;
-            else
-                break;
-
-            /* if it's the same code as an ESC character, wait
-             * and get another character and then figure out
-             * what to store in the packet based on that.
-             */
-        case ESC:
-            check_recv_char(c);
-
-            /* if "c" is not one of these two, then we
-             * have a protocol violation.  The best bet
-             * seems to be to leave the byte alone and
-             * just stuff it into the packet
-             */
-            switch(c) {
+    hal_error_t ret = hal_serial_recv_char(&c);
+    if (ret != HAL_OK)
+        return perror("hal_slip_recv_char"), ret;
+    *complete = 0;
+    switch (c) {
+    case END:
+        if (*len)
+            *complete = 1;
+        break;
+    case ESC:
+        esc_flag = 1;
+        break;
+    default:
+        if (esc_flag) {
+            esc_flag = 0;
+            switch (c) {
             case ESC_END:
-                c = END;
+                buf_push(END);
                 break;
             case ESC_ESC:
-                c = ESC;
+                buf_push(ESC);
                 break;
+            default:
+                buf_push(c);
             }
-
-            /* here we fall into the default handler and let
-             * it store the character for us
-             */
-        default:
-            if (received < len)
-                p[received++] = c;
         }
+        else {
+            buf_push(c);
+        }
+        break;
+    }
+    return HAL_OK;
+}
+
+/* Receive a message with SLIP framing, blocking mode.
+ */
+hal_error_t hal_slip_recv(uint8_t * const buf, size_t * const len, const size_t maxlen)
+{
+    int complete;
+    hal_error_t ret;
+    
+    while (1) {
+	ret = hal_slip_recv_char(buf, len, maxlen, &complete);
+	if ((ret != HAL_OK) || complete)
+	    return ret;
     }
-#undef check_recv_char
 }
diff --git a/slip_internal.h b/slip_internal.h
index 103f72d..e3b7af0 100644
--- a/slip_internal.h
+++ b/slip_internal.h
@@ -37,15 +37,23 @@
 
 #include "hal_internal.h"
 
-/* Defined in slip.c - send/recv a block of data with SLIP framing.
+/* Defined in slip.c - send/recv serial data with SLIP framing.
  */
-extern int hal_slip_send(const uint8_t * const p, const size_t len);
-extern int hal_slip_recv(uint8_t * const p, const size_t len);
+extern hal_error_t hal_slip_send_char(const uint8_t c);
+extern hal_error_t hal_slip_send(const uint8_t * const buf, const size_t len);
+extern hal_error_t hal_slip_recv_char(uint8_t * const buf, size_t * const len, const size_t maxlen, int * const complete);
+extern hal_error_t hal_slip_recv(uint8_t * const buf, size_t * const len, const size_t maxlen);
 
-/* Defined in rpc_[client|server]_serial.c - send/recv one byte over a
- * serial connection.
+/* Defined in rpc_serial.c - send/recv one byte over a serial connection.
  */
-extern int hal_slip_send_char(const uint8_t c);
-extern int hal_slip_recv_char(uint8_t * const c);
+extern hal_error_t hal_serial_send_char(const uint8_t c);
+extern hal_error_t hal_serial_recv_char(uint8_t * const c);
+
+#ifndef STM32F4XX
+#include <termios.h>            /* speed_t */
+extern hal_error_t hal_serial_init(const char * const device, const speed_t speed);
+extern hal_error_t hal_serial_close(void);
+extern int hal_serial_get_fd(void);
+#endif
 
 #endif /* _HAL_SLIP_INTERNAL_H */



More information about the Commits mailing list