diff options
author | Paweł Szewczyk <p.szewczyk@samsung.com> | 2018-02-08 14:33:19 +0100 |
---|---|---|
committer | saerome kim <saerome.kim@samsung.com> | 2018-04-05 10:01:56 +0000 |
commit | d0a595500968bd7d1b0b7e3a7a271646d8effc89 (patch) | |
tree | 42706c9e83a2519d8f7188f846d20a7e9313af3b | |
parent | 6263c60a6d11c64a07668e181a414b13f4e1a7d0 (diff) | |
download | mtp-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-x | CMakeLists.txt | 12 | ||||
-rw-r--r-- | include/transport/mtp_descs_strings.h | 62 | ||||
-rwxr-xr-x | mtp-responder.service | 2 | ||||
-rwxr-xr-x | mtp-responder.socket | 6 | ||||
-rwxr-xr-x | packaging/mtp-responder.spec | 5 | ||||
-rw-r--r-- | src/extract_descs/mtp_extract_descs_strs.c | 55 | ||||
-rw-r--r-- | src/transport/mtp_descs_strings.c | 108 | ||||
-rw-r--r-- | src/transport/mtp_usb_driver.c | 3 | ||||
-rwxr-xr-x | src/transport/mtp_usb_driver_ffs.c | 142 |
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; |