FreeCalypso > hg > freecalypso-tools
comparison ffstools/tiffs-rd/decode.c @ 726:d68275d47a32
tiffs IVA: decode command implemented
| author | Mychaela Falconia <falcon@freecalypso.org> |
|---|---|
| date | Fri, 28 Aug 2020 03:11:16 +0000 |
| parents | |
| children | ed983d4040a8 |
comparison
equal
deleted
inserted
replaced
| 725:232e36a227dd | 726:d68275d47a32 |
|---|---|
| 1 /* | |
| 2 * This C module implements the decode command, displaying certain | |
| 3 * FFS files in a developer-friendly decoded form. | |
| 4 */ | |
| 5 | |
| 6 #include <sys/types.h> | |
| 7 #include <stdio.h> | |
| 8 #include <stdlib.h> | |
| 9 #include <string.h> | |
| 10 #include <strings.h> | |
| 11 #include <unistd.h> | |
| 12 #include "types.h" | |
| 13 #include "struct.h" | |
| 14 #include "globals.h" | |
| 15 #include "pathname.h" | |
| 16 | |
| 17 extern void write_afcdac_ascii(); | |
| 18 extern void write_stdmap_ascii(); | |
| 19 extern void write_adccal_table(); | |
| 20 extern void write_afcparams_table(); | |
| 21 extern void write_tx_ramps_table(); | |
| 22 extern void write_tx_levels_table(); | |
| 23 extern void write_tx_calchan_table(); | |
| 24 extern void write_tx_caltemp_table(); | |
| 25 extern void write_rx_calchan_table(); | |
| 26 extern void write_rx_caltemp_table(); | |
| 27 extern void write_rx_agcparams_table(); | |
| 28 | |
| 29 static struct map { | |
| 30 char *req_name; | |
| 31 char *pathname; | |
| 32 int need_band; | |
| 33 unsigned size; | |
| 34 void (*decode_func)(); | |
| 35 } map_table[] = { | |
| 36 {"adccal", "/sys/adccal", 0, 36, write_adccal_table}, | |
| 37 {"afcdac", "/gsm/rf/afcdac", 0, 2, write_afcdac_ascii}, | |
| 38 {"afcparams", "/gsm/rf/afcparams", 0, 24, write_afcparams_table}, | |
| 39 {"stdmap", "/gsm/rf/stdmap", 0, 2, write_stdmap_ascii}, | |
| 40 {"tx-ramps", "/gsm/rf/tx/ramps.%s", 1, 512, write_tx_ramps_table}, | |
| 41 {"tx-levels", "/gsm/rf/tx/levels.%s", 1, 128, write_tx_levels_table}, | |
| 42 {"tx-calchan", "/gsm/rf/tx/calchan.%s", 1, 128, write_tx_calchan_table}, | |
| 43 {"tx-caltemp", "/gsm/rf/tx/caltemp.%s", 1, 40, write_tx_caltemp_table}, | |
| 44 {"rx-calchan", "/gsm/rf/rx/calchan.%s", 1, 40, write_rx_calchan_table}, | |
| 45 {"rx-caltemp", "/gsm/rf/rx/caltemp.%s", 1, 44, write_rx_caltemp_table}, | |
| 46 {"rx-agcparams", "/gsm/rf/rx/agcparams.%s", 1, 8, write_rx_agcparams_table}, | |
| 47 {0, 0, 0, 0, 0} | |
| 48 }; | |
| 49 | |
| 50 static u8 file_read_buf[512]; | |
| 51 static unsigned file_expected_size; | |
| 52 static unsigned file_read_ptr; | |
| 53 | |
| 54 static void | |
| 55 read_chunk(ch) | |
| 56 struct chunkinfo *ch; | |
| 57 { | |
| 58 if (!ch->len) | |
| 59 return; | |
| 60 if (file_read_ptr + ch->len > file_expected_size) { | |
| 61 fprintf(stderr, "error: FFS file is longer than expected\n"); | |
| 62 exit(1); | |
| 63 } | |
| 64 bcopy(ch->start, file_read_buf + file_read_ptr, ch->len); | |
| 65 file_read_ptr += ch->len; | |
| 66 } | |
| 67 | |
| 68 static void | |
| 69 segment_read_callback(inf, opaque) | |
| 70 struct inode_info *inf; | |
| 71 u_long opaque; | |
| 72 { | |
| 73 struct chunkinfo chi; | |
| 74 | |
| 75 size_extra_chunk(inf, &chi); | |
| 76 read_chunk(&chi); | |
| 77 } | |
| 78 | |
| 79 cmd_decode(argc, argv) | |
| 80 char **argv; | |
| 81 { | |
| 82 struct map *map; | |
| 83 char pathname[PATHNAME_BUF_SIZE]; | |
| 84 int headino; | |
| 85 struct inode_info *inf; | |
| 86 struct chunkinfo chi; | |
| 87 | |
| 88 if (argc < 2) { | |
| 89 usage: fprintf(stderr, "usage: decode file-keyword [band]\n"); | |
| 90 exit(1); | |
| 91 } | |
| 92 for (map = map_table; map->req_name; map++) | |
| 93 if (!strcmp(map->req_name, argv[1])) | |
| 94 break; | |
| 95 if (!map->req_name) { | |
| 96 fprintf(stderr, "error: file keyword \"%s\" not known\n", | |
| 97 argv[1]); | |
| 98 exit(1); | |
| 99 } | |
| 100 if (map->need_band) { | |
| 101 if (argc < 3) { | |
| 102 fprintf(stderr, | |
| 103 "error: band not specified for %s table\n", | |
| 104 map->req_name); | |
| 105 exit(1); | |
| 106 } | |
| 107 if (argc > 3) | |
| 108 goto usage; | |
| 109 if (strlen(argv[2]) > 7) { | |
| 110 fprintf(stderr, | |
| 111 "error: band name argument is too long\n"); | |
| 112 exit(1); | |
| 113 } | |
| 114 sprintf(pathname, map->pathname, argv[2]); | |
| 115 } else { | |
| 116 if (argc > 2) | |
| 117 goto usage; | |
| 118 strcpy(pathname, map->pathname); | |
| 119 } | |
| 120 file_expected_size = map->size; | |
| 121 | |
| 122 read_ffs_image(); | |
| 123 find_inode_block(); | |
| 124 alloc_inode_table(); | |
| 125 find_root_inode(); | |
| 126 | |
| 127 headino = find_pathname(pathname); | |
| 128 inf = inode_info[headino]; | |
| 129 if (inf->type != 0xF1) { | |
| 130 fprintf(stderr, "error: FFS object is not a regular file\n"); | |
| 131 exit(1); | |
| 132 } | |
| 133 size_head_chunk(inf, &chi); | |
| 134 read_chunk(&chi); | |
| 135 iterate_seg_file(headino, segment_read_callback, 0L, 0, 0); | |
| 136 if (file_read_ptr < file_expected_size) { | |
| 137 fprintf(stderr, "error: FFS file is shorter than expected\n"); | |
| 138 exit(1); | |
| 139 } | |
| 140 map->decode_func(file_read_buf, stdout); | |
| 141 exit(0); | |
| 142 } |
