<p>Vadim Yanitskiy <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/12885">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
Harald Welte: Looks good to me, approved
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">firmware/lib: introduce TIFFS filesystem support<br><br>All known TI GSM firmwares implement some kind of flash file system, or FFS.<br>We call it TIFFS (Texas Instruments FFS) because it is TI's invention.<br><br>TIFFS is a file system with a hierarchical directory tree structure, and<br>with Unixy forward-slash-separated, case-sensitive pathnames; the semantics<br>of "what is a file" and "what is a directory" are exactly the same as in<br>UNIX; and TIFFS even supports symlinks, although that support is a little<br>under-developed, and apparently no FFS symlinks were ever used in any<br>production GSM device. Thus the FFS implemented in TI-based GSM devices<br>(modems and "dumbphone" handsets) is really no different from, for example,<br>JFFS2 in embedded Linux systems.<br><br>The FFS in a GSM device typically stores two kinds of content:<br><br> - Factory data: IMEI, RF calibration values, device make/model/revision<br> ID strings etc. These files are expected to be programmed on the<br> factory production line and not changed afterward.<br><br> - Dynamic data written into the FFS in normal device operation: contacts,<br> settings / preferences, call history, received SMS, etc.<br><br>It should be noted that both Compal (Mot C1xx) and Foxconn (Pirelli DP-L10)<br>vendors moved their vital per-unit factory data out of the FFS into their<br>own ad hoc flash data structures, leaving their FFS only for less<br>critical data. However, we do enable TIFFS access for them anyway.<br><br>The location of TIFFS within the flash memory of a given GSM device is<br>defined by the firmware design of that device, but is always some integral<br>number of contiguous flash sectors.<br><br> - On Motorola/Compal C139/140 phones, the FFS used by the original<br> proprietary firmware occupies 5 sectors of 64 KiB each (320 KiB<br> in total), starting at 0x370000. C11x/123 use smaller FFS<br> configurations, whereas C155/156 seem to have switched to some<br> other FFS format, different from our familiar TIFFS.<br><br> - On the Pirelli DP-L10, the FFS used by the original proprietary<br> firmware occupies 18 sectors of 256 KiB each (for 4.5 MiB in total),<br> starting at the beginning of the 2nd flash chip select (0x02000000<br> in the ARM7 address space).<br><br> - On FCDEV3B (FreeCalypso hardware), the FFS is located in the first<br> 8 sectors (of 256 KiB each) in the 2nd flash chip select bank,<br> which appears at 0x01800000 in the ARM7 address space.<br><br> - On the GTA01/02 GSM modem, FFS occupies 7 sectors of 64 KiB each,<br> starting at flash offset 0x380000.<br><br>For more information, please refer to the FreeCalypso project<br>documentation, from where this great contribution comes from.<br><br>Please note that existing MediaTek targets most likely use different<br>storage format as they have nothing from TI Calypso. Also, we don't<br>(yet) know the location of TIFFS on SE J100i and Compal E99 targets.<br><br>The TIFFS support is needed for the follow-up change, that<br>implements reading of the factory RF calibration values.<br><br>Tweaked (coding style changes) by Vadim Yanitskiy <axilirator@gmail.com><br>Change-Id: If6e212baeb10953129fb0d5253d263567f5e12d6<br>Related: OS#3582<br>---<br>M src/target/firmware/Makefile<br>M src/target/firmware/board/compal_e86/init.c<br>M src/target/firmware/board/compal_e88/init.c<br>M src/target/firmware/board/fcdev3b/init.c<br>M src/target/firmware/board/gta0x/init.c<br>M src/target/firmware/board/pirelli_dpl10/init.c<br>M src/target/firmware/include/string.h<br>A src/target/firmware/include/tiffs.h<br>M src/target/firmware/lib/Makefile<br>A src/target/firmware/lib/index.c<br>A src/target/firmware/lib/memcmp.S<br>A src/target/firmware/lib/strcmp.c<br>A src/target/firmware/tiffs/Makefile<br>A src/target/firmware/tiffs/globals.c<br>A src/target/firmware/tiffs/globals.h<br>A src/target/firmware/tiffs/init.c<br>A src/target/firmware/tiffs/readfile.c<br>17 files changed, 496 insertions(+), 2 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/target/firmware/Makefile b/src/target/firmware/Makefile</span><br><span>index 1196d10..914db6c 100644</span><br><span>--- a/src/target/firmware/Makefile</span><br><span>+++ b/src/target/firmware/Makefile</span><br><span>@@ -107,6 +107,7 @@</span><br><span> layer1/liblayer1.a \</span><br><span> lib/libmini.a \</span><br><span> comm/libcomm.a \</span><br><span style="color: hsl(120, 100%, 40%);">+ tiffs/libtiffs.a \</span><br><span> ../../shared/libosmocore/build-target/src/.libs/libosmocore.a \</span><br><span> ../../shared/libosmocore/build-target/src/gsm/.libs/libosmogsm.a \</span><br><span> ../../shared/libosmocore/build-target/src/codec/.libs/libosmocodec.a</span><br><span>@@ -123,6 +124,7 @@</span><br><span> -include calypso/Makefile</span><br><span> -include layer1/Makefile</span><br><span> -include comm/Makefile</span><br><span style="color: hsl(120, 100%, 40%);">+-include tiffs/Makefile</span><br><span> -include lib/Makefile</span><br><span> </span><br><span> # Include rules</span><br><span>diff --git a/src/target/firmware/board/compal_e86/init.c b/src/target/firmware/board/compal_e86/init.c</span><br><span>index fed9f85..725f184 100644</span><br><span>--- a/src/target/firmware/board/compal_e86/init.c</span><br><span>+++ b/src/target/firmware/board/compal_e86/init.c</span><br><span>@@ -31,6 +31,7 @@</span><br><span> #include <keypad.h></span><br><span> #include <console.h></span><br><span> #include <flash/cfi_flash.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tiffs.h></span><br><span> </span><br><span> #include <calypso/irq.h></span><br><span> #include <calypso/clock.h></span><br><span>@@ -146,4 +147,7 @@</span><br><span> </span><br><span> /* enable LEDB driver of Iota for keypad backlight */</span><br><span> twl3025_reg_write(AUXLED, 0x02);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Initialize TIFFS reader (5 sectors of 64 KiB each) */</span><br><span style="color: hsl(120, 100%, 40%);">+ tiffs_init(0x370000, 0x10000, 5);</span><br><span> }</span><br><span>diff --git a/src/target/firmware/board/compal_e88/init.c b/src/target/firmware/board/compal_e88/init.c</span><br><span>index 04ae458..956f7dc 100755</span><br><span>--- a/src/target/firmware/board/compal_e88/init.c</span><br><span>+++ b/src/target/firmware/board/compal_e88/init.c</span><br><span>@@ -30,6 +30,7 @@</span><br><span> #include <keypad.h></span><br><span> #include <console.h></span><br><span> #include <flash/cfi_flash.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tiffs.h></span><br><span> </span><br><span> #include <calypso/irq.h></span><br><span> #include <calypso/clock.h></span><br><span>@@ -142,4 +143,7 @@</span><br><span> </span><br><span> /* Initialize the charging controller */</span><br><span> battery_compal_e88_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Initialize TIFFS reader (6 sectors of 8 KiB each) */</span><br><span style="color: hsl(120, 100%, 40%);">+ tiffs_init(0x001f0000, 0x2000, 6);</span><br><span> }</span><br><span>diff --git a/src/target/firmware/board/fcdev3b/init.c b/src/target/firmware/board/fcdev3b/init.c</span><br><span>index 92be667..c070536 100644</span><br><span>--- a/src/target/firmware/board/fcdev3b/init.c</span><br><span>+++ b/src/target/firmware/board/fcdev3b/init.c</span><br><span>@@ -32,6 +32,7 @@</span><br><span> #include <keypad.h></span><br><span> #include <console.h></span><br><span> #include <flash/cfi_flash.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tiffs.h></span><br><span> </span><br><span> #include <calypso/irq.h></span><br><span> #include <calypso/clock.h></span><br><span>@@ -138,4 +139,7 @@</span><br><span> </span><br><span> /* Initialize ABB driver (uses SPI) */</span><br><span> twl3025_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Initialize TIFFS reader (8 sectors of 256 KiB each) */</span><br><span style="color: hsl(120, 100%, 40%);">+ tiffs_init(0x01800000, 0x40000, 8);</span><br><span> }</span><br><span>diff --git a/src/target/firmware/board/gta0x/init.c b/src/target/firmware/board/gta0x/init.c</span><br><span>index b93f79c..7fba756 100644</span><br><span>--- a/src/target/firmware/board/gta0x/init.c</span><br><span>+++ b/src/target/firmware/board/gta0x/init.c</span><br><span>@@ -30,6 +30,7 @@</span><br><span> #include <keypad.h></span><br><span> #include <console.h></span><br><span> #include <flash/cfi_flash.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tiffs.h></span><br><span> </span><br><span> #include <calypso/irq.h></span><br><span> #include <calypso/clock.h></span><br><span>@@ -132,4 +133,7 @@</span><br><span> </span><br><span> /* Initialize ABB driver (uses SPI) */</span><br><span> twl3025_init();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Initialize TIFFS reader (7 sectors of 64 KiB each) */</span><br><span style="color: hsl(120, 100%, 40%);">+ tiffs_init(0x380000, 0x10000, 7);</span><br><span> }</span><br><span>diff --git a/src/target/firmware/board/pirelli_dpl10/init.c b/src/target/firmware/board/pirelli_dpl10/init.c</span><br><span>index da23308..1af6e7c 100644</span><br><span>--- a/src/target/firmware/board/pirelli_dpl10/init.c</span><br><span>+++ b/src/target/firmware/board/pirelli_dpl10/init.c</span><br><span>@@ -31,6 +31,7 @@</span><br><span> #include <keypad.h></span><br><span> #include <console.h></span><br><span> #include <flash/cfi_flash.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <tiffs.h></span><br><span> </span><br><span> #include <calypso/irq.h></span><br><span> #include <calypso/clock.h></span><br><span>@@ -156,4 +157,7 @@</span><br><span> </span><br><span> /* enable LEDB driver of Iota for keypad backlight */</span><br><span> twl3025_reg_write(AUXLED, 0x02);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Initialize TIFFS reader (18 sectors of 256 KiB each) */</span><br><span style="color: hsl(120, 100%, 40%);">+ tiffs_init(0x02000000, 0x40000, 18);</span><br><span> }</span><br><span>diff --git a/src/target/firmware/include/string.h b/src/target/firmware/include/string.h</span><br><span>index f060659..ecef13d 100644</span><br><span>--- a/src/target/firmware/include/string.h</span><br><span>+++ b/src/target/firmware/include/string.h</span><br><span>@@ -9,4 +9,7 @@</span><br><span> void *memset(void *s, int c, size_t n);</span><br><span> void *memcpy(void *dest, const void *src, size_t n);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int memcmp(const void *s1, const void *s2, size_t n);</span><br><span style="color: hsl(120, 100%, 40%);">+int strcmp(const char *s1, const char *s2);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #endif</span><br><span>diff --git a/src/target/firmware/include/tiffs.h b/src/target/firmware/include/tiffs.h</span><br><span>new file mode 100644</span><br><span>index 0000000..4713c4e</span><br><span>--- /dev/null</span><br><span>+++ b/src/target/firmware/include/tiffs.h</span><br><span>@@ -0,0 +1,33 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * The external API for the TIFFS reader library (libtiffs).</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * For the file reading functions, the return code is 0 if the file wasn't</span><br><span style="color: hsl(120, 100%, 40%);">+ * found or there is no valid FFS (no error msg printed), 1 if the file was</span><br><span style="color: hsl(120, 100%, 40%);">+ * found and read successfully, or negative if some other error(s) occurred</span><br><span style="color: hsl(120, 100%, 40%);">+ * (error msg printed internally).</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define INODE_TO_DATAPTR(i) \</span><br><span style="color: hsl(120, 100%, 40%);">+ ((uint8_t *)tiffs_base_addr + ((i)->dataptr << 4))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define TIFFS_OBJTYPE_FILE 0xF1</span><br><span style="color: hsl(120, 100%, 40%);">+#define TIFFS_OBJTYPE_DIR 0xF2</span><br><span style="color: hsl(120, 100%, 40%);">+#define TIFFS_OBJTYPE_SEGMENT 0xF4</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct tiffs_inode {</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t len;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t reserved1;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t type;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t descend;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t sibling;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t dataptr;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t sequence;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint16_t updates;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int tiffs_init(uint32_t base_addr, uint32_t sector_size, unsigned nsectors);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int tiffs_read_file_maxlen(const char *pathname, uint8_t *buf,</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t maxlen, size_t *lenrtn);</span><br><span style="color: hsl(120, 100%, 40%);">+int tiffs_read_file_fixedlen(const char *pathname, uint8_t *buf,</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t expect_len);</span><br><span>diff --git a/src/target/firmware/lib/Makefile b/src/target/firmware/lib/Makefile</span><br><span>index a2a6d45..7546198 100644</span><br><span>--- a/src/target/firmware/lib/Makefile</span><br><span>+++ b/src/target/firmware/lib/Makefile</span><br><span>@@ -2,6 +2,7 @@</span><br><span> LIBRARIES+=mini</span><br><span> LIB_mini_DIR=lib</span><br><span> LIB_mini_SRCS=vsprintf.c string.c ctype.c printf.c console.c ctors.c \</span><br><span style="color: hsl(0, 100%, 40%);">- changebit.S clearbit.S delay.c div64.S lib1funcs.S memcpy.S memset.S setbit.S testchangebit.S testclearbit.S testsetbit.S</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(120, 100%, 40%);">+ changebit.S clearbit.S delay.c div64.S lib1funcs.S memcpy.S \</span><br><span style="color: hsl(120, 100%, 40%);">+ memset.S setbit.S testchangebit.S testclearbit.S testsetbit.S \</span><br><span style="color: hsl(120, 100%, 40%);">+ memcmp.S index.c strcmp.c</span><br><span> </span><br><span>diff --git a/src/target/firmware/lib/index.c b/src/target/firmware/lib/index.c</span><br><span>new file mode 100644</span><br><span>index 0000000..bb304c0</span><br><span>--- /dev/null</span><br><span>+++ b/src/target/firmware/lib/index.c</span><br><span>@@ -0,0 +1,12 @@</span><br><span style="color: hsl(120, 100%, 40%);">+char *</span><br><span style="color: hsl(120, 100%, 40%);">+index(p, ch)</span><br><span style="color: hsl(120, 100%, 40%);">+ register char *p, ch;</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ for (;; ++p) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (*p == ch)</span><br><span style="color: hsl(120, 100%, 40%);">+ return(p);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!*p)</span><br><span style="color: hsl(120, 100%, 40%);">+ return((char *)0);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ /* NOTREACHED */</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/target/firmware/lib/memcmp.S b/src/target/firmware/lib/memcmp.S</span><br><span>new file mode 100644</span><br><span>index 0000000..c60b170</span><br><span>--- /dev/null</span><br><span>+++ b/src/target/firmware/lib/memcmp.S</span><br><span>@@ -0,0 +1,18 @@</span><br><span style="color: hsl(120, 100%, 40%);">+ .text</span><br><span style="color: hsl(120, 100%, 40%);">+ .code 32</span><br><span style="color: hsl(120, 100%, 40%);">+ .globl memcmp</span><br><span style="color: hsl(120, 100%, 40%);">+memcmp:</span><br><span style="color: hsl(120, 100%, 40%);">+ cmp r2, #0</span><br><span style="color: hsl(120, 100%, 40%);">+ beq zero_len_out</span><br><span style="color: hsl(120, 100%, 40%);">+ mov r3, r0</span><br><span style="color: hsl(120, 100%, 40%);">+1: ldrb r0, [r3], #1</span><br><span style="color: hsl(120, 100%, 40%);">+ ldrb r12, [r1], #1</span><br><span style="color: hsl(120, 100%, 40%);">+ subs r0, r0, r12</span><br><span style="color: hsl(120, 100%, 40%);">+ bxne lr</span><br><span style="color: hsl(120, 100%, 40%);">+ subs r2, r2, #1</span><br><span style="color: hsl(120, 100%, 40%);">+ bne 1b</span><br><span style="color: hsl(120, 100%, 40%);">+ bx lr</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+zero_len_out:</span><br><span style="color: hsl(120, 100%, 40%);">+ mov r0, #0</span><br><span style="color: hsl(120, 100%, 40%);">+ bx lr</span><br><span>diff --git a/src/target/firmware/lib/strcmp.c b/src/target/firmware/lib/strcmp.c</span><br><span>new file mode 100644</span><br><span>index 0000000..9a7fa81</span><br><span>--- /dev/null</span><br><span>+++ b/src/target/firmware/lib/strcmp.c</span><br><span>@@ -0,0 +1,12 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Compare strings: s1>s2: >0 s1==s2: 0 s1<s2: <0</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+strcmp(s1, s2)</span><br><span style="color: hsl(120, 100%, 40%);">+ register char *s1, *s2;</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ while (*s1 == *s2++)</span><br><span style="color: hsl(120, 100%, 40%);">+ if (*s1++=='\0')</span><br><span style="color: hsl(120, 100%, 40%);">+ return(0);</span><br><span style="color: hsl(120, 100%, 40%);">+ return(*s1 - *--s2);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/target/firmware/tiffs/Makefile b/src/target/firmware/tiffs/Makefile</span><br><span>new file mode 100644</span><br><span>index 0000000..6ded9e8</span><br><span>--- /dev/null</span><br><span>+++ b/src/target/firmware/tiffs/Makefile</span><br><span>@@ -0,0 +1,5 @@</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+LIBRARIES+=tiffs</span><br><span style="color: hsl(120, 100%, 40%);">+LIB_tiffs_DIR=tiffs</span><br><span style="color: hsl(120, 100%, 40%);">+LIB_tiffs_SRCS=globals.c init.c readfile.c</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/src/target/firmware/tiffs/globals.c b/src/target/firmware/tiffs/globals.c</span><br><span>new file mode 100644</span><br><span>index 0000000..ffbba42</span><br><span>--- /dev/null</span><br><span>+++ b/src/target/firmware/tiffs/globals.c</span><br><span>@@ -0,0 +1,12 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* global variables for the TIFFS reader code */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include "globals.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uint32_t tiffs_base_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+uint32_t tiffs_sector_size;</span><br><span style="color: hsl(120, 100%, 40%);">+unsigned tiffs_nsectors;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct tiffs_inode *tiffs_active_index;</span><br><span style="color: hsl(120, 100%, 40%);">+int tiffs_root_ino;</span><br><span style="color: hsl(120, 100%, 40%);">+int tiffs_init_done;</span><br><span>diff --git a/src/target/firmware/tiffs/globals.h b/src/target/firmware/tiffs/globals.h</span><br><span>new file mode 100644</span><br><span>index 0000000..7c64693</span><br><span>--- /dev/null</span><br><span>+++ b/src/target/firmware/tiffs/globals.h</span><br><span>@@ -0,0 +1,9 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* global variables for the TIFFS reader code - extern declarations */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+extern uint32_t tiffs_base_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+extern uint32_t tiffs_sector_size;</span><br><span style="color: hsl(120, 100%, 40%);">+extern unsigned tiffs_nsectors;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+extern struct tiffs_inode *tiffs_active_index;</span><br><span style="color: hsl(120, 100%, 40%);">+extern int tiffs_root_ino;</span><br><span style="color: hsl(120, 100%, 40%);">+extern int tiffs_init_done;</span><br><span>diff --git a/src/target/firmware/tiffs/init.c b/src/target/firmware/tiffs/init.c</span><br><span>new file mode 100644</span><br><span>index 0000000..6a3b48a</span><br><span>--- /dev/null</span><br><span>+++ b/src/target/firmware/tiffs/init.c</span><br><span>@@ -0,0 +1,103 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* TIFFS (TI Flash File System) reader implementation */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2017 by Mychaela Falconia <mychaela.falconia@gmail.com></span><br><span style="color: hsl(120, 100%, 40%);">+ * Tweaked (coding style changes) by Vadim Yanitskiy <axilirator@gmail.com></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License along</span><br><span style="color: hsl(120, 100%, 40%);">+ * with this program; if not, write to the Free Software Foundation, Inc.,</span><br><span style="color: hsl(120, 100%, 40%);">+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdio.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <inttypes.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <tiffs.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include "globals.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Each flash sector used for TIFFS begins with this 6-byte signature */</span><br><span style="color: hsl(120, 100%, 40%);">+static const uint8_t ffs_sector_signature[6] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ 'F', 'f', 's', '#', 0x10, 0x02</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int find_indexblk(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint32_t sector_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t *sector_ptr;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ sector_addr = tiffs_base_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < tiffs_nsectors; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ sector_ptr = (uint8_t *) sector_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!memcmp(sector_ptr, ffs_sector_signature, 6)</span><br><span style="color: hsl(120, 100%, 40%);">+ && sector_ptr[8] == 0xAB) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Found TIFFS active index block "</span><br><span style="color: hsl(120, 100%, 40%);">+ "at 0x%" PRIx32 "\n", sector_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+ tiffs_active_index = (struct tiffs_inode *) sector_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ sector_addr += tiffs_sector_size;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ puts("TIFFS error: no active index block found\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int find_rootino(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct tiffs_inode *irec;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned ino = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ while (++ino < tiffs_sector_size >> 4) {</span><br><span style="color: hsl(120, 100%, 40%);">+ irec = tiffs_active_index + ino;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (irec->type != TIFFS_OBJTYPE_DIR)</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (*INODE_TO_DATAPTR(irec) != '/')</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Found TIFFS root inode at #%x\n", ino);</span><br><span style="color: hsl(120, 100%, 40%);">+ tiffs_root_ino = ino;</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ puts("TIFFS error: no root inode found\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int tiffs_init(uint32_t base_addr, uint32_t sector_size, unsigned nsectors)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("Looking for TIFFS (TI Flash File System) header at "</span><br><span style="color: hsl(120, 100%, 40%);">+ "0x%" PRIx32 ", %u sectors of 0x%" PRIx32 " bytes\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ base_addr, nsectors, sector_size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ tiffs_base_addr = base_addr;</span><br><span style="color: hsl(120, 100%, 40%);">+ tiffs_sector_size = sector_size;</span><br><span style="color: hsl(120, 100%, 40%);">+ tiffs_nsectors = nsectors;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = find_indexblk();</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = find_rootino();</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ tiffs_init_done = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/target/firmware/tiffs/readfile.c b/src/target/firmware/tiffs/readfile.c</span><br><span>new file mode 100644</span><br><span>index 0000000..f3e916f</span><br><span>--- /dev/null</span><br><span>+++ b/src/target/firmware/tiffs/readfile.c</span><br><span>@@ -0,0 +1,264 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* TIFFS (TI Flash File System) reader implementation */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2017 by Mychaela Falconia <mychaela.falconia@gmail.com></span><br><span style="color: hsl(120, 100%, 40%);">+ * Tweaked (coding style changes) by Vadim Yanitskiy <axilirator@gmail.com></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License along</span><br><span style="color: hsl(120, 100%, 40%);">+ * with this program; if not, write to the Free Software Foundation, Inc.,</span><br><span style="color: hsl(120, 100%, 40%);">+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdio.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <tiffs.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include "globals.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+extern char *index();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define MAX_FN_COMPONENT 20</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static unsigned find_named_child(unsigned start, const char *seekname)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct tiffs_inode *irec;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned ino;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (ino = start; ino != 0xFFFF; ino = irec->sibling) {</span><br><span style="color: hsl(120, 100%, 40%);">+ irec = tiffs_active_index + ino;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!irec->type)</span><br><span style="color: hsl(120, 100%, 40%);">+ continue;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!strcmp((const char *) INODE_TO_DATAPTR(irec), seekname))</span><br><span style="color: hsl(120, 100%, 40%);">+ return ino;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int pathname_to_inode(const char *pathname)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ char seekname[MAX_FN_COMPONENT + 1];</span><br><span style="color: hsl(120, 100%, 40%);">+ struct tiffs_inode *irec;</span><br><span style="color: hsl(120, 100%, 40%);">+ const char *cur, *next;</span><br><span style="color: hsl(120, 100%, 40%);">+ unsigned ino, namelen;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ cur = pathname;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (*cur == '/')</span><br><span style="color: hsl(120, 100%, 40%);">+ cur++;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (ino = tiffs_root_ino; cur; cur = next) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!*cur)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ next = index(cur, '/');</span><br><span style="color: hsl(120, 100%, 40%);">+ if (next == cur) {</span><br><span style="color: hsl(120, 100%, 40%);">+ puts("Malformed TIFFS pathname: multiple adjacent slashes\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (next) {</span><br><span style="color: hsl(120, 100%, 40%);">+ namelen = next - cur;</span><br><span style="color: hsl(120, 100%, 40%);">+ next++;</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ namelen = strlen(cur);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (namelen > MAX_FN_COMPONENT) {</span><br><span style="color: hsl(120, 100%, 40%);">+ puts("Malformed TIFFS pathname: component name too long\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(seekname, cur, namelen);</span><br><span style="color: hsl(120, 100%, 40%);">+ seekname[namelen] = '\0';</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ irec = tiffs_active_index + ino;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (irec->type != TIFFS_OBJTYPE_DIR) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* printf("Error: non-terminal non-directory\n"); */</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ino = find_named_child(irec->descend, seekname);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ino) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* printf("Error: pathname component not found\n"); */</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return ino;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static uint8_t *find_endofchunk(int ino)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct tiffs_inode *irec;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t *ptr;</span><br><span style="color: hsl(120, 100%, 40%);">+ int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ irec = tiffs_active_index + ino;</span><br><span style="color: hsl(120, 100%, 40%);">+ ptr = INODE_TO_DATAPTR(irec) + irec->len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < 16; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ ptr--;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!*ptr)</span><br><span style="color: hsl(120, 100%, 40%);">+ return ptr;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (*ptr != 0xFF)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("TIFFS error: inode #%x has no valid termination\n", ino);</span><br><span style="color: hsl(120, 100%, 40%);">+ return ptr; /* XXX */</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int get_file_head(const char *pathname, uint8_t **startret,</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t *sizeret, int *continue_ret)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct tiffs_inode *irec;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t *start, *end;</span><br><span style="color: hsl(120, 100%, 40%);">+ int ino, cont, size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ ino = pathname_to_inode(pathname);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (ino <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return ino;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ irec = tiffs_active_index + ino;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (irec->type != TIFFS_OBJTYPE_FILE) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("TIFFS error: '%s' is not a regular file\n", pathname);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ start = INODE_TO_DATAPTR(irec);</span><br><span style="color: hsl(120, 100%, 40%);">+ start += strlen((const char *) start) + 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ end = find_endofchunk(ino);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ size = end - start;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (size < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ size = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ cont = irec->descend;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (cont == 0xFFFF)</span><br><span style="color: hsl(120, 100%, 40%);">+ cont = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (startret)</span><br><span style="color: hsl(120, 100%, 40%);">+ *startret = start;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (sizeret)</span><br><span style="color: hsl(120, 100%, 40%);">+ *sizeret = size;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (continue_ret)</span><br><span style="color: hsl(120, 100%, 40%);">+ *continue_ret = cont;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int get_segment(int ino, uint8_t **startret,</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t *sizeret, int *continue_ret)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct tiffs_inode *irec;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t *start, *end;</span><br><span style="color: hsl(120, 100%, 40%);">+ int cont, size;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (;;) {</span><br><span style="color: hsl(120, 100%, 40%);">+ irec = tiffs_active_index + ino;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (irec->type)</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (irec->sibling == 0xFFFF) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("TIFFS error: segment inode #%d: "</span><br><span style="color: hsl(120, 100%, 40%);">+ "deleted and no sibling\n", ino);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ ino = irec->sibling;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (irec->type != TIFFS_OBJTYPE_SEGMENT) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("TIFFS error: inode #%x is not a segment\n", ino);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ start = INODE_TO_DATAPTR(irec);</span><br><span style="color: hsl(120, 100%, 40%);">+ end = find_endofchunk(ino);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ size = end - start;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (size <= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("TIFFS error: segment inode #%x has bad length\n", ino);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ cont = irec->descend;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (cont == 0xFFFF)</span><br><span style="color: hsl(120, 100%, 40%);">+ cont = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (startret)</span><br><span style="color: hsl(120, 100%, 40%);">+ *startret = start;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (sizeret)</span><br><span style="color: hsl(120, 100%, 40%);">+ *sizeret = size;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (continue_ret)</span><br><span style="color: hsl(120, 100%, 40%);">+ *continue_ret = cont;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int tiffs_read_file_maxlen(const char *pathname, uint8_t *buf,</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t maxlen, size_t *lenrtn)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t chunk_size, real_len, roomleft;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t *chunk_start;</span><br><span style="color: hsl(120, 100%, 40%);">+ int stat, cont;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!tiffs_init_done) {</span><br><span style="color: hsl(120, 100%, 40%);">+ puts("TIFFS reader is not initialized\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ stat = get_file_head(pathname, &chunk_start, &chunk_size, &cont);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (stat <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return stat;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (chunk_size > maxlen) {</span><br><span style="color: hsl(120, 100%, 40%);">+toobig: printf("TIFFS error: '%s' is bigger than the read buffer\n", pathname);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ real_len = chunk_size;</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(buf, chunk_start, chunk_size);</span><br><span style="color: hsl(120, 100%, 40%);">+ buf += chunk_size;</span><br><span style="color: hsl(120, 100%, 40%);">+ roomleft = maxlen - chunk_size;</span><br><span style="color: hsl(120, 100%, 40%);">+ while (cont) {</span><br><span style="color: hsl(120, 100%, 40%);">+ stat = get_segment(cont, &chunk_start, &chunk_size, &cont);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (stat < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return stat;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (chunk_size > roomleft)</span><br><span style="color: hsl(120, 100%, 40%);">+ goto toobig;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ real_len += chunk_size;</span><br><span style="color: hsl(120, 100%, 40%);">+ memcpy(buf, chunk_start, chunk_size);</span><br><span style="color: hsl(120, 100%, 40%);">+ buf += chunk_size;</span><br><span style="color: hsl(120, 100%, 40%);">+ roomleft -= chunk_size;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (lenrtn)</span><br><span style="color: hsl(120, 100%, 40%);">+ *lenrtn = real_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int tiffs_read_file_fixedlen(const char *pathname, uint8_t *buf,</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t expect_len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t real_len;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = tiffs_read_file_maxlen(pathname, buf, expect_len, &real_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (real_len != expect_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("TIFFS error: '%s' has the wrong length\n", pathname);</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/12885">change 12885</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/12885"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmocom-bb </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: If6e212baeb10953129fb0d5253d263567f5e12d6 </div>
<div style="display:none"> Gerrit-Change-Number: 12885 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: Vadim Yanitskiy <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-Reviewer: Max <msuraev@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Vadim Yanitskiy <axilirator@gmail.com> </div>