From 3ac733180b0c18d04106ef2650a45c1f7c532ff1 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Mon, 22 Apr 2019 16:53:12 +0900 Subject: [PATCH 01/16] scripts: Print out brief information about network connection This patch refactors init script in order to provide brief information of the target network as below: Network Information: Wired: xxx.xxx.xxx.xxx Wireless: xxx.xxx.xxx.xxx [SSID: xxxxxxxxx] Change-Id: I5df962443cc846e60a5952dbb3e8dadb37273dd3 Signed-off-by: Dongwoo Lee --- scripts/flash-init.sh | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/scripts/flash-init.sh b/scripts/flash-init.sh index aba4d7e..e5d12f8 100755 --- a/scripts/flash-init.sh +++ b/scripts/flash-init.sh @@ -34,7 +34,7 @@ clear_bootmode() { #------------------------------------------------ # Copy Module and Firmware file #------------------------------------------------ -copy_module() { +setup_wireless() { MODULES_PART=`"$BLKID" --label modules` if [ "$MODULES_PART" != "" ]; then echo "Module partition is $MODULES_PART" @@ -53,20 +53,22 @@ copy_module() { $INSMOD /lib/firmware/brcm/brcmfmac.ko sleep 1 - echo "wlan0 ipaddr is 192.168.43.1" - $IFCONFIG $WLANIF 192.168.43.1 up + WLANIP="192.168.43.1" + $IFCONFIG $WLANIF ${WLANIP} up $DNSMASQ -p 0 -9 -C /lib/firmware/brcm/dnsmasq.conf - $HOSTAPD -B /lib/firmware/brcm/hostapd.conf + SSID=`$HOSTAPD -B /lib/firmware/brcm/hostapd.conf | "$GREP" -oP '(?<=ssid\s\")(.*?)(?=\")'` else echo "There is no module partition" + WLANIP="N/A" + SSID="N/A" fi } #------------------------------------------------ -# print_ip +# setup_writed_nic() #------------------------------------------------ -print_ip() { +setup_wired_nic() { IPADDR=`"$IP" -4 addr show $NETIF | "$GREP" -oP '(?<=inet\s)\d+(\.\d+){3}'` if [ "z$IPADDR" == "z" ]; then IPADDR="192.168.0.100" @@ -93,6 +95,18 @@ print_ip() { } #------------------------------------------------ +# print_info() +#------------------------------------------------ +print_info() { + echo "" + echo "Tizen flash manager is ready." + echo "" + echo "Network Information:" + echo "Wired: ${IPADDR}" + echo "Wireless: ${WLANIP} [SSID: ${SSID}]" +} + +#------------------------------------------------ # do_flash #------------------------------------------------ do_flash() { @@ -108,7 +122,8 @@ do_flash() { #------------------------------------------------ # Main Routine Start #------------------------------------------------ -print_ip +setup_wired_nic +setup_wireless clear_bootmode -copy_module +print_info do_flash -- 2.7.4 From 6d921f96e595d984efb9dc9cb9a47e87478c373a Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Thu, 9 May 2019 14:24:14 +0900 Subject: [PATCH 02/16] packaging: move firmware file to data directory Move firmare file to data directory from /lib/firmware/brcm/. Change-Id: I5d37d3fda035bc271fb62ef0c8f8b2926828fbf1 Signed-off-by: Jaehoon Chung --- packaging/initrd-flash.spec | 18 +++++++++--------- scripts/41-flash.list | 14 +++++++------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/packaging/initrd-flash.spec b/packaging/initrd-flash.spec index 9bfc980..d6dc741 100644 --- a/packaging/initrd-flash.spec +++ b/packaging/initrd-flash.spec @@ -52,11 +52,11 @@ cp ./scripts/41-flash.list %{buildroot}%{_datadir}/initrd-recovery/initrd.list.d cp ./data/partition_* %{buildroot}%{_datadir}/ -mkdir -p %{buildroot}%{_libdir}/firmware/brcm -cp ./data/brcmfmac* %{buildroot}%{_libdir}/firmware/brcm -cp ./data/LICENCE.broadcom_bcm43xx %{buildroot}%{_libdir}/firmware/brcm -cp ./data/hostapd.conf %{buildroot}%{_libdir}/firmware/brcm -cp ./data/dnsmasq.conf %{buildroot}%{_libdir}/firmware/brcm +mkdir -p %{buildroot}%{_datadir}/firmware/brcm +cp ./data/brcmfmac* %{buildroot}%{_datadir}/firmware/brcm +cp ./data/LICENCE.broadcom_bcm43xx %{buildroot}%{_datadir}/firmware/brcm +cp ./data/hostapd.conf %{buildroot}%{_datadir}/firmware/brcm +cp ./data/dnsmasq.conf %{buildroot}%{_datadir}/firmware/brcm %post @@ -71,10 +71,10 @@ mv %{_datadir}/partition_rpi3.info %{_datadir}/partition.info %attr(700,root,root) %{_bindir}/flash-manager %attr(700,root,root) %{init_script_dir}/*.sh %attr(700,root,root) %{_datadir}/initrd-recovery/initrd.list.d/*.list -%attr(700,root,root) %{_libdir}/firmware/brcm/brcmfmac* -%attr(700,root,root) %{_libdir}/firmware/brcm/LICENCE.broadcom_bcm43xx -%attr(700,root,root) %{_libdir}/firmware/brcm/hostapd.conf -%attr(700,root,root) %{_libdir}/firmware/brcm/dnsmasq.conf %files -n fm-data-rpi3 %attr(700,root,root) %{_datadir}/partition_rpi3.info +%attr(700,root,root) %{_datadir}/firmware/brcm/brcmfmac* +%attr(700,root,root) %{_datadir}/firmware/brcm/LICENCE.broadcom_bcm43xx +%attr(700,root,root) %{_datadir}/firmware/brcm/hostapd.conf +%attr(700,root,root) %{_datadir}/firmware/brcm/dnsmasq.conf diff --git a/scripts/41-flash.list b/scripts/41-flash.list index 3f165d1..66a2c69 100755 --- a/scripts/41-flash.list +++ b/scripts/41-flash.list @@ -2,6 +2,13 @@ MVWITHLIBS=" /usr/lib/initrd-recovery/flash/flash-init.sh /bin/flash-manager +/usr/share/firmware/brcm/brcmfmac43430-sdio.bin +/usr/share/firmware/brcm/brcmfmac43455-sdio.bin +/usr/share/firmware/brcm/brcmfmac43430-sdio.txt +/usr/share/firmware/brcm/brcmfmac43455-sdio.txt +/usr/share/firmware/brcm/LICENCE.broadcom_bcm43xx +/usr/share/firmware/brcm/hostapd.conf +/usr/share/firmware/brcm/dnsmasq.conf " WITHLIBS=" @@ -29,11 +36,4 @@ SYMLINKS=" VERBATIMS=" /usr/share/partition.info -/usr/lib/firmware/brcm/brcmfmac43430-sdio.bin -/usr/lib/firmware/brcm/brcmfmac43455-sdio.bin -/usr/lib/firmware/brcm/brcmfmac43430-sdio.txt -/usr/lib/firmware/brcm/brcmfmac43455-sdio.txt -/usr/lib/firmware/brcm/LICENCE.broadcom_bcm43xx -/usr/lib/firmware/brcm/hostapd.conf -/usr/lib/firmware/brcm/dnsmasq.conf " -- 2.7.4 From 19f856576e42745cf8a1d2256c3b6cb54e4263eb Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Thu, 9 May 2019 16:10:40 +0900 Subject: [PATCH 03/16] scripts: flash-init: create symbolic link about firmware path Create symbolic link about firmware path. Change-Id: Ia0243afbafddbeef2bf797b3ad184150af75f4c5 Signed-off-by: Jaehoon Chung --- scripts/41-flash.list | 1 + scripts/flash-init.sh | 2 ++ 2 files changed, 3 insertions(+) diff --git a/scripts/41-flash.list b/scripts/41-flash.list index 66a2c69..c9c2611 100755 --- a/scripts/41-flash.list +++ b/scripts/41-flash.list @@ -26,6 +26,7 @@ WITHLIBS=" /bin/find /bin/hostapd /bin/dnsmasq +/bin/ln " # LinkFileName:Target diff --git a/scripts/flash-init.sh b/scripts/flash-init.sh index e5d12f8..799e80a 100755 --- a/scripts/flash-init.sh +++ b/scripts/flash-init.sh @@ -18,6 +18,7 @@ FIND="/usr/bin/find" INSMOD="/usr/sbin/insmod" DNSMASQ="/usr/bin/dnsmasq" HOSTAPD="/usr/bin/hostapd" +LINK="/usr/bin/ln" NETIF="eth0" WLANIF="wlan0" @@ -44,6 +45,7 @@ setup_wireless() { BRCMUTIL=`$FIND ${TMP_PATH} -name brcmutil.ko` echo "Module brcmfmac is $BRCMFMAC" echo "Module brcmutil is $BRCMUTIL" + $LINK -s /usr/share/firmware /lib/firmware $COPY $BRCMFMAC /lib/firmware/brcm/ $COPY $BRCMUTIL /lib/firmware/brcm/ $SYNC -- 2.7.4 From b45ae10a1ffaa0ee18581c655c0b4117d25eba69 Mon Sep 17 00:00:00 2001 From: Junghoon Kim Date: Thu, 9 May 2019 21:26:39 +0900 Subject: [PATCH 04/16] data: Update the partition info file to support 32-bit architecture This patch adds the dtb and zImage to the partition info file, in order to support 32-bit architecture. Also, common u-boot and config files have been added to facilitate testing between 32-bit and 64-bit architectures. Change-Id: Idf27f33e50bbafbf438b78d6b336d4794416aa18 Signed-off-by: Junghoon Kim --- data/partition_rpi3.info | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/data/partition_rpi3.info b/data/partition_rpi3.info index 8acd369..e22defc 100644 --- a/data/partition_rpi3.info +++ b/data/partition_rpi3.info @@ -6,7 +6,13 @@ p:/dev/mmcblk0p6:modules.img:x p:/dev/mmcblk0p7:ramdisk.img:x p:/dev/mmcblk0p8:ramdisk-recovery.img:x f:/dev/mmcblk0p1:Image:/ +f:/dev/mmcblk0p1:zImage:/ f:/dev/mmcblk0p1:bcm2710-rpi-3-b-plus.dtb:/ f:/dev/mmcblk0p1:bcm2710-rpi-cm3.dtb:/ f:/dev/mmcblk0p1:bcm2710-rpi-3-b.dtb:/ f:/dev/mmcblk0p1:bcm2837-rpi-3-b.dtb:/ +f:/dev/mmcblk0p1:bcm2837-rpi-3-b-plus.dtb:/ +f:/dev/mmcblk0p1:u-boot.bin:/ +f:/dev/mmcblk0p1:uboot.env:/ +f:/dev/mmcblk0p1:boot.scr.uimg:/ +f:/dev/mmcblk0p1:config.txt:/ -- 2.7.4 From ad730409dcecc9e34e7b5ecc2da459a43640854b Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Tue, 25 Jun 2019 10:23:49 +0900 Subject: [PATCH 05/16] CMakeLists: Apply PIE flags To support ASLR, this patch applies PIE (position independent executable) flags to CMakeLists.txt. Change-Id: If7eae9c8aad08fe9da3083cbdad64a7221fdaa98 Signed-off-by: Dongwoo Lee --- CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ca1de19..c722f06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,9 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(flash-manager C) +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE -O2") +SET(CMAKE_EXE_LINKER_FLAGS "-pie") + FIND_PACKAGE(Threads REQUIRED) ADD_EXECUTABLE(${PROJECT_NAME} src/main.c src/thor.c src/dfu.c src/net.c) @@ -9,6 +12,4 @@ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src) TARGET_LINK_LIBRARIES(flash-manager "${CMAKE_THREAD_LIBS_INIT}" blkid) -ADD_DEFINITIONS(-Wall -g -O2) - INSTALL(TARGETS ${PROJECT_NAME} DESTINATION bin) -- 2.7.4 From 4162a2d539e6d3a52521c3cff9b0960db5a954ca Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Mon, 8 Jul 2019 16:07:45 +0900 Subject: [PATCH 06/16] dfu: Free resources on error This patch makes resources are freed on error case while scanning the type of filesystem with blkid APIs. This resource leakage was reported by static analystic tool. Change-Id: Ibeba4190316fb1db0bde02eaca0648c0db0bad2e Signed-off-by: Dongwoo Lee --- src/dfu.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/dfu.c b/src/dfu.c index 0131e42..4edf1a1 100644 --- a/src/dfu.c +++ b/src/dfu.c @@ -102,7 +102,7 @@ static char *get_partition_fstype(const char *devname) blkid_tag_iterate tag_iter; blkid_dev dev; blkid_cache cache = NULL; - const char *type, *value; + const char *type, *value, *fstype = NULL; int ret; ret = blkid_get_cache(&cache, NULL); @@ -113,29 +113,29 @@ static char *get_partition_fstype(const char *devname) dev = blkid_get_dev(cache, devname, 0); if (!dev) - return NULL; + goto err_put_cache; dev = blkid_verify(cache, dev); if (!dev) - return NULL; + goto err_put_cache; tag_iter = blkid_tag_iterate_begin(dev); while (blkid_tag_next(tag_iter, &type, &value) == 0) { if (!strncmp(type, "TYPE", 4)) { - char *fstype = strdup(value); - + fstype = strdup(value); if (!fstype) - return NULL; + fprintf(stderr, "failed to duplicate fs type string\n"); - blkid_tag_iterate_end(tag_iter); - blkid_put_cache(cache); - return fstype; + break; } } + blkid_tag_iterate_end(tag_iter); + +err_put_cache: blkid_put_cache(cache); - return NULL; + return fstype; } static int mount_dev(const char *dev) -- 2.7.4 From dc56768ae46d1076abe20e03c66fd3d99bf49dc2 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Fri, 3 Jan 2020 14:46:28 +0900 Subject: [PATCH 07/16] data: Add rpi4 dtb as a flashing entity To support tizen flash manager for rpi4, this adds a dtb file for bcm2711 into partition information file. Change-Id: I9b4a97c5d80f40c329d04f87d1eb1b29066d17f0 Signed-off-by: Dongwoo Lee --- data/partition_rpi3.info | 1 + 1 file changed, 1 insertion(+) diff --git a/data/partition_rpi3.info b/data/partition_rpi3.info index e22defc..ad1bb42 100644 --- a/data/partition_rpi3.info +++ b/data/partition_rpi3.info @@ -12,6 +12,7 @@ f:/dev/mmcblk0p1:bcm2710-rpi-cm3.dtb:/ f:/dev/mmcblk0p1:bcm2710-rpi-3-b.dtb:/ f:/dev/mmcblk0p1:bcm2837-rpi-3-b.dtb:/ f:/dev/mmcblk0p1:bcm2837-rpi-3-b-plus.dtb:/ +f:/dev/mmcblk0p1:bcm2711-rpi-4-b.dtb:/ f:/dev/mmcblk0p1:u-boot.bin:/ f:/dev/mmcblk0p1:uboot.env:/ f:/dev/mmcblk0p1:boot.scr.uimg:/ -- 2.7.4 From 2b507f419bfe606103e1f680af31b9838f8f919d Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Wed, 8 Jan 2020 17:53:40 +0900 Subject: [PATCH 08/16] Fix gcc9 build warnings This fixes build warnings on compiling with gcc9. Change-Id: I7ff58499fc2813931ff49c8f7d58e851b08ef5dc Signed-off-by: Dongwoo Lee --- src/dfu.c | 3 ++- src/thor.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/dfu.c b/src/dfu.c index 4edf1a1..ea548f5 100644 --- a/src/dfu.c +++ b/src/dfu.c @@ -102,7 +102,8 @@ static char *get_partition_fstype(const char *devname) blkid_tag_iterate tag_iter; blkid_dev dev; blkid_cache cache = NULL; - const char *type, *value, *fstype = NULL; + const char *type, *value; + char *fstype = NULL; int ret; ret = blkid_get_cache(&cache, NULL); diff --git a/src/thor.c b/src/thor.c index 1d131cf..d6dfa09 100644 --- a/src/thor.c +++ b/src/thor.c @@ -81,7 +81,7 @@ static int thor_process_rqt_info(struct tfm_context *ctx, struct rqt_pkt *rqt) case RQT_INFO_VER_KERNEL: case RQT_INFO_VER_PLATFORM: case RQT_INFO_VER_CSC: - strncpy(rsp.str_data[0], "Unknown", sizeof("Unknown")); + strncpy(rsp.str_data[0], "Unknown", 32); break; default: fprintf(stderr, "Not supported information request: %d\n", -- 2.7.4 From 7062cae242638f20b61cda27f10a67b54879e427 Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Fri, 10 Jan 2020 15:10:49 +0900 Subject: [PATCH 09/16] dfu: do stringop with termination character Doing string operation with strlen() result, there is possibilty of omission of termination character. Do stringop with termination character with strlen() + 1. The destination buffer is allocated sum of all strlen() and 1, there is no overflow. Change-Id: I35627dbbb0ac72bc58398ccfffa43802729c5b85 Signed-off-by: Seung-Woo Kim --- src/dfu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dfu.c b/src/dfu.c index ea548f5..0a1b297 100644 --- a/src/dfu.c +++ b/src/dfu.c @@ -236,8 +236,8 @@ static int dfu_start_entity(struct tfm_context *ctx, int idx, unsigned long size } strncpy(file, DFU_MOUNT_PATH, path_prefix + 1); - strncat(file, info[DFU_INFO_PATH], path_suffix); - strncat(file, info[DFU_INFO_NAME], path_name); + strncat(file, info[DFU_INFO_PATH], path_suffix + 1); + strncat(file, info[DFU_INFO_NAME], path_name + 1); break; } default: -- 2.7.4 From 47fba2f480c071a3b308910dbd47e6aa2b49cb49 Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Fri, 10 Jan 2020 15:29:42 +0900 Subject: [PATCH 10/16] fix use string after null check The result of strdup() can be null, so use it after null check. Change-Id: I61b5e5a4d4b631984eb19240b46afe0e94752043 Signed-off-by: Seung-Woo Kim --- src/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 194e2c8..80267db 100644 --- a/src/main.c +++ b/src/main.c @@ -39,7 +39,8 @@ int _main(int argc, char *argv[]) if (opt_table) free(opt_table); opt_table = strdup(optarg); - part_table = opt_table; + if (opt_table) + part_table = opt_table; } else { fprintf(stderr, "path should be specified with '-i'\n"); -- 2.7.4 From 737d065c7fa0dc71223f6eb83dcb938b640dbea4 Mon Sep 17 00:00:00 2001 From: Seung-Woo Kim Date: Mon, 10 Feb 2020 15:28:36 +0900 Subject: [PATCH 11/16] Fix to check memory allocation failure The strdup() can be failed and return NULL. Not to access wrong memory, explictly check memory allocation failure. Change-Id: I2917cf0cebd6488004b653c29137c0acbb56074e Signed-off-by: Seung-Woo Kim --- src/main.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 80267db..32c2473 100644 --- a/src/main.c +++ b/src/main.c @@ -39,8 +39,13 @@ int _main(int argc, char *argv[]) if (opt_table) free(opt_table); opt_table = strdup(optarg); - if (opt_table) + if (opt_table) { part_table = opt_table; + } else { + fprintf(stderr, "Out of memory\n"); + ret = -1; + goto out; + } } else { fprintf(stderr, "path should be specified with '-i'\n"); -- 2.7.4 From 29950f08d56bd278a198463489be60d6bbdba49c Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Wed, 18 Mar 2020 12:35:59 +0900 Subject: [PATCH 12/16] thor: Bump protocol version to 5.0 To support the images exceeds 4GB, thor protocol 5.0 is applied. This requires thor client support: Ref: https://git.tizen.org/cgit/tools/lthor/commit/?id=30fa9f0cbfc4b089bb7e733b9cb75a60e1d10369 u-boot thor downloader already supports protocol 5.0: Ref: https://gitlab.denx.de/u-boot/u-boot/-/commit/1fe9ae76b113103bcc40aa15949f9dd8aa0a06a2 Change-Id: I149361ca2f40b5775249f3672e3e19b2f6394b68 Signed-off-by: Dongwoo Lee --- src/thor-proto.h | 2 +- src/thor.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/thor-proto.h b/src/thor-proto.h index f384b46..c26aefd 100644 --- a/src/thor-proto.h +++ b/src/thor-proto.h @@ -84,7 +84,7 @@ struct data_res_pkt { int32_t cnt; /* Int. Datas. */ } __attribute__((__packed__)); -#define VER_PROTOCOL_MAJOR 4 +#define VER_PROTOCOL_MAJOR 5 #define VER_PROTOCOL_MINOR 0 #define RQT_PKT_SIZE sizeof(struct rqt_pkt) diff --git a/src/thor.c b/src/thor.c index d6dfa09..e19d33f 100644 --- a/src/thor.c +++ b/src/thor.c @@ -216,7 +216,8 @@ static int thor_process_rqt_download(struct tfm_context *ctx, struct rqt_pkt *rq switch (rqt->sub_id) { case RQT_DL_INIT: - ctx->thor_file_size = (unsigned long)rqt->int_data[0]; + ctx->thor_file_size = (uint64_t)rqt->int_data[0] + + ((uint64_t)rqt->int_data[1] << 32); break; case RQT_DL_FILE_INFO: file_type = rqt->int_data[0]; @@ -226,7 +227,8 @@ static int thor_process_rqt_download(struct tfm_context *ctx, struct rqt_pkt *rq break; } - ctx->thor_file_size = (unsigned long)rqt->int_data[1]; + ctx->thor_file_size = (uint64_t)rqt->int_data[1] + + ((uint64_t)rqt->int_data[2] << 32); memcpy(f_name, rqt->str_data[0], FILE_NAME_MAXLEN); rsp.int_data[0] = DATA_PKT_SIZE; -- 2.7.4 From bdeb2d6876465d4d3b38b91f0f06b9a993dc5f59 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Tue, 17 Mar 2020 13:29:24 +0900 Subject: [PATCH 13/16] tfm: Refactor code structure To cleanup code and resolve dependency on each module, this just refactors code structure without functional changes. Change-Id: I0c9e4b50d1054255c4f33f2a0218469c0647d2c7 Signed-off-by: Dongwoo Lee --- src/dfu.c | 408 ++++++++++++++++++++++++++++++++++--------------------------- src/dfu.h | 46 +++---- src/main.c | 27 ++-- src/tfm.h | 22 +--- src/thor.c | 170 ++++++++++++++++---------- 5 files changed, 370 insertions(+), 303 deletions(-) diff --git a/src/dfu.c b/src/dfu.c index 0a1b297..4ae9145 100644 --- a/src/dfu.c +++ b/src/dfu.c @@ -31,7 +31,44 @@ #include "dfu.h" #include "thor-proto.h" -static char *dfu_info[DFU_INFO_NUM][DFU_INFO_MAX] = {NULL,}; +#define DFU_DELIMITER " :,\t\n" +#define DFU_ENTRY_LIST_MAXLEN 100 +#define DFU_MOUNT_PATH "/mnt/tfm-temp" + +#define DFU_INFO_MODE_PARTITION 'p' +#define DFU_INFO_MODE_FILE 'f' + +enum dfu_entry_attr { + DFU_INFO_MODE = 0, + DFU_INFO_PARTITION, + DFU_INFO_NAME, + DFU_INFO_PATH, + DFU_INFO_MAX, +}; + +enum dfu_thread_state { + DFU_THREAD_STATE_ERROR = -1, + DFU_THREAD_STATE_IDLE, + DFU_THREAD_STATE_FLASHING, +}; + +struct dfu_frame { + void *buf; + unsigned long len; + TAILQ_ENTRY(dfu_frame) entry; +}; + +struct dfu_context { + pthread_t thread; + pthread_mutex_t mutex; + pthread_mutex_t sync_mutex; + pthread_cond_t data_arrived; + pthread_cond_t write_done; + pthread_cond_t sync_done; + TAILQ_HEAD(tailhead, dfu_frame) ioq; + + char *dfu_entry_list[DFU_ENTRY_LIST_MAXLEN][DFU_INFO_MAX]; +}; void *dfu_get_buffer(unsigned long size) { @@ -55,44 +92,45 @@ void dfu_put_buffer(void *ptr) free(ptr); } -static int find_match(const char *name) +static char **find_entry_match(struct dfu_context *ctx, const char *name) { int i; - for (i = 0; i < DFU_INFO_NUM; i++) { - char *entry = dfu_info[i][DFU_INFO_NAME]; + for (i = 0; i < DFU_ENTRY_LIST_MAXLEN; i++) { + char *entry = ctx->dfu_entry_list[i][DFU_INFO_NAME]; if (entry && !strncmp(entry, name, strlen(entry))) - return i; + return ctx->dfu_entry_list[i]; } - return -ENOENT; + return NULL; } -int dfu_request_io(struct tfm_context *ctx, unsigned long len) +int dfu_request_io(struct dfu_entry *e, void *buffer, unsigned long len) { - int notify = 0; + struct dfu_context *ctx = e->ctx; struct dfu_frame *frame; + int notify = 0; frame = malloc(sizeof(*frame)); if (!frame) return -ENOMEM; - frame->buf = ctx->transfer_buffer; + frame->buf = buffer; frame->len = len; - pthread_mutex_lock(&ctx->dfu_mutex); + pthread_mutex_lock(&ctx->mutex); - if (TAILQ_EMPTY(&ctx->dfu_ioq_head)) + if (TAILQ_EMPTY(&ctx->ioq)) notify = 1; /* dfu_thread_main() de-queues i/o request and processes it */ - TAILQ_INSERT_TAIL(&ctx->dfu_ioq_head, frame, entry); + TAILQ_INSERT_TAIL(&ctx->ioq, frame, entry); - pthread_mutex_unlock(&ctx->dfu_mutex); + pthread_mutex_unlock(&ctx->mutex); if (notify) - pthread_cond_signal(&ctx->dfu_data_arrive); + pthread_cond_signal(&ctx->data_arrived); return 0; } @@ -179,53 +217,112 @@ static void umount_dev(void) rmdir(DFU_MOUNT_PATH); } -void dfu_sync(struct tfm_context *ctx) +static void dfu_thread_cleanup(void *ptr) { - char **info = ctx->dfu_info; + struct dfu_entry *e = ptr; + struct dfu_context *ctx = e->ctx; + struct dfu_frame *frame; - pthread_mutex_lock(&ctx->dfu_sync_mutex); - if (!ctx->transfer_done) - pthread_cond_wait(&ctx->dfu_write_done, &ctx->dfu_sync_mutex); - pthread_mutex_unlock(&ctx->dfu_sync_mutex); + while (!TAILQ_EMPTY(&ctx->ioq)) { + frame = TAILQ_FIRST(&ctx->ioq); - switch (*info[DFU_INFO_MODE]) { - case DFU_INFO_MODE_FILE: - fsync(ctx->dfu_fd); - close(ctx->dfu_fd); - umount_dev(); - break; - case DFU_INFO_MODE_PARTITION: - close(ctx->dfu_fd); - break; - default: - break; + TAILQ_REMOVE(&ctx->ioq, frame, entry); + + dfu_put_buffer(frame->buf); + free(frame); } - pthread_cond_signal(&ctx->dfu_sync_done); + free(e); +} - fprintf(stdout, "finished\n"); +static void *dfu_thread_main(void *ptr) +{ + struct dfu_entry *e = ptr; + struct dfu_context *ctx = e->ctx; + struct dfu_frame *frame; + int state = DFU_THREAD_STATE_IDLE; + uint64_t progress = 0; + int ret; + + pthread_cleanup_push(dfu_thread_cleanup, ptr); + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + + while (state != DFU_THREAD_STATE_ERROR) { + pthread_mutex_lock(&ctx->mutex); + + while (TAILQ_EMPTY(&ctx->ioq)) { + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + state = DFU_THREAD_STATE_IDLE; + pthread_cond_wait(&ctx->data_arrived, &ctx->mutex); + } + + if (state == DFU_THREAD_STATE_IDLE) { + state = DFU_THREAD_STATE_FLASHING; + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); + } + + frame = TAILQ_FIRST(&ctx->ioq); + + TAILQ_REMOVE(&ctx->ioq, frame, entry); + + pthread_mutex_unlock(&ctx->mutex); + + ret = write(e->fd, frame->buf, frame->len); + + if (ret < frame->len) { + fprintf(stderr, "Error occurs while flashing\n"); + state = DFU_THREAD_STATE_ERROR; + } + + progress += frame->len; + + fprintf(stdout, "#"); + fflush(stdout); + + dfu_put_buffer(frame->buf); + free(frame); + + /* transfer finished */ + if (state != DFU_THREAD_STATE_ERROR + && progress >= e->file_size) { + e->transfer_done = 1; + + state = DFU_THREAD_STATE_IDLE; + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + + pthread_cond_signal(&ctx->write_done); + + pthread_mutex_lock(&ctx->sync_mutex); + pthread_cond_wait(&ctx->sync_done, + &ctx->sync_mutex); + pthread_mutex_unlock(&ctx->sync_mutex); + break; + } + } + + pthread_cleanup_pop(1); + + return NULL; } -static int dfu_start_entity(struct tfm_context *ctx, int idx, unsigned long size) +static int dfu_start_entry(struct dfu_entry *e, char **entry, uint64_t size) { - char **info = dfu_info[idx]; char *file; - int fd; + int fd, ret = 0; - switch (*info[DFU_INFO_MODE]) { + switch (*entry[DFU_INFO_MODE]) { case DFU_INFO_MODE_PARTITION: - file = strdup(info[DFU_INFO_PARTITION]); + file = strdup(entry[DFU_INFO_PARTITION]); if (!file) return -ENOMEM; break; case DFU_INFO_MODE_FILE: { - int ret; int path_prefix = strlen(DFU_MOUNT_PATH); - int path_suffix = strlen(info[DFU_INFO_PATH]); - int path_name = strlen(info[DFU_INFO_NAME]); + int path_suffix = strlen(entry[DFU_INFO_PATH]); + int path_name = strlen(entry[DFU_INFO_NAME]); - ret = mount_dev(info[DFU_INFO_PARTITION]); + ret = mount_dev(entry[DFU_INFO_PARTITION]); if (ret < 0) return -EINVAL; @@ -236,138 +333,98 @@ static int dfu_start_entity(struct tfm_context *ctx, int idx, unsigned long size } strncpy(file, DFU_MOUNT_PATH, path_prefix + 1); - strncat(file, info[DFU_INFO_PATH], path_suffix + 1); - strncat(file, info[DFU_INFO_NAME], path_name + 1); + strncat(file, entry[DFU_INFO_PATH], path_suffix + 1); + strncat(file, entry[DFU_INFO_NAME], path_name + 1); break; } default: - fprintf(stderr, "flash entry '%s' has wrong mode\n", info[DFU_INFO_NAME]); + fprintf(stderr, + "flash entry '%s' has wrong mode\n", + entry[DFU_INFO_NAME]); return -EINVAL; } fd = open(file, O_WRONLY); if (fd < 0) { - fprintf(stderr, "cannot open target: %s\n", info[DFU_INFO_NAME]); - free(file); - return -EIO; + fprintf(stderr, + "cannot open target: %s\n", + entry[DFU_INFO_NAME]); + ret = -EIO; + goto err; } - ctx->dfu_fd = fd; - - ctx->dfu_info = info; - ctx->transfer_done = 0; + e->entry = entry; + e->fd = fd; + e->file_size = size; + e->transfer_done = 0; +err: free(file); - return 0; + return ret; } -int dfu_start(struct tfm_context *ctx, const char *entity) +struct dfu_entry *dfu_start(struct dfu_context *ctx, + uint64_t size, const char *filename) { - unsigned long size = ctx->thor_file_size; - int idx, ret; - idx = find_match(entity); - if (idx < 0) { - fprintf(stderr, "Cannot find dfu info for %s\n", entity); - return -EINVAL; - } + struct dfu_entry *e; + char **entry; + int ret; - ret = dfu_start_entity(ctx, idx, size); - if (ret < 0) { - fprintf(stderr, "Cannot start download: %s\n", entity); - return -EINVAL; + entry = find_entry_match(ctx, filename); + if (!entry) { + fprintf(stderr, "Cannot find dfu info for %s\n", filename); + return NULL; } - fprintf(stdout, "Start download: %s...", entity); - fflush(stdout); + e = (struct dfu_entry *)malloc(sizeof(*e)); + if (!e) + return NULL; - return 0; -} + ret = dfu_start_entry(e, entry, size); + if (ret < 0) { + fprintf(stderr, "Cannot start download: %s\n", filename); + free(e); + return NULL; + } -static void dfu_thread_cleanup(void *ptr) -{ - struct tfm_context *ctx = ptr; - struct dfu_frame *frame; + pthread_create(&ctx->thread, NULL, dfu_thread_main, e); - while (!TAILQ_EMPTY(&ctx->dfu_ioq_head)) { - frame = TAILQ_FIRST(&ctx->dfu_ioq_head); + e->ctx = ctx; - TAILQ_REMOVE(&ctx->dfu_ioq_head, frame, entry); + fprintf(stdout, "Start download: %s...", filename); + fflush(stdout); - dfu_put_buffer(frame->buf); - free(frame); - } + return e; } -static void *dfu_thread_main(void *ptr) +void dfu_sync(struct dfu_entry *e) { - struct tfm_context *ctx = ptr; - struct dfu_frame *frame; - int state = DFU_THREAD_STATE_IDLE; - uint64_t progress = 0; - int ret; - - pthread_cleanup_push(dfu_thread_cleanup, ptr); - - while (state != DFU_THREAD_STATE_ERROR) { - pthread_mutex_lock(&ctx->dfu_mutex); - - while (TAILQ_EMPTY(&ctx->dfu_ioq_head)) { - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - state = DFU_THREAD_STATE_IDLE; - pthread_cond_wait(&ctx->dfu_data_arrive, &ctx->dfu_mutex); - } - - if (state == DFU_THREAD_STATE_IDLE) { - state = DFU_THREAD_STATE_FLASHING; - pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); - } - - frame = TAILQ_FIRST(&ctx->dfu_ioq_head); - - TAILQ_REMOVE(&ctx->dfu_ioq_head, frame, entry); - - pthread_mutex_unlock(&ctx->dfu_mutex); + struct dfu_context *ctx = e->ctx; + char **info = e->entry; - ret = write(ctx->dfu_fd, frame->buf, frame->len); - - if (ret < frame->len) { - fprintf(stderr, "Error occurs while flashing\n"); - state = DFU_THREAD_STATE_ERROR; - } + pthread_mutex_lock(&ctx->sync_mutex); + if (!e->transfer_done) + pthread_cond_wait(&ctx->write_done, &ctx->sync_mutex); + pthread_mutex_unlock(&ctx->sync_mutex); - progress += frame->len; - - fprintf(stdout, "#"); - fflush(stdout); - - dfu_put_buffer(frame->buf); - free(frame); - - /* transfer finished */ - if (state != DFU_THREAD_STATE_ERROR && progress >= ctx->thor_file_size) { - progress = 0; - ctx->transfer_done = 1; - - fprintf(stdout, "\nTransfer completed. Please wait for sync..."); - fflush(stdout); - - state = DFU_THREAD_STATE_IDLE; - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); - - pthread_cond_signal(&ctx->dfu_write_done); - - pthread_mutex_lock(&ctx->dfu_sync_mutex); - pthread_cond_wait(&ctx->dfu_sync_done, - &ctx->dfu_sync_mutex); - pthread_mutex_unlock(&ctx->dfu_sync_mutex); - } + switch (*info[DFU_INFO_MODE]) { + case DFU_INFO_MODE_FILE: + fsync(e->fd); + close(e->fd); + umount_dev(); + break; + case DFU_INFO_MODE_PARTITION: + close(e->fd); + break; + default: + break; } - pthread_cleanup_pop(1); + pthread_cond_signal(&ctx->sync_done); - return NULL; + fprintf(stdout, "finished\n"); } static int parse_dfu_info(char *buf, char **info) @@ -388,36 +445,35 @@ static int parse_dfu_info(char *buf, char **info) return 0; } -static void destroy_dfu_info(void) +static void destroy_dfu_info(struct dfu_context *ctx) { int i, j; - for (i = 0; i < DFU_INFO_NUM; i++) { + for (i = 0; i < DFU_ENTRY_LIST_MAXLEN; i++) { for (j = 0; j < DFU_INFO_MAX; j++) - if (dfu_info[i][j]) { - free(dfu_info[i][j]); - dfu_info[i][j] = NULL; + if (ctx->dfu_entry_list[i][j]) { + free(ctx->dfu_entry_list[i][j]); + ctx->dfu_entry_list[i][j] = NULL; } } } - -static int init_dfu_info(const char *dfu_info_file) +int dfu_init_entry(struct dfu_context *ctx, const char *entry_file) { FILE *fp; char buf[1024]; int i = 0; int ret; - fp = fopen(dfu_info_file, "r"); + fp = fopen(entry_file, "r"); if (!fp) return -ENOENT; - while (i < DFU_INFO_NUM && !feof(fp)) { + while (i < DFU_ENTRY_LIST_MAXLEN && !feof(fp)) { if (fgets(buf, 1024, fp) == NULL) break; - ret = parse_dfu_info(buf, dfu_info[i++]); + ret = parse_dfu_info(buf, ctx->dfu_entry_list[i++]); if (ret < 0) { fprintf(stderr, "cannot parse dfu info"); goto err_free_all; @@ -430,45 +486,39 @@ static int init_dfu_info(const char *dfu_info_file) err_free_all: fclose(fp); - destroy_dfu_info(); + destroy_dfu_info(ctx); return ret; } -int dfu_init(struct tfm_context *ctx, const char *dfu_info_file) +struct dfu_context *dfu_alloc_context(void) { - int ret; + struct dfu_context *ctx; - ret = init_dfu_info(dfu_info_file); - if (ret < 0) { - fprintf(stderr, "failed to get flash entries\n"); - return ret; - } + ctx = (struct dfu_context *)malloc(sizeof(*ctx)); + if (!ctx) + return NULL; - TAILQ_INIT(&ctx->dfu_ioq_head); + ctx->thread = 0; + TAILQ_INIT(&ctx->ioq); - pthread_mutex_init(&ctx->dfu_mutex, NULL); - pthread_mutex_init(&ctx->dfu_sync_mutex, NULL); - pthread_cond_init(&ctx->dfu_data_arrive, NULL); - pthread_cond_init(&ctx->dfu_write_done, NULL); - pthread_cond_init(&ctx->dfu_sync_done, NULL); + pthread_mutex_init(&ctx->mutex, NULL); + pthread_mutex_init(&ctx->sync_mutex, NULL); + pthread_cond_init(&ctx->data_arrived, NULL); + pthread_cond_init(&ctx->write_done, NULL); + pthread_cond_init(&ctx->sync_done, NULL); - ret = pthread_create(&ctx->dfu_thread, NULL, dfu_thread_main, ctx); - if (ret < 0) { - fprintf(stderr, "failed to create thread for dfu\n"); - return ret; - } + memset(ctx->dfu_entry_list, 0, sizeof(ctx->dfu_entry_list)); - return 0; + return ctx; } -void dfu_exit(struct tfm_context *ctx) +void dfu_free_context(struct dfu_context *ctx) { - pthread_cancel(ctx->dfu_thread); - pthread_join(ctx->dfu_thread, NULL); - destroy_dfu_info(); - if (ctx->connect) { - free(ctx->connect); - ctx->connect = NULL; - } + if (!ctx) + return; + + pthread_cancel(ctx->thread); + destroy_dfu_info(ctx); + free(ctx); } diff --git a/src/dfu.h b/src/dfu.h index 589a9a1..0d35883 100644 --- a/src/dfu.h +++ b/src/dfu.h @@ -18,41 +18,27 @@ #define __DFU_H #include -#include "tfm.h" +#include -#define DFU_DELIMITER " :,\t\n" -#define DFU_INFO_NUM 100 -#define DFU_MOUNT_PATH "/mnt/tfm-temp" +struct dfu_context; -#define DFU_INFO_MODE_PARTITION 'p' -#define DFU_INFO_MODE_FILE 'f' - -enum dfu_info_entry { - DFU_INFO_MODE = 0, - DFU_INFO_PARTITION, - DFU_INFO_NAME, - DFU_INFO_PATH, - DFU_INFO_MAX, -}; - -enum dfu_thread_state { - DFU_THREAD_STATE_ERROR = -1, - DFU_THREAD_STATE_IDLE, - DFU_THREAD_STATE_FLASHING, -}; - -struct dfu_frame { - void *buf; - unsigned long len; - TAILQ_ENTRY(dfu_frame) entry; +struct dfu_entry { + struct dfu_context *ctx; + char **entry; + int fd; + uint64_t file_size; + int transfer_done; }; void *dfu_get_buffer(unsigned long size); void dfu_put_buffer(void *ptr); -int dfu_init(struct tfm_context *ctx, const char *dfu_info_file); -void dfu_exit(struct tfm_context *ctx); -int dfu_start(struct tfm_context *ctx, const char *entity); -int dfu_request_io(struct tfm_context *ctx, unsigned long len); -void dfu_sync(struct tfm_context *ctx); +struct dfu_context *dfu_alloc_context(void); +void dfu_free_context(struct dfu_context *ctx); +int dfu_init_entry(struct dfu_context *ctx, const char *entry_file); +struct dfu_entry *dfu_start(struct dfu_context *ctx, + uint64_t size, const char *filename); +void dfu_sync(struct dfu_entry *e); +int dfu_request_io(struct dfu_entry *e, void *buffer, unsigned long len); + #endif diff --git a/src/main.c b/src/main.c index 32c2473..376d8be 100644 --- a/src/main.c +++ b/src/main.c @@ -25,12 +25,13 @@ int _main(int argc, char *argv[]) { - struct tfm_context ctx; + struct tfm_context tfm; + struct dfu_context *dfu; const char *part_table = "/usr/share/partition.info"; char *opt_table = NULL; int ret, opt; - memset(&ctx, 0, sizeof(ctx)); + memset(&tfm, 0, sizeof(tfm)); while ((opt = getopt(argc, argv, "p:i:")) != -1) { switch (opt) { @@ -65,7 +66,7 @@ int _main(int argc, char *argv[]) ret = -1; goto out_optfree; } - ctx.port = (int)val; + tfm.port = (int)val; break; } default: @@ -74,35 +75,41 @@ int _main(int argc, char *argv[]) } } - ret = dfu_init(&ctx, part_table); - if (ret < 0) { + dfu = dfu_alloc_context(); + if (!dfu) { ret = -1; goto out_optfree; } - ret = net_connect(&ctx); + ret = dfu_init_entry(dfu, part_table); + if (ret < 0) { + ret = -1; + goto out_dfuexit; + } + + ret = net_connect(&tfm); if (ret < 0) { ret = -1; goto out_dfuexit; } - ret = thor_init(&ctx); + ret = thor_setup(&tfm); if (ret < 0) { ret = -1; goto out_netdisconn; } - ret = thor_process(&ctx); + ret = thor_process(&tfm, dfu); if (ret < 0) { ret = -1; goto out_netdisconn; } out_netdisconn: - net_disconnect(&ctx); + net_disconnect(&tfm); out_dfuexit: - dfu_exit(&ctx); + dfu_free_context(dfu); out_optfree: if (opt_table) diff --git a/src/tfm.h b/src/tfm.h index 747de2d..8760e35 100644 --- a/src/tfm.h +++ b/src/tfm.h @@ -19,9 +19,10 @@ #include #include -#include #include +#include "dfu.h" + struct tfm_connect { int fd; ssize_t (*rx_data)(int fd, void *buf, ssize_t len); @@ -29,26 +30,11 @@ struct tfm_connect { }; struct tfm_context { - char **dfu_info; - int dfu_fd; - pthread_t dfu_thread; - pthread_mutex_t dfu_mutex; - pthread_mutex_t dfu_sync_mutex; - pthread_cond_t dfu_data_arrive; - pthread_cond_t dfu_write_done; - pthread_cond_t dfu_sync_done; - TAILQ_HEAD(tailhead, dfu_frame) dfu_ioq_head; - struct tfm_connect *connect; - uint64_t thor_file_size; - uint64_t remain; - void *transfer_buffer; - int transfer_done; - int port; }; -int thor_init(struct tfm_context *ctx); -int thor_process(struct tfm_context *ctx); +int thor_setup(struct tfm_context *tfm); +int thor_process(struct tfm_context *tfm, struct dfu_context *dfu); #endif diff --git a/src/thor.c b/src/thor.c index e19d33f..1c255d2 100644 --- a/src/thor.c +++ b/src/thor.c @@ -26,18 +26,20 @@ #include #include +#include "tfm.h" #include "dfu.h" #include "thor-proto.h" -static inline ssize_t thor_rx_data(struct tfm_connect *conn, void *buf, ssize_t len) -{ - return conn->rx_data(conn->fd, buf, len); -} +struct thor_context { + struct rqt_pkt *rqt; + struct tfm_connect *intf; + struct dfu_context *dfu; + struct dfu_entry *dfu_entry; -static inline ssize_t thor_tx_data(struct tfm_connect *conn, void *buf, ssize_t len) -{ - return conn->tx_data(conn->fd, buf, len); -} + void *buffer; + uint64_t file_size; + uint64_t remain; +}; static unsigned int _checkboard(void) { @@ -48,19 +50,21 @@ static unsigned int _checkboard(void) return -1; } -static int thor_send_rsp(struct tfm_connect *conn, const struct res_pkt *rsp) +static int thor_send_rsp(struct thor_context *tctx, struct res_pkt *rsp) { + struct tfm_connect *intf = tctx->intf; ssize_t n; - n = thor_tx_data(conn, (void *)rsp, RES_PKT_SIZE); + n = intf->tx_data(intf->fd, (void *)rsp, RES_PKT_SIZE); if (n < sizeof(*rsp)) return -EIO; return 0; } -static int thor_process_rqt_info(struct tfm_context *ctx, struct rqt_pkt *rqt) +static int thor_process_rqt_info(struct thor_context *tctx) { + struct rqt_pkt *rqt = tctx->rqt; struct res_pkt rsp; int ret; @@ -89,7 +93,7 @@ static int thor_process_rqt_info(struct tfm_context *ctx, struct rqt_pkt *rqt) return -EINVAL; } - ret = thor_send_rsp(ctx->connect, &rsp); + ret = thor_send_rsp(tctx, &rsp); if (ret < 0) { fprintf(stderr, "failed to send response of REQUEST_INFO\n"); return ret; @@ -98,9 +102,9 @@ static int thor_process_rqt_info(struct tfm_context *ctx, struct rqt_pkt *rqt) return 0; } -static int thor_process_rqt_cmd(struct tfm_context *ctx, struct rqt_pkt *rqt) +static int thor_process_rqt_cmd(struct thor_context *tctx) { - struct tfm_connect *conn = ctx->connect; + struct rqt_pkt *rqt = tctx->rqt; struct res_pkt rsp; int ret; @@ -111,7 +115,7 @@ static int thor_process_rqt_cmd(struct tfm_context *ctx, struct rqt_pkt *rqt) switch (rqt->sub_id) { case RQT_CMD_REBOOT: - thor_send_rsp(conn, &rsp); + thor_send_rsp(tctx, &rsp); ret = reboot(RB_AUTOBOOT); if (ret < 0) { @@ -120,7 +124,7 @@ static int thor_process_rqt_cmd(struct tfm_context *ctx, struct rqt_pkt *rqt) } break; case RQT_CMD_POWEROFF: - thor_send_rsp(conn, &rsp); + thor_send_rsp(tctx, &rsp); break; default: fprintf(stderr, "Not supported command request: %d", @@ -131,29 +135,32 @@ static int thor_process_rqt_cmd(struct tfm_context *ctx, struct rqt_pkt *rqt) return 0; } -static void thor_send_data_rsp(struct tfm_connect *conn, int ack, int count) +static void thor_send_data_rsp(struct thor_context *tctx, int ack, int count) { + struct tfm_connect *intf = tctx->intf; struct data_res_pkt rsp; rsp.ack = ack; rsp.cnt = count; - thor_tx_data(conn, &rsp, DATA_RES_PKT_SIZE); + intf->tx_data(intf->fd, &rsp, DATA_RES_PKT_SIZE); } -static int thor_download_head(struct tfm_context *ctx, unsigned int packet_size) +static int +thor_download_head(struct thor_context *tctx, unsigned int packet_size) { - struct tfm_connect *conn = ctx->connect; + struct tfm_connect *intf = tctx->intf; + struct dfu_entry *e = tctx->dfu_entry; uint64_t recv = 0; - uint64_t total = ctx->thor_file_size; + uint64_t total = tctx->file_size; void *buf; int usb_pkt_cnt = 0, n; int ret; - ctx->transfer_buffer = buf = dfu_get_buffer(FLASH_UNIT_SIZE); + tctx->buffer = buf = dfu_get_buffer(FLASH_UNIT_SIZE); while (total - recv >= packet_size) { - n = thor_rx_data(conn, buf, packet_size); + n = intf->rx_data(intf->fd, buf, packet_size); if (n < packet_size) return -EIO; @@ -162,52 +169,52 @@ static int thor_download_head(struct tfm_context *ctx, unsigned int packet_size) buf += packet_size; if ((recv % FLASH_UNIT_SIZE) == 0) { - ret = dfu_request_io(ctx, FLASH_UNIT_SIZE); + ret = dfu_request_io(e, tctx->buffer, FLASH_UNIT_SIZE); if (ret < 0) return -EIO; - ctx->transfer_buffer = buf = dfu_get_buffer(FLASH_UNIT_SIZE); + tctx->buffer = buf = dfu_get_buffer(FLASH_UNIT_SIZE); } - thor_send_data_rsp(conn, 0, ++usb_pkt_cnt); + thor_send_data_rsp(tctx, 0, ++usb_pkt_cnt); } - ctx->remain = (total - recv) + (uint64_t)(buf - ctx->transfer_buffer); + tctx->remain = (total - recv) + (uint64_t)(buf - tctx->buffer); if ((total - recv) > 0) { - n = thor_rx_data(conn, buf, packet_size); + n = intf->rx_data(intf->fd, buf, packet_size); if (n < packet_size) return -EIO; recv += n; - thor_send_data_rsp(conn, 0, ++usb_pkt_cnt); + thor_send_data_rsp(tctx, 0, ++usb_pkt_cnt); } return 0; } -static int thor_download_tail(struct tfm_context *ctx) +static int thor_download_tail(struct thor_context *tctx) { + struct dfu_entry *e = tctx->dfu_entry; int ret; - if (ctx->remain) { - ret = dfu_request_io(ctx, ctx->remain); + if (tctx->remain) { + ret = dfu_request_io(e, tctx->buffer, tctx->remain); if (ret < 0) return -EIO; } else { /* if there is no remain, buffer should be freed */ - dfu_put_buffer(ctx->transfer_buffer); + dfu_put_buffer(tctx->buffer); } - dfu_sync(ctx); + dfu_sync(e); return 0; } -static int thor_process_rqt_download(struct tfm_context *ctx, struct rqt_pkt *rqt) +static int thor_process_rqt_download(struct thor_context *tctx) { - struct tfm_connect *conn = ctx->connect; - char f_name[FILE_NAME_MAXLEN + 1] = {0,}; + struct rqt_pkt *rqt = tctx->rqt; struct res_pkt rsp; - int ret = 0, head, file_type; + int ret = 0; memset(&rsp, 0, RES_PKT_SIZE); @@ -216,10 +223,16 @@ static int thor_process_rqt_download(struct tfm_context *ctx, struct rqt_pkt *rq switch (rqt->sub_id) { case RQT_DL_INIT: - ctx->thor_file_size = (uint64_t)rqt->int_data[0] + tctx->file_size = (uint64_t)rqt->int_data[0] + ((uint64_t)rqt->int_data[1] << 32); break; case RQT_DL_FILE_INFO: + { + struct dfu_context *dfu = tctx->dfu; + struct dfu_entry *e; + char f_name[FILE_NAME_MAXLEN + 1] = {0,}; + int file_type; + file_type = rqt->int_data[0]; if (file_type != BINARY_TYPE_NORMAL) { fprintf(stderr, "Currently only NORMAL_FILE is supported\n"); @@ -227,34 +240,45 @@ static int thor_process_rqt_download(struct tfm_context *ctx, struct rqt_pkt *rq break; } - ctx->thor_file_size = (uint64_t)rqt->int_data[1] + tctx->file_size = (uint64_t)rqt->int_data[1] + ((uint64_t)rqt->int_data[2] << 32); + memcpy(f_name, rqt->str_data[0], FILE_NAME_MAXLEN); rsp.int_data[0] = DATA_PKT_SIZE; - ret = dfu_start(ctx, f_name); - if (ret < 0) { + e = dfu_start(dfu, tctx->file_size, f_name); + if (!e) { fprintf(stderr, "failed to start dfu\n"); ret = -EINVAL; } + + tctx->dfu_entry = e; break; + } case RQT_DL_FILE_START: - ret = thor_send_rsp(conn, &rsp); + ret = thor_send_rsp(tctx, &rsp); if (ret < 0) { fprintf(stderr, "failed to send response\n"); ret = rsp.ack = -EINVAL; break; } - head = thor_download_head(ctx, DATA_PKT_SIZE); - if (head < 0) - ctx->remain = 0; + ret = thor_download_head(tctx, DATA_PKT_SIZE); + if (ret < 0) + tctx->remain = 0; - return head; + return ret; case RQT_DL_FILE_END: - rsp.ack = thor_download_tail(ctx); + rsp.ack = thor_download_tail(tctx); ret = rsp.ack; - ctx->remain = 0; + tctx->remain = 0; + tctx->file_size = 0; + /* + * dfu_entry and buffer will be freed by dfu_thread_cleanup, + * so just make it NULL here. + */ + tctx->dfu_entry = NULL; + tctx->buffer = NULL; break; case RQT_DL_EXIT: break; @@ -264,23 +288,24 @@ static int thor_process_rqt_download(struct tfm_context *ctx, struct rqt_pkt *rq ret = -EINVAL; } - thor_send_rsp(conn, &rsp); + thor_send_rsp(tctx, &rsp); return ret; } -static int thor_do_request(struct tfm_context *ctx, struct rqt_pkt *rqt) +static int thor_do_request(struct thor_context *tctx) { + struct rqt_pkt *rqt = tctx->rqt; int ret; switch (rqt->id) { case RQT_INFO: - ret = thor_process_rqt_info(ctx, rqt); + ret = thor_process_rqt_info(tctx); break; case RQT_CMD: - ret = thor_process_rqt_cmd(ctx, rqt); + ret = thor_process_rqt_cmd(tctx); break; case RQT_DL: - ret = thor_process_rqt_download(ctx, rqt); + ret = thor_process_rqt_download(tctx); break; case RQT_UL: fprintf(stderr, "Request \"UPLOAD\" is not supported\n"); @@ -294,17 +319,17 @@ static int thor_do_request(struct tfm_context *ctx, struct rqt_pkt *rqt) return ret; } -static int thor_handshake(struct tfm_connect *conn) +static int thor_handshake(struct tfm_connect *intf) { char buf[5]; ssize_t n; - n = thor_rx_data(conn, buf, 4/* strlen("THOR") */); + n = intf->rx_data(intf->fd, buf, 4/* strlen("THOR") */); if (n < 4) return -EIO; if (!strncmp(buf, "THOR", 4)) { - n = thor_tx_data(conn, "ROHT", 4); + n = intf->tx_data(intf->fd, "ROHT", 4); if (n < 4) return -EIO; } else { @@ -315,20 +340,21 @@ static int thor_handshake(struct tfm_connect *conn) return 0; } -int thor_init(struct tfm_context *ctx) +int thor_process(struct tfm_context *tfm, struct dfu_context *dfu) { - return thor_handshake(ctx->connect); -} - -int thor_process(struct tfm_context *ctx) -{ - struct tfm_connect *conn = ctx->connect; + struct tfm_connect *intf = tfm->connect; + struct thor_context tctx; struct rqt_pkt rqt; ssize_t n; int ret; + memset(&tctx, 0, sizeof(tctx)); + + tctx.intf = intf; + tctx.dfu = dfu; + for (;;) { - n = thor_rx_data(conn, &rqt, RQT_PKT_SIZE); + n = intf->rx_data(intf->fd, &rqt, RQT_PKT_SIZE); if (n < sizeof(rqt)) { fprintf(stderr, "Failed to receive data from the host(%zd:%zu)", @@ -336,10 +362,22 @@ int thor_process(struct tfm_context *ctx) return -EIO; } - ret = thor_do_request(ctx, &rqt); + tctx.rqt = &rqt; + + ret = thor_do_request(&tctx); if (ret < 0) return ret; } return 0; } + +int thor_setup(struct tfm_context *tfm) +{ + if (!tfm->connect) { + fprintf(stderr, "Invalid connection\n"); + return -EINVAL; + } + + return thor_handshake(tfm->connect); +} -- 2.7.4 From 5df0e1d2947d87e15492f3fe103dcd4d68992beb Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Tue, 17 Mar 2020 13:36:02 +0900 Subject: [PATCH 14/16] interface: Add support for multiple transfer interfaces To support USB connection, multiple interface f/w should be required before. This adds only interface f/w, so network connection is still processed without f/w. Change-Id: I367f9e961daefe3b9005104084955edbe0851057 Signed-off-by: Dongwoo Lee --- CMakeLists.txt | 2 +- src/interface.c | 222 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/interface.h | 70 ++++++++++++++++++ 3 files changed, 293 insertions(+), 1 deletion(-) create mode 100644 src/interface.c create mode 100644 src/interface.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c722f06..9fcc572 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ SET(CMAKE_EXE_LINKER_FLAGS "-pie") FIND_PACKAGE(Threads REQUIRED) -ADD_EXECUTABLE(${PROJECT_NAME} src/main.c src/thor.c src/dfu.c src/net.c) +ADD_EXECUTABLE(${PROJECT_NAME} src/main.c src/thor.c src/dfu.c src/interface.c src/net.c) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/src) diff --git a/src/interface.c b/src/interface.c new file mode 100644 index 0000000..de6f559 --- /dev/null +++ b/src/interface.c @@ -0,0 +1,222 @@ +/* + * flash-manager - Tizen kernel-level image flashing solution + * + * 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 +#include +#include +#include +#include +#include + +#include "tfm.h" +#include "interface.h" + +struct tfm_interface_context { + struct tfm_interface *connected; + + pthread_mutex_t mutex; + pthread_cond_t signal; + + LIST_HEAD(intflist, tfm_interface) interface_list; +}; + +INTERFACE interface_avail_list = LIST_HEAD_INITIALIZER(interface_avail_list); + +ssize_t tfm_interface_send(struct tfm_interface *intf, void *buf, ssize_t len) +{ + if (!intf) + return -EINVAL; + + if (intf->ops && intf->ops->tx_data) + return intf->ops->tx_data(intf->txd, buf, len); + + return -ENOENT; +} + +ssize_t tfm_interface_recv(struct tfm_interface *intf, void *buf, ssize_t len) +{ + if (!intf) + return -EINVAL; + + if (intf->ops && intf->ops->rx_data) + return intf->ops->rx_data(intf->rxd, buf, len); + + return -ENOENT; +} + +int tfm_interface_set_private(struct tfm_interface_context *ictx, + char *name, void *data) +{ + struct tfm_interface *intf = NULL; + + LIST_FOREACH(intf, &ictx->interface_list, entry) { + if (!strncmp(intf->name, name, strlen(name))) + break; + } + + if (!intf) { + fprintf(stderr, "cannot find interface: %s\n", name); + return -ENOENT; + } + + intf->priv = data; + + return 0; +} + +static void *connect_thread_main(void *ptr) +{ + struct tfm_interface *intf = ptr; + struct tfm_interface_context *ictx = intf->ctx; + int ret; + + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + + /* for checking which interface is connected */ + intf->tid = pthread_self(); + + if (!intf->ops || !intf->ops->connect || !intf->ops->disconnect) + return NULL; + + ret = intf->ops->connect(intf); + if (ret < 0) { + fprintf(stderr, "failed to connect: %s\n", intf->name); + return NULL; + } + + pthread_mutex_lock(&ictx->mutex); + if (ictx->connected) { + pthread_mutex_unlock(&ictx->mutex); + fprintf(stderr, + "interface %s will be ignored due to %s\n", + intf->name, ictx->connected->name); + intf->ops->disconnect(intf); + return NULL; + } + + ictx->connected = intf; + pthread_mutex_unlock(&ictx->mutex); + + fprintf(stdout, "interface %s is connected.\n", intf->name); + + pthread_cond_signal(&ictx->signal); + + return NULL; +} + +struct tfm_interface *tfm_interface_connect(struct tfm_interface_context *ictx) +{ + struct tfm_interface *intf; + + LIST_FOREACH(intf, &ictx->interface_list, entry) { + pthread_t t; + + pthread_create(&t, NULL, connect_thread_main, (void *)intf); + pthread_detach(t); + } + + pthread_mutex_lock(&ictx->mutex); + while (!ictx->connected) + pthread_cond_wait(&ictx->signal, &ictx->mutex); + pthread_mutex_unlock(&ictx->mutex); + + LIST_FOREACH(intf, &ictx->interface_list, entry) { + /* Terminate threads waiting for other connection */ + if (intf != ictx->connected) { + intf->ctx = NULL; + pthread_cancel(intf->tid); + } + } + + return ictx->connected; +} + +void tfm_interface_disconnect(struct tfm_interface *intf) +{ + if (!intf) + return; + + if (intf->ops && intf->ops->disconnect) + intf->ops->disconnect(intf); + + intf->ctx->connected = NULL; +} + +static void destroy_interface_list(struct tfm_interface_context *ictx) +{ + struct tfm_interface *intf, *temp; + + intf = LIST_FIRST(&ictx->interface_list); + while (intf != NULL) { + temp = intf; + intf = LIST_NEXT(intf, entry); + + LIST_REMOVE(temp, entry); + free(temp); + } +} + +struct tfm_interface_context *tfm_interface_init(void) +{ + struct tfm_interface_context *ictx; + struct tfm_interface_driver *driver; + + ictx = (struct tfm_interface_context *)malloc(sizeof(*ictx)); + if (!ictx) + return NULL; + + ictx->connected = NULL; + + pthread_mutex_init(&ictx->mutex, NULL); + pthread_cond_init(&ictx->signal, NULL); + + LIST_INIT(&ictx->interface_list); + + LIST_FOREACH(driver, &interface_avail_list, entry) { + struct tfm_interface *intf; + + intf = (struct tfm_interface *)malloc(sizeof(*intf)); + if (!intf) + goto err; + + intf->name = driver->name; + intf->rxd = intf->txd = -1; + intf->ops = &driver->ops; + intf->priv = NULL; + intf->tid = 0; + intf->ctx = ictx; + + LIST_INSERT_HEAD(&ictx->interface_list, intf, entry); + } + + return ictx; + +err: + destroy_interface_list(ictx); + free(ictx); + + return NULL; +} + +void tfm_interface_exit(struct tfm_interface_context *ictx) +{ + if (!ictx) + return; + + tfm_interface_disconnect(ictx->connected); + destroy_interface_list(ictx); + free(ictx); +} diff --git a/src/interface.h b/src/interface.h new file mode 100644 index 0000000..7bb9c02 --- /dev/null +++ b/src/interface.h @@ -0,0 +1,70 @@ +/* + * flash-manager - Tizen kernel-level image flashing solution + * + * 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. + */ + +#ifndef __INTERFACE_H +#define __INTERFACE_H + +#include +#include +#include + +typedef LIST_HEAD(availlist, tfm_interface_driver) INTERFACE; + +#define INTERFACE_REGISTER(_intf) extern INTERFACE interface_avail_list; \ +static void __attribute__ ((constructor)) tfm_##_intf##_interface_init(void) \ +{ \ + LIST_INSERT_HEAD(&interface_avail_list, &_intf, entry); \ +} + +struct tfm_interface_context; +struct tfm_interface; + +struct tfm_interface_ops { + int (*connect)(struct tfm_interface *intf); + int (*disconnect)(struct tfm_interface *intf); + ssize_t (*rx_data)(int fd, void *buf, ssize_t len); + ssize_t (*tx_data)(int fd, void *buf, ssize_t len); +}; + +struct tfm_interface_driver { + char *name; + struct tfm_interface_ops ops; + + LIST_ENTRY(tfm_interface_driver) entry; +}; + +struct tfm_interface { + char *name; + int rxd; + int txd; + struct tfm_interface_ops *ops; + + void *priv; + pthread_t tid; + struct tfm_interface_context *ctx; + + LIST_ENTRY(tfm_interface) entry; +}; + +ssize_t tfm_interface_send(struct tfm_interface *intf, void *buf, ssize_t len); +ssize_t tfm_interface_recv(struct tfm_interface *intf, void *buf, ssize_t len); +int tfm_interface_set_private(struct tfm_interface_context *ictx, + char *name, void *data); +struct tfm_interface *tfm_interface_connect(struct tfm_interface_context *ictx); +void tfm_interface_disconnect(struct tfm_interface *intf); +struct tfm_interface_context *tfm_interface_init(void); +void tfm_interface_exit(struct tfm_interface_context *ictx); +#endif -- 2.7.4 From bfa980fadb2273fb752ea4b45f4177cd012065e2 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Tue, 17 Mar 2020 13:42:38 +0900 Subject: [PATCH 15/16] interface: net: Apply interface f/w into network transfer Since this, network connection is processed upon interface f/w. Change-Id: I87df71a923f010bb013e0b4166c50949bb19a153 Signed-off-by: Dongwoo Lee --- src/main.c | 37 +++++++++++++++++++------------ src/net.c | 74 +++++++++++++++++++++++++++++++++----------------------------- src/net.h | 27 ----------------------- src/tfm.h | 18 +++------------ src/thor.c | 34 ++++++++++++++--------------- 5 files changed, 83 insertions(+), 107 deletions(-) delete mode 100644 src/net.h diff --git a/src/main.c b/src/main.c index 376d8be..141f165 100644 --- a/src/main.c +++ b/src/main.c @@ -20,18 +20,24 @@ #include #include +#include "tfm.h" #include "dfu.h" -#include "net.h" +#include "interface.h" int _main(int argc, char *argv[]) { - struct tfm_context tfm; + struct tfm_interface_context *supported_interfaces; struct dfu_context *dfu; + struct tfm_interface *intf; const char *part_table = "/usr/share/partition.info"; char *opt_table = NULL; int ret, opt; - memset(&tfm, 0, sizeof(tfm)); + supported_interfaces = tfm_interface_init(); + if (!supported_interfaces) { + ret = -1; + goto out; + } while ((opt = getopt(argc, argv, "p:i:")) != -1) { switch (opt) { @@ -45,13 +51,13 @@ int _main(int argc, char *argv[]) } else { fprintf(stderr, "Out of memory\n"); ret = -1; - goto out; + goto out_intfexit; } } else { fprintf(stderr, "path should be specified with '-i'\n"); ret = -1; - goto out; + goto out_intfexit; } break; case 'p': @@ -66,7 +72,8 @@ int _main(int argc, char *argv[]) ret = -1; goto out_optfree; } - tfm.port = (int)val; + tfm_interface_set_private(supported_interfaces, + "net", (void *)val); break; } default: @@ -87,26 +94,26 @@ int _main(int argc, char *argv[]) goto out_dfuexit; } - ret = net_connect(&tfm); - if (ret < 0) { + intf = tfm_interface_connect(supported_interfaces); + if (!intf) { ret = -1; goto out_dfuexit; } - ret = thor_setup(&tfm); + ret = thor_setup(intf); if (ret < 0) { ret = -1; - goto out_netdisconn; + goto out_disconn; } - ret = thor_process(&tfm, dfu); + ret = thor_process(intf, dfu); if (ret < 0) { ret = -1; - goto out_netdisconn; + goto out_disconn; } -out_netdisconn: - net_disconnect(&tfm); +out_disconn: + tfm_interface_disconnect(intf); out_dfuexit: dfu_free_context(dfu); @@ -114,6 +121,8 @@ out_dfuexit: out_optfree: if (opt_table) free(opt_table); +out_intfexit: + tfm_interface_exit(supported_interfaces); out: exit(ret); diff --git a/src/net.c b/src/net.c index b946fa4..9de6741 100644 --- a/src/net.c +++ b/src/net.c @@ -23,80 +23,86 @@ #include #include -#include "net.h" +#include "tfm.h" +#include "interface.h" -static ssize_t net_rx_data(int sock, void *buf, ssize_t len) +#define DEFAULT_PORT 23456 + +static ssize_t net_rx_data(int fd, void *buf, ssize_t len) { - return recv(sock, buf, len, MSG_WAITALL); + return recv(fd, buf, len, MSG_WAITALL); } -static ssize_t net_tx_data(int sock, void *buf, ssize_t len) +static ssize_t net_tx_data(int fd, void *buf, ssize_t len) { - return send(sock, buf, len, 0); + return send(fd, buf, len, 0); } -int net_connect(struct tfm_context *ctx) +static int net_connect(struct tfm_interface *intf) { struct sockaddr_in servaddr; - struct tfm_connect *conn; - int listener, sock; - int ret = 0; - - conn = malloc(sizeof(*conn)); - if (!conn) - return -ENOMEM; + int listener, ret = 0; + int port; listener = socket(AF_INET, SOCK_STREAM, 0); if (listener < 0) { fprintf(stderr, "Failed to create socket\n"); - ret = -EINVAL; - goto err_free; + return -EINVAL; } + port = (unsigned long) intf->priv; + if (port <= 1024) + port = DEFAULT_PORT; + + fprintf(stdout, "%s using port: %d\n", intf->name, port); + memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); - servaddr.sin_port = htons((ctx->port ? ctx->port : DEFAULT_PORT)); + servaddr.sin_port = htons(port); ret = bind(listener, (struct sockaddr *) &servaddr, sizeof(servaddr)); if (ret < 0) { fprintf(stderr, "Failed to bind socket\n"); - goto err_socket; + goto err; } ret = listen(listener, 1024); if (ret < 0) { fprintf(stderr, "Failed to call listen\n"); - goto err_socket; + goto err; } - sock = accept(listener, NULL, NULL); - if (sock < 0) { + ret = accept(listener, NULL, NULL); + if (ret < 0) { fprintf(stderr, "Failed to accept connection\n"); - ret = sock; - goto err_socket; + goto err; } - conn->fd = sock; - conn->rx_data = net_rx_data; - conn->tx_data = net_tx_data; - ctx->connect = conn; + intf->rxd = intf->txd = ret; close(listener); return 0; -err_socket: +err: close(listener); -err_free: - free(conn); return ret; } -void net_disconnect(struct tfm_context *ctx) +static int net_disconnect(struct tfm_interface *intf) { - close(ctx->connect->fd); - - free(ctx->connect); - ctx->connect = NULL; + /* since rxd == txd, we close only rxd */ + return close(intf->rxd); } + +static struct tfm_interface_driver network = { + .name = "net", + .ops = { + .connect = net_connect, + .disconnect = net_disconnect, + .rx_data = net_rx_data, + .tx_data = net_tx_data, + }, +}; +INTERFACE_REGISTER(network) diff --git a/src/net.h b/src/net.h deleted file mode 100644 index dc96b4d..0000000 --- a/src/net.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * flash-manager - Tizen kernel-level image flashing solution - * - * 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. - */ - -#ifndef __NET_H -#define __NET_H - -#include "tfm.h" - -#define DEFAULT_PORT 23456 - -int net_connect(struct tfm_context *ctx); -void net_disconnect(struct tfm_context *ctx); - -#endif diff --git a/src/tfm.h b/src/tfm.h index 8760e35..7d18f4e 100644 --- a/src/tfm.h +++ b/src/tfm.h @@ -16,25 +16,13 @@ #ifndef __TFM_H #define __TFM_H - #include #include #include #include "dfu.h" +#include "interface.h" -struct tfm_connect { - int fd; - ssize_t (*rx_data)(int fd, void *buf, ssize_t len); - ssize_t (*tx_data)(int fd, void *buf, ssize_t len); -}; - -struct tfm_context { - struct tfm_connect *connect; - int port; -}; - -int thor_setup(struct tfm_context *tfm); -int thor_process(struct tfm_context *tfm, struct dfu_context *dfu); - +int thor_setup(struct tfm_interface *intf); +int thor_process(struct tfm_interface *intf, struct dfu_context *dfu); #endif diff --git a/src/thor.c b/src/thor.c index 1c255d2..426dd40 100644 --- a/src/thor.c +++ b/src/thor.c @@ -28,11 +28,12 @@ #include "tfm.h" #include "dfu.h" +#include "interface.h" #include "thor-proto.h" struct thor_context { struct rqt_pkt *rqt; - struct tfm_connect *intf; + struct tfm_interface *intf; struct dfu_context *dfu; struct dfu_entry *dfu_entry; @@ -52,10 +53,10 @@ static unsigned int _checkboard(void) static int thor_send_rsp(struct thor_context *tctx, struct res_pkt *rsp) { - struct tfm_connect *intf = tctx->intf; + struct tfm_interface *intf = tctx->intf; ssize_t n; - n = intf->tx_data(intf->fd, (void *)rsp, RES_PKT_SIZE); + n = tfm_interface_send(intf, (void *)rsp, RES_PKT_SIZE); if (n < sizeof(*rsp)) return -EIO; @@ -137,19 +138,19 @@ static int thor_process_rqt_cmd(struct thor_context *tctx) static void thor_send_data_rsp(struct thor_context *tctx, int ack, int count) { - struct tfm_connect *intf = tctx->intf; + struct tfm_interface *intf = tctx->intf; struct data_res_pkt rsp; rsp.ack = ack; rsp.cnt = count; - intf->tx_data(intf->fd, &rsp, DATA_RES_PKT_SIZE); + tfm_interface_send(intf, &rsp, DATA_RES_PKT_SIZE); } static int thor_download_head(struct thor_context *tctx, unsigned int packet_size) { - struct tfm_connect *intf = tctx->intf; + struct tfm_interface *intf = tctx->intf; struct dfu_entry *e = tctx->dfu_entry; uint64_t recv = 0; uint64_t total = tctx->file_size; @@ -160,7 +161,7 @@ thor_download_head(struct thor_context *tctx, unsigned int packet_size) tctx->buffer = buf = dfu_get_buffer(FLASH_UNIT_SIZE); while (total - recv >= packet_size) { - n = intf->rx_data(intf->fd, buf, packet_size); + n = tfm_interface_recv(intf, buf, packet_size); if (n < packet_size) return -EIO; @@ -181,7 +182,7 @@ thor_download_head(struct thor_context *tctx, unsigned int packet_size) tctx->remain = (total - recv) + (uint64_t)(buf - tctx->buffer); if ((total - recv) > 0) { - n = intf->rx_data(intf->fd, buf, packet_size); + n = tfm_interface_recv(intf, buf, packet_size); if (n < packet_size) return -EIO; recv += n; @@ -319,17 +320,17 @@ static int thor_do_request(struct thor_context *tctx) return ret; } -static int thor_handshake(struct tfm_connect *intf) +static int thor_handshake(struct tfm_interface *intf) { char buf[5]; ssize_t n; - n = intf->rx_data(intf->fd, buf, 4/* strlen("THOR") */); + n = tfm_interface_recv(intf, buf, 4/* strlen("THOR") */); if (n < 4) return -EIO; if (!strncmp(buf, "THOR", 4)) { - n = intf->tx_data(intf->fd, "ROHT", 4); + n = tfm_interface_send(intf, "ROHT", 4); if (n < 4) return -EIO; } else { @@ -340,9 +341,8 @@ static int thor_handshake(struct tfm_connect *intf) return 0; } -int thor_process(struct tfm_context *tfm, struct dfu_context *dfu) +int thor_process(struct tfm_interface *intf, struct dfu_context *dfu) { - struct tfm_connect *intf = tfm->connect; struct thor_context tctx; struct rqt_pkt rqt; ssize_t n; @@ -354,7 +354,7 @@ int thor_process(struct tfm_context *tfm, struct dfu_context *dfu) tctx.dfu = dfu; for (;;) { - n = intf->rx_data(intf->fd, &rqt, RQT_PKT_SIZE); + n = tfm_interface_recv(intf, &rqt, RQT_PKT_SIZE); if (n < sizeof(rqt)) { fprintf(stderr, "Failed to receive data from the host(%zd:%zu)", @@ -372,12 +372,12 @@ int thor_process(struct tfm_context *tfm, struct dfu_context *dfu) return 0; } -int thor_setup(struct tfm_context *tfm) +int thor_setup(struct tfm_interface *intf) { - if (!tfm->connect) { + if (!intf) { fprintf(stderr, "Invalid connection\n"); return -EINVAL; } - return thor_handshake(tfm->connect); + return thor_handshake(intf); } -- 2.7.4 From 62c1a507383c0858abf47f1f1ab8472ba42973d6 Mon Sep 17 00:00:00 2001 From: Dongwoo Lee Date: Tue, 17 Mar 2020 13:44:33 +0900 Subject: [PATCH 16/16] tfm: Get rid of unnecessary global header tfm.h Global tfm context is no more used, so global header tfm.h is neither required. This just removes unnecessary header, thus has no functional changes. Change-Id: I69daaaa255dea57676e04bdb0c8145cf4049ed87 Signed-off-by: Dongwoo Lee --- src/interface.c | 1 - src/main.c | 2 +- src/net.c | 2 +- src/thor.c | 1 - src/{tfm.h => thor.h} | 7 ++----- 5 files changed, 4 insertions(+), 9 deletions(-) rename src/{tfm.h => thor.h} (89%) diff --git a/src/interface.c b/src/interface.c index de6f559..69d2084 100644 --- a/src/interface.c +++ b/src/interface.c @@ -21,7 +21,6 @@ #include #include -#include "tfm.h" #include "interface.h" struct tfm_interface_context { diff --git a/src/main.c b/src/main.c index 141f165..0281c30 100644 --- a/src/main.c +++ b/src/main.c @@ -20,7 +20,7 @@ #include #include -#include "tfm.h" +#include "thor.h" #include "dfu.h" #include "interface.h" diff --git a/src/net.c b/src/net.c index 9de6741..6cd8587 100644 --- a/src/net.c +++ b/src/net.c @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include #include @@ -23,7 +24,6 @@ #include #include -#include "tfm.h" #include "interface.h" #define DEFAULT_PORT 23456 diff --git a/src/thor.c b/src/thor.c index 426dd40..6cb6984 100644 --- a/src/thor.c +++ b/src/thor.c @@ -26,7 +26,6 @@ #include #include -#include "tfm.h" #include "dfu.h" #include "interface.h" #include "thor-proto.h" diff --git a/src/tfm.h b/src/thor.h similarity index 89% rename from src/tfm.h rename to src/thor.h index 7d18f4e..7a88006 100644 --- a/src/tfm.h +++ b/src/thor.h @@ -14,11 +14,8 @@ * limitations under the License. */ -#ifndef __TFM_H -#define __TFM_H -#include -#include -#include +#ifndef __THOR_H +#define __THOR_H #include "dfu.h" #include "interface.h" -- 2.7.4