From 1895af8e15474f87b6b34ca7a4e04425cf36c7ec Mon Sep 17 00:00:00 2001 From: Amaury Pouly Date: Sun, 8 Jan 2017 16:07:18 +0100 Subject: nwztools/scitool: rework node size, remove relaxed mode The cool now takes the database as a hint and will not complain if the device returns less data. The tool also supports user provided size and raw node numbers that are not in the database (advanced usage). Change-Id: I8cec536718d7eff01c7803bea648d6122b82377a --- utils/nwztools/scsitools/scsitool.c | 113 ++++++++++++++++++++++-------------- 1 file changed, 69 insertions(+), 44 deletions(-) diff --git a/utils/nwztools/scsitools/scsitool.c b/utils/nwztools/scsitools/scsitool.c index ad7586a452..46951fdbbb 100644 --- a/utils/nwztools/scsitools/scsitool.c +++ b/utils/nwztools/scsitools/scsitool.c @@ -39,7 +39,6 @@ bool g_debug = false; const char *g_force_series = NULL; char *g_out_prefix = NULL; -bool g_relaxed = false; rb_scsi_device_t g_dev; static void print_hex(void *_buffer, int buffer_size) @@ -360,17 +359,10 @@ int get_model_and_series(int *model_index, int *series_index) return 0; } -/* read nvp node, retrun nonzero on error, update size to actual length */ -int read_nvp_node(int series_index, enum nwz_nvp_node_t node, void *buffer, size_t *size) +/* Read nvp node, retrun nonzero on error, update size to actual length. The + * index is the raw node number sent to the device */ +int read_nvp_node(int node_index, void *buffer, size_t *size) { - int node_index = NWZ_NVP_INVALID; - if(nwz_series[series_index].nvp_index) - node_index = (*nwz_series[series_index].nvp_index)[node]; - if(node_index == NWZ_NVP_INVALID) - { - printf("This device doesn't have node '%s'\n", nwz_nvp[node].name); - return 5; - } /* the returned data has a 4 byte header: * - byte 0/1 is the para_noise index, written as a 16bit big-endian number * - byte 2/3 is the node index, written as a 16-bit big-endian number @@ -394,12 +386,6 @@ int read_nvp_node(int series_index, enum nwz_nvp_node_t node, void *buffer, size cprintf(GREY, "Device responded with invalid data\n"); return 1; } - if(!g_relaxed && xfer_size - 4 != (int)*size) - { - free(xfer_buf); - cprintf(GREY, "Device didn't send the expected amount of data\n"); - return 7; - } *size = xfer_size - 4; /* unscramble and copy */ for(int i = 4, idx = get_big_endian16(xfer_buf); i < xfer_size; i++, idx++) @@ -410,16 +396,8 @@ int read_nvp_node(int series_index, enum nwz_nvp_node_t node, void *buffer, size } /* read nvp node, retrun nonzero on error */ -int write_nvp_node(int series_index, enum nwz_nvp_node_t node, void *buffer, int size) +int write_nvp_node(int node_index, void *buffer, int size) { - int node_index = NWZ_NVP_INVALID; - if(nwz_series[series_index].nvp_index) - node_index = (*nwz_series[series_index].nvp_index)[node]; - if(node_index == NWZ_NVP_INVALID) - { - printf("This device doesn't have node '%s'\n", nwz_nvp[node].name); - return 5; - } /* the data buffer is prepended with a 4 byte header: * - byte 0/1 is the para_noise index, written as a 16bit big-endian number * - byte 2/3 is the node index, written as a 16-bit big-endian number */ @@ -446,41 +424,84 @@ int write_nvp_node(int series_index, enum nwz_nvp_node_t node, void *buffer, int int get_dnk_nvp(int argc, char **argv) { - if(argc != 1) + if(argc != 1 && argc != 2) { printf("You must specify a known nvp node or a full node specification:\n"); printf("Node usage: \n"); + printf("Node usage: \n"); printf("Nodes:\n"); for(unsigned i = 0; i < NWZ_NVP_COUNT; i++) printf(" %-6s%s\n", nwz_nvp[i].name, nwz_nvp[i].desc); + printf("You can also specify a decimal or hexadecimal value directly\n"); return 1; } int series_index, model_index; int ret = get_model_and_series(&model_index, &series_index); if(ret) return ret; + size_t size = 0; + /* maybe user specified an explicit size */ + if(argc == 2) + { + char *end; + size = strtoul(argv[1], &end, 0); + if(*end) + { + printf("Invalid user-specified size '%s'\n", argv[1]); + return 5; + } + } /* find entry in NVP */ - enum nwz_nvp_node_t node = NWZ_NVP_COUNT; + const char *node_name = argv[0]; + const char *node_desc = NULL; + int node_index = NWZ_NVP_INVALID; for(int i = 0; i < NWZ_NVP_COUNT; i++) - if(strcmp(nwz_nvp[i].name, argv[0]) == 0) - node = i; - if(node== NWZ_NVP_COUNT) + if(strcmp(nwz_nvp[i].name, node_name) == 0) + { + if(nwz_series[series_index].nvp_index) + node_index = (*nwz_series[series_index].nvp_index)[i]; + if(node_index == NWZ_NVP_INVALID) + { + printf("This device doesn't have node '%s'\n", node_name); + return 5; + } + node_desc = nwz_nvp[i].desc; + /* if not overriden, try to get size from database */ + if(size == 0) + size = nwz_nvp[i].size; + } + /* if we can't find it, maybe check if it's a number */ + if(node_index == NWZ_NVP_INVALID) { - printf("I don't know about node '%s'\n", argv[0]); + char *end; + node_index = strtol(node_name, &end, 0); + if(*end) + node_index = NWZ_NVP_INVALID; /* string is not a number */ + } + if(node_index == NWZ_NVP_INVALID) + { + printf("I don't know about node '%s'\n", node_name); return 4; } - size_t size = nwz_nvp[node].size; - /* in relaxed mode, always ask for a lot of data to make sure we get everything */ - if(g_relaxed) + /* if we don't have a size, take a big size to be sure */ + if(size == 0) + { size = 4096; + printf("Note: node size unknown, trying to read %u bytes\n", (unsigned)size); + } + if(g_debug) + printf("Asking device for %u bytes\n", (unsigned)size); + /* take the size in the database as a hint of the size, but the device could + * return less data */ uint8_t *buffer = malloc(size); - ret = read_nvp_node(series_index, node, buffer, &size); + ret = read_nvp_node(node_index, buffer, &size); if(ret != 0) { free(buffer); return ret; } - cprintf(GREEN, "%s:\n", nwz_nvp[node].name); + cprintf(GREEN, "%s (node %d%s%s):\n", node_name, node_index, + node_desc ? "," : "", node_desc ? node_desc : ""); print_hex(buffer, size); free(buffer); @@ -696,10 +717,18 @@ int do_dest(int argc, char **argv) /* get model/series */ int model_index, series_index; int ret = get_model_and_series(&model_index, &series_index); + int shp_index = NWZ_NVP_INVALID; + if(nwz_series[series_index].nvp_index) + shp_index = (*nwz_series[series_index].nvp_index)[NWZ_NVP_SHP]; + if(shp_index == NWZ_NVP_INVALID) + { + printf("This device doesn't have node 'shp'\n"); + return 5; + } /* in all cases, we need to read shp */ size_t size = nwz_nvp[NWZ_NVP_SHP].size; uint8_t *shp = malloc(size); - ret = read_nvp_node(series_index, NWZ_NVP_SHP, shp, &size); + ret = read_nvp_node(shp_index, shp, &size); if(ret != 0) { free(shp); @@ -770,7 +799,7 @@ int do_dest(int argc, char **argv) } set_little_endian32(shp, dst); set_little_endian32(shp + 4, sps); - int ret = write_nvp_node(series_index, NWZ_NVP_SHP, shp, size); + int ret = write_nvp_node(shp_index, shp, size); free(shp); return ret; } @@ -817,7 +846,6 @@ static void usage(void) printf(" -d/--debug Display debug messages\n"); printf(" -c/--no-color Disable color output\n"); printf(" -s/--series Force series (disable auto-detection, use '?' for the list)\n"); - printf(" -r/--relaxed Relax length checks on nvp properties\n"); printf("Commands:\n"); for(unsigned i = 0; i < NR_CMDS; i++) printf(" %s\t%s\n", cmd_list[i].name, cmd_list[i].desc); @@ -837,7 +865,7 @@ int main(int argc, char **argv) {0, 0, 0, 0} }; - int c = getopt_long(argc, argv, "?dcfo:s:r", long_options, NULL); + int c = getopt_long(argc, argv, "?dcfo:s:", long_options, NULL); if(c == -1) break; switch(c) @@ -859,9 +887,6 @@ int main(int argc, char **argv) case 's': g_force_series = optarg; break; - case 'r': - g_relaxed = true; - break; default: abort(); } -- cgit v1.2.3