1 /* SPIFFS Image Generation on Build Example
2 
3    This example code is in the Public Domain (or CC0 licensed, at your option.)
4 
5    Unless required by applicable law or agreed to in writing, this
6    software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
7    CONDITIONS OF ANY KIND, either express or implied.
8 */
9 
10 #include <stdio.h>
11 #include <string.h>
12 #include <sys/unistd.h>
13 #include <sys/stat.h>
14 #include "esp_err.h"
15 #include "esp_log.h"
16 #include "esp_spiffs.h"
17 #include "mbedtls/md5.h"
18 
19 static const char *TAG = "example";
20 
read_hello_txt(void)21 static void read_hello_txt(void)
22 {
23     ESP_LOGI(TAG, "Reading hello.txt");
24 
25     // Open for reading hello.txt
26     FILE* f = fopen("/spiffs/hello.txt", "r");
27     if (f == NULL) {
28         ESP_LOGE(TAG, "Failed to open hello.txt");
29         return;
30     }
31 
32     char buf[64];
33     memset(buf, 0, sizeof(buf));
34     fread(buf, 1, sizeof(buf), f);
35     fclose(f);
36 
37     // Display the read contents from the file
38     ESP_LOGI(TAG, "Read from hello.txt: %s", buf);
39 }
40 
compute_alice_txt_md5(void)41 static void compute_alice_txt_md5(void)
42 {
43     ESP_LOGI(TAG, "Computing alice.txt MD5 hash");
44 
45     // The file alice.txt lives under a subdirectory, though SPIFFS itself is flat
46     FILE* f = fopen("/spiffs/sub/alice.txt", "r");
47     if (f == NULL) {
48         ESP_LOGE(TAG, "Failed to open alice.txt");
49         return;
50     }
51 
52     // Read file and compute the digest chunk by chunk
53     #define MD5_MAX_LEN 16
54 
55     char buf[64];
56     mbedtls_md5_context ctx;
57     unsigned char digest[MD5_MAX_LEN];
58 
59     mbedtls_md5_init(&ctx);
60     mbedtls_md5_starts_ret(&ctx);
61 
62     size_t read;
63 
64     do {
65         read = fread((void*) buf, 1, sizeof(buf), f);
66         mbedtls_md5_update_ret(&ctx, (unsigned const char*) buf, read);
67     } while(read == sizeof(buf));
68 
69     mbedtls_md5_finish_ret(&ctx, digest);
70 
71     // Create a string of the digest
72     char digest_str[MD5_MAX_LEN * 2];
73 
74     for (int i = 0; i < MD5_MAX_LEN; i++) {
75         sprintf(&digest_str[i * 2], "%02x", (unsigned int)digest[i]);
76     }
77 
78     // For reference, MD5 should be deeb71f585cbb3ae5f7976d5127faf2a
79     ESP_LOGI(TAG, "Computed MD5 hash of alice.txt: %s", digest_str);
80 
81     fclose(f);
82 }
83 
app_main(void)84 void app_main(void)
85 {
86     ESP_LOGI(TAG, "Initializing SPIFFS");
87 
88     esp_vfs_spiffs_conf_t conf = {
89       .base_path = "/spiffs",
90       .partition_label = NULL,
91       .max_files = 5,
92       .format_if_mount_failed = false
93     };
94 
95     // Use settings defined above to initialize and mount SPIFFS filesystem.
96     // Note: esp_vfs_spiffs_register is an all-in-one convenience function.
97     esp_err_t ret = esp_vfs_spiffs_register(&conf);
98 
99     if (ret != ESP_OK) {
100         if (ret == ESP_FAIL) {
101             ESP_LOGE(TAG, "Failed to mount or format filesystem");
102         } else if (ret == ESP_ERR_NOT_FOUND) {
103             ESP_LOGE(TAG, "Failed to find SPIFFS partition");
104         } else {
105             ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret));
106         }
107         return;
108     }
109 
110     size_t total = 0, used = 0;
111     ret = esp_spiffs_info(NULL, &total, &used);
112     if (ret != ESP_OK) {
113         ESP_LOGE(TAG, "Failed to get SPIFFS partition information (%s)", esp_err_to_name(ret));
114     } else {
115         ESP_LOGI(TAG, "Partition size: total: %d, used: %d", total, used);
116     }
117 
118     /* The following calls demonstrate reading files from the generated SPIFFS
119      * image. The images should contain the same files and contents as the spiffs_image directory.
120      */
121 
122     // Read and display the contents of a small text file (hello.txt)
123     read_hello_txt();
124 
125     // Compute and display the MD5 hash of a large text file (alice.txt)
126     compute_alice_txt_md5();
127 
128     // All done, unmount partition and disable SPIFFS
129     esp_vfs_spiffs_unregister(NULL);
130     ESP_LOGI(TAG, "SPIFFS unmounted");
131 }
132