summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaweł Szewczyk <p.szewczyk@samsung.com>2018-02-08 14:33:19 +0100
committersaerome kim <saerome.kim@samsung.com>2018-04-05 10:01:56 +0000
commitd0a595500968bd7d1b0b7e3a7a271646d8effc89 (patch)
tree42706c9e83a2519d8f7188f846d20a7e9313af3b
parent6263c60a6d11c64a07668e181a414b13f4e1a7d0 (diff)
downloadmtp-responder-d0a595500968bd7d1b0b7e3a7a271646d8effc89.tar.gz
mtp-responder-d0a595500968bd7d1b0b7e3a7a271646d8effc89.tar.bz2
mtp-responder-d0a595500968bd7d1b0b7e3a7a271646d8effc89.zip
Use systemd functionfs socket activation
This includes creating binary files with descriptors and strings at compile time and systemd configuration of ffs socket. Change-Id: Ib38dc151e5e5d047ddb873661505ca13ddfc3306 Signed-off-by: Paweł Szewczyk <p.szewczyk@samsung.com>
-rwxr-xr-xCMakeLists.txt12
-rw-r--r--include/transport/mtp_descs_strings.h62
-rwxr-xr-xmtp-responder.service2
-rwxr-xr-xmtp-responder.socket6
-rwxr-xr-xpackaging/mtp-responder.spec5
-rw-r--r--src/extract_descs/mtp_extract_descs_strs.c55
-rw-r--r--src/transport/mtp_descs_strings.c108
-rw-r--r--src/transport/mtp_usb_driver.c3
-rwxr-xr-xsrc/transport/mtp_usb_driver_ffs.c142
9 files changed, 262 insertions, 133 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f2ce402..2b384e2 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,7 +13,7 @@ AUX_SOURCE_DIRECTORY(${CMAKE_SOURCE_DIR}/src/util SRCS)
INCLUDE(FindPkgConfig)
pkg_check_modules(pkgs REQUIRED glib-2.0 capi-content-media-content
- capi-media-metadata-extractor vconf dlog tapi capi-system-info storage libsystemd-daemon)
+ capi-media-metadata-extractor vconf dlog tapi capi-system-info storage libsystemd-daemon libsystemd)
FOREACH(flag ${pkgs_CFLAGS})
SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
@@ -30,3 +30,13 @@ TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} pthread rt gcrypt)
INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin)
INSTALL(FILES mtp-responder.conf DESTINATION /opt/var/lib/misc)
+
+ADD_EXECUTABLE(extract_descs_strs ${CMAKE_SOURCE_DIR}/src/extract_descs/mtp_extract_descs_strs.c
+ ${CMAKE_SOURCE_DIR}/src/transport/mtp_descs_strings.c)
+ADD_CUSTOM_COMMAND(OUTPUT descs strs
+ COMMAND ./extract_descs_strs
+ DEPENDS extract_descs_strs)
+ADD_CUSTOM_TARGET(descs_strs ALL DEPENDS descs strs)
+
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/descs DESTINATION /etc/mtp-responder)
+INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/strs DESTINATION /etc/mtp-responder)
diff --git a/include/transport/mtp_descs_strings.h b/include/transport/mtp_descs_strings.h
new file mode 100644
index 0000000..37747ba
--- /dev/null
+++ b/include/transport/mtp_descs_strings.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012, 2013, 2018 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 <linux/usb/ch9.h>
+#include <linux/usb/functionfs.h>
+#include <endian.h>
+
+#ifndef FUNCTIONFS_DESCRIPTORS_MAGIC_V2
+#define FUNCTIONFS_DESCRIPTORS_MAGIC_V2 3
+enum functionfs_flags {
+ FUNCTIONFS_HAS_FS_DESC = 1,
+ FUNCTIONFS_HAS_HS_DESC = 2,
+ FUNCTIONFS_HAS_SS_DESC = 4,
+ FUNCTIONFS_HAS_MS_OS_DESC = 8,
+};
+#endif
+
+#define cpu_to_le16(x) htole16(x)
+#define cpu_to_le32(x) htole32(x)
+#define le32_to_cpu(x) le32toh(x)
+#define le16_to_cpu(x) le16toh(x)
+
+extern struct mtp_usb_descs{
+ struct {
+ __le32 magic;
+ __le32 length;
+ __le32 flags;
+ __le32 fs_count;
+ __le32 hs_count;
+ // __le32 os_count;
+ } header;
+ struct {
+ struct usb_interface_descriptor intf;
+ struct usb_endpoint_descriptor_no_audio bulk_in;
+ struct usb_endpoint_descriptor_no_audio bulk_out;
+ struct usb_endpoint_descriptor_no_audio int_in;
+ } __attribute__((packed)) fs_descs, hs_descs;
+ // struct {} __attribute__((packed)) os_descs;
+} __attribute__((packed)) descriptors;
+
+#define STR_INTERFACE "Samsung MTP"
+
+extern struct mtp_usb_strs {
+ struct usb_functionfs_strings_head header;
+ struct {
+ __le16 code;
+ const char str1[sizeof(STR_INTERFACE)];
+ } __attribute__((packed)) lang0;
+} __attribute__((packed)) strings;
diff --git a/mtp-responder.service b/mtp-responder.service
index 24acdfe..69433c4 100755
--- a/mtp-responder.service
+++ b/mtp-responder.service
@@ -9,3 +9,5 @@ Type=simple
ExecStart=/usr/bin/mtp-responder
KillMode=process
SmackProcessLabel=System
+USBFunctionDescriptors=/etc/mtp-responder/descs
+USBFunctionStrings=/etc/mtp-responder/strs
diff --git a/mtp-responder.socket b/mtp-responder.socket
new file mode 100755
index 0000000..0abae50
--- /dev/null
+++ b/mtp-responder.socket
@@ -0,0 +1,6 @@
+[Unit]
+Description=MTP responder functionfs socket
+
+[Socket]
+ListenUSBFunction=/dev/usb-funcs/mtp
+Service=mtp-responder.service
diff --git a/packaging/mtp-responder.spec b/packaging/mtp-responder.spec
index b1f1861..93187ae 100755
--- a/packaging/mtp-responder.spec
+++ b/packaging/mtp-responder.spec
@@ -22,6 +22,7 @@ BuildRequires: pkgconfig(capi-media-metadata-extractor)
BuildRequires: pkgconfig(capi-system-info)
Buildrequires: pkgconfig(storage)
BuildRequires: pkgconfig(libsystemd-daemon)
+BuildRequires: pkgconfig(libsystemd)
Requires(post): /usr/bin/vconftool
%define upgrade_script_path /usr/share/upgrade/scripts
@@ -53,6 +54,7 @@ mkdir -p %{buildroot}%{upgrade_script_path}
cp -f scripts/500.%{name}-upgrade.sh %{buildroot}%{upgrade_script_path}
install -D -m 0644 mtp-responder.service %{buildroot}/%{_unitdir}/mtp-responder.service
+install -D -m 0644 mtp-responder.socket %{buildroot}/%{_unitdir}/mtp-responder.socket
%post
mkdir -p %{_sysconfdir}/systemd/default-extra-dependencies/ignore-units.d/
@@ -64,6 +66,9 @@ ln -sf %{_unitdir}/mtp-responder.service %{_sysconfdir}/systemd/default-extra-de
%defattr(-,root,root,-)
%{_bindir}/mtp-responder
%{_unitdir}/mtp-responder.service
+%{_unitdir}/mtp-responder.socket
%{_prefix}/lib/udev/rules.d/99-mtp-responder.rules
/opt/var/lib/misc/mtp-responder.conf
%{upgrade_script_path}/500.%{name}-upgrade.sh
+/etc/mtp-responder/descs
+/etc/mtp-responder/strs
diff --git a/src/extract_descs/mtp_extract_descs_strs.c b/src/extract_descs/mtp_extract_descs_strs.c
new file mode 100644
index 0000000..947c4e2
--- /dev/null
+++ b/src/extract_descs/mtp_extract_descs_strs.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, 2013, 2018 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 <errno.h>
+#include <stdio.h>
+#include "mtp_descs_strings.h"
+
+static int write_blob(const char *filename, const void *blob, size_t size)
+{
+ int ret;
+ FILE *fp;
+
+ fp = fopen(filename, "w");
+ if (!fp) {
+ fprintf(stderr, "Could not open %s: %m\n", filename);
+ return -errno;
+ }
+
+ ret = fwrite(blob, size, 1, fp);
+ if (ret < 0) {
+ fprintf(stderr, "Could not write to %s\n");
+ goto out;
+ }
+
+ ret = 0;
+
+out:
+ fclose(fp);
+ return ret;
+}
+
+int main()
+{
+ int ret;
+
+ ret = write_blob("descs", &descriptors, sizeof(descriptors));
+ if (ret < 0)
+ return ret;
+
+ ret = write_blob("strs", &strings, sizeof(strings));
+ return ret;
+}
diff --git a/src/transport/mtp_descs_strings.c b/src/transport/mtp_descs_strings.c
new file mode 100644
index 0000000..f5d90e2
--- /dev/null
+++ b/src/transport/mtp_descs_strings.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2012, 2013, 2018 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 "mtp_descs_strings.h"
+
+struct mtp_usb_descs descriptors = {
+ .header = {
+ .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2),
+ .length = cpu_to_le32(sizeof(descriptors)),
+ .flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC, // | FUNCTIONFS_HAS_MS_OS_DESC,
+ .fs_count = 4,
+ .hs_count = 4,
+ // .os_count = 0;
+ },
+ .fs_descs = {
+ // drivers/usb/gadget/f_mtp_slp.c:207
+ .intf = {
+ .bLength = sizeof(descriptors.fs_descs.intf),
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bNumEndpoints = 3,
+ .bInterfaceClass = USB_CLASS_STILL_IMAGE,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 1,
+ .iInterface = 1,
+ },
+ .bulk_in = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 1 | USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = __constant_cpu_to_le16(64),
+ },
+ .bulk_out = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 2 | USB_DIR_OUT,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = __constant_cpu_to_le16(64),
+ },
+ .int_in = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 3 | USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .wMaxPacketSize = __constant_cpu_to_le16(64),
+ .bInterval = 6,
+ },
+ },
+ .hs_descs = {
+ .intf = {
+ .bLength = sizeof(descriptors.fs_descs.intf),
+ .bDescriptorType = USB_DT_INTERFACE,
+ .bNumEndpoints = 3,
+ .bInterfaceClass = USB_CLASS_STILL_IMAGE,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 1,
+ .iInterface = 1,
+ },
+ .bulk_in = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 1 | USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = __constant_cpu_to_le16(512),
+ },
+ .bulk_out = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 2 | USB_DIR_OUT,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = __constant_cpu_to_le16(512),
+ },
+ .int_in = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+ .bEndpointAddress = 3 | USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .wMaxPacketSize = __constant_cpu_to_le16(64),
+ .bInterval = 6,
+ },
+ },
+};
+
+struct mtp_usb_strs strings = {
+ .header = {
+ .magic = cpu_to_le32(FUNCTIONFS_STRINGS_MAGIC),
+ .length = cpu_to_le32(sizeof(strings)),
+ .str_count = cpu_to_le32(1),
+ .lang_count = cpu_to_le32(1),
+ },
+ .lang0 = {
+ cpu_to_le16(0x0409), /* en-us */
+ STR_INTERFACE,
+ },
+};
diff --git a/src/transport/mtp_usb_driver.c b/src/transport/mtp_usb_driver.c
index 5576c55..6fde025 100644
--- a/src/transport/mtp_usb_driver.c
+++ b/src/transport/mtp_usb_driver.c
@@ -15,6 +15,7 @@
*/
#include <unistd.h>
+#include <systemd/sd-daemon.h>
#include "mtp_usb_driver.h"
static const mtp_usb_driver_t *usb_driver;
@@ -26,7 +27,7 @@ mtp_bool _transport_init_usb_device(void)
{
if (access(MTP_DRIVER_PATH, F_OK) == 0) {
usb_driver = &mtp_usb_driver_slp;
- } else if (access(MTP_EP0_PATH, F_OK) == 0) {
+ } else if (access(MTP_EP0_PATH, F_OK) == 0 || sd_listen_fds(0) >= 4) {
usb_driver = &mtp_usb_driver_ffs;
} else {
ERR("No suport for USB gadgets in kernel");
diff --git a/src/transport/mtp_usb_driver_ffs.c b/src/transport/mtp_usb_driver_ffs.c
index e972756..091daa8 100755
--- a/src/transport/mtp_usb_driver_ffs.c
+++ b/src/transport/mtp_usb_driver_ffs.c
@@ -25,6 +25,7 @@
#include <glib.h>
#include "mtp_usb_driver.h"
#include "mtp_device.h"
+#include "mtp_descs_strings.h"
#include "ptp_datacodes.h"
#include "mtp_support.h"
#include "ptp_container.h"
@@ -33,8 +34,7 @@
#include "mtp_transport.h"
#include "mtp_event_handler.h"
#include <sys/prctl.h>
-#include <linux/usb/ch9.h>
-#include <linux/usb/functionfs.h>
+#include <systemd/sd-daemon.h>
/*
* GLOBAL AND EXTERN VARIABLES
@@ -44,15 +44,6 @@ extern mtp_config_t g_conf;
/*
* STATIC VARIABLES AND FUNCTIONS
*/
-#ifndef FUNCTIONFS_DESCRIPTORS_MAGIC_V2
-#define FUNCTIONFS_DESCRIPTORS_MAGIC_V2 3
-enum functionfs_flags {
- FUNCTIONFS_HAS_FS_DESC = 1,
- FUNCTIONFS_HAS_HS_DESC = 2,
- FUNCTIONFS_HAS_SS_DESC = 4,
- FUNCTIONFS_HAS_MS_OS_DESC = 8,
-};
-#endif
/*PIMA15740-2000 spec*/
#define USB_PTPREQUEST_CANCELIO 0x64 /* Cancel request */
@@ -62,126 +53,6 @@ enum functionfs_flags {
#define USB_PTPREQUEST_CANCELIO_SIZE 6
#define USB_PTPREQUEST_GETSTATUS_SIZE 12
-#define cpu_to_le16(x) htole16(x)
-#define cpu_to_le32(x) htole32(x)
-#define le32_to_cpu(x) le32toh(x)
-#define le16_to_cpu(x) le16toh(x)
-
-static const struct {
- struct {
- __le32 magic;
- __le32 length;
- __le32 flags;
- __le32 fs_count;
- __le32 hs_count;
- // __le32 os_count;
- } header;
- struct {
- struct usb_interface_descriptor intf;
- struct usb_endpoint_descriptor_no_audio bulk_in;
- struct usb_endpoint_descriptor_no_audio bulk_out;
- struct usb_endpoint_descriptor_no_audio int_in;
- } __attribute__((packed)) fs_descs, hs_descs;
- // struct {} __attribute__((packed)) os_descs;
-} __attribute__((packed)) descriptors = {
- .header = {
- .magic = cpu_to_le32(FUNCTIONFS_DESCRIPTORS_MAGIC_V2),
- .length = cpu_to_le32(sizeof(descriptors)),
- .flags = FUNCTIONFS_HAS_FS_DESC | FUNCTIONFS_HAS_HS_DESC, // | FUNCTIONFS_HAS_MS_OS_DESC,
- .fs_count = 4,
- .hs_count = 4,
- // .os_count = 0;
- },
- .fs_descs = {
- // drivers/usb/gadget/f_mtp_slp.c:207
- .intf = {
- .bLength = sizeof(descriptors.fs_descs.intf),
- .bDescriptorType = USB_DT_INTERFACE,
- .bNumEndpoints = 3,
- .bInterfaceClass = USB_CLASS_STILL_IMAGE,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 1,
- .iInterface = 1,
- },
- .bulk_in = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 1 | USB_DIR_IN,
- .bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(64),
- },
- .bulk_out = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 2 | USB_DIR_OUT,
- .bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(64),
- },
- .int_in = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 3 | USB_DIR_IN,
- .bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(64),
- .bInterval = 6,
- },
- },
- .hs_descs = {
- .intf = {
- .bLength = sizeof(descriptors.fs_descs.intf),
- .bDescriptorType = USB_DT_INTERFACE,
- .bNumEndpoints = 3,
- .bInterfaceClass = USB_CLASS_STILL_IMAGE,
- .bInterfaceSubClass = 1,
- .bInterfaceProtocol = 1,
- .iInterface = 1,
- },
- .bulk_in = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 1 | USB_DIR_IN,
- .bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
- },
- .bulk_out = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 2 | USB_DIR_OUT,
- .bmAttributes = USB_ENDPOINT_XFER_BULK,
- .wMaxPacketSize = __constant_cpu_to_le16(512),
- },
- .int_in = {
- .bLength = USB_DT_ENDPOINT_SIZE,
- .bDescriptorType = USB_DT_ENDPOINT,
- .bEndpointAddress = 3 | USB_DIR_IN,
- .bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(64),
- .bInterval = 6,
- },
- },
-};
-
-#define STR_INTERFACE "Samsung MTP"
-
-static const struct {
- struct usb_functionfs_strings_head header;
- struct {
- __le16 code;
- const char str1[sizeof(STR_INTERFACE)];
- } __attribute__((packed)) lang0;
-} __attribute__((packed)) strings = {
- .header = {
- .magic = cpu_to_le32(FUNCTIONFS_STRINGS_MAGIC),
- .length = cpu_to_le32(sizeof(strings)),
- .str_count = cpu_to_le32(1),
- .lang_count = cpu_to_le32(1),
- },
- .lang0 = {
- cpu_to_le16(0x0409), /* en-us */
- STR_INTERFACE,
- },
-};
-
static mtp_int32 g_usb_ep0 = -1; /* read (g_usb_ep0, ...) */
static mtp_int32 g_usb_ep_in = -1; /* write (g_usb_ep_in, ...) */
static mtp_int32 g_usb_ep_out = -1; /* read (g_usb_ep_out, ...) */
@@ -203,6 +74,15 @@ static mtp_bool __io_init()
{
int ret;
+ if (sd_listen_fds(0) >= 4) {
+ g_usb_ep0 = SD_LISTEN_FDS_START;
+ g_usb_ep_in = SD_LISTEN_FDS_START + 1;
+ g_usb_ep_out = SD_LISTEN_FDS_START + 2;
+ g_usb_ep_status = SD_LISTEN_FDS_START + 3;
+
+ return TRUE;
+ }
+
g_usb_ep0 = open(MTP_EP0_PATH, O_RDWR);
if (g_usb_ep0 < 0)
goto out;