summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
authorAmaury Pouly <amaury.pouly@gmail.com>2017-01-08 16:07:18 +0100
committerAmaury Pouly <amaury.pouly@gmail.com>2017-01-08 16:07:18 +0100
commit1895af8e15474f87b6b34ca7a4e04425cf36c7ec (patch)
tree1f2744270117cc4c11d4ea9057a4bc163550dd45 /utils
parent26774ece35dd435345ca862a4d09ac94ed89e47b (diff)
downloadrockbox-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.c113
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 @@
39bool g_debug = false; 39bool g_debug = false;
40const char *g_force_series = NULL; 40const char *g_force_series = NULL;
41char *g_out_prefix = NULL; 41char *g_out_prefix = NULL;
42bool g_relaxed = false;
43rb_scsi_device_t g_dev; 42rb_scsi_device_t g_dev;
44 43
45static void print_hex(void *_buffer, int buffer_size) 44static 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
364int 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 */
364int 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 */
413int write_nvp_node(int series_index, enum nwz_nvp_node_t node, void *buffer, int size) 399int 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
447int get_dnk_nvp(int argc, char **argv) 425int 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 }