core: Add FFSDescriptors and FFSStrings service parameters
authorPawel Szewczyk <p.szewczyk@samsung.com>
Fri, 4 Sep 2015 10:23:51 +0000 (12:23 +0200)
committerPawel Szewczyk <p.szewczyk@samsung.com>
Tue, 22 Sep 2015 14:32:16 +0000 (16:32 +0200)
By using these parameters functionfs service can specify ffs descriptors
and strings which should be written to ep0.

src/core/dbus-service.c
src/core/load-fragment-gperf.gperf.m4
src/core/service.c
src/core/service.h
src/core/socket.c

index e1f3d56..3436342 100644 (file)
@@ -62,6 +62,8 @@ const sd_bus_vtable bus_service_vtable[] = {
         SD_BUS_PROPERTY("StatusText", "s", NULL, offsetof(Service, status_text), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("StatusErrno", "i", NULL, offsetof(Service, status_errno), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         SD_BUS_PROPERTY("Result", "s", property_get_result, offsetof(Service, result), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("USBFunctionDescriptors", "s", NULL, offsetof(Service, usb_function_descriptors), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
+        SD_BUS_PROPERTY("USBFunctionStrings", "s", NULL, offsetof(Service, usb_function_strings), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         BUS_EXEC_STATUS_VTABLE("ExecMain", offsetof(Service, main_exec_status), SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE),
         BUS_EXEC_COMMAND_LIST_VTABLE("ExecStartPre", offsetof(Service, exec_command[SERVICE_EXEC_START_PRE]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
         BUS_EXEC_COMMAND_LIST_VTABLE("ExecStart", offsetof(Service, exec_command[SERVICE_EXEC_START]), SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION),
index d227f2a..69e8d7a 100644 (file)
@@ -233,6 +233,8 @@ Service.FileDescriptorStoreMax,  config_parse_unsigned,              0,
 Service.NotifyAccess,            config_parse_notify_access,         0,                             offsetof(Service, notify_access)
 Service.Sockets,                 config_parse_service_sockets,       0,                             0
 Service.BusPolicy,               config_parse_bus_endpoint_policy,   0,                             offsetof(Service, exec_context)
+Service.USBFunctionDescriptors,  config_parse_path,                  0,                             offsetof(Service, usb_function_descriptors)
+Service.USBFunctionStrings,      config_parse_path,                  0,                             offsetof(Service, usb_function_strings)
 EXEC_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
 CGROUP_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
 KILL_CONTEXT_CONFIG_ITEMS(Service)m4_dnl
index fc28ba4..f7de5e8 100644 (file)
@@ -482,6 +482,12 @@ static int service_verify(Service *s) {
                 return -EINVAL;
         }
 
+        if (s->usb_function_descriptors && !s->usb_function_strings)
+                log_unit_warning(UNIT(s), "Service has USBFunctionDescriptors= setting, but no USBFunctionStrings=. Ignoring.");
+
+        if (!s->usb_function_descriptors && s->usb_function_strings)
+                log_unit_warning(UNIT(s), "Service has USBFunctionStrings= setting, but no USBFunctionDescriptors=. Ignoring.");
+
         return 0;
 }
 
index 7da0a93..789dff2 100644 (file)
@@ -212,6 +212,9 @@ struct Service {
         ServiceFDStore *fd_store;
         unsigned n_fd_store;
         unsigned n_fd_store_max;
+
+        char *usb_function_descriptors;
+        char *usb_function_strings;
 };
 
 extern const UnitVTable service_vtable;
index d8de58e..54e94c4 100644 (file)
@@ -50,6 +50,7 @@
 #include "formats-util.h"
 #include "signal-util.h"
 #include "socket.h"
+#include "copy.h"
 
 static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
         [SOCKET_DEAD] = UNIT_INACTIVE,
@@ -1165,6 +1166,22 @@ static int socket_symlink(Socket *s) {
         return 0;
 }
 
+static int ffs_write_descs(int fd, Unit *u) {
+        Service *s = SERVICE(u);
+        int r;
+
+        if (!s->usb_function_descriptors || !s->usb_function_strings)
+                return -EINVAL;
+
+        r = copy_file_fd(s->usb_function_descriptors, fd, false);
+        if (r < 0)
+                return 0;
+
+        r = copy_file_fd(s->usb_function_strings, fd, false);
+
+        return r;
+}
+
 static int select_ep(const struct dirent *d) {
         return d->d_name[0] != '.' && !streq(d->d_name, "ep0");
 }
@@ -1323,6 +1340,10 @@ static int socket_open_fds(Socket *s) {
                         if (r < 0)
                                 goto rollback;
 
+                        r = ffs_write_descs(p->fd, s->service.unit);
+                        if (r < 0)
+                                goto rollback;
+
                         r = ffs_dispatch_eps(p);
                         if (r < 0)
                                 goto rollback;