summaryrefslogtreecommitdiff
path: root/lib/x1000-installer/src/xf_update.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/x1000-installer/src/xf_update.c')
-rw-r--r--lib/x1000-installer/src/xf_update.c149
1 files changed, 0 insertions, 149 deletions
diff --git a/lib/x1000-installer/src/xf_update.c b/lib/x1000-installer/src/xf_update.c
deleted file mode 100644
index 5a7c3b0430..0000000000
--- a/lib/x1000-installer/src/xf_update.c
+++ /dev/null
@@ -1,149 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2021 Aidan MacDonald
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "xf_update.h"
23#include "xf_error.h"
24#include "file.h"
25#include "md5.h"
26#include <string.h>
27
28static int process_stream(struct xf_nandio* nio,
29 struct xf_map* map,
30 struct xf_stream* stream)
31{
32 void* buffer;
33 size_t count;
34 int rc;
35
36 /* calculate MD5 on the fly if taking a backup */
37 md5_context md5_ctx;
38 if(nio->mode == XF_NANDIO_READ)
39 md5_starts(&md5_ctx);
40
41 /* first deal with the file data */
42 size_t bytes_left = map->length;
43 while(bytes_left > 0) {
44 count = bytes_left;
45 rc = xf_nandio_get_buffer(nio, &buffer, &count);
46 if(rc)
47 return rc;
48
49 if(nio->mode == XF_NANDIO_READ) {
50 md5_update(&md5_ctx, buffer, count);
51 rc = xf_stream_write(stream, buffer, count);
52 } else {
53 rc = xf_stream_read(stream, buffer, count);
54 }
55
56 bytes_left -= count;
57
58 if(rc < 0 || (size_t)rc > count)
59 return XF_E_IO;
60
61 if((size_t)rc < count) {
62 /* backup - we could not write all the data */
63 if(nio->mode == XF_NANDIO_READ)
64 return XF_E_IO;
65
66 /* update - clear rest of buffer to 0xff */
67 memset(buffer + rc, 0xff, count - rc);
68 break;
69 }
70 }
71
72 /* if updating - write blanks to the remainder of the region */
73 while(bytes_left > 0) {
74 count = bytes_left;
75 rc = xf_nandio_get_buffer(nio, &buffer, &count);
76 if(rc)
77 return rc;
78
79 memset(buffer, 0xff, count);
80 bytes_left -= count;
81 }
82
83 /* finalize the MD5 sum */
84 if(nio->mode == XF_NANDIO_READ) {
85 md5_finish(&md5_ctx, map->md5);
86 map->file_length = map->length;
87 map->flags |= XF_MAP_HAS_MD5 | XF_MAP_HAS_FILE_LENGTH;
88 }
89
90 return XF_E_SUCCESS;
91}
92
93static int process_map(struct xf_nandio* nio, struct xf_map* map, int map_size,
94 xf_update_open_stream_cb open_stream, void* os_arg)
95{
96 int rc, rc2;
97 struct xf_stream stream;
98
99 /* ensure the map is sequential and non-overlapping before continuing */
100 if(xf_map_validate(map, map_size) != 0)
101 return XF_E_INVALID_PARAMETER;
102
103 for(int i = 0; i < map_size; ++i) {
104 /* seek to initial offset */
105 rc = xf_nandio_seek(nio, map[i].offset);
106 if(rc)
107 return rc;
108
109 rc = open_stream(os_arg, map[i].name, &stream);
110 if(rc)
111 return XF_E_CANNOT_OPEN_FILE;
112
113 /* process the stream and be sure to close it even on error */
114 rc = process_stream(nio, &map[i], &stream);
115 rc2 = xf_stream_close(&stream);
116
117 /* bail if either operation raised an error */
118 if(rc)
119 return rc;
120 if(rc2)
121 return rc2;
122 }
123
124 /* now flush to ensure all data was written */
125 rc = xf_nandio_flush(nio);
126 if(rc)
127 return rc;
128
129 return XF_E_SUCCESS;
130}
131
132static const enum xf_nandio_mode update_mode_to_nandio[] = {
133 [XF_UPDATE] = XF_NANDIO_PROGRAM,
134 [XF_BACKUP] = XF_NANDIO_READ,
135 [XF_VERIFY] = XF_NANDIO_VERIFY,
136};
137
138int xf_updater_run(enum xf_update_mode mode, struct xf_nandio* nio,
139 struct xf_map* map, int map_size,
140 xf_update_open_stream_cb open_stream, void* arg)
141{
142 /* Switch NAND I/O into the correct mode */
143 int rc = xf_nandio_set_mode(nio, update_mode_to_nandio[mode]);
144 if(rc)
145 return rc;
146
147 /* This does all the real work */
148 return process_map(nio, map, map_size, open_stream, arg);
149}