]> granicus.if.org Git - esp-idf/commitdiff
mfg_util: Add changes to mfg_util as per changes in nvs_util
authorShivani Tipnis <shivani@espressif.com>
Mon, 29 Oct 2018 07:49:20 +0000 (13:19 +0530)
committerShivani Tipnis <shivani@espressif.com>
Wed, 3 Apr 2019 06:01:49 +0000 (11:31 +0530)
revert changeson this file

Update README for mfg util

Update to correct coding style of script

16 files changed:
.flake8
components/nvs_flash/nvs_partition_generator/nvs_partition_gen.py
components/nvs_flash/test_nvs_host/test_nvs.cpp
tools/mass_mfg/docs/README.rst
tools/mass_mfg/mfg_gen.py
tools/mass_mfg/samples/sample_config.csv
tools/mass_mfg/samples/sample_values.csv [deleted file]
tools/mass_mfg/samples/sample_values_multipage_blob.csv [new file with mode: 0644]
tools/mass_mfg/samples/sample_values_singlepage_blob.csv [new file with mode: 0644]
tools/mass_mfg/testdata/sample.base64 [new file with mode: 0644]
tools/mass_mfg/testdata/sample.hex [new file with mode: 0644]
tools/mass_mfg/testdata/sample.txt [new file with mode: 0644]
tools/mass_mfg/testdata/sample_blob.bin [new file with mode: 0644]
tools/mass_mfg/testdata/sample_encryption_keys.bin [new file with mode: 0644]
tools/mass_mfg/testdata/sample_multipage_blob.bin [new file with mode: 0644]
tools/mass_mfg/testdata/sample_singlepage_blob.bin [new file with mode: 0644]

diff --git a/.flake8 b/.flake8
index 34bb7118afdff6a17b9932af8fa584c9ebfddd38..51358d9ef2f726250f50d8bd18f3d1cdad0fd32a 100644 (file)
--- a/.flake8
+++ b/.flake8
@@ -159,5 +159,3 @@ exclude =
         components/wifi_provisioning/python/wifi_config_pb2.py,
         components/wifi_provisioning/python/wifi_constants_pb2.py,
         examples/provisioning/custom_config/components/custom_provisioning/python/custom_config_pb2.py,
-    # temporary list (should be empty)
-        tools/mass_mfg/mfg_gen.py,
index 07c9af49eeba2de5103a268b026272b2372373e6..64563869df712449a8c817f3c611b93f00f81b39 100755 (executable)
@@ -501,7 +501,7 @@ class NVS(object):
     def create_new_page(self, is_rsrv_page=False):
         # Update available size as each page is created
         if self.size == 0:
-            raise InsufficientSizeError("Size parameter is is less than the size of data in csv.Please increase size.")
+            raise InsufficientSizeError("Size parameter is less than the size of data in csv.Please increase size.")
         if not is_rsrv_page:
             self.size = self.size - Page.PAGE_PARAMS["max_size"]
         self.page_num += 1
index e97bb6f399b20f02843c30ae991107a9ccbdce8a..7e8699a8cff7401e123f6695a8e2ec6deea5637f 100644 (file)
@@ -2166,6 +2166,7 @@ TEST_CASE("check and read data from partition generated via partition generation
 
     check_nvs_part_gen_args("test", 3, "../nvs_partition_generator/testdata/sample_singlepage_blob.bin", false, NULL);
 
+    childpid = fork();
     if (childpid == 0) {
         exit(execlp("rm", " rm",
                     "-rf",
@@ -2216,6 +2217,7 @@ TEST_CASE("check and read data from partition generated via partition generation
 
     check_nvs_part_gen_args("test", 4, "../nvs_partition_generator/testdata/sample_multipage_blob.bin",false,NULL);
 
+    childpid = fork();
     if (childpid == 0) {
         exit(execlp("rm", " rm",
                     "-rf",
@@ -2228,6 +2230,177 @@ TEST_CASE("check and read data from partition generated via partition generation
     }
 }
 
+TEST_CASE("check and read data from partition generated via manufacturing utility with multipage blob support disabled", "[mfg_gen]")
+{
+    int childpid = fork();
+    int status;
+
+    if (childpid == 0) {
+        exit(execlp("bash", "bash",
+                    "-c",
+                    "rm -rf ../../../tools/mass_mfg/host_test | \
+                    cp -rf ../../../tools/mass_mfg/testdata mfg_testdata | \
+                    cp -rf ../nvs_partition_generator/testdata . | \
+                    mkdir -p ../../../tools/mass_mfg/host_test",NULL));
+    } else {
+        CHECK(childpid > 0);
+        waitpid(childpid, &status, 0);
+        CHECK(WEXITSTATUS(status) != -1);
+
+        childpid = fork();
+        if (childpid == 0) {
+            exit(execlp("python", "python",
+                        "../../../tools/mass_mfg/mfg_gen.py",
+                        "--conf",
+                        "../../../tools/mass_mfg/samples/sample_config.csv",
+                        "--values",
+                        "../../../tools/mass_mfg/samples/sample_values_singlepage_blob.csv",
+                        "--prefix",
+                        "Test",
+                        "--size",
+                        "0x3000",
+                        "--outdir",
+                        "../../../tools/mass_mfg/host_test",
+                        "--version",
+                        "v1",NULL));
+
+        } else {
+            CHECK(childpid > 0);
+            waitpid(childpid, &status, 0);
+            CHECK(WEXITSTATUS(status) != -1);
+
+            childpid = fork();
+            if (childpid == 0) {
+                exit(execlp("python", "python",
+                            "../nvs_partition_generator/nvs_partition_gen.py",
+                            "--input",
+                            "../../../tools/mass_mfg/host_test/csv/Test-1.csv",
+                            "--output",
+                            "../nvs_partition_generator/Test-1-partition.bin",
+                            "--size",
+                            "0x3000",
+                            "--version",
+                            "v1",NULL));
+
+            } else {
+                CHECK(childpid > 0);
+                waitpid(childpid, &status, 0);
+                CHECK(WEXITSTATUS(status) != -1);
+
+            }
+
+        }
+
+    }
+
+    SpiFlashEmulator emu1("../../../tools/mass_mfg/host_test/bin/Test-1.bin");
+    check_nvs_part_gen_args("test", 3, "mfg_testdata/sample_singlepage_blob.bin", false, NULL);
+
+    SpiFlashEmulator emu2("../nvs_partition_generator/Test-1-partition.bin");
+    check_nvs_part_gen_args("test", 3, "testdata/sample_singlepage_blob.bin", false, NULL);
+
+
+    childpid = fork();
+    if (childpid == 0) {
+        exit(execlp("bash", " bash",
+                    "-c",
+                    "rm -rf ../../../tools/mass_mfg/host_test | \
+                    rm -rf mfg_testdata | \
+                    rm -rf testdata",NULL));
+    } else {
+        CHECK(childpid > 0);
+        waitpid(childpid, &status, 0);
+        CHECK(WEXITSTATUS(status) != -1);
+
+    }
+
+}
+
+TEST_CASE("check and read data from partition generated via manufacturing utility with multipage blob support enabled", "[mfg_gen]")
+{
+    int childpid = fork();
+    int status;
+
+    if (childpid == 0) {
+        exit(execlp("bash", " bash",
+                    "-c",
+                    "rm -rf ../../../tools/mass_mfg/host_test | \
+                    cp -rf ../../../tools/mass_mfg/testdata mfg_testdata | \
+                    cp -rf ../nvs_partition_generator/testdata . | \
+                    mkdir -p ../../../tools/mass_mfg/host_test",NULL));
+    } else {
+        CHECK(childpid > 0);
+        waitpid(childpid, &status, 0);
+        CHECK(WEXITSTATUS(status) != -1);
+
+        childpid = fork();
+        if (childpid == 0) {
+            exit(execlp("python", "python",
+                        "../../../tools/mass_mfg/mfg_gen.py",
+                        "--conf",
+                        "../../../tools/mass_mfg/samples/sample_config.csv",
+                        "--values",
+                        "../../../tools/mass_mfg/samples/sample_values_multipage_blob.csv",
+                        "--prefix",
+                        "Test",
+                        "--size",
+                        "0x4000",
+                        "--outdir",
+                        "../../../tools/mass_mfg/host_test",
+                        "--version",
+                        "v2",NULL));
+
+        } else {
+            CHECK(childpid > 0);
+            waitpid(childpid, &status, 0);
+            CHECK(WEXITSTATUS(status) != -1);
+
+            childpid = fork();
+            if (childpid == 0) {
+                exit(execlp("python", "python",
+                            "../nvs_partition_generator/nvs_partition_gen.py",
+                            "--input",
+                            "../../../tools/mass_mfg/host_test/csv/Test-1.csv",
+                            "--output",
+                            "../nvs_partition_generator/Test-1-partition.bin",
+                            "--size",
+                            "0x4000",
+                            "--version",
+                            "v2",NULL));
+
+            } else {
+                CHECK(childpid > 0);
+                waitpid(childpid, &status, 0);
+                CHECK(WEXITSTATUS(status) != -1);
+
+            }
+
+        }
+
+    }
+
+    SpiFlashEmulator emu1("../../../tools/mass_mfg/host_test/bin/Test-1.bin");
+    check_nvs_part_gen_args("test", 4, "mfg_testdata/sample_multipage_blob.bin", false, NULL);
+
+    SpiFlashEmulator emu2("../nvs_partition_generator/Test-1-partition.bin");
+    check_nvs_part_gen_args("test", 4, "testdata/sample_multipage_blob.bin", false, NULL);
+
+    childpid = fork();
+    if (childpid == 0) {
+        exit(execlp("bash", " bash",
+                    "-c",
+                    "rm -rf ../../../tools/mass_mfg/host_test | \
+                    rm -rf mfg_testdata | \
+                    rm -rf testdata",NULL));
+    } else {
+        CHECK(childpid > 0);
+        waitpid(childpid, &status, 0);
+        CHECK(WEXITSTATUS(status) != -1);
+
+    }
+
+}
+
 #if CONFIG_NVS_ENCRYPTION
 TEST_CASE("check underlying xts code for 32-byte size sector encryption", "[nvs]")
 {
@@ -2614,6 +2787,246 @@ TEST_CASE("test nvs apis for nvs partition generator utility with encryption ena
         }
     }
 
+}
+
+TEST_CASE("check and read data from partition generated via manufacturing utility with encryption enabled using sample keyfile", "[mfg_gen]")
+{
+    int childpid = fork();
+    int status;
+
+    if (childpid == 0) {
+        exit(execlp("bash", " bash",
+                    "-c",
+                    "rm -rf ../../../tools/mass_mfg/host_test | \
+                    cp -rf ../../../tools/mass_mfg/testdata mfg_testdata | \
+                    cp -rf ../nvs_partition_generator/testdata . | \
+                    mkdir -p ../../../tools/mass_mfg/host_test",NULL));
+    } else {
+        CHECK(childpid > 0);
+        waitpid(childpid, &status, 0);
+        CHECK(WEXITSTATUS(status) != -1);
+
+        childpid = fork();
+        if (childpid == 0) {
+            exit(execlp("python", "python",
+                        "../../../tools/mass_mfg/mfg_gen.py",
+                        "--conf",
+                        "../../../tools/mass_mfg/samples/sample_config.csv",
+                        "--values",
+                        "../../../tools/mass_mfg/samples/sample_values_multipage_blob.csv",
+                        "--prefix",
+                        "Test",
+                        "--size",
+                        "0x4000",
+                        "--outdir",
+                        "../../../tools/mass_mfg/host_test",
+                        "--version",
+                        "v2",
+                        "--encrypt",
+                        "true",
+                        "--keyfile",
+                        "mfg_testdata/sample_encryption_keys.bin",NULL));
+
+        } else {
+            CHECK(childpid > 0);
+            waitpid(childpid, &status, 0);
+            CHECK(WEXITSTATUS(status) != -1);
+
+            childpid = fork();
+            if (childpid == 0) {
+                exit(execlp("python", "python",
+                            "../nvs_partition_generator/nvs_partition_gen.py",
+                            "--input",
+                            "../../../tools/mass_mfg/host_test/csv/Test-1.csv",
+                            "--output",
+                            "../nvs_partition_generator/Test-1-partition-encrypted.bin",
+                            "--size",
+                            "0x4000",
+                            "--version",
+                            "v2",
+                            "--encrypt",
+                            "true",
+                            "--keyfile",
+                            "testdata/sample_encryption_keys.bin",NULL));
+
+            } else {
+                CHECK(childpid > 0);
+                waitpid(childpid, &status, 0);
+                CHECK(WEXITSTATUS(status) != -1);
+
+            }
+
+        }
+
+    }
+
+    SpiFlashEmulator emu1("../../../tools/mass_mfg/host_test/bin/Test-1.bin");
+
+    TEST_ESP_OK(nvs_flash_deinit());
+
+    nvs_sec_cfg_t cfg;
+    for(int count = 0; count < NVS_KEY_SIZE; count++) {
+        cfg.eky[count] = 0x11;
+        cfg.tky[count] = 0x22;
+    }
+
+    check_nvs_part_gen_args(NVS_DEFAULT_PART_NAME, 4, "mfg_testdata/sample_multipage_blob.bin", true, &cfg);
+
+    SpiFlashEmulator emu2("../nvs_partition_generator/Test-1-partition-encrypted.bin");
+
+    TEST_ESP_OK(nvs_flash_deinit());
+
+    check_nvs_part_gen_args(NVS_DEFAULT_PART_NAME, 4, "testdata/sample_multipage_blob.bin", true, &cfg);
+
+
+    childpid = fork();
+    if (childpid == 0) {
+        exit(execlp("bash", " bash",
+                    "-c",
+                    "rm -rf ../../../tools/mass_mfg/host_test | \
+                    rm -rf mfg_testdata | \
+                    rm -rf testdata",NULL));
+    } else {
+        CHECK(childpid > 0);
+        waitpid(childpid, &status, 0);
+        CHECK(WEXITSTATUS(status) != -1);
+
+    }
+
+}
+
+TEST_CASE("check and read data from partition generated via manufacturing utility with encryption enabled using new generated key", "[mfg_gen]")
+{
+    int childpid = fork();
+    int status;
+
+    if (childpid == 0) {
+        exit(execlp("bash", " bash",
+                    "-c",
+                    "rm -rf ../../../tools/mass_mfg/host_test | \
+                    cp -rf ../../../tools/mass_mfg/testdata mfg_testdata | \
+                    cp -rf ../nvs_partition_generator/testdata . | \
+                    mkdir -p ../../../tools/mass_mfg/host_test",NULL));
+    } else {
+        CHECK(childpid > 0);
+        waitpid(childpid, &status, 0);
+        CHECK(WEXITSTATUS(status) != -1);
+
+        childpid = fork();
+        if (childpid == 0) {
+            exit(execlp("python", "python",
+                        "../../../tools/mass_mfg/mfg_gen.py",
+                        "--keygen",
+                        "true",
+                        "--outdir",
+                        "../../../tools/mass_mfg/host_test",
+                        "--keyfile",
+                        "encr_keys_host_test.bin",NULL));
+
+        } else {
+            CHECK(childpid > 0);
+            waitpid(childpid, &status, 0);
+            CHECK(WEXITSTATUS(status) != -1);
+
+            childpid = fork();
+            if (childpid == 0) {
+                exit(execlp("python", "python",
+                            "../../../tools/mass_mfg/mfg_gen.py",
+                            "--conf",
+                            "../../../tools/mass_mfg/samples/sample_config.csv",
+                            "--values",
+                            "../../../tools/mass_mfg/samples/sample_values_multipage_blob.csv",
+                            "--prefix",
+                            "Test",
+                            "--size",
+                            "0x4000",
+                            "--outdir",
+                            "../../../tools/mass_mfg/host_test",
+                            "--version",
+                            "v2",
+                            "--encrypt",
+                            "true",
+                            "--keyfile",
+                            "../../../tools/mass_mfg/host_test/keys/encr_keys_host_test.bin",NULL));
+
+            } else {
+                CHECK(childpid > 0);
+                waitpid(childpid, &status, 0);
+                CHECK(WEXITSTATUS(status) != -1);
+
+                childpid = fork();
+                if (childpid == 0) {
+                    exit(execlp("python", "python",
+                                "../nvs_partition_generator/nvs_partition_gen.py",
+                                "--input",
+                                "../../../tools/mass_mfg/host_test/csv/Test-1.csv",
+                                "--output",
+                                "../nvs_partition_generator/Test-1-partition-encrypted.bin",
+                                "--size",
+                                "0x4000",
+                                "--version",
+                                "v2",
+                                "--encrypt",
+                                "true",
+                                "--keyfile",
+                                "../../../tools/mass_mfg/host_test/keys/encr_keys_host_test.bin",NULL));
+
+                } else {
+                    CHECK(childpid > 0);
+                    waitpid(childpid, &status, 0);
+                    CHECK(WEXITSTATUS(status) != -1);
+
+                }
+
+            }
+
+        }
+
+    }
+
+
+    SpiFlashEmulator emu1("../../../tools/mass_mfg/host_test/bin/Test-1.bin");
+
+    char buffer[64];
+    FILE *fp;
+
+    fp = fopen("../../../tools/mass_mfg/host_test/keys/encr_keys_host_test.bin","rb");
+    fread(buffer,sizeof(buffer),1,fp);
+
+    fclose(fp);
+
+    TEST_ESP_OK(nvs_flash_deinit());
+
+    nvs_sec_cfg_t cfg;
+
+    for(int count = 0; count < NVS_KEY_SIZE; count++) {
+        cfg.eky[count] = buffer[count] & 255;
+        cfg.tky[count] = buffer[count+32] & 255;
+    }
+
+    check_nvs_part_gen_args(NVS_DEFAULT_PART_NAME, 4, "mfg_testdata/sample_multipage_blob.bin", true, &cfg);
+
+    SpiFlashEmulator emu2("../nvs_partition_generator/Test-1-partition-encrypted.bin");
+
+    TEST_ESP_OK(nvs_flash_deinit());
+
+    check_nvs_part_gen_args(NVS_DEFAULT_PART_NAME, 4, "testdata/sample_multipage_blob.bin", true, &cfg);
+
+    childpid = fork();
+    if (childpid == 0) {
+        exit(execlp("bash", " bash",
+                    "-c",
+                    "rm -rf keys | \
+                    rm -rf mfg_testdata | \
+                    rm -rf testdata | \
+                    rm -rf ../../../tools/mass_mfg/host_test",NULL));
+    } else {
+        CHECK(childpid > 0);
+        waitpid(childpid, &status, 0);
+        CHECK(WEXITSTATUS(status) != -1);
+
+    }
+
 }
 #endif
 
index 881fed6967cd2f111494090a605a27c848da5529..ba43dd5e9f1874ce1427496fa0e6ef8310c85fdc 100644 (file)
@@ -23,6 +23,8 @@ Prerequisites
 
 .. note:: Make sure the python path is set in the PATH environment variable before using this utility.
 
+Make sure to include packages from `requirement.txt` in top level IDF directory.
+
 Workflow
 -----------
 
@@ -63,7 +65,7 @@ Below is a sample example of such a configuration file::
 
        app,namespace,
        firmware_key,data,hex2bin
-       serial_no,data,i32,REPEAT
+       serial_no,data,string,REPEAT
        device_no,data,i32
 
 
@@ -89,11 +91,11 @@ Each row should have the ``value`` of the corresponding keys, separated by comma
 Below is a sample example of such a values file::
 
        id,firmware_key,serial_no,device_no 
-       1,1a2b3c4d5e6faabb,111,101 
+       1,1a2b3c4d5e6faabb,A1,101 
        2,1a2b3c4d5e6fccdd,,102 
        3,1a2b3c4d5e6feeff,,103 
 
-.. note:: *A new Master CSV Values File is created in the same folder as the input Master CSV File with the values inserted at each line for the key with 'REPEAT' tag.* 
+.. note:: *If 'REPEAT' tag is present, a new Master CSV Values File is created in the same folder as the input Master CSV File with the values inserted at each line for the key with 'REPEAT' tag.* 
 
 .. note:: *Intermediate CSV files are created by this utility which are input to the nvs partition utility to generate the binary files.*
 
@@ -114,14 +116,17 @@ The mfg\_gen.py utility is using the generated CSV Configuration file and Master
 *Sample CSV Configuration file and Master CSV Values file is provided with this utility.* 
 
 **Usage**::
+    
+    $ ./mfg_gen.py [-h] [--conf CONFIG_FILE] [--values VALUES_FILE]
+                    [--prefix PREFIX] [--fileid FILEID] [--outdir OUTDIR]
+                    [--size PART_SIZE] [--version {v1,v2}]
+                    [--keygen {true,false}] [--encrypt {true,false}]
+                    [--keyfile KEYFILE]
 
-    $ ./mfg_gen.py [-h] --size PART_SIZE --conf CONFIG_FILE --values VALUES_FILE --prefix PREFIX [--fileid FILEID] [--outdir OUTDIR]
 
 +------------------------+----------------------------------------------------------------------------------------------+
 |   Arguments            |                                     Description                                              |                                   
 +========================+==============================================================================================+
-| --size PART_SIZE       |  Size of NVS Partition in bytes (must be multiple of 4096)                                   |
-+------------------------+----------------------------------------------------------------------------------------------+
 | --conf CONFIG_FILE     |  the input configuration csv file                                                            |
 +------------------------+----------------------------------------------------------------------------------------------+
 | --values VALUES_FILE   |  the input values csv file                                                                   |
@@ -133,11 +138,45 @@ The mfg\_gen.py utility is using the generated CSV Configuration file and Master
 +------------------------+----------------------------------------------------------------------------------------------+
 | --outdir OUTDIR        | the output directory to store the files created (Default: current directory)                 |
 +------------------------+----------------------------------------------------------------------------------------------+
+| --size PART_SIZE       |  Size of NVS Partition in bytes (must be multiple of 4096)                                   |
++------------------------+----------------------------------------------------------------------------------------------+
+| --version {v1,v2}      | Set version. Default: v2                                                                     |
++------------------------+----------------------------------------------------------------------------------------------+
+| --keygen {true,false}  | Generate keys for encryption.                                                                |
+|                        | Default: false                                                                               |
++------------------------+----------------------------------------------------------------------------------------------+
+| --encrypt {true,false} | Set encryption mode. Default: false                                                          |
++------------------------+----------------------------------------------------------------------------------------------+
+| --keyfile KEYFILE      | File having key for encryption (Applicable only if encryption mode is true)                  |
++------------------------+----------------------------------------------------------------------------------------------+
 
-**You can use the below command to run this utility with the sample files provided**::
+*You can use the below commands to run this utility with the sample files provided*::
    
-   $ ./mfg_gen.py --size 0x3000 --conf samples/sample_config.csv --values samples/sample_values.csv --prefix Fan
+    $ ./mfg_gen.py --conf samples/sample_config.csv --values samples/sample_values_singlepage_blob.csv --prefix Fan --size 0x3000
+
+    $ ./mfg_gen.py --conf samples/sample_config.csv --values samples/sample_values_multipage_blob.csv --prefix Fan --size 0x4000
+    
+.. note:: When you use this utility to generate per device instance factory images --conf, --values, --prefix and --size arguments are mandatory.
+    
+    $ ./mfg_gen.py --conf samples/sample_config.csv --values samples/sample_values_singlepage_blob.csv --prefix Fan --size 0x3000 --outdir tmp
+
+.. note:: The --outdir directory is created if not present. 
+
+.. note:: The file path given in the ``file`` type in the values file is expected to be relative to the current directory from which you are running the utility.
+    
+    $ ./mfg_gen.py --conf samples/sample_config.csv --values samples/sample_values_singlepage_blob.csv --prefix Fan --size 0x3000 --encrypt true --keygen true
+
+.. note:: ``keys/`` directory is generated with the encryption keys filename of the form ``prefix-fileid-keys.bin``.
+    
+*You can also run the below command to use the utility to* **only** *generate encryption keys binary file ( following example 'keys/' directory is created in current path), which can further be used to encrypt per device instance factory images*::
+    
+    $ ./mfg_gen.py --keygen true
+    
+    $ ./mfg_gen.py --keygen true --keyfile encr_keys.bin
+
+.. note:: When running utility to generate only ``keys``, if --keyfile is given it will generate encryption keys with filename given in --keyfile argument.
 
+.. note:: When you use this utility to generate only encryption keys --keygen argument is mandatory.
 
 .. note:: The default numeric value: 1,2,3... of ``fileid`` argument, corresponds to each row having device instance values in master csv values file.
 
index c5502161c0a6edb0d1e6563096b86fad084e6ba7..ecaa4319b676d4b57eac434dcb6d0824ac777774 100755 (executable)
@@ -22,10 +22,14 @@ import sys
 import os
 import csv
 import argparse
-import shutil
 import distutils.dir_util
-sys.path.insert(0, os.getenv('IDF_PATH') + "/components/nvs_flash/nvs_partition_generator/")
-import nvs_partition_gen
+
+try:
+    sys.path.insert(0, os.getenv('IDF_PATH') + "/components/nvs_flash/nvs_partition_generator/")
+    import nvs_partition_gen
+except Exception as e:
+    print(e)
+    sys.exit("Please check IDF_PATH")
 
 
 def verify_values_exist(input_values_file, keys_in_values_file):
@@ -36,13 +40,13 @@ def verify_values_exist(input_values_file, keys_in_values_file):
 
     values_file = open(input_values_file, 'r')
     values_file_reader = csv.reader(values_file, delimiter=',')
-    keys = next(values_file_reader)
+    next(values_file_reader)
 
     for values_data in values_file_reader:
-        line_no +=1
+        line_no += 1
         if len(values_data) != key_count_in_values_file:
-            raise SystemExit("\nOops...Number of values is not equal to number of keys in file: %s at line No:%s\n"\
-            % (str(input_values_file), str(line_no)))
+            raise SystemExit("\nOops...Number of values is not equal to number of keys in file: %s at line No:%s\n"
+                             % (str(input_values_file), str(line_no)))
 
 
 def verify_keys_exist(values_file_keys, input_config_file):
@@ -62,18 +66,16 @@ def verify_keys_exist(values_file_keys, input_config_file):
             else:
                 keys_missing.append([config_data[0], line_no])
 
-
     if keys_missing:
         for key, line_no in keys_missing:
-            print("Key:`", str(key), "` at line no:", str(line_no),\
-            " in config file is not found in values file.")
+            print("Key:`", str(key), "` at line no:", str(line_no),
+                  " in config file is not found in values file.")
         config_file.close()
         raise SystemExit(1)
 
     config_file.close()
 
 
-
 def verify_datatype_encoding(input_config_file):
     """ Verify datatype and encodings from config file is valid
     """
@@ -84,15 +86,14 @@ def verify_datatype_encoding(input_config_file):
     config_file = open(input_config_file,'r')
     config_file_reader = csv.reader(config_file, delimiter=',')
     for config_data in config_file_reader:
-        line_no+=1
+        line_no += 1
         if config_data[1] not in valid_datatypes:
-            raise SystemExit("Oops...config file: %s has invalid datatype at line no:%s\n`" \
-            % (str(input_config_file), str(line_no)))
+            raise SystemExit("Oops...config file: %s has invalid datatype at line no:%s\n`"
+                             % (str(input_config_file), str(line_no)))
         if 'namespace' not in config_data:
             if config_data[2] not in valid_encodings:
-                raise SystemExit("Oops...config file: %s has invalid encoding at line no:%s\n`" \
-                % (str(input_config_file), str(line_no)))
-
+                raise SystemExit("Oops...config file: %s has invalid encoding at line no:%s\n`"
+                                 % (str(input_config_file), str(line_no)))
 
 
 def verify_file_data_count(input_config_file, keys_repeat):
@@ -105,8 +106,8 @@ def verify_file_data_count(input_config_file, keys_repeat):
     for line in config_file_reader:
         line_no += 1
         if len(line) != 3 and line[0] not in keys_repeat:
-            raise SystemExit("Oops...data missing in config file at line no:%s <format needed:key,type,encoding>\n" \
-            % str(line_no) )
+            raise SystemExit("Oops...data missing in config file at line no:%s <format needed:key,type,encoding>\n"
+                             % str(line_no))
     config_file.close()
 
 
@@ -131,9 +132,8 @@ def verify_data_in_file(input_config_file, input_values_file, config_file_keys,
 
         verify_values_exist(input_values_file, keys_in_values_file)
 
-    except StandardError as std_err:
-        print(std_err)
-    except:
+    except Exception as err:
+        print(err)
         raise
 
 
@@ -180,8 +180,8 @@ def add_config_data_per_namespace(input_config_file):
     return config_data_to_write
 
 
-def get_fileid_val(file_identifier, keys_in_config_file, keys_in_values_file,\
-values_data_line, key_value_data, fileid_value):
+def get_fileid_val(file_identifier, keys_in_config_file, keys_in_values_file,
+                   values_data_line, key_value_data, fileid_value):
     """ Get file identifier value
     """
     file_id_found = False
@@ -224,7 +224,6 @@ def add_data_to_file(config_data_to_write, key_value_pair, output_csv_file):
                     del key_value_pair[0]
                     output_file_writer.writerow(data_to_write)
 
-
     # Set index to start of file
     target_csv_file.seek(0)
 
@@ -241,11 +240,9 @@ def create_dir(filetype, output_dir_path):
     return output_target_dir
 
 
-def set_repeat_value(total_keys_repeat, keys, csv_file):
+def set_repeat_value(total_keys_repeat, keys, csv_file, target_filename):
     key_val_pair = []
     key_repeated = []
-    filename, file_ext = os.path.splitext(csv_file)
-    target_filename = filename + "_created" + file_ext
     with open(csv_file, 'r') as read_from, open(target_filename,'w') as write_to:
         csv_file_reader = csv.reader(read_from, delimiter=',')
         headers = next(csv_file_reader)
@@ -259,7 +256,6 @@ def set_repeat_value(total_keys_repeat, keys, csv_file):
         for row in csv_file_reader:
             index = -1
             key_val_new = list(zip_longest(keys, row))
-
             key_val_pair = total_keys_values[:]
             key_repeated = total_keys_repeat[:]
             while key_val_new and key_repeated:
@@ -273,37 +269,31 @@ def set_repeat_value(total_keys_repeat, keys, csv_file):
                 del key_val_new[0]
                 del key_val_pair[0]
 
-
     return target_filename
 
 
-def main(input_config_file=None,input_values_file=None,target_file_name_prefix=None,\
-file_identifier=None,output_dir_path=None):
+def main(input_config_file=None,input_values_file=None,target_file_name_prefix=None,
+         file_identifier=None,output_dir_path=None,part_size=None,input_version=None,
+         input_is_keygen=None,input_is_encrypt=None,input_is_keyfile=None):
     try:
-        if all(arg is None for arg in [input_config_file,input_values_file,target_file_name_prefix,\
-            file_identifier,output_dir_path]):
+        if all(arg is None for arg in [input_config_file,input_values_file,target_file_name_prefix,
+                                       file_identifier,output_dir_path]):
             parser = argparse.ArgumentParser(prog='./mfg_gen.py',
                                              description="Create binary files from input config and values file",
                                              formatter_class=argparse.RawDescriptionHelpFormatter)
 
-            parser.add_argument("--size",
-                                dest='part_size',
-                                required=True,
-                                help='Size of NVS Partition in bytes (must be multiple of 4096)')
-
             parser.add_argument('--conf',
                                 dest='config_file',
-                                required=True,
-                                help='the input configuration csv file')
+                                help='the input configuration csv file',
+                                default=None)
 
             parser.add_argument('--values',
                                 dest='values_file',
-                                required=True,
-                                help='the input values csv file')
+                                help='the input values csv file',
+                                default=None)
 
             parser.add_argument('--prefix',
                                 dest='prefix',
-                                required=True,
                                 help='the unique name as each filename prefix')
 
             parser.add_argument('--fileid',
@@ -313,30 +303,80 @@ file_identifier=None,output_dir_path=None):
 
             parser.add_argument('--outdir',
                                 dest='outdir',
-                                default='./',
+                                default=os.getcwd(),
                                 help='the output directory to store the files created\
                                 (Default: current directory)')
 
-            args = parser.parse_args()
+            parser.add_argument("--size",
+                                dest='part_size',
+                                help='Size of NVS Partition in bytes (must be multiple of 4096)')
+
+            parser.add_argument("--version",
+                                dest="version",
+                                help='Set version. Default: v2',
+                                choices=['v1','v2'],
+                                default='v2',
+                                type=str.lower)
+
+            parser.add_argument("--keygen",
+                                dest="keygen",
+                                help='Generate keys for encryption. Default: false',
+                                choices=['true','false'],
+                                default='false',
+                                type=str.lower)
+
+            parser.add_argument("--encrypt",
+                                dest="encrypt",
+                                help='Set encryption mode. Default: false',
+                                choices=['true','false'],
+                                default='false',
+                                type=str.lower)
+
+            parser.add_argument("--keyfile",
+                                dest="keyfile",
+                                help='File having key for encryption (Applicable only if encryption mode is true)',
+                                default=None)
 
-            # Verify if output_dir_path argument is given then output directory exists
-            if not os.path.isdir(args.outdir):
-                parser.error('--outdir ' + args.outdir + ' does not exist...')
+            args = parser.parse_args()
 
-            # Add '/' to outdir if it is not present
-            if not args.outdir.endswith('/'):
-                args.outdir = args.outdir + '/'
+            args.outdir = os.path.join(args.outdir, '')
 
-            input_part_size = args.part_size
             input_config_file = args.config_file
             input_values_file = args.values_file
             target_file_name_prefix = args.prefix
             output_dir_path = args.outdir
+            part_size = args.part_size
+            input_version = args.version
+            input_is_keygen = args.keygen
+            input_is_encrypt = args.encrypt
+            input_is_keyfile = args.keyfile
             file_identifier = ''
+            print_arg_str = "Invalid.\nTo generate binary --conf, --values, --prefix and --size arguments are mandatory.\
+            \nTo generate encryption keys --keygen argument is mandatory."
+            print_encrypt_arg_str = "Missing parameter. Enter --keygen or --keyfile."
 
             if args.fileid:
                 file_identifier = args.fileid
 
+            if input_config_file and input_is_encrypt.lower() == 'true' and input_is_keygen.lower() == 'true' and input_is_keyfile:
+                sys.exit('Invalid. Cannot provide both --keygen and --keyfile argument together.')
+
+            nvs_partition_gen.check_input_args(input_config_file, input_values_file, part_size, input_is_keygen,
+                                               input_is_encrypt, input_is_keyfile, input_version, print_arg_str,
+                                               print_encrypt_arg_str, output_dir_path)
+
+            if not input_config_file and input_is_keygen:
+                if input_is_encrypt == 'true':
+                    sys.exit("Invalid.\nOnly --keyfile and --outdir arguments allowed.\n")
+                # Generate Key Only
+                nvs_partition_gen.nvs_part_gen(input_filename=input_config_file, output_filename=input_values_file,
+                                               input_part_size=part_size, is_key_gen=input_is_keygen,
+                                               encrypt_mode=input_is_encrypt, key_file=input_is_keyfile,
+                                               version_no=input_version, output_dir=output_dir_path)
+                exit(0)
+
+            if not (input_config_file and input_values_file and target_file_name_prefix and part_size):
+                sys.exit(print_arg_str)
 
         keys_in_values_file = []
         keys_in_config_file = []
@@ -344,12 +384,12 @@ file_identifier=None,output_dir_path=None):
         key_value_data = []
         csv_file_list = []
         keys_repeat = []
-        is_keys_missing = True
-        file_id_found = False
         is_empty_line = False
         files_created = False
         file_identifier_value = '0'
         output_target_dir = ''
+        target_values_file = None
+        output_file_prefix = None
 
         # Verify config file is not empty
         if os.stat(input_config_file).st_size == 0:
@@ -357,7 +397,7 @@ file_identifier=None,output_dir_path=None):
 
         # Verify values file is not empty
         if os.stat(input_values_file).st_size == 0:
-            raise SystemExit("Oops...values file: %s is empty." % input_values_file )
+            raise SystemExit("Oops...values file: %s is empty." % input_values_file)
 
         # Verify config file does not have empty lines
         csv_config_file = open(input_config_file,'r')
@@ -372,17 +412,15 @@ file_identifier=None,output_dir_path=None):
                         is_empty_line = False
                         break
                 if is_empty_line:
-                    raise SystemExit("Oops...config file: %s cannot have empty lines. " % input_config_file )
+                    raise SystemExit("Oops...config file: %s cannot have empty lines. " % input_config_file)
                 if not config_data:
-                    raise SystemExit("Oops...config file: %s cannot have empty lines." % input_config_file )
+                    raise SystemExit("Oops...config file: %s cannot have empty lines." % input_config_file)
 
             csv_config_file.seek(0)
 
             # Extract keys from config file
             for config_data in config_file_reader:
-                if 'namespace' in config_data:
-                    namespace = config_data[0]
-                else:
+                if 'namespace' not in config_data:
                     keys_in_config_file.append(config_data[0])
                 if 'REPEAT' in config_data:
                     keys_repeat.append(config_data[0])
@@ -394,8 +432,6 @@ file_identifier=None,output_dir_path=None):
             csv_config_file.close()
 
         is_empty_line = False
-
-
         # Verify values file does not have empty lines
         csv_values_file = open(input_values_file, 'r')
         try:
@@ -409,9 +445,9 @@ file_identifier=None,output_dir_path=None):
                         is_empty_line = False
                         break
                 if is_empty_line:
-                    raise SystemExit("Oops...values file: %s cannot have empty lines." % input_values_file )
+                    raise SystemExit("Oops...values file: %s cannot have empty lines." % input_values_file)
                 if not values_data:
-                    raise SystemExit("Oops...values file: %s cannot have empty lines." % input_values_file )
+                    raise SystemExit("Oops...values file: %s cannot have empty lines." % input_values_file)
 
             csv_values_file.seek(0)
 
@@ -428,12 +464,11 @@ file_identifier=None,output_dir_path=None):
         # Verify file identifier exists in values file
         if file_identifier:
             if file_identifier not in keys_in_values_file:
-                raise SystemExit('Oops...target_file_identifier: %s does not exist in values file.\n' % file_identifier )
-
+                raise SystemExit('Oops...target_file_identifier: %s does not exist in values file.\n' % file_identifier)
 
         # Verify data in the input_config_file and input_values_file
-        verify_data_in_file(input_config_file, input_values_file, keys_in_config_file,\
-        keys_in_values_file, keys_repeat)
+        verify_data_in_file(input_config_file, input_values_file, keys_in_config_file,
+                            keys_in_values_file, keys_repeat)
 
         # Add config data per namespace to `config_data_to_write` list
         config_data_to_write = add_config_data_per_namespace(input_config_file)
@@ -443,20 +478,23 @@ file_identifier=None,output_dir_path=None):
                 values_file_reader = csv.reader(csv_values_file, delimiter=',')
                 keys = next(values_file_reader)
 
-            target_values_file = set_repeat_value(keys_repeat, keys, input_values_file)
+            filename, file_ext = os.path.splitext(input_values_file)
+            target_filename = filename + "_created" + file_ext
+            if keys_repeat:
+                target_values_file = set_repeat_value(keys_repeat, keys, input_values_file, target_filename)
+            else:
+                target_values_file = input_values_file
 
             csv_values_file = open(target_values_file, 'r')
 
             values_file_reader = csv.reader(csv_values_file, delimiter=',')
             next(values_file_reader)
-
-
             for values_data_line in values_file_reader:
                 key_value_data = list(zip_longest(keys_in_values_file,values_data_line))
 
                 # Get file identifier value from values file
-                file_identifier_value = get_fileid_val(file_identifier, keys_in_config_file, \
-                keys_in_values_file, values_data_line, key_value_data, file_identifier_value)
+                file_identifier_value = get_fileid_val(file_identifier, keys_in_config_file,
+                                                       keys_in_values_file, values_data_line, key_value_data, file_identifier_value)
 
                 key_value_pair = key_value_data[:]
 
@@ -468,7 +506,7 @@ file_identifier=None,output_dir_path=None):
                 csv_file_list.append(csv_filename)
                 output_csv_file = output_target_dir + csv_filename
                 if os.path.isfile(output_csv_file):
-                    raise SystemExit("Target csv file: %s already exists.`" % output_csv_file )
+                    raise SystemExit("Target csv file: %s already exists.`" % output_csv_file)
 
                 # Add values corresponding to each key to csv target file
                 add_data_to_file(config_data_to_write, key_value_pair, output_csv_file)
@@ -477,16 +515,20 @@ file_identifier=None,output_dir_path=None):
                 output_target_dir = create_dir("bin/", output_dir_path)
 
                 # Verify if output bin file does not exist
-                output_bin_file = output_target_dir + target_file_name_prefix + "-" +\
-                file_identifier_value + ".bin"
+                # todo for keys
+                output_file_prefix = target_file_name_prefix + "-" + file_identifier_value
+                output_bin_file = output_target_dir + output_file_prefix + ".bin"
                 if os.path.isfile(output_bin_file):
-                    raise SystemExit("Target csv file: %s already exists.`" % output_bin_file )
+                    raise SystemExit("Target csv file: %s already exists.`" % output_bin_file)
 
                 # Create output csv and bin file
+                if input_is_keygen.lower() == 'true' and input_is_keyfile:
+                    input_is_keyfile = os.path.basename(input_is_keyfile)
+                nvs_partition_gen.nvs_part_gen(input_filename=output_csv_file, output_filename=output_bin_file,
+                                               input_part_size=part_size, is_key_gen=input_is_keygen,
+                                               encrypt_mode=input_is_encrypt, key_file=input_is_keyfile,
+                                               version_no=input_version, encr_key_prefix=output_file_prefix, output_dir=output_dir_path)
                 print("CSV Generated: ", str(output_csv_file))
-                nvs_partition_gen.nvs_part_gen(input_filename = output_csv_file, output_filename = output_bin_file,\
-                                               input_size=input_part_size)
-                print("NVS Flash Binary Generated: ", str(output_bin_file))
 
                 files_created = True
 
@@ -496,14 +538,13 @@ file_identifier=None,output_dir_path=None):
             exit(1)
         finally:
             csv_values_file.close()
-
-
-        return csv_file_list, files_created
+        return csv_file_list, files_created, target_values_file
 
     except ValueError as err:
         print(err)
-    except:
+    except Exception:
         raise
 
+
 if __name__ == "__main__":
     main()
index 7b7dc400a9bd54ce3d519a91d9df86477e52a11b..dc5167159140795d8276e88bd6e5f154311bcb32 100644 (file)
@@ -1,4 +1,15 @@
-app,namespace,  
-firmware_key,data,hex2bin
-serial_no,data,i32,REPEAT
-device_no,data,i32
+dummyNamespace,namespace,
+dummyU8Key,data,u8
+dummyI8Key,data,i8
+dummyU16Key,data,u16
+dummyU32Key,data,u32
+dummyI32Key,data,i32,REPEAT
+dummyStringKey,data,string
+dummyHex2BinKey,data,hex2bin
+dummyBase64Key,data,base64
+hexFileKey,file,hex2bin
+base64FileKey,file,base64
+stringFileKey,file,string
+blobFileAKey,file,binary
+blobFileBKey,file,binary
+binFileKey,file,binary
diff --git a/tools/mass_mfg/samples/sample_values.csv b/tools/mass_mfg/samples/sample_values.csv
deleted file mode 100644 (file)
index 08b552d..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-id,firmware_key,serial_no,device_no
-1,1a2b3c4d5e6faabb,111,101
-2,1a2b3c4d5e6fccdd,,102
-3,1a2b3c4d5e6feeff,,103
-4,1a2b3c4d5e6faabb,,104
-5,1a2b3c4d5e6feedd,,105
diff --git a/tools/mass_mfg/samples/sample_values_multipage_blob.csv b/tools/mass_mfg/samples/sample_values_multipage_blob.csv
new file mode 100644 (file)
index 0000000..0fb8e7d
--- /dev/null
@@ -0,0 +1,4 @@
+id,dummyU8Key,dummyI8Key,dummyU16Key,dummyU32Key,dummyI32Key,dummyStringKey,dummyHex2BinKey,dummyBase64Key,hexFileKey,base64FileKey,stringFileKey,blobFileAKey,blobFileBKey,binFileKey
+1,127,-128,32768,4294967295,-2147483648,0A:0B:0C:0D:0E:0F,010203abcdef,MTIzYWJj,testdata/sample.hex,testdata/sample.base64,testdata/sample.txt,testdata/sample_blob.bin,testdata/sample_blob.bin,testdata/sample_multipage_blob.bin
+2,126,-127,32767,4294967294,,A0:B0:C0:D0:E0:F0,102030abcdef,MTIzYWFh,testdata/sample.hex,testdata/sample.base64,testdata/sample.txt,testdata/sample_blob.bin,testdata/sample_blob.bin,testdata/sample_multipage_blob.bin
+3,125,-126,32766,4294967293,,00:B3:C4:BD:E2:0F,010203efcdab,MTIzYmJi,testdata/sample.hex,testdata/sample.base64,testdata/sample.txt,testdata/sample_blob.bin,testdata/sample_blob.bin,testdata/sample_multipage_blob.bin
diff --git a/tools/mass_mfg/samples/sample_values_singlepage_blob.csv b/tools/mass_mfg/samples/sample_values_singlepage_blob.csv
new file mode 100644 (file)
index 0000000..1e3508d
--- /dev/null
@@ -0,0 +1,4 @@
+id,dummyU8Key,dummyI8Key,dummyU16Key,dummyU32Key,dummyI32Key,dummyStringKey,dummyHex2BinKey,dummyBase64Key,hexFileKey,base64FileKey,stringFileKey,blobFileAKey,blobFileBKey,binFileKey
+1,127,-128,32768,4294967295,-2147483648,0A:0B:0C:0D:0E:0F,010203abcdef,MTIzYWJj,testdata/sample.hex,testdata/sample.base64,testdata/sample.txt,testdata/sample_blob.bin,testdata/sample_blob.bin,testdata/sample_singlepage_blob.bin
+2,126,-127,32767,4294967294,,A0:B0:C0:D0:E0:F0,102030abcdef,MTIzYWFh,testdata/sample.hex,testdata/sample.base64,testdata/sample.txt,testdata/sample_blob.bin,testdata/sample_blob.bin,testdata/sample_singlepage_blob.bin
+3,125,-126,32766,4294967293,,00:B3:C4:BD:E2:0F,010203efcdab,MTIzYmJi,testdata/sample.hex,testdata/sample.base64,testdata/sample.txt,testdata/sample_blob.bin,testdata/sample_blob.bin,testdata/sample_singlepage_blob.bin
diff --git a/tools/mass_mfg/testdata/sample.base64 b/tools/mass_mfg/testdata/sample.base64
new file mode 100644 (file)
index 0000000..0c16c99
--- /dev/null
@@ -0,0 +1 @@
+AQIDBAUGBwgJq83v
diff --git a/tools/mass_mfg/testdata/sample.hex b/tools/mass_mfg/testdata/sample.hex
new file mode 100644 (file)
index 0000000..454f6b3
--- /dev/null
@@ -0,0 +1 @@
+0123456789abcdef
\ No newline at end of file
diff --git a/tools/mass_mfg/testdata/sample.txt b/tools/mass_mfg/testdata/sample.txt
new file mode 100644 (file)
index 0000000..e85d5b4
--- /dev/null
@@ -0,0 +1 @@
+abcdefghijklmnopqrstuvwxyz
\ No newline at end of file
diff --git a/tools/mass_mfg/testdata/sample_blob.bin b/tools/mass_mfg/testdata/sample_blob.bin
new file mode 100644 (file)
index 0000000..eac2d31
--- /dev/null
@@ -0,0 +1 @@
+start0000000000000000000000start0123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef0000000000000000end00000000000000000000000000end
\ No newline at end of file
diff --git a/tools/mass_mfg/testdata/sample_encryption_keys.bin b/tools/mass_mfg/testdata/sample_encryption_keys.bin
new file mode 100644 (file)
index 0000000..9ef4439
--- /dev/null
@@ -0,0 +1 @@
+\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11\11"""""""""""""""""""""""""""""""",ïÏ<ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
\ No newline at end of file
diff --git a/tools/mass_mfg/testdata/sample_multipage_blob.bin b/tools/mass_mfg/testdata/sample_multipage_blob.bin
new file mode 100644 (file)
index 0000000..fe69eca
--- /dev/null
@@ -0,0 +1 @@
+start0000000000000000000000start0123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef0000000000000000end00000000000000000000000000end
\ No newline at end of file
diff --git a/tools/mass_mfg/testdata/sample_singlepage_blob.bin b/tools/mass_mfg/testdata/sample_singlepage_blob.bin
new file mode 100644 (file)
index 0000000..f607291
--- /dev/null
@@ -0,0 +1 @@
+start0000000000000000000000start0123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef00000000000000000123456789abcdef0000000000000000