From a71fa7c23ae2a11b7f02c3601fef8bbbafa90261 Mon Sep 17 00:00:00 2001 From: Adrian Szyndela Date: Fri, 11 Jun 2021 15:17:12 +0200 Subject: [PATCH] uart: replace gdbus with direct implementation Move open/close code from peripheral-bus. Add flocks() where appropriate. Change-Id: Ia74be68f4acad0a9a494c82ca6183077cc804e49 --- CMakeLists.txt | 1 - include/gdbus/peripheral_gdbus_uart.h | 25 ------ src/gdbus/peripheral_gdbus_uart.c | 124 -------------------------- src/peripheral_uart.c | 78 +++++++++++----- 4 files changed, 58 insertions(+), 170 deletions(-) delete mode 100644 include/gdbus/peripheral_gdbus_uart.h delete mode 100644 src/gdbus/peripheral_gdbus_uart.c diff --git a/CMakeLists.txt b/CMakeLists.txt index edcfbac..1c10c3a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,7 +67,6 @@ SET(SOURCES src/peripheral_gpio.c src/gdbus/peripheral_gdbus_gpio.c src/gdbus/peripheral_gdbus_pwm.c src/gdbus/peripheral_gdbus_adc.c - src/gdbus/peripheral_gdbus_uart.c src/gdbus/peripheral_io_gdbus.c) ADD_LIBRARY(${fw_name} SHARED ${SOURCES}) diff --git a/include/gdbus/peripheral_gdbus_uart.h b/include/gdbus/peripheral_gdbus_uart.h deleted file mode 100644 index bf7af68..0000000 --- a/include/gdbus/peripheral_gdbus_uart.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __PERIPHERAL_GDBUS_UART_H_ -#define __PERIPHERAL_GDBUS_UART_H_ - -#include "peripheral_gdbus_common.h" - -int peripheral_gdbus_uart_open(peripheral_uart_h uart, int port); -int peripheral_gdbus_uart_close(peripheral_uart_h uart); - -#endif /* __PERIPHERAL_GDBUS_UART_H_ */ diff --git a/src/gdbus/peripheral_gdbus_uart.c b/src/gdbus/peripheral_gdbus_uart.c deleted file mode 100644 index 86f7575..0000000 --- a/src/gdbus/peripheral_gdbus_uart.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "peripheral_gdbus_uart.h" - -#define UART_FD_INDEX 0 - -static PeripheralIoGdbusUart *uart_proxy = NULL; - -static int __uart_proxy_init(void) -{ - GError *error = NULL; - - if (uart_proxy != NULL) { - _E("Uart proxy is already created"); - g_object_ref(uart_proxy); - return PERIPHERAL_ERROR_NONE; - } - - uart_proxy = peripheral_io_gdbus_uart_proxy_new_for_bus_sync( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - PERIPHERAL_GDBUS_NAME, - PERIPHERAL_GDBUS_UART_PATH, - NULL, - &error); - - if (uart_proxy == NULL) { - if (error) { - _E("Failed to create uart proxy : %s", error->message); - g_error_free(error); - } - return PERIPHERAL_ERROR_IO_ERROR; - } - - return PERIPHERAL_ERROR_NONE; -} - -static int __uart_proxy_deinit(void) -{ - RETVM_IF(uart_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "Uart proxy is NULL"); - - g_object_unref(uart_proxy); - if (!G_IS_OBJECT(uart_proxy)) - uart_proxy = NULL; - - return PERIPHERAL_ERROR_NONE; -} - -int peripheral_gdbus_uart_open(peripheral_uart_h uart, int port) -{ - int ret; - GError *error = NULL; - GUnixFDList *fd_list = NULL; - - ret = __uart_proxy_init(); - if (ret != PERIPHERAL_ERROR_NONE) - return ret; - - if (peripheral_io_gdbus_uart_call_open_sync( - uart_proxy, - port, - NULL, - &uart->handle, - &ret, - &fd_list, - NULL, - &error) == FALSE) { - _E("Failed to request daemon to uart open : %s", error->message); - g_error_free(error); - return PERIPHERAL_ERROR_IO_ERROR; - } - - // TODO : If ret is not PERIPHERAL_ERROR_NONE, fd list it NULL from daemon. - if (ret != PERIPHERAL_ERROR_NONE) - return ret; - - uart->fd = g_unix_fd_list_get(fd_list, UART_FD_INDEX, &error); - if (uart->fd < 0) { - _E("Failed to get fd for uart : %s", error->message); - g_error_free(error); - ret = PERIPHERAL_ERROR_IO_ERROR; - } - - g_object_unref(fd_list); - - return ret; -} - -int peripheral_gdbus_uart_close(peripheral_uart_h uart) -{ - RETVM_IF(uart_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "Uart proxy is NULL"); - - int ret; - GError *error = NULL; - - if (peripheral_io_gdbus_uart_call_close_sync( - uart_proxy, - uart->handle, - &ret, - NULL, - &error) == FALSE) { - _E("Failed to request daemon to gpio uart : %s", error->message); - g_error_free(error); - return PERIPHERAL_ERROR_IO_ERROR; - } - - __uart_proxy_deinit(); - - return ret; -} diff --git a/src/peripheral_uart.c b/src/peripheral_uart.c index b572f83..3330bd2 100644 --- a/src/peripheral_uart.c +++ b/src/peripheral_uart.c @@ -14,12 +14,16 @@ * limitations under the License. */ +#include #include +#include +#include +#include #include +#include #include "peripheral_io.h" #include "peripheral_handle.h" -#include "peripheral_gdbus_uart.h" #include "peripheral_interface_uart.h" #include "peripheral_log.h" @@ -29,6 +33,10 @@ #define UART_FEATURE_FALSE 0 #define UART_FEATURE_TRUE 1 +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) +#endif + static int uart_feature = UART_FEATURE_UNKNOWN; static bool __is_feature_supported(void) @@ -46,34 +54,71 @@ static bool __is_feature_supported(void) return (uart_feature == UART_FEATURE_TRUE ? true : false); } +static inline void cleanup_handlep(peripheral_uart_h *handle) +{ + if (*handle != NULL) { + if ((*handle)->fd != -1) + close((*handle)->fd); + free(*handle); + } +} + /** * @brief Initializes uart communication and creates uart handle. */ int peripheral_uart_open(int port, peripheral_uart_h *uart) { - peripheral_uart_h handle; - int ret = PERIPHERAL_ERROR_NONE; - RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "UART feature is not supported"); RETVM_IF(uart == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid uart handle"); RETVM_IF(port < 0, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid port number"); + __attribute__ ((cleanup(cleanup_handlep))) peripheral_uart_h handle = NULL; handle = (peripheral_uart_h)calloc(1, sizeof(struct _peripheral_uart_s)); if (handle == NULL) { _E("Failed to allocate peripheral_uart_h"); return PERIPHERAL_ERROR_OUT_OF_MEMORY; } - ret = peripheral_gdbus_uart_open(handle, port); - if (ret != PERIPHERAL_ERROR_NONE) { - _E("Failed to open uart port, ret : %d", ret); - free(handle); - handle = NULL; + const char *sysfs_uart_path[] = { + "/dev/ttyS", + "/dev/ttyAMA", + "/dev/ttySAC", + }; + + size_t index; + char path[sizeof("/dev/ttyABC1234567890")] = {0, }; /* space for /dev/ttyXXX%d */ + + for (index = 0; index < ARRAY_SIZE(sysfs_uart_path); index++) { + snprintf(path, sizeof path, "%s%d", sysfs_uart_path[index], port); + if (access(path, F_OK) == 0) + break; + } + + if (index == ARRAY_SIZE(sysfs_uart_path)) + return PERIPHERAL_ERROR_NO_DEVICE; + + handle->fd = open(path, O_RDWR | O_NOCTTY | O_NONBLOCK | O_CLOEXEC); + CHECK_ERROR(handle->fd < 0); + + if (flock(handle->fd, LOCK_EX | LOCK_NB)) { + if (errno == EWOULDBLOCK) { + _E("path : %s is not available", path); + return PERIPHERAL_ERROR_RESOURCE_BUSY; + } else { + _E("path: %s flock() error: %d", path, errno); + return PERIPHERAL_ERROR_IO_ERROR; + } } *uart = handle; + handle = NULL; + + return PERIPHERAL_ERROR_NONE; +} - return ret; +static void peripheral_uart_flush(peripheral_uart_h uart) +{ + tcflush(uart->fd, TCIOFLUSH); } /** @@ -81,21 +126,14 @@ int peripheral_uart_open(int port, peripheral_uart_h *uart) */ int peripheral_uart_close(peripheral_uart_h uart) { - int ret = PERIPHERAL_ERROR_NONE; - RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "UART feature is not supported"); RETVM_IF(uart == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "uart handle is NULL"); - ret = peripheral_gdbus_uart_close(uart); - if (ret != PERIPHERAL_ERROR_NONE) - _E("Failed to close uart communication, continuing anyway, ret : %d", ret); - - peripheral_interface_uart_close(uart); + peripheral_uart_flush(uart); - free(uart); - uart = NULL; + cleanup_handlep(&uart); - return ret; + return PERIPHERAL_ERROR_NONE; } /** -- 2.34.1