SET(PREFIX ${CMAKE_INSTALL_PREFIX})
SET(VERSION 0.0.1)
-SET(dependents "dlog glib-2.0 gio-2.0 gio-unix-2.0 iniparser")
+SET(dependents "dlog glib-2.0 gio-2.0 gio-unix-2.0 iniparser libudev")
FIND_PROGRAM(GDBUS_CODEGEN NAMES gdbus-codegen)
EXEC_PROGRAM(${GDBUS_CODEGEN} ARGS
--- /dev/null
+SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add",\
+ RUN+="/bin/chown root:system_fw /sys%p/value",\
+ RUN+="/bin/chmod g+rw /sys%p/value",\
+ RUN+="/bin/chsmack -a System /sys%p/value"
+SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add",\
+ RUN+="/bin/chown root:system_fw /sys%p/direction",\
+ RUN+="/bin/chmod g+rw /sys%p/direction",\
+ RUN+="/bin/chsmack -a System /sys%p/direction"
+SUBSYSTEM=="gpio", KERNEL=="gpio*", ACTION=="add",\
+ RUN+="/bin/chown root:system_fw /sys%p/edge",\
+ RUN+="/bin/chmod g+rw /sys%p/edge",\
+ RUN+="/bin/chsmack -a System /sys%p/edge"
[Unit]
Description=Peripheral Service Daemon
Requires=dbus.service
+After=systemd-tmpfiles-setup.service
[Service]
SmackProcessLabel=System
Source0: %{name}-%{version}.tar.gz
Source1: %{name}.manifest
Source2: %{name}.service
+Source3: %{name}.tmpfiles.conf
+Source4: 90-gpio.rules
BuildRequires: cmake
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(gio-2.0)
BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(libsystemd)
BuildRequires: pkgconfig(capi-system-peripheral-io)
BuildRequires: pkgconfig(iniparser)
+BuildRequires: pkgconfig(libudev)
Requires(post): /sbin/ldconfig
Requires(postun): /sbin/ldconfig
%make_install
mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants
install -m 0644 %SOURCE2 %{buildroot}%{_unitdir}/peripheral-bus.service
+mkdir -p %{buildroot}%{_tmpfilesdir}
+install -m 0644 %SOURCE3 %{buildroot}%{_tmpfilesdir}/%{name}.conf
+mkdir -p %{buildroot}%{_udevrulesdir}
+install -m 0644 %SOURCE4 %{buildroot}%{_udevrulesdir}
%install_service multi-user.target.wants peripheral-bus.service
mkdir -p %{buildroot}/etc/peripheral-bus
%manifest %{name}.manifest
%defattr(-,root,root,-)
%license LICENSE.APLv2
-%{_bindir}/peripheral-bus
-%{_unitdir}/peripheral-bus.service
-%{_unitdir}/multi-user.target.wants/peripheral-bus.service
+%{_bindir}/%{name}
+%{_unitdir}/%{name}.service
+%{_tmpfilesdir}/%{name}.conf
+/usr/lib/udev/rules.d/90-gpio.rules
+%{_unitdir}/multi-user.target.wants/%{name}.service
/etc/peripheral-bus/*.ini
--- /dev/null
+#Type Path Mode UID GID Age Argument
+z /sys/class/gpio/export 0220 root system_fw -
+t /sys/class/gpio/export - - - - security.SMACK64="System"
+z /sys/class/gpio/unexport 0220 root system_fw -
+t /sys/class/gpio/unexport - - - - security.SMACK64="System"
+z /sys/devices/platform/soc/*.gpio/gpiochip* 0775 root system_fw -
+t /sys/devices/platform/soc/*.gpio/gpiochip* - - - - security.SMACK64="System"
#include <stdio.h>
#include <stdlib.h>
#include <gio/gio.h>
+#include <poll.h>
+#include <sys/time.h>
+#include <libudev.h>
#include <peripheral_io.h>
return true;
}
+static int gpio_wait_for_udev(int gpiopin)
+{
+ #define GPIO_NAME_LEN 8
+ struct udev *udev;
+ struct udev_monitor *monitor;
+ struct udev_device *dev;
+ struct pollfd pfd;
+ char gpio_name[GPIO_NAME_LEN];
+ int ret = -EIO;
+
+ udev = udev_new();
+ if (!udev) {
+ _E("Cannot create udev");
+ return ret;
+ }
+
+ monitor = udev_monitor_new_from_netlink(udev, "udev");
+ if (!monitor) {
+ _E("Cannot create udev monitor");
+ udev_unref(udev);
+ return ret;
+ }
+
+ ret = udev_monitor_filter_add_match_subsystem_devtype(monitor, "gpio", NULL);
+ if (ret < 0) {
+ _E("Failed to add monitor filter");
+ goto out;
+ }
+
+ ret = udev_monitor_enable_receiving(monitor);
+ if (ret < 0) {
+ _E("Failed to enable udev receiving");
+ goto out;
+ }
+
+ pfd.fd = udev_monitor_get_fd(monitor);
+ pfd.events = POLLIN;
+
+ snprintf(gpio_name, GPIO_NAME_LEN, "gpio%d", gpiopin);
+
+ for (int cnt = 0; cnt < 10; cnt++) {
+ if (poll(&pfd, 1, 100) < 0) {
+ _E("Failed to watch udev monitor");
+ goto out;
+ }
+
+ dev = udev_monitor_receive_device(monitor);
+ if (dev) {
+ if (strcmp(udev_device_get_sysname(dev), gpio_name) == 0) {
+ _D("udev for %s is initialized", gpio_name);
+ ret = 0;
+ goto out;
+ }
+ }
+ }
+ _E("Time out");
+
+out:
+ udev_monitor_unref(monitor);
+ udev_unref(udev);
+
+ return ret;
+}
+
+
int peripheral_bus_gpio_open(gint pin, pb_data_h *handle, gpointer user_data)
{
peripheral_bus_s *pb_data = (peripheral_bus_s*)user_data;
goto err;
}
+ if (gpio_wait_for_udev(pin) < 0) {
+ _E("device nodes are not writable");
+ ret = PERIPHERAL_ERROR_UNKNOWN;
+ goto err;
+ }
+
gpio_handle->type = PERIPHERAL_BUS_TYPE_GPIO;
gpio_handle->list = &pb_data->gpio_list;
gpio_handle->dev.gpio.pin = pin;
GPIO_EDGE_BOTH = 3,
} gpio_edge_e;
-int gpio_get_edge_mode(int gpiopin, gpio_edge_e *edge);
-int gpio_get_direction(int gpiopin, gpio_direction_e *dir);
-int gpio_read(int gpiopin, int *value);
int gpio_open(int gpiopin);
int gpio_close(int gpiopin);
int gpio_set_edge_mode(int gpiopin, gpio_edge_e edge);
+int gpio_get_edge_mode(int gpiopin, gpio_edge_e *edge);
int gpio_set_direction(int gpiopin, gpio_direction_e dir);
+int gpio_get_direction(int gpiopin, gpio_direction_e *dir);
int gpio_write(int gpiopin, int value);
+int gpio_read(int gpiopin, int *value);
int gpio_open_isr(int gpiopin);
int gpio_close_isr(int file_hndl);
int gpio_read_isr(void *fdset, char *rev_buf, int length);
-//int gpio_read_isr(void *fdset, char *rev_buf, int length);
#endif/*__GPIO_H__*/