i2c: replace gdbus with direct implementation 44/259744/6
authorAdrian Szyndela <adrian.s@samsung.com>
Wed, 9 Jun 2021 09:23:25 +0000 (11:23 +0200)
committerAdrian Szyndela <adrian.s@samsung.com>
Fri, 25 Jun 2021 06:01:51 +0000 (08:01 +0200)
Move open/close code from peripheral-bus.
Add flocks() where appropriate.

Change-Id: I57bffbe463cacf2674484e8d8cf8fadfe672218f

CMakeLists.txt
include/gdbus/peripheral_gdbus_i2c.h [deleted file]
include/interface/peripheral_interface_common.h
include/peripheral_handle.h
src/gdbus/peripheral_gdbus_i2c.c [deleted file]
src/peripheral_i2c.c

index 43c0b29..8fea6c2 100644 (file)
@@ -67,7 +67,6 @@ SET(SOURCES src/peripheral_gpio.c
                        src/interface/peripheral_interface_spi.c
                        src/interface/peripheral_interface_uart.c
                        src/gdbus/peripheral_gdbus_gpio.c
-                       src/gdbus/peripheral_gdbus_i2c.c
                        src/gdbus/peripheral_gdbus_pwm.c
                        src/gdbus/peripheral_gdbus_adc.c
                        src/gdbus/peripheral_gdbus_uart.c
diff --git a/include/gdbus/peripheral_gdbus_i2c.h b/include/gdbus/peripheral_gdbus_i2c.h
deleted file mode 100644 (file)
index 643d7c8..0000000
+++ /dev/null
@@ -1,26 +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_I2C_H__
-#define __PERIPHERAL_GDBUS_I2C_H__
-
-#include "peripheral_gdbus_common.h"
-
-int peripheral_gdbus_i2c_open(peripheral_i2c_h i2c, int bus, int address);
-int peripheral_gdbus_i2c_open_flags(peripheral_i2c_h i2c, int bus, int address, int flags);
-int peripheral_gdbus_i2c_close(peripheral_i2c_h i2c);
-
-#endif /* __PERIPHERAL_GDBUS_I2C_H__ */
index d6137ce..675c3fb 100644 (file)
@@ -46,4 +46,4 @@ typedef struct predefined_type {
        int len;
 } predefined_type_s;
 
-#endif /*__PERIPHERAL_INTERFACE_COMMON_H__*/
\ No newline at end of file
+#endif /*__PERIPHERAL_INTERFACE_COMMON_H__*/
index b3ca528..b766364 100644 (file)
@@ -54,7 +54,6 @@ struct _peripheral_gpio_s {
  * @brief Internal struct for i2c context
  */
 struct _peripheral_i2c_s {
-       uint handle;
        int fd;
 };
 
diff --git a/src/gdbus/peripheral_gdbus_i2c.c b/src/gdbus/peripheral_gdbus_i2c.c
deleted file mode 100644 (file)
index fe3a5f7..0000000
+++ /dev/null
@@ -1,167 +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_i2c.h"
-
-#define I2C_FD_INDEX 0
-
-static PeripheralIoGdbusI2c *i2c_proxy = NULL;
-
-static int __i2c_proxy_init(void)
-{
-       GError *error = NULL;
-
-       if (i2c_proxy != NULL) {
-               _E("I2c proxy is already created");
-               g_object_ref(i2c_proxy);
-               return PERIPHERAL_ERROR_NONE;
-       }
-
-       i2c_proxy = peripheral_io_gdbus_i2c_proxy_new_for_bus_sync(
-               G_BUS_TYPE_SYSTEM,
-               G_DBUS_PROXY_FLAGS_NONE,
-               PERIPHERAL_GDBUS_NAME,
-               PERIPHERAL_GDBUS_I2C_PATH,
-               NULL,
-               &error);
-
-       if (i2c_proxy == NULL) {
-               if (error) {
-                       _E("Failed to create i2c proxy : %s", error->message);
-                       g_error_free(error);
-               }
-               return PERIPHERAL_ERROR_IO_ERROR;
-       }
-
-       return PERIPHERAL_ERROR_NONE;
-}
-
-static int __i2c_proxy_deinit(void)
-{
-       RETVM_IF(i2c_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "I2c proxy is NULL");
-
-       g_object_unref(i2c_proxy);
-       if (!G_IS_OBJECT(i2c_proxy))
-               i2c_proxy = NULL;
-
-       return PERIPHERAL_ERROR_NONE;
-}
-
-int peripheral_gdbus_i2c_open(peripheral_i2c_h i2c, int bus, int address)
-{
-       int ret;
-       GError *error = NULL;
-       GUnixFDList *fd_list = NULL;
-
-       ret = __i2c_proxy_init();
-       if (ret != PERIPHERAL_ERROR_NONE)
-               return ret;
-
-       if (peripheral_io_gdbus_i2c_call_open_sync(
-                       i2c_proxy,
-                       bus,
-                       address,
-                       NULL,
-                       &i2c->handle,
-                       &ret,
-                       &fd_list,
-                       NULL,
-                       &error) == FALSE) {
-               _E("Failed to request daemon to i2c 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;
-
-       i2c->fd = g_unix_fd_list_get(fd_list, I2C_FD_INDEX, &error);
-       if (i2c->fd < 0) {
-               _E("Failed to get fd for i2c : %s", error->message);
-               g_error_free(error);
-               ret = PERIPHERAL_ERROR_IO_ERROR;
-       }
-
-       g_object_unref(fd_list);
-
-       return ret;
-}
-
-int peripheral_gdbus_i2c_open_flags(peripheral_i2c_h i2c, int bus, int address, int flags)
-{
-       int ret;
-       GError *error = NULL;
-       GUnixFDList *fd_list = NULL;
-
-       ret = __i2c_proxy_init();
-       if (ret != PERIPHERAL_ERROR_NONE)
-               return ret;
-
-       if (peripheral_io_gdbus_i2c_call_open_flags_sync(
-                       i2c_proxy,
-                       bus,
-                       address,
-                       flags,
-                       NULL,
-                       &i2c->handle,
-                       &ret,
-                       &fd_list,
-                       NULL,
-                       &error) == FALSE) {
-               _E("Failed to request daemon to i2c 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;
-
-       i2c->fd = g_unix_fd_list_get(fd_list, I2C_FD_INDEX, &error);
-       if (i2c->fd < 0) {
-               _E("Failed to get fd for i2c : %s", error->message);
-               g_error_free(error);
-               ret = PERIPHERAL_ERROR_IO_ERROR;
-       }
-
-       g_object_unref(fd_list);
-
-       return ret;
-}
-
-int peripheral_gdbus_i2c_close(peripheral_i2c_h i2c)
-{
-       RETVM_IF(i2c_proxy == NULL, PERIPHERAL_ERROR_IO_ERROR, "I2c proxy is NULL");
-
-       int ret;
-       GError *error = NULL;
-
-       if (peripheral_io_gdbus_i2c_call_close_sync(
-                       i2c_proxy,
-                       i2c->handle,
-                       &ret,
-                       NULL,
-                       &error) == FALSE) {
-               _E("Failed to request daemon to i2c close : %s", error->message);
-               g_error_free(error);
-               return PERIPHERAL_ERROR_IO_ERROR;
-       }
-
-       __i2c_proxy_deinit();
-
-       return ret;
-}
index 5f493f2..b97f4c1 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
+#include <errno.h>
 #include <stdlib.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
 #include <system_info.h>
 
 #include "peripheral_io.h"
 #include "peripheral_handle.h"
-#include "peripheral_gdbus_i2c.h"
 #include "peripheral_interface_i2c.h"
 #include "peripheral_log.h"
 
@@ -56,41 +57,29 @@ static bool __is_feature_supported(void)
        return (i2c_feature == I2C_FEATURE_TRUE ? true : false);
 }
 
-int peripheral_i2c_open(int bus, int address, peripheral_i2c_h *i2c)
-{
-       peripheral_i2c_h handle;
-       int ret = PERIPHERAL_ERROR_NONE;
-
-       RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "I2C feature is not supported");
-       RETVM_IF(i2c == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid i2c handle");
-       RETVM_IF(bus < 0 || address < 0, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid parameter");
-
-       handle = (peripheral_i2c_h)malloc(sizeof(struct _peripheral_i2c_s));
-       if (handle == NULL) {
-               _E("Failed to allocate peripheral_i2c_h");
-               return PERIPHERAL_ERROR_OUT_OF_MEMORY;
-       }
-
-       ret = peripheral_gdbus_i2c_open(handle, bus, address);
-       if (ret != PERIPHERAL_ERROR_NONE) {
-               _E("Failed to open i2c communication, ret : %d", ret);
-               free(handle);
-               handle = NULL;
+static inline void cleanup_handlep(peripheral_i2c_h *handle) {
+       if (*handle != NULL) {
+               if ((*handle)->fd != -1)
+                       close((*handle)->fd);
+               free(*handle);
        }
-
-       *i2c = handle;
-
-       return ret;
 }
 
 int peripheral_i2c_open_flags(int bus, int address, peripheral_open_flags_e flags, peripheral_i2c_h *i2c)
 {
-       peripheral_i2c_h handle;
        int ret = PERIPHERAL_ERROR_NONE;
+       int lock_type = LOCK_EX;
+
+#define DEV_PATH_BASE "/dev/i2c-"
+       char path[sizeof(DEV_PATH_BASE "0000000000")] = {0, };  /* space for /dev/i2c-%d */
 
        RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "I2C feature is not supported");
        RETVM_IF(i2c == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid i2c handle");
        RETVM_IF(bus < 0 || address < 0, PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid parameter");
+       RETVM_IF(flags != PERIPHERAL_OPEN_FLAGS_PRIVATE && flags != PERIPHERAL_OPEN_FLAGS_SHARED,
+                       PERIPHERAL_ERROR_INVALID_PARAMETER, "Invalid flags");
+
+       __attribute__ ((cleanup(cleanup_handlep))) peripheral_i2c_h handle = NULL;
 
        handle = (peripheral_i2c_h)malloc(sizeof(struct _peripheral_i2c_s));
        if (handle == NULL) {
@@ -98,16 +87,35 @@ int peripheral_i2c_open_flags(int bus, int address, peripheral_open_flags_e flag
                return PERIPHERAL_ERROR_OUT_OF_MEMORY;
        }
 
-       ret = peripheral_gdbus_i2c_open_flags(handle, bus, address, flags);
-       if (ret != PERIPHERAL_ERROR_NONE) {
-               _E("Failed to open i2c communication, ret : %d", ret);
-               free(handle);
-               handle = NULL;
+       snprintf(path, sizeof path, DEV_PATH_BASE "%d", bus);
+       handle->fd = open(path, O_RDWR | O_CLOEXEC);
+       CHECK_ERROR(handle->fd < 0);
+
+       ret = ioctl(handle->fd, I2C_SLAVE, address);
+       CHECK_ERROR(ret);
+
+       if (flags == PERIPHERAL_OPEN_FLAGS_SHARED)
+               lock_type = LOCK_SH;
+
+       if (flock(handle->fd, lock_type | LOCK_NB)) {
+               if (errno == EWOULDBLOCK) {
+                       _E("bus : %d, address : 0x%x is not available", bus, address);
+                       return PERIPHERAL_ERROR_RESOURCE_BUSY;
+               } else {
+                       _E("bus : %d, address : 0x%x flock() error: %d", bus, address, errno);
+                       return PERIPHERAL_ERROR_IO_ERROR;
+               }
        }
 
        *i2c = handle;
+       handle = NULL;
 
-       return ret;
+       return PERIPHERAL_ERROR_NONE;
+}
+
+int peripheral_i2c_open(int bus, int address, peripheral_i2c_h *i2c)
+{
+       return peripheral_i2c_open_flags(bus, address, PERIPHERAL_OPEN_FLAGS_PRIVATE, i2c);
 }
 
 int peripheral_i2c_close(peripheral_i2c_h i2c)
@@ -117,10 +125,6 @@ int peripheral_i2c_close(peripheral_i2c_h i2c)
        RETVM_IF(__is_feature_supported() == false, PERIPHERAL_ERROR_NOT_SUPPORTED, "I2C feature is not supported");
        RETVM_IF(i2c == NULL, PERIPHERAL_ERROR_INVALID_PARAMETER, "i2c handle is NULL");
 
-       ret = peripheral_gdbus_i2c_close(i2c);
-       if (ret != PERIPHERAL_ERROR_NONE)
-               _E("Failed to close i2c communcation, ret : %d", ret);
-
        peripheral_interface_i2c_close(i2c);
 
        free(i2c);