]> sigrok.org Git - libsigrok.git/blobdiff - hardware/common/serial.c
Return SR_ERR_MALLOC upon allocation errors.
[libsigrok.git] / hardware / common / serial.c
index ad88958a0d0feb5c6601651687acdb1dd593c4cd..38d4a5f121e08acaeb35da9340f095a14e1c65de 100644 (file)
@@ -166,7 +166,7 @@ SR_PRIV void *serial_backup_params(int fd)
        /* TODO: 'term' is never g_free()'d? */
        if (!(term = g_try_malloc(sizeof(struct termios)))) {
                sr_err("serial: %s: term malloc failed", __func__);
-               return NULL;
+               return -1;
        }
 
        tcgetattr(fd, term);
@@ -218,6 +218,12 @@ SR_PRIV int serial_set_params(int fd, int baudrate, int bits, int parity,
        case 9600:
                dcb.BaudRate = CBR_9600;
                break;
+       case 4800:
+               dcb.BaudRate = CBR_4800;
+               break;
+       case 2400:
+               dcb.BaudRate = CBR_2400;
+               break;
        default:
                /* TODO: Error handling. */
                break;
@@ -238,6 +244,12 @@ SR_PRIV int serial_set_params(int fd, int baudrate, int bits, int parity,
                return SR_ERR;
 
        switch (baudrate) {
+       case 2400:
+               baud = B2400;
+               break;
+       case 4800:
+               baud = B4800;
+               break;
        case 9600:
                baud = B9600;
                break;
@@ -371,3 +383,37 @@ SR_PRIV int serial_set_paramstr(int fd, const char *paramstr)
                return SR_ERR_ARG;
 }
 
+SR_PRIV int serial_readline(int fd, char **buf, int *buflen,
+                           uint64_t timeout_ms)
+{
+       uint64_t start;
+       int maxlen, len;
+
+       timeout_ms *= 1000;
+       start = g_get_monotonic_time();
+
+       maxlen = *buflen;
+       *buflen = len = 0;
+       while(1) {
+               len = maxlen - *buflen - 1;
+               if (len < 1)
+                       break;
+               len = serial_read(fd, *buf + *buflen, 1);
+               if (len > 0) {
+                       *buflen += len;
+                       *(*buf + *buflen) = '\0';
+                       if (*buflen > 0 && *(*buf + *buflen - 1) == '\r') {
+                               /* Strip LF and terminate. */
+                               *(*buf + --*buflen) = '\0';
+                               break;
+                       }
+               }
+               if (g_get_monotonic_time() - start > timeout_ms)
+                       /* Timeout */
+                       break;
+               g_usleep(2000);
+       }
+       sr_dbg("Received %d: '%s'.", *buflen, *buf);
+
+       return SR_OK;
+}