FreeCalypso > hg > freecalypso-tools
view ffstools/tiffs-rd/decode.c @ 733:bed7981ac8ca
doc/Compal-FFS: update for IMEI found in OTP cells
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 28 Aug 2020 15:58:46 +0000 |
parents | ed983d4040a8 |
children |
line wrap: on
line source
/* * This C module implements the decode command, displaying certain * FFS files in a developer-friendly decoded form. */ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include <unistd.h> #include "types.h" #include "struct.h" #include "globals.h" #include "pathname.h" extern void write_afcdac_ascii(); extern void write_stdmap_ascii(); extern void write_adccal_table(); extern void write_afcparams_table(); extern void write_tx_ramps_table(); extern void write_tx_levels_table(); extern void write_tx_calchan_table(); extern void write_tx_caltemp_table(); extern void write_rx_calchan_table(); extern void write_rx_caltemp_table(); extern void write_rx_agcparams_table(); static void pcm_IMEI_decode(bin, outf) u8 *bin; FILE *outf; { u8 rev[8]; unsigned n; for (n = 0; n < 8; n++) rev[n] = ((bin[n] & 0xF0) >> 4) | ((bin[n] & 0x0F) << 4); fprintf(outf, "%02X%02X%02X%02X-%02X%02X%02X-%02X\n", rev[0], rev[1], rev[2], rev[3], rev[4], rev[5], rev[6], rev[7]); } static struct map { char *req_name; char *pathname; int need_band; unsigned size; void (*decode_func)(); } map_table[] = { {"adccal", "/sys/adccal", 0, 36, write_adccal_table}, {"afcdac", "/gsm/rf/afcdac", 0, 2, write_afcdac_ascii}, {"afcparams", "/gsm/rf/afcparams", 0, 24, write_afcparams_table}, {"stdmap", "/gsm/rf/stdmap", 0, 2, write_stdmap_ascii}, {"tx-ramps", "/gsm/rf/tx/ramps.%s", 1, 512, write_tx_ramps_table}, {"tx-levels", "/gsm/rf/tx/levels.%s", 1, 128, write_tx_levels_table}, {"tx-calchan", "/gsm/rf/tx/calchan.%s", 1, 128, write_tx_calchan_table}, {"tx-caltemp", "/gsm/rf/tx/caltemp.%s", 1, 40, write_tx_caltemp_table}, {"rx-calchan", "/gsm/rf/rx/calchan.%s", 1, 40, write_rx_calchan_table}, {"rx-caltemp", "/gsm/rf/rx/caltemp.%s", 1, 44, write_rx_caltemp_table}, {"rx-agcparams", "/gsm/rf/rx/agcparams.%s", 1, 8, write_rx_agcparams_table}, {"pcm-IMEI", "/pcm/IMEI", 0, 8, pcm_IMEI_decode}, {0, 0, 0, 0, 0} }; static u8 file_read_buf[512]; static unsigned file_expected_size; static unsigned file_read_ptr; static void read_chunk(ch) struct chunkinfo *ch; { if (!ch->len) return; if (file_read_ptr + ch->len > file_expected_size) { fprintf(stderr, "error: FFS file is longer than expected\n"); exit(1); } bcopy(ch->start, file_read_buf + file_read_ptr, ch->len); file_read_ptr += ch->len; } static void segment_read_callback(inf, opaque) struct inode_info *inf; u_long opaque; { struct chunkinfo chi; size_extra_chunk(inf, &chi); read_chunk(&chi); } cmd_decode(argc, argv) char **argv; { struct map *map; char pathname[PATHNAME_BUF_SIZE]; int headino; struct inode_info *inf; struct chunkinfo chi; if (argc < 2) { usage: fprintf(stderr, "usage: decode file-keyword [band]\n"); exit(1); } for (map = map_table; map->req_name; map++) if (!strcmp(map->req_name, argv[1])) break; if (!map->req_name) { fprintf(stderr, "error: file keyword \"%s\" not known\n", argv[1]); exit(1); } if (map->need_band) { if (argc < 3) { fprintf(stderr, "error: band not specified for %s table\n", map->req_name); exit(1); } if (argc > 3) goto usage; if (strlen(argv[2]) > 7) { fprintf(stderr, "error: band name argument is too long\n"); exit(1); } sprintf(pathname, map->pathname, argv[2]); } else { if (argc > 2) goto usage; strcpy(pathname, map->pathname); } file_expected_size = map->size; read_ffs_image(); find_inode_block(); alloc_inode_table(); find_root_inode(); headino = find_pathname(pathname); inf = inode_info[headino]; if (inf->type != 0xF1) { fprintf(stderr, "error: FFS object is not a regular file\n"); exit(1); } size_head_chunk(inf, &chi); read_chunk(&chi); iterate_seg_file(headino, segment_read_callback, 0L, 0, 0); if (file_read_ptr < file_expected_size) { fprintf(stderr, "error: FFS file is shorter than expected\n"); exit(1); } map->decode_func(file_read_buf, stdout); exit(0); }