Start services for legacy functions 56/174856/3
authorPaweł Szewczyk <p.szewczyk@samsung.com>
Fri, 6 Apr 2018 13:53:22 +0000 (15:53 +0200)
committerPaweł Szewczyk <p.szewczyk@samsung.com>
Fri, 6 Apr 2018 13:53:22 +0000 (15:53 +0200)
Change-Id: Ie5913698b135e45f3e55267d6830f2aa996e96a4
Signed-off-by: Paweł Szewczyk <p.szewczyk@samsung.com>
hw/usb_client/CMakeLists.txt
hw/usb_client/usb_client.c
packaging/device-manager-plugin-artik.spec

index f7b32c1..4a10107 100644 (file)
@@ -4,7 +4,7 @@ PROJECT(usb_client C)
 SET(PREFIX ${CMAKE_INSTALL_PREFIX})
 
 INCLUDE(FindPkgConfig)
-pkg_check_modules(usb_client_pkgs REQUIRED hwcommon dlog glib-2.0)
+pkg_check_modules(usb_client_pkgs REQUIRED hwcommon dlog glib-2.0 libusbgx libsystemd)
 
 FOREACH(flag ${usb_client_pkgs_CFLAGS})
        SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
index 2716eea..f7faa5b 100644 (file)
@@ -23,6 +23,7 @@
 #include <limits.h>
 #include <stdio.h>
 #include <string.h>
+#include <systemd/sd-bus.h>
 
 #define zalloc(amount) calloc(1, amount)
 
 /* +5 to be always big enough */
 #define INT_BUF_SIZE (sizeof(int)*8 + 5)
 
+#define SYSTEMD_DBUS_SERVICE "org.freedesktop.systemd1"
+#define SYSTEMD_DBUS_PATH "/org/freedesktop/systemd1"
+#define SYSTEMD_DBUS_MANAGER_IFACE "org.freedesktop.systemd1.Manager"
+
+#define SYSTEMD_SERVICE_SUFFIX ".service"
+#define MAX_SERVICE_NAME 1024
+
+static int systemd_unit_interface(const char *method, const char *unit)
+{
+       sd_bus *bus = NULL;
+       int r;
+
+       r = sd_bus_open_system(&bus);
+       if (r < 0)
+               return r;
+
+       r = sd_bus_call_method(bus,
+                       SYSTEMD_DBUS_SERVICE,
+                       SYSTEMD_DBUS_PATH,
+                       SYSTEMD_DBUS_MANAGER_IFACE,
+                       method,
+                       NULL,
+                       NULL,
+                       "ss",
+                       unit,
+                       "replace");
+
+       sd_bus_unref(bus);
+       return r;
+}
+
+static int systemd_start_service(const char *service_name)
+{
+       char unit[MAX_SERVICE_NAME];
+       int ret;
+
+       ret = snprintf(unit, sizeof(unit), "%s" SYSTEMD_SERVICE_SUFFIX,
+                      service_name);
+       if (ret < 0 || ret >= sizeof(unit))
+               return -ENAMETOOLONG;
+
+       return systemd_unit_interface("StartUnit", unit);
+}
+
+static int systemd_stop_service(const char *service_name)
+{
+       char unit[MAX_SERVICE_NAME];
+       int ret;
+
+       ret = snprintf(unit, sizeof(unit), "%s" SYSTEMD_SERVICE_SUFFIX,
+                      service_name);
+       if (ret < 0 || ret >= sizeof(unit))
+               return -ENAMETOOLONG;
+
+       return systemd_unit_interface("StopUnit", unit);
+}
+
 static int get_int_from_file(char *path, int *_val)
 {
        char buf[INT_BUF_SIZE];
@@ -524,14 +582,71 @@ static int legacy_reconfigure_gadget(struct usb_client *usb,
 
 static int legacy_enable(struct usb_client *usb)
 {
-       return sys_set_str(LEGACY_ENABLE_PATH,
+       int ret;
+       int i;
+       struct usb_gadget *gadget;
+       struct usb_function_with_service *fws;
+
+       ret = sys_set_str(LEGACY_ENABLE_PATH,
                           LEGACY_ENABLE);
+       if (ret < 0)
+               return ret;
+
+       ret = legacy_get_current_gadget(usb, &gadget);
+       if (ret < 0)
+               goto disable_gadget;
+
+       for (i = 0; gadget->funcs[i]; ++i) {
+               if (gadget->funcs[i]->function_group !=
+                   USB_FUNCTION_GROUP_WITH_SERVICE)
+                       continue;
+
+               fws = container_of(gadget->funcs[i],
+                                  struct usb_function_with_service, func);
+               ret = systemd_start_service(fws->service);
+               if (ret < 0)
+                       goto stop_services;
+       }
+
+       return 0;
+stop_services:
+       while (--i >= 0) {
+               if (gadget->funcs[i]->function_group !=
+                   USB_FUNCTION_GROUP_WITH_SERVICE)
+                       continue;
+
+               fws = container_of(gadget->funcs[i],
+                                  struct usb_function_with_service, func);
+               systemd_stop_service(fws->service);
+       }
+
+disable_gadget:
+       sys_set_str(LEGACY_ENABLE_PATH, LEGACY_DISABLE);
+       return ret;
 }
 
 static int legacy_disable(struct usb_client *usb)
 {
-       return sys_set_str(LEGACY_ENABLE_PATH,
-                          LEGACY_DISABLE);
+       int ret;
+       int i;
+       struct usb_gadget *gadget;
+       struct usb_function_with_service *fws;
+
+       ret = legacy_get_current_gadget(usb, &gadget);
+       if (ret < 0)
+               return ret;
+
+       for (i = 0; gadget->funcs[i]; ++i) {
+               if (gadget->funcs[i]->function_group != USB_FUNCTION_GROUP_WITH_SERVICE)
+                       continue;
+
+               fws = container_of(gadget->funcs[i], struct usb_function_with_service, func);
+               ret = systemd_stop_service(fws->service);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return sys_set_str(LEGACY_ENABLE_PATH, LEGACY_DISABLE);
 }
 
 static void legacy_free_config(struct usb_configuration *config)
@@ -565,7 +680,7 @@ static void legacy_free_gadget(struct usb_gadget *gadget)
        if (!gadget)
                return;
 
-               if (gadget->strs) {
+       if (gadget->strs) {
                for (i = 0; gadget->strs[i].lang_code; ++i) {
                        free(gadget->strs[i].manufacturer);
                        free(gadget->strs[i].product);
index dda9808..5feaf0e 100755 (executable)
@@ -14,6 +14,8 @@ BuildRequires:  pkgconfig(hwcommon)
 BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  pkgconfig(libudev)
 BuildRequires:  pkgconfig(capi-system-peripheral-io)
+BuildRequires:  pkgconfig(libusbgx)
+BuildRequires:  pkgconfig(libsystemd)
 
 %description
 Device manager plugin artik