From 2232cb2e64241fd56293a6bcc51365dd220bdd5d Mon Sep 17 00:00:00 2001
From: raiden00pl <raiden00@railab.me>
Date: Thu, 6 Oct 2022 15:12:49 +0200
Subject: [PATCH] NuttX port   tools/coctl.c: eliminate multiple definitions of
 poll error for flat address space systems

  tools/coctl.c: use readline instead of getline

  tools/coctl.c: fix printf warnings

  fix compiler warnings related to 'struct __frbuf'

     warning: 'struct __frbuf' declared inside parameter list will not be visible outside of this definition or declaration
     warning: 'struct __fwbuf' declared inside parameter list will not be visible outside of this definition or declaration

  src/io/poll.c: NuttX support

  src/util/frbuf.c: NuttX support

  src/util/fwbuf.c: NuttX support

  src/can/socket.c: NuttX support

  src/io/can.c: add support for NuttX
---
 include/lely/co/val.h |  2 +-
 src/can/socket.c      |  7 +++-
 src/io/can.c          | 93 ++++++++++++++++++++++++++++++++++++++++++-
 src/io/poll.c         |  2 +-
 src/util/frbuf.c      | 18 ++++-----
 src/util/fwbuf.c      | 27 +++++++------
 tools/coctl.c         | 22 +++++-----
 7 files changed, 134 insertions(+), 37 deletions(-)

diff --git a/include/lely/co/val.h b/include/lely/co/val.h
index 2629763d..b5cee564 100644
--- a/include/lely/co/val.h
+++ b/include/lely/co/val.h
@@ -28,7 +28,7 @@
 #include <float.h>
 #include <stddef.h>
 
-#if !LELY_NO_CO_DCF || !LELY_NO_CO_OBJ_FILE
+#if !LELY_NO_STDIO
 // The read file buffer from <lely/util/frbuf.h>
 struct __frbuf;
 // The write file buffer from <lely/util/fwbuf.h>
diff --git a/src/can/socket.c b/src/can/socket.c
index 4fc133dd..b059c849 100644
--- a/src/can/socket.c
+++ b/src/can/socket.c
@@ -39,6 +39,11 @@
 #include <linux/can/error.h>
 #endif
 
+#ifdef __NuttX__
+#include <nuttx/can.h>
+#include <netpacket/can.h>
+#endif
+
 int
 can_frame_is_error(const struct can_frame *frame, enum can_state *pstate,
 		enum can_error *perror)
@@ -51,7 +56,7 @@ can_frame_is_error(const struct can_frame *frame, enum can_state *pstate,
 	enum can_state state = pstate ? *pstate : CAN_STATE_ACTIVE;
 	enum can_error error = perror ? *perror : 0;
 
-#ifdef HAVE_LINUX_CAN_ERROR_H
+#if defined(HAVE_LINUX_CAN_ERROR_H) || defined(__NuttX__)
 	if (frame->can_dlc != CAN_ERR_DLC) {
 		set_errnum(ERRNUM_INVAL);
 		return -1;
diff --git a/src/io/can.c b/src/io/can.c
index ca7e7d95..35d9a9f2 100644
--- a/src/io/can.c
+++ b/src/io/can.c
@@ -26,7 +26,7 @@
 #if !LELY_NO_STDIO
 
 #include <lely/util/errnum.h>
-#if !LELY_NO_CAN && defined(__linux__) && HAVE_LINUX_CAN_H
+#if !LELY_NO_CAN && ((defined(__linux__) && HAVE_LINUX_CAN_H) || defined(__NuttX__))
 #include <lely/can/socket.h>
 #endif
 #include "handle.h"
@@ -38,7 +38,7 @@
 #include <assert.h>
 #include <string.h>
 
-#if defined(__linux__) && HAVE_LINUX_CAN_H
+#if (defined(__linux__) && HAVE_LINUX_CAN_H) || defined(__NuttX__)
 
 #ifdef HAVE_LINUX_CAN_ERROR_H
 #include <linux/can/error.h>
@@ -56,6 +56,13 @@
 #include <linux/can/raw.h>
 #endif
 
+#ifdef __NuttX__
+#include <sys/ioctl.h>
+#include <nuttx/can.h>
+#include <netpacket/can.h>
+#include <net/if.h>
+#endif
+
 /// A CAN device.
 struct can {
 	/// The I/O device base handle.
@@ -656,6 +663,88 @@ io_can_set_txqlen(io_handle_t handle, size_t txqlen)
 
 #endif // HAVE_LINUX_CAN_NETLINK_H && HAVE_LINUX_RTNETLINK_H
 
+#if defined(__NuttX__)
+int
+io_can_get_ec(io_handle_t handle, uint16_t *ptxec, uint16_t *prxec)
+{
+  /* tx error count */
+
+  *ptxec = 0;
+
+  /* rx error count */
+
+  *prxec = 0;
+
+  return 0;
+}
+
+int
+io_can_get_bitrate(io_handle_t handle, uint32_t *pbitrate)
+{
+	if (!handle) {
+		errno = EBADF;
+		return -1;
+	}
+
+	if (handle->vtab != &can_vtab) {
+		errno = ENXIO;
+		return -1;
+	}
+	struct can *can = (struct can *)handle;
+  struct ifreq ifr;
+  if_indextoname(can->ifindex, ifr.ifr_name);
+
+  if (ioctl(handle->fd, SIOCGCANBITRATE, &ifr) == -1) {
+		return -1;
+	}
+
+  *pbitrate = ifr.ifr_ifru.ifru_can_data.arbi_bitrate * 1000;
+
+  return 0;
+}
+
+int
+io_can_set_bitrate(io_handle_t handle, uint32_t bitrate)
+{
+	if (!handle) {
+		errno = EBADF;
+		return -1;
+	}
+
+	if (handle->vtab != &can_vtab) {
+		errno = ENXIO;
+		return -1;
+	}
+	struct can *can = (struct can *)handle;
+  struct ifreq ifr;
+  if_indextoname(can->ifindex, ifr.ifr_name);
+
+  ifr.ifr_ifru.ifru_can_data.arbi_bitrate = bitrate / 1000;
+  ifr.ifr_ifru.ifru_can_data.data_bitrate = bitrate / 1000;
+  ifr.ifr_ifru.ifru_can_data.arbi_samplep = 0;
+  ifr.ifr_ifru.ifru_can_data.data_samplep = 0;
+
+  if (ioctl(handle->fd, SIOCSCANBITRATE, &ifr) == -1) {
+		return -1;
+	}
+
+  return 0;
+}
+
+int
+io_can_get_txqlen(io_handle_t handle, size_t *ptxqlen)
+{
+  return -1;
+}
+
+int
+io_can_set_txqlen(io_handle_t handle, size_t txqlen)
+{
+  return -1;
+}
+
+#endif // __NuttX__
+
 static void
 can_fini(struct io_handle *handle)
 {
diff --git a/src/io/poll.c b/src/io/poll.c
index d474e337..e07b36ce 100644
--- a/src/io/poll.c
+++ b/src/io/poll.c
@@ -261,7 +261,7 @@ io_poll_watch(io_poll_t *poll, io_handle_t handle, struct io_event *event,
 
 	assert(handle->vtab);
 	switch (handle->vtab->type) {
-#if defined(__linux__) && defined(HAVE_LINUX_CAN_H)
+#if (defined(__linux__) && defined(HAVE_LINUX_CAN_H)) || defined(__NuttX__)
 	case IO_TYPE_CAN:
 #endif
 #if _POSIX_C_SOURCE >= 200112L
diff --git a/src/util/frbuf.c b/src/util/frbuf.c
index 73a15bc8..403901a5 100644
--- a/src/util/frbuf.c
+++ b/src/util/frbuf.c
@@ -57,7 +57,7 @@ struct __frbuf {
 	HANDLE hFileMappingObject;
 	/// The base address of the file mapping.
 	LPVOID lpBaseAddress;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 	/// The file descriptor.
 	int fd;
 	/// The base address of the current file mapping.
@@ -75,7 +75,7 @@ struct __frbuf {
 void *
 __frbuf_alloc(void)
 {
-	void *ptr = malloc(sizeof(struct __frbuf));
+	void *ptr = zalloc(sizeof(struct __frbuf));
 	if (!ptr)
 		set_errc(errno2c(errno));
 	return ptr;
@@ -102,7 +102,7 @@ __frbuf_init(struct __frbuf *buf, const char *filename)
 
 	buf->hFileMappingObject = INVALID_HANDLE_VALUE;
 	buf->lpBaseAddress = NULL;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 	buf->fd = open(filename, O_RDONLY | O_CLOEXEC);
 	if (buf->fd == -1)
 		return NULL;
@@ -125,7 +125,7 @@ __frbuf_fini(struct __frbuf *buf)
 
 #if _WIN32
 	CloseHandle(buf->hFile);
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 	close(buf->fd);
 #else
 	fclose(buf->stream);
@@ -176,7 +176,7 @@ frbuf_get_size(frbuf_t *buf)
 	if (!GetFileSizeEx(buf->hFile, &FileSize))
 		return -1;
 	return FileSize.QuadPart;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 #ifdef __linux__
 	struct stat64 stat;
 	if (fstat64(buf->fd, &stat) == -1)
@@ -221,7 +221,7 @@ frbuf_get_pos(frbuf_t *buf)
 	if (!SetFilePointerEx(buf->hFile, li, &li, FILE_CURRENT))
 		return -1;
 	return li.QuadPart;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 #ifdef __linux__
 	return lseek64(buf->fd, 0, SEEK_CUR);
 #else
@@ -250,7 +250,7 @@ frbuf_set_pos(frbuf_t *buf, intmax_t pos)
 	if (!SetFilePointerEx(buf->hFile, li, &li, FILE_BEGIN))
 		return -1;
 	return li.QuadPart;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 #ifdef __linux__
 	return lseek64(buf->fd, pos, SEEK_SET);
 #else
@@ -283,7 +283,7 @@ frbuf_read(frbuf_t *buf, void *ptr, size_t size)
 	if (!ReadFile(buf->hFile, ptr, size, &nNumberOfBytesRead, NULL))
 		return -1;
 	return nNumberOfBytesRead;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 	ssize_t result;
 	do
 		result = read(buf->fd, ptr, size);
@@ -347,7 +347,7 @@ error_ReadFile:
 error_get_pos:
 	SetLastError(dwErrCode);
 	return result;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 	ssize_t result;
 #ifdef __linux__
 	do
diff --git a/src/util/fwbuf.c b/src/util/fwbuf.c
index 22c61fd7..26b7e03b 100644
--- a/src/util/fwbuf.c
+++ b/src/util/fwbuf.c
@@ -72,7 +72,7 @@ struct __fwbuf {
 	LPVOID lpBaseAddress;
 	/// The number of bytes mapped at <b>lpBaseAddress</b>.
 	SIZE_T dwNumberOfBytesToMap;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 	/// A pointer to the name of the temporary file.
 	char *tmpname;
 	/// The file descriptor of the directory containing the temporary file.
@@ -175,7 +175,7 @@ error_GetTempFileNameA:
 error_strdup:
 	SetLastError(dwErrCode);
 	return NULL;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 	int errsv = 0;
 
 	buf->filename = strdup(filename);
@@ -295,7 +295,7 @@ __fwbuf_fini(struct __fwbuf *buf)
 	fwbuf_commit(buf);
 	set_errc(errc);
 
-#if _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#if _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 	free(buf->tmpname);
 #endif
 	free(buf->filename);
@@ -348,7 +348,7 @@ fwbuf_get_size(fwbuf_t *buf)
 		return -1;
 	}
 	return FileSize.QuadPart;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 #ifdef __linux__
 	struct stat64 stat;
 	if (fstat64(buf->fd, &stat) == -1) {
@@ -388,7 +388,7 @@ fwbuf_set_size(fwbuf_t *buf, intmax_t size)
 		return -1;
 
 	return 0;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 #ifdef __linux__
 	if (ftruncate64(buf->fd, size) == -1) {
 #else
@@ -424,7 +424,7 @@ fwbuf_get_pos(fwbuf_t *buf)
 		return -1;
 	}
 	return li.QuadPart;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 #ifdef __linux__
 	intmax_t pos = lseek64(buf->fd, 0, SEEK_CUR);
 #else
@@ -456,7 +456,8 @@ fwbuf_set_pos(fwbuf_t *buf, intmax_t pos)
 		return -1;
 	}
 	return li.QuadPart;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+/* #elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) */
+#elif  !defined(__NuttX__)
 #ifdef __linux__
 	pos = lseek64(buf->fd, pos, SEEK_SET);
 #else
@@ -503,7 +504,7 @@ fwbuf_write(fwbuf_t *buf, const void *ptr, size_t size)
 		return -1;
 	}
 	return nNumberOfBytesWritten;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 	ssize_t result;
 	do
 		result = write(buf->fd, ptr, size);
@@ -587,7 +588,7 @@ error_get_pos:
 error_pos:
 	SetLastError(buf->dwErrCode);
 	return result;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 	ssize_t result;
 #ifdef __linux__
 	do
@@ -931,7 +932,7 @@ fwbuf_clearerr(fwbuf_t *buf)
 
 #if _WIN32
 	buf->dwErrCode = 0;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 	buf->errsv = 0;
 #else
 	buf->errnum = 0;
@@ -947,7 +948,7 @@ fwbuf_error(fwbuf_t *buf)
 	if (buf->dwErrCode)
 		SetLastError(buf->dwErrCode);
 	return !!buf->dwErrCode;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 	if (buf->errsv)
 		errno = buf->errsv;
 	return !!buf->errsv;
@@ -966,7 +967,7 @@ fwbuf_cancel(fwbuf_t *buf)
 #if _WIN32
 	if (!buf->dwErrCode)
 		buf->dwErrCode = ERROR_OPERATION_ABORTED;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 	if (!buf->errsv)
 		buf->errsv = ECANCELED;
 #else
@@ -1013,7 +1014,7 @@ fwbuf_commit(fwbuf_t *buf)
 done:
 	SetLastError(buf->dwErrCode = dwErrCode);
 	return result;
-#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__)
+#elif _POSIX_C_SOURCE >= 200112L && !defined(__NEWLIB__) && !defined(__NuttX__)
 	int errsv = errno;
 
 	if (buf->fd == -1)
diff --git a/tools/coctl.c b/tools/coctl.c
index 351b81c0..5f851b50 100644
--- a/tools/coctl.c
+++ b/tools/coctl.c
@@ -39,6 +39,9 @@
 #include <signal.h>
 #include <stdlib.h>
 #include <string.h>
+#include <inttypes.h>
+
+#include <system/readline.h>
 
 #if _WIN32
 #include <io.h>
@@ -90,7 +93,7 @@ int io_thrd_start(void *arg);
 void co_net_err(struct co_net *net);
 
 struct co_net net[CO_GW_NUM_NET];
-io_poll_t *poll;
+static io_poll_t *poll;
 
 int flags;
 int inhibit = INHIBIT;
@@ -315,8 +318,8 @@ main(int argc, char *argv[])
 	errno = errsv;
 	int eof = 0;
 
-	char *line = NULL;
-	size_t n = 0;
+#define LINE_SIZE 100
+	char line[LINE_SIZE];
 	co_unsigned32_t seq = 1;
 	char *cmd = NULL;
 	while (!done) {
@@ -358,11 +361,11 @@ main(int argc, char *argv[])
 			if (cmd)
 				printf("... ");
 			else
-				printf("[%u] ", seq);
+				printf("[%" PRIu32 "] ", seq);
 			fflush(stdout);
 		}
 		// Keep reading lines until end-of-file.
-		if (getline(&line, &n, stdin) == -1) {
+		if (readline(line, LINE_SIZE-1, stdin, stdout) == -1) {
 			if (tty)
 				fputc('\n', stdout);
 			if (ferror(stdin)) {
@@ -409,7 +412,7 @@ main(int argc, char *argv[])
 				free(cmd);
 				cmd = tmp;
 			} else {
-				if (asprintf(&cmd, "[%u] %s", seq, line)
+				if (asprintf(&cmd, "[%" PRIu32 "] %s", seq, line)
 						== -1) {
 					cmd = NULL;
 					break;
@@ -431,7 +434,7 @@ main(int argc, char *argv[])
 					result = asprintf(&tmp, "%s%s%s",
 							recv_buf, cmd, line);
 				else
-					result = asprintf(&tmp, "%s[%u] %s",
+					result = asprintf(&tmp, "%s[%" PRIu32 "] %s",
 							recv_buf, seq, line);
 				if (result < 0) {
 					mtx_unlock(&recv_mtx);
@@ -444,7 +447,7 @@ main(int argc, char *argv[])
 					result = asprintf(&recv_buf, "%s%s",
 							cmd, line);
 				else
-					result = asprintf(&recv_buf, "[%u] %s",
+					result = asprintf(&recv_buf, "[%" PRIu32 "] %s",
 							seq, line);
 				if (result < 0) {
 					recv_buf = NULL;
@@ -466,7 +469,6 @@ main(int argc, char *argv[])
 		}
 	}
 	free(cmd);
-	free(line);
 
 	io_poll_signal(poll, 1);
 	thrd_join(thr, NULL);
@@ -561,7 +563,7 @@ gw_rate(co_unsigned16_t id, co_unsigned16_t rate, void *data)
 		return;
 	bitrate = rate * 1000;
 	if (io_can_set_bitrate(net[id - 1].handle, bitrate) == -1)
-		diag(DIAG_ERROR, 0, "unable to set bitrate of %s to %u bit/s",
+		diag(DIAG_ERROR, 0, "unable to set bitrate of %s to %" PRIu32 " bit/s",
 				net[id - 1].can_path, bitrate);
 }
 
-- 
2.37.2

