diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2017-01-08 16:07:18 +0100 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2017-01-08 16:07:18 +0100 |
commit | 1895af8e15474f87b6b34ca7a4e04425cf36c7ec (patch) | |
tree | 1f2744270117cc4c11d4ea9057a4bc163550dd45 /utils | |
parent | 26774ece35dd435345ca862a4d09ac94ed89e47b (diff) | |
download | rockbox-1895af8e15474f87b6b34ca7a4e04425cf36c7ec.tar.gz rockbox-1895af8e15474f87b6b34ca7a4e04425cf36c7ec.zip |
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
Diffstat (limited to 'utils')
-rw-r--r-- | utils/nwztools/scsitools/scsitool.c | 113 |
1 files 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 @@ | |||
39 | bool g_debug = false; | 39 | bool g_debug = false; |
40 | const char *g_force_series = NULL; | 40 | const char *g_force_series = NULL; |
41 | char *g_out_prefix = NULL; | 41 | char *g_out_prefix = NULL; |
42 | bool g_relaxed = false; | ||
43 | rb_scsi_device_t g_dev; | 42 | rb_scsi_device_t g_dev; |
44 | 43 | ||
45 | static void print_hex(void *_buffer, int buffer_size) | 44 | static void print_hex(void *_buffer, int buffer_size) |
@@ -360,17 +359,10 @@ int get_model_and_series(int *model_index, int *series_index) | |||
360 | return 0; | 359 | return 0; |
361 | } | 360 | } |
362 | 361 | ||
363 | /* read nvp node, retrun nonzero on error, update size to actual length */ | 362 | /* Read nvp node, retrun nonzero on error, update size to actual length. The |
364 | int read_nvp_node(int series_index, enum nwz_nvp_node_t node, void *buffer, size_t *size) | 363 | * index is the raw node number sent to the device */ |
364 | int read_nvp_node(int node_index, void *buffer, size_t *size) | ||
365 | { | 365 | { |
366 | int node_index = NWZ_NVP_INVALID; | ||
367 | if(nwz_series[series_index].nvp_index) | ||
368 | node_index = (*nwz_series[series_index].nvp_index)[node]; | ||
369 | if(node_index == NWZ_NVP_INVALID) | ||
370 | { | ||
371 | printf("This device doesn't have node '%s'\n", nwz_nvp[node].name); | ||
372 | return 5; | ||
373 | } | ||
374 | /* the returned data has a 4 byte header: | 366 | /* the returned data has a 4 byte header: |
375 | * - byte 0/1 is the para_noise index, written as a 16bit big-endian number | 367 | * - byte 0/1 is the para_noise index, written as a 16bit big-endian number |
376 | * - byte 2/3 is the node index, written as a 16-bit big-endian number | 368 | * - 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 | |||
394 | cprintf(GREY, "Device responded with invalid data\n"); | 386 | cprintf(GREY, "Device responded with invalid data\n"); |
395 | return 1; | 387 | return 1; |
396 | } | 388 | } |
397 | if(!g_relaxed && xfer_size - 4 != (int)*size) | ||
398 | { | ||
399 | free(xfer_buf); | ||
400 | cprintf(GREY, "Device didn't send the expected amount of data\n"); | ||
401 | return 7; | ||
402 | } | ||
403 | *size = xfer_size - 4; | 389 | *size = xfer_size - 4; |
404 | /* unscramble and copy */ | 390 | /* unscramble and copy */ |
405 | for(int i = 4, idx = get_big_endian16(xfer_buf); i < xfer_size; i++, idx++) | 391 | 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 | |||
410 | } | 396 | } |
411 | 397 | ||
412 | /* read nvp node, retrun nonzero on error */ | 398 | /* read nvp node, retrun nonzero on error */ |
413 | int write_nvp_node(int series_index, enum nwz_nvp_node_t node, void *buffer, int size) | 399 | int write_nvp_node(int node_index, void *buffer, int size) |
414 | { | 400 | { |
415 | int node_index = NWZ_NVP_INVALID; | ||
416 | if(nwz_series[series_index].nvp_index) | ||
417 | node_index = (*nwz_series[series_index].nvp_index)[node]; | ||
418 | if(node_index == NWZ_NVP_INVALID) | ||
419 | { | ||
420 | printf("This device doesn't have node '%s'\n", nwz_nvp[node].name); | ||
421 | return 5; | ||
422 | } | ||
423 | /* the data buffer is prepended with a 4 byte header: | 401 | /* the data buffer is prepended with a 4 byte header: |
424 | * - byte 0/1 is the para_noise index, written as a 16bit big-endian number | 402 | * - byte 0/1 is the para_noise index, written as a 16bit big-endian number |
425 | * - byte 2/3 is the node index, written as a 16-bit big-endian number */ | 403 | * - 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 | |||
446 | 424 | ||
447 | int get_dnk_nvp(int argc, char **argv) | 425 | int get_dnk_nvp(int argc, char **argv) |
448 | { | 426 | { |
449 | if(argc != 1) | 427 | if(argc != 1 && argc != 2) |
450 | { | 428 | { |
451 | printf("You must specify a known nvp node or a full node specification:\n"); | 429 | printf("You must specify a known nvp node or a full node specification:\n"); |
452 | printf("Node usage: <node>\n"); | 430 | printf("Node usage: <node>\n"); |
431 | printf("Node usage: <node> <size>\n"); | ||
453 | printf("Nodes:\n"); | 432 | printf("Nodes:\n"); |
454 | for(unsigned i = 0; i < NWZ_NVP_COUNT; i++) | 433 | for(unsigned i = 0; i < NWZ_NVP_COUNT; i++) |
455 | printf(" %-6s%s\n", nwz_nvp[i].name, nwz_nvp[i].desc); | 434 | printf(" %-6s%s\n", nwz_nvp[i].name, nwz_nvp[i].desc); |
435 | printf("You can also specify a decimal or hexadecimal value directly\n"); | ||
456 | return 1; | 436 | return 1; |
457 | } | 437 | } |
458 | int series_index, model_index; | 438 | int series_index, model_index; |
459 | int ret = get_model_and_series(&model_index, &series_index); | 439 | int ret = get_model_and_series(&model_index, &series_index); |
460 | if(ret) | 440 | if(ret) |
461 | return ret; | 441 | return ret; |
442 | size_t size = 0; | ||
443 | /* maybe user specified an explicit size */ | ||
444 | if(argc == 2) | ||
445 | { | ||
446 | char *end; | ||
447 | size = strtoul(argv[1], &end, 0); | ||
448 | if(*end) | ||
449 | { | ||
450 | printf("Invalid user-specified size '%s'\n", argv[1]); | ||
451 | return 5; | ||
452 | } | ||
453 | } | ||
462 | /* find entry in NVP */ | 454 | /* find entry in NVP */ |
463 | enum nwz_nvp_node_t node = NWZ_NVP_COUNT; | 455 | const char *node_name = argv[0]; |
456 | const char *node_desc = NULL; | ||
457 | int node_index = NWZ_NVP_INVALID; | ||
464 | for(int i = 0; i < NWZ_NVP_COUNT; i++) | 458 | for(int i = 0; i < NWZ_NVP_COUNT; i++) |
465 | if(strcmp(nwz_nvp[i].name, argv[0]) == 0) | 459 | if(strcmp(nwz_nvp[i].name, node_name) == 0) |
466 | node = i; | 460 | { |
467 | if(node== NWZ_NVP_COUNT) | 461 | if(nwz_series[series_index].nvp_index) |
462 | node_index = (*nwz_series[series_index].nvp_index)[i]; | ||
463 | if(node_index == NWZ_NVP_INVALID) | ||
464 | { | ||
465 | printf("This device doesn't have node '%s'\n", node_name); | ||
466 | return 5; | ||
467 | } | ||
468 | node_desc = nwz_nvp[i].desc; | ||
469 | /* if not overriden, try to get size from database */ | ||
470 | if(size == 0) | ||
471 | size = nwz_nvp[i].size; | ||
472 | } | ||
473 | /* if we can't find it, maybe check if it's a number */ | ||
474 | if(node_index == NWZ_NVP_INVALID) | ||
468 | { | 475 | { |
469 | printf("I don't know about node '%s'\n", argv[0]); | 476 | char *end; |
477 | node_index = strtol(node_name, &end, 0); | ||
478 | if(*end) | ||
479 | node_index = NWZ_NVP_INVALID; /* string is not a number */ | ||
480 | } | ||
481 | if(node_index == NWZ_NVP_INVALID) | ||
482 | { | ||
483 | printf("I don't know about node '%s'\n", node_name); | ||
470 | return 4; | 484 | return 4; |
471 | } | 485 | } |
472 | size_t size = nwz_nvp[node].size; | 486 | /* if we don't have a size, take a big size to be sure */ |
473 | /* in relaxed mode, always ask for a lot of data to make sure we get everything */ | 487 | if(size == 0) |
474 | if(g_relaxed) | 488 | { |
475 | size = 4096; | 489 | size = 4096; |
490 | printf("Note: node size unknown, trying to read %u bytes\n", (unsigned)size); | ||
491 | } | ||
492 | if(g_debug) | ||
493 | printf("Asking device for %u bytes\n", (unsigned)size); | ||
494 | /* take the size in the database as a hint of the size, but the device could | ||
495 | * return less data */ | ||
476 | uint8_t *buffer = malloc(size); | 496 | uint8_t *buffer = malloc(size); |
477 | ret = read_nvp_node(series_index, node, buffer, &size); | 497 | ret = read_nvp_node(node_index, buffer, &size); |
478 | if(ret != 0) | 498 | if(ret != 0) |
479 | { | 499 | { |
480 | free(buffer); | 500 | free(buffer); |
481 | return ret; | 501 | return ret; |
482 | } | 502 | } |
483 | cprintf(GREEN, "%s:\n", nwz_nvp[node].name); | 503 | cprintf(GREEN, "%s (node %d%s%s):\n", node_name, node_index, |
504 | node_desc ? "," : "", node_desc ? node_desc : ""); | ||
484 | print_hex(buffer, size); | 505 | print_hex(buffer, size); |
485 | 506 | ||
486 | free(buffer); | 507 | free(buffer); |
@@ -696,10 +717,18 @@ int do_dest(int argc, char **argv) | |||
696 | /* get model/series */ | 717 | /* get model/series */ |
697 | int model_index, series_index; | 718 | int model_index, series_index; |
698 | int ret = get_model_and_series(&model_index, &series_index); | 719 | int ret = get_model_and_series(&model_index, &series_index); |
720 | int shp_index = NWZ_NVP_INVALID; | ||
721 | if(nwz_series[series_index].nvp_index) | ||
722 | shp_index = (*nwz_series[series_index].nvp_index)[NWZ_NVP_SHP]; | ||
723 | if(shp_index == NWZ_NVP_INVALID) | ||
724 | { | ||
725 | printf("This device doesn't have node 'shp'\n"); | ||
726 | return 5; | ||
727 | } | ||
699 | /* in all cases, we need to read shp */ | 728 | /* in all cases, we need to read shp */ |
700 | size_t size = nwz_nvp[NWZ_NVP_SHP].size; | 729 | size_t size = nwz_nvp[NWZ_NVP_SHP].size; |
701 | uint8_t *shp = malloc(size); | 730 | uint8_t *shp = malloc(size); |
702 | ret = read_nvp_node(series_index, NWZ_NVP_SHP, shp, &size); | 731 | ret = read_nvp_node(shp_index, shp, &size); |
703 | if(ret != 0) | 732 | if(ret != 0) |
704 | { | 733 | { |
705 | free(shp); | 734 | free(shp); |
@@ -770,7 +799,7 @@ int do_dest(int argc, char **argv) | |||
770 | } | 799 | } |
771 | set_little_endian32(shp, dst); | 800 | set_little_endian32(shp, dst); |
772 | set_little_endian32(shp + 4, sps); | 801 | set_little_endian32(shp + 4, sps); |
773 | int ret = write_nvp_node(series_index, NWZ_NVP_SHP, shp, size); | 802 | int ret = write_nvp_node(shp_index, shp, size); |
774 | free(shp); | 803 | free(shp); |
775 | return ret; | 804 | return ret; |
776 | } | 805 | } |
@@ -817,7 +846,6 @@ static void usage(void) | |||
817 | printf(" -d/--debug Display debug messages\n"); | 846 | printf(" -d/--debug Display debug messages\n"); |
818 | printf(" -c/--no-color Disable color output\n"); | 847 | printf(" -c/--no-color Disable color output\n"); |
819 | printf(" -s/--series <name> Force series (disable auto-detection, use '?' for the list)\n"); | 848 | printf(" -s/--series <name> Force series (disable auto-detection, use '?' for the list)\n"); |
820 | printf(" -r/--relaxed Relax length checks on nvp properties\n"); | ||
821 | printf("Commands:\n"); | 849 | printf("Commands:\n"); |
822 | for(unsigned i = 0; i < NR_CMDS; i++) | 850 | for(unsigned i = 0; i < NR_CMDS; i++) |
823 | printf(" %s\t%s\n", cmd_list[i].name, cmd_list[i].desc); | 851 | printf(" %s\t%s\n", cmd_list[i].name, cmd_list[i].desc); |
@@ -837,7 +865,7 @@ int main(int argc, char **argv) | |||
837 | {0, 0, 0, 0} | 865 | {0, 0, 0, 0} |
838 | }; | 866 | }; |
839 | 867 | ||
840 | int c = getopt_long(argc, argv, "?dcfo:s:r", long_options, NULL); | 868 | int c = getopt_long(argc, argv, "?dcfo:s:", long_options, NULL); |
841 | if(c == -1) | 869 | if(c == -1) |
842 | break; | 870 | break; |
843 | switch(c) | 871 | switch(c) |
@@ -859,9 +887,6 @@ int main(int argc, char **argv) | |||
859 | case 's': | 887 | case 's': |
860 | g_force_series = optarg; | 888 | g_force_series = optarg; |
861 | break; | 889 | break; |
862 | case 'r': | ||
863 | g_relaxed = true; | ||
864 | break; | ||
865 | default: | 890 | default: |
866 | abort(); | 891 | abort(); |
867 | } | 892 | } |