Move open/close code from peripheral-bus.
Add flocks() where appropriate.
Change-Id: I57bffbe463cacf2674484e8d8cf8fadfe672218f
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
+++ /dev/null
-/*
- * 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__ */
int len;
} predefined_type_s;
-#endif /*__PERIPHERAL_INTERFACE_COMMON_H__*/
\ No newline at end of file
+#endif /*__PERIPHERAL_INTERFACE_COMMON_H__*/
* @brief Internal struct for i2c context
*/
struct _peripheral_i2c_s {
- uint handle;
int fd;
};
+++ /dev/null
-/*
- * 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;
-}
* 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"
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) {
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)
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);