diag_sand_framework.h (85210B)
1 /** 2 * \file diag_sand_framework.h 3 * 4 * Framework utilities, structures and definitions 5 */ 6 /* 7 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 8 * 9 * Copyright 2007-2020 Broadcom Inc. All rights reserved. 10 */ 11 12 #ifndef DIAG_SAND_FRAMEWORK_H_INCLUDED 13 #define DIAG_SAND_FRAMEWORK_H_INCLUDED 14 15 #include <bcm/types.h> 16 #include <sal/types.h> 17 #include <sal/appl/field_types.h> 18 #include <shared/utilex/utilex_rhlist.h> 19 #include <appl/diag/parse.h> 20 #include <appl/diag/shell.h> 21 #include <appl/diag/sand/diag_sand_utils.h> 22 23 /* Command flags */ 24 /** 25 * Use this flag to make the ctest part of precommit & Atlas 26 * 1. If there is static test invocation list - PRECOMMIT per test takes precedence, flag per command is not relevant 27 * 2. IF there is only default test - flag per command is relevant 28 * 3. For dynamic list the check is double 29 * 3.1 To assign individual flag to each generated test use CTEST_PASS for command and appropriate flag per test 30 * 3.2 To block all dynamic commands from participate in precommit, use POSTCOMMIT or 0 31 * This flag precedence paradigm is valid for all ctest related flags 32 */ 33 #define CTEST_PRECOMMIT SAL_BIT(0) 34 /** 35 * The flag double flags absence 36 * No flag means that test will not participate in precommit but will be included in any other activity 37 * Precommit list is generated always by using boolean argument pre on command line for "run/list/export" 38 * This pre argument is used by precommit regression testing and atlas 39 */ 40 #define CTEST_POSTCOMMIT SAL_BIT(1) 41 /** 42 * Shell command willing to have proprietary argument processing, should use these command to skip framework one 43 */ 44 #define SH_CMD_LEGACY SAL_BIT(2) 45 /** 46 * Ctest - used to skip the command or specific test when running/export tests. These tests will be marked as skip on 47 * test lists 48 * Shell command - skip example execution 49 */ 50 #define SH_CMD_SKIP_EXEC SAL_BIT(3) 51 /** 52 * Internal framework flag assigned when ctest command examples execution is used with LoGger argument 53 * Prints full command before execution 54 */ 55 #define SH_CMD_LOG SAL_BIT(4) 56 /** 57 * There are certain test that should be processed differently. Tests marked by this flag are included in run/export 58 * only when random argument is used 59 */ 60 #define CTEST_RANDOM SAL_BIT(5) 61 /** 62 * Used for root level commands in shell framework to signal strict keyword verification vs keyword dictionary 63 */ 64 #define SH_CMD_VERIFY SAL_BIT(6) 65 /** 66 * Reserved for framework use - signals that sub-commands of this specific root should be registered in common shell 67 * dynamic list - allows e.g. to skip dnx keyword to invoke commands registered under dnx 68 */ 69 #define SH_CMD_SKIP_ROOT SAL_BIT(7) 70 /** 71 * Used to enable/disable command under success of conditional callback, that is supposed to be attached to command 72 * E.g. - command has no meaning for Adapter or the opposite, 73 * or command is only enabled when certain soc property present 74 */ 75 #define SH_CMD_CONDITIONAL SAL_BIT(8) 76 /** 77 * Represents system command argument "all" 78 * For internal framework usage only 79 */ 80 #define SH_CMD_ALL SAL_BIT(9) 81 /** 82 * Represents system command argument "force" 83 * For internal framework usage only 84 */ 85 #define SH_CMD_FORCE SAL_BIT(10) 86 /** 87 * Represents system command argument "failure" 88 * For internal framework usage only 89 */ 90 #define SH_CMD_FAILURE_ONLY SAL_BIT(11) 91 /* 92 * Tests that should not run after WB, should be marked by this flag 93 */ 94 #define SH_CMD_SKIP_TEST_WB SAL_BIT(12) 95 /** 96 * Represents system command argument "quiet", which deprecate all messages while executing shell examples 97 * For internal framework usage only 98 */ 99 #define SH_CMD_SILENT SAL_BIT(13) 100 /** 101 * Flag allows to pass control of random/precommit/postcommit to flag per dynamically generated test. 102 * See explanation to PRECOMMIT 103 */ 104 #define CTEST_PASS SAL_BIT(14) 105 /** 106 * Flag used in traverse to signal that the callback should be applied to branches as well and not only leafs. 107 * For internal use only 108 */ 109 #define SH_CMD_TRAVERSE_ALL SAL_BIT(15) 110 /** 111 * Flag used to signal shell command to redirect output into XML with predefined file. Previous one will be overwritten 112 */ 113 #define SH_CMD_OUTPUT_XML SAL_BIT(16) 114 /** 115 * Roll back to the original (before running the test) DBAL and SW state configuration after the test is done running. 116 */ 117 #define SH_CMD_ROLLBACK SAL_BIT(17) 118 /** 119 * Flag used to check whether amount of memory allocated was equal to freed one and in case of mismatch 120 * shell command will return error 121 */ 122 #define SH_CMD_MEMORY_CHECK SAL_BIT(18) 123 /** 124 * Flag used to mark the command which XML output will not be verified vs gold result during testing 125 * Stand alone comparison may be still performed 126 */ 127 #define SH_CMD_NO_XML_VERIFY SAL_BIT(19) 128 /** 129 * Flag used to mark the command which XML output will not be verified vs gold result during testing 130 * Stand alone comparison may be still performed 131 */ 132 #define SH_CMD_EXEC_LIST_ONLY SAL_BIT(20) 133 /** 134 * Flag used to mark the command which XML output will not be verified vs gold result during testing 135 * Stand alone comparison may be still performed 136 */ 137 #define SH_CMD_EXEC_PER_CORE SAL_BIT(21) 138 /** 139 * Flag used to mark the command which XML output will be verified vs CUSTOM gold result during testing. 140 */ 141 #define SH_CMD_CUSTOM_XML_VERIFY SAL_BIT(22) 142 /** 143 * Flag used to mark the command which test output will be in the user manual. 144 */ 145 #define CTEST_UM SAL_BIT(23) 146 /** 147 * Flag used to mark if the command is not part of the release user manual 148 */ 149 #define SH_CMD_NOT_RELEASE SAL_BIT(24) 150 /** 151 * Flag used to mark the when Ctest export should include all tests regardless soc properties/device 152 * (part of tests will not be included as a result of internal cb_invoke and building of the commands tree in the init stage). 153 */ 154 #define CTEST_ALL SAL_BIT(25) 155 156 #define CTEST_DEFAULT "default" 157 158 /** 159 * \brief 160 * Presence of this flag in argument state means that user explicitly used this option in shell command invocation 161 */ 162 #define SH_SAND_ARG_PRESENT SAL_BIT(0) 163 /** 164 * \brief 165 * Presence of this flag in argument state means that option has mask: name=value,mask 166 */ 167 #define SH_SAND_ARG_MASKED SAL_BIT(1) 168 /** 169 * \brief 170 * Presence of this flag in argument state means that option has range: name=start-end 171 * Range may be provided only for non-negative value 172 */ 173 #define SH_SAND_ARG_RANGE SAL_BIT(2) 174 /** 175 * \brief 176 * Presence of this flag in argument state means that option is dynamic one verified through callback 177 * Validation range is not enforced over dynamic options 178 */ 179 #define SH_SAND_ARG_DYNAMIC SAL_BIT(3) 180 /** 181 * \brief 182 * Presence of this flag in argument state means that option may be provided without argument name 183 */ 184 #define SH_SAND_ARG_FREE SAL_BIT(4) 185 /** 186 * \brief 187 * Presence of this flag in argument state means that examples are not required to utilize this argument 188 */ 189 #define SH_SAND_ARG_QUIET SAL_BIT(5) 190 191 /** 192 * \brief Maximum string size for single token input 193 */ 194 #define SH_SAND_MAX_TOKEN_SIZE 1024 195 #define SH_SAND_MAX_ARRAY32_SIZE 16 196 #define SH_SAND_MAX_SHORTCUT_SIZE 12 197 #define SH_SAND_MAX_KEYWORD_SIZE 32 198 #define SH_SAND_MAX_RESOURCE_SIZE SH_SAND_MAX_KEYWORD_SIZE + 3 /* Basic keyword plus 1 character for null term 199 * and 2 for plural form */ 200 #define SH_SAND_MAX_COMMAND_DEPTH 10 201 #define SH_SAND_MAX_TIME_SIZE 64 202 203 #define SH_SAND_MAX_UINT32 0xFFFFFFFF 204 205 #define FAMILY_NAME(unit) (SOC_IS_DNX(unit) ? ("dnx") : (SOC_IS_DNXF(unit) ? ("dnxf") : (""))) 206 207 struct sh_sand_cmd_s; 208 209 /** 210 * Enum that represent if it is a shell or ctest. 211 */ 212 typedef enum 213 { 214 MANUAL_TYPE_CTEST, 215 MANUAL_TYPE_SHELL, 216 MANUAL_TYPE_SHELL_RELEASE 217 } sh_manual_type_e; 218 219 /** 220 * \brief Typedef to construct structure that will hold all possible options of true and false 221 */ 222 typedef struct 223 { 224 /** 225 * String representing true or false statement 226 */ 227 char *string; 228 /** 229 * Value that will be FALSE for negative, TRUE for positive answers 230 */ 231 int value; 232 /** 233 * Description of specific enum value 234 */ 235 char *desc; 236 /** 237 * String allowing to obtain dynamic value, 238 * e.g. if first token is DNX_DATA - values will be obtained fron DNX Data module 239 */ 240 char *plugin_str; 241 } sh_sand_enum_t; 242 243 /** 244 * \brief Typedef for shell leaf command 245 * \par DIRECT INPUT: 246 * \param [in] keyword option name to be verified through the callback 247 * \param [in] id_p pointer to option identifier to be used by shell command, may be NULL 248 * \par INDIRECT OUTPUT: 249 * \param [out] id option identifier to be used by shell command, transferred through id_p variable 250 * \par DIRECT OUTPUT: 251 * \retval SAL_FIELD_TYPE_NONE for failure - option does not exist 252 * \retval SAL_FIELD_TYPE_* any other valid field type 253 */ 254 typedef shr_error_e( 255 *sh_sand_option_cb_t) ( 256 int unit, 257 char *keyword, 258 sal_field_type_e * type, 259 uint32 *id_p, 260 /* 261 * Void pointer for different kind os extensions 262 */ 263 void **ext_ptr_p); 264 265 /** 266 * \brief Typedef for init dynamic test/invocation list per leaf command 267 * \param [in] keyword option name to be verified through the callback 268 * \param [in] id_p pointer to option identifier to be used by shell command, may be NULL 269 * \return 270 * \retval _SHR_E_NONE for success 271 * \retval shr_error_e for any error 272 */ 273 typedef shr_error_e( 274 *sh_sand_invoke_cb_t) ( 275 int unit, 276 rhlist_t * invoke_list); 277 278 /* 279 * Flags for examples generation 280 */ 281 /** Add to list auto generated examples as well - used mainly for test purposes */ 282 #define SH_SAND_EXAMPLES_DYNAMIC 0x01 283 /** Add to list examples with full command, otherwise there will be only arguments */ 284 #define SH_SAND_EXAMPLES_FULL 0x02 285 286 /** 287 * \brief Typedef for init dynamic examples list per leaf command 288 * \param [in] unit - unit ID 289 * \param [in] flags - flags field is reserved for future use 290 * \param [in] sh_sand_cmd - leaf command, which examples we need to generate 291 * \param [in] examples_list - pointer to the example list used in add_exampel API 292 * 293 * \return 294 * \retval _SHR_E_NONE for success 295 * \retval shr_error_e for any error 296 */ 297 typedef shr_error_e( 298 *sh_sand_example_generate_cb_t) ( 299 int unit, 300 int flags, 301 struct sh_sand_cmd_s * sh_sand_cmd, 302 rhlist_t * examples_list); 303 304 /** 305 * \brief Typedef for init/deinit configuration before/after examples invocation 306 * \param [in] unit - unit id 307 * \return 308 * \retval _SHR_E_NONE for success 309 * \retval shr_error_e for any error 310 */ 311 typedef shr_error_e( 312 *sh_sand_simple_cb_t) ( 313 int unit); 314 315 /** 316 * \brief Union allowing to handle all types of parameters through the same pointer 317 */ 318 typedef union 319 { 320 /** 321 * String, copied from input 322 */ 323 char val_str[SH_SAND_MAX_TOKEN_SIZE]; 324 /** 325 * It is plain int value, but we use separate to mark the boolean 326 */ 327 int val_bool; 328 /** 329 * It is plain int value, but we use separate to mark the enum 330 */ 331 int val_enum; 332 /** 333 * 32 bit signed value 334 */ 335 int val_int32; 336 /** 337 * 32 bit unsigned value 338 */ 339 uint32 val_uint32; 340 /** 341 * MAC address - array of 6 bytes 342 */ 343 sal_mac_addr_t mac_addr; 344 /** 345 * IPv4 address - unsigned 32 bit value 346 */ 347 sal_ip_addr_t ip4_addr; 348 /** 349 * IPv6 address - array of 16 bytes 350 */ 351 sal_ip6_addr_t ip6_addr; 352 /** 353 * Array 32 bit unsigned value 354 */ 355 uint32 array_uint32[SH_SAND_MAX_ARRAY32_SIZE]; 356 /** 357 * Ports bitmap 358 */ 359 bcm_pbmp_t ports_bitmap; 360 } sh_sand_param_u; 361 362 /** 363 * \brief Union allowing to handle all types of parameters through the same pointer 364 */ 365 typedef union 366 { 367 /** 368 * 32 bit signed value 369 */ 370 int val_int32; 371 /** 372 * 32 bit unsigned value 373 */ 374 uint32 val_uint32; 375 } sh_sand_validation_u; 376 377 /* 378 * Keyword Flags 379 */ 380 #define SH_SAND_KEYWORD_SINGLE_CHARACTER_SHORTCUT 0x0001 381 #define SH_SAND_KEYWORD_ALLOW_DOUBLE 0x0002 382 383 /** 384 * \brief Control structure for command keyword definition, provided by framework 385 */ 386 typedef struct sh_sand_keyword_s 387 { 388 /** 389 * Keyword 390 */ 391 char *keyword; 392 /* 393 */ 394 uint32 flags; 395 /** 396 * Shortcut for the keyword obtained by capital letters 397 */ 398 char short_key[SH_SAND_MAX_SHORTCUT_SIZE]; 399 /** 400 * List for all alternatives, that should not be assigned separate keyword 401 * 1. Plural form for the keyword, no plural being provided in the sh_sand_keywords means auto creation 402 * 2. Any variation that is keyword_# or keyword# 403 */ 404 rhlist_t *var_list[SOC_MAX_NUM_DEVICES]; 405 /** 406 * How much times specific keyword was used 407 */ 408 int count; 409 /** 410 * List of commands used this keyword 411 */ 412 rhlist_t *cmd_list[SOC_MAX_NUM_DEVICES]; 413 } sh_sand_keyword_t; 414 415 /** 416 * \brief Control structure for cli option definition, provided by command developer 417 */ 418 typedef struct sh_sand_option_s 419 { 420 /** 421 * Option Name 422 */ 423 char *keyword; 424 /** 425 * Option type, used to scan from string into value and print the option 426 */ 427 sal_field_type_e type; 428 /** 429 * Brief description, used in usage 430 */ 431 char *desc; 432 /** 433 * Default string in the same format, as CLI user is supposed to enter 434 */ 435 char *def; 436 /* 437 * Void pointer for different kind of extensions 438 */ 439 void *ext_ptr; 440 /* 441 * String representing valid range for certain types of options:INT32, UINT32 442 */ 443 char *valid_range; 444 /* 445 * Misc flags: See Shell Argument FLags above - SH_SAND_ARG_* 446 */ 447 int flags; 448 /* 449 * On init/verify short key based on capital letters in sh_sand_keyword is assigned 450 */ 451 char *short_key; 452 /* 453 * On init/verify put here pointer to resource for the keyword found 454 */ 455 char *full_key; 456 } sh_sand_option_t; 457 458 /** 459 * \brief Control structure for processed CLI option, provided by framework to leaf command. 460 * Structure is initialized once and then only param_buffer, param and present variables are updated per command invocation 461 */ 462 typedef struct sh_sand_args_s 463 { 464 /** 465 * Entry allows single element to be queued on argument list, provided as input parameter for leaf routine 466 */ 467 rhentry_t entry; 468 /** 469 * Option type, used to scan from string into value and print the option 470 */ 471 sal_field_type_e type; 472 /** 473 * Identify different info per option 474 * whether specific parameter was present or not on command line 475 * whether mask was present or not, range or not 476 * See full list above SH_SAND_ARG_* 477 */ 478 int state; 479 /** 480 * Identify whether specific parameter is requested to be present - aka must option. 481 * It happens, when no default is defined. Pay attention that string option having empty one as default is valid default definition 482 * Only NULL pointer for default is considered absence of default 483 */ 484 int requested; 485 /** 486 * If option present 487 * 1. If the option is single it will be here 488 * 2. If it is range, start will be here 489 * 3. If it is masked value, value will be here 490 */ 491 sh_sand_param_u param1; 492 /** 493 * If option present 494 * 1. If the option is single, nothing will be here - should not be accessed 495 * 2. If it is range, end will be here 496 * 3. If it is masked value, value will be here, if no mask provided will filled by 0xFF 497 */ 498 sh_sand_param_u param2; 499 /** 500 * Identify different default info per option 501 * whether specific parameter was present or not on command line 502 * whether mask was present or not, range or not 503 */ 504 int def_state; 505 /** 506 * Contains default value for param1 (see above) 507 */ 508 sh_sand_param_u def_param1; 509 /** 510 * Contains default value for param2 (see above) 511 */ 512 sh_sand_param_u def_param2; 513 /** 514 * Low end of valid range 515 */ 516 sh_sand_validation_u low; 517 /** 518 * High end of valid range 519 */ 520 sh_sand_validation_u high; 521 /* 522 * Void pointer for different kind of extensions 523 */ 524 void *ext_ptr; 525 /* 526 * Shortcut for option 527 */ 528 char *short_key; 529 } sh_sand_arg_t; 530 531 /* 532 * \brief - describes ctest test type 533 */ 534 typedef enum 535 { 536 SHR_SAND_CTEST_TYPE_UNKNOWN, 537 SHR_SAND_CTEST_TYPE_SEMANTIC, 538 SHR_SAND_CTEST_TYPE_FUNCTIONAL 539 } sh_sand_ctest_type_t; 540 541 /* 542 * \brief - describes ctest documentation 543 */ 544 typedef struct 545 { 546 /* 547 * Number 1-3, 1 - most important 548 */ 549 uint32 priority; 550 551 /* 552 * Test type. If NULL, the default is being used. 553 */ 554 sh_sand_ctest_type_t type; 555 556 /* 557 * In case Test module contain several sub features, each sub-feature will be mentioned as sub-topic 558 * Default is being used instead when NULL. 559 */ 560 const char *sub_feature; 561 562 /* 563 * Functional Requirements - The user story, i.e. requirement from customer point of view. 564 * Man's brief is used instead when NULL. 565 */ 566 const char *brief; 567 568 /* 569 * CFD JIRA if any 570 */ 571 const char *bug; 572 573 /* 574 * Description of what is going on in the test. 575 * FULL description from man is taken instead when NULL. 576 */ 577 const char *procedures; 578 579 /* 580 * Result expected from running "Test Procedure". 581 * Default is being used instead when NULL. 582 */ 583 const char *result; 584 585 /* 586 * Additional notes, if any, free text. 587 * Default is being used instead when NULL. 588 */ 589 const char *note; 590 591 } sh_sand_ctest_doc_t; 592 593 /** 594 * \brief Set of pointers to different info strings, which assembles into usage or man page 595 */ 596 typedef struct 597 { 598 /** 599 * brief command description not more than 80 characters 600 */ 601 const char *brief; 602 /** 603 * Full command description limited by 1024 characters. May be increased through PRT_LONG_STR_SIZE 604 */ 605 const char *full; 606 /** 607 * How command line should look like. 608 * E.g. access list [name=str] [property={reg, mem, signal, array}] 609 */ 610 char *synopsis; 611 /** 612 * Characteristic examples of command usage 613 */ 614 char *examples; 615 /** 616 * Characteristic examples of command usage 617 */ 618 char *compatibility; 619 /* 620 * Invoke this callback (if not NULL) before execution of examples 621 * Usually serves to establish configuration that will allow command to work 622 */ 623 sh_sand_simple_cb_t init_cb; 624 /* 625 * Invoke this callback (if not NULL) after execution of examples to clean the system 626 */ 627 sh_sand_simple_cb_t deinit_cb; 628 /* 629 * Callback allowing to add dynamically list of examples/tests per command 630 */ 631 sh_sand_example_generate_cb_t example_generate_cb; 632 } sh_sand_man_t; 633 634 /** 635 * \brief Control structure for shell command arguments, generated by command init and updated on invoke 636 */ 637 typedef struct 638 { 639 /** 640 * Pointer to static arguments list processed by framework. 641 */ 642 rhlist_t *stat_args_list; /* List of actual arguments, initialized on verify */ 643 /** 644 * Pointer to dynamic arguments list obtained through callback from user. 645 * List is emptied on action completion, but not erased 646 */ 647 rhlist_t *dyn_args_list; /* List of actual arguments, approved dynamically by user */ 648 /** 649 * String that will contain all command line options 650 * It is set to EMPTY before new command options processing 651 */ 652 char options_str[SH_SAND_MAX_TOKEN_SIZE]; 653 /* 654 * Each command may generate number of tables, all the tables from 1 invocation should be placed under the same node 655 * 1. time stamp will be nullified before command invocation 656 * 2. 1st table will create command node 657 * 3. rest of tables will be placed under the same command node 658 */ 659 char time_str[SH_SAND_MAX_TIME_SIZE]; 660 /* 661 * System commands require pointer to underlying command array 662 */ 663 struct sh_sand_cmd_s *sh_sand_cmd_a; 664 struct sh_sand_cmd_s *sh_sys_cmd_a; 665 struct sh_sand_cmd_s *sh_sand_cmd; 666 } sh_sand_control_t; 667 668 /** 669 * \brief Typedef for shell leaf command 670 * \par DIRECT INPUT: 671 * \param [in] unit unit id 672 * \param [in] args pointer standard bcm shell argument structure, used by parse.h MACROS and routines 673 * \param [in] ctr pointer to list of options processed by sand framework to be used with SH_SAND MACROS 674 * \par DIRECT OUTPUT: 675 * \retval _SHR_E_NONE for success 676 * \retval _SHR_E_PARAM problem with input parameters, usage should be printed 677 * \retval other errors for other failure type 678 * \remark automatically frees the list 679 */ 680 typedef shr_error_e( 681 *sh_sand_func_t) ( 682 int unit, 683 args_t * args, 684 sh_sand_control_t * ctr); 685 686 /** 687 * \brief Control structure for full definition, provided by command developer 688 */ 689 typedef struct sh_sand_invoke_s 690 { 691 /** 692 * Pointer to test name 693 */ 694 char *name; 695 /** 696 * Pointer to string with all parameters requested for specific command 697 * e.g for "ctest mdb" - "table=LPM_PRIVATE", so that entire test line will be "ctest mdb table=LPM_PRIVATE" 698 */ 699 char *params; 700 /** 701 * Flow execution flags, pointing to the stage test will take part in or other flow control 702 */ 703 int flags; 704 } sh_sand_invoke_t; 705 706 /** 707 * \brief Control structure for test list 708 */ 709 typedef struct sh_sand_test_s 710 { 711 /** 712 * Entry allows single element to be queued on argument list, provided as input parameter for leaf routine 713 */ 714 rhentry_t entry; 715 /** 716 * Pointer to string with all parameters requested for specific command 717 * e.g for "ctest mdb" - "table=LPM_PRIVATE", so that entire test line will be "ctest mdb table=LPM_PRIVATE" 718 */ 719 char *params; 720 /** 721 * Flow execution flags, pointing to the stage test will take part in or other flow control 722 */ 723 int flags; 724 } sh_sand_test_t; 725 /** 726 * \brief Control structure for shell command definition, provided by command developer 727 */ 728 729 typedef struct sh_sand_cmd_s 730 { 731 /** 732 * Command name 733 */ 734 char *keyword; 735 /** 736 * Pointer to leaf callback, if there is one 737 */ 738 sh_sand_func_t action; 739 /** 740 * Pointer to next level command array, if there is one 741 */ 742 struct sh_sand_cmd_s *child_cmd_a; 743 /** 744 * Pointer to options list 745 */ 746 sh_sand_option_t *options; 747 /** 748 * Pointer to man info structure, must be provided if command has leaf 749 */ 750 sh_sand_man_t *man; /* Manual structure */ 751 /* 752 * When there is a need to accept dynamic options, callback need to be provided 753 * Callback returns variable type and unique id that will allow to identify it inside without search 754 */ 755 sh_sand_option_cb_t option_cb; 756 /* 757 * When there is a need to accept dynamic options, callback need to be provided 758 * Callback returns variable type and unique id that will allow to identify it inside without search 759 */ 760 sh_sand_invoke_t *invokes; 761 /* 762 * Misc flags, including 763 * 1. Legacy mode serves to support legacy commands, do not enable with new/rewritten ones 764 * 2. PRE/POST Commit indication for CTEST 765 */ 766 int flags; 767 /* 768 * Callback allowing to add dynamically list of invocations/tests per command 769 * For non-ctest shell commands is used as enable/disable callback. 770 * If callback returns FALSE - command is not active 771 */ 772 sh_sand_invoke_cb_t invoke_cb; 773 /* 774 * From this place down - dynamic variable, changing in each command invocation 775 */ 776 /* 777 * On init/verify short key based on capital letters in sh_sand_keyword is assigned 778 */ 779 char *short_key; 780 /* 781 * On init/verify put here pointer to resource for the keyword found 782 */ 783 char *full_key; 784 /* 785 * String containing sequence of commands from root to the leaf 786 */ 787 char cmd_only[SH_SAND_MAX_TOKEN_SIZE]; 788 /** 789 * Pointer to legacy command list 790 */ 791 rhlist_t *legacy_list; 792 /** 793 * Pointer to parent command, if it is not the root 794 */ 795 struct sh_sand_cmd_s *parent_cmd; 796 /* 797 * String containing label. 798 */ 799 char label[SH_SAND_MAX_TOKEN_SIZE]; 800 801 /* 802 * CTest documentation 803 */ 804 sh_sand_ctest_doc_t *doc; 805 806 } sh_sand_cmd_t; 807 808 typedef struct 809 { 810 rhentry_t entry; 811 /* 812 * Short Key to utilize capital letters shortcuts in legacy commands 813 */ 814 char short_key[SH_SAND_MAX_SHORTCUT_SIZE]; 815 /* 816 * Pointer to next tokens list 817 */ 818 rhlist_t *next_tokens_list; 819 /** 820 * Message to be printed when legacy command is used 821 */ 822 char *message; 823 /** 824 * Substitute command to be invoked on behalf of legacy one, no command is NULL 825 */ 826 char *substitute; 827 } sh_sand_legacy_entry_t; 828 829 typedef struct 830 { 831 /** 832 * Legacy command 833 */ 834 const char *command; 835 /** 836 * Message to be printed when legacy command is used 837 */ 838 const char *message; 839 /** 840 * Substitute command to be invoked on behalf of legacy one, no command is NULL 841 */ 842 const char *substitute; 843 } sh_sand_legacy_cmd_t; 844 845 /** 846 * \brief Iterate over command array looking for valid commands 847 * \param [in] sh_sand_cmd_curr - pointer to command that holds current 848 * \param [in] sh_sand_cmd_array - pointer to command array that is being iterated 849 * \param [in] flags - pointer to CTEST flags 850 * \remark Valid commands are ones without CONDITIONAL flag or with null callback or callback returning success or with CTEST_ALL flag 851 */ 852 #define SH_SAND_CMD_ITERATOR_COND(sh_sand_cmd_curr, sh_sand_cmd_array, flags) \ 853 for (sh_sand_cmd_curr = sh_sand_cmd_array; \ 854 sh_sand_cmd_curr != NULL && sh_sand_cmd_curr->keyword != NULL; sh_sand_cmd_curr++) \ 855 if(!(sh_sand_cmd_curr->flags & SH_CMD_CONDITIONAL) || \ 856 (sh_sand_cmd_curr->invoke_cb == NULL) || \ 857 (sh_sand_cmd_curr->invoke_cb(unit, NULL) == _SHR_E_NONE) || \ 858 (flags & CTEST_ALL) ) 859 860 /** 861 * \brief Typedef for traverse callback command 862 * \par DIRECT INPUT: 863 * \param [in] unit unit id 864 * \param [in] args pointer standard bcm shell argument structure, used by parse.h MACROS and routines 865 * \param [in] cmd pointer to leaf command that traversing arrived to 866 * \param [in] prt_ctr pointer to PRT control structure for recursive output 867 * \param [in] depth recursion depth for different purposes, like print or recursion control 868 * \par DIRECT OUTPUT: 869 * \retval _SHR_E_NONE for success 870 * \retval _SHR_E_PARAM problem with input parameters, usage should be printed 871 * \retval other errors for other failure type 872 * \remark automatically frees the list 873 */ 874 typedef shr_error_e( 875 *sh_sand_traverse_cb_t) ( 876 int unit, 877 args_t * args, 878 sh_sand_cmd_t * cmd, 879 void *flex_ptr, 880 int depth); 881 882 /** 883 * \brief Routine serves to invoke command from any level, it then acts recursively parsing command line 884 * \par DIRECT INPUT: 885 * \param [in] unit unit id 886 * \param [in] args pointer standard bcm shell argument structure, used by parse.h MACROS and routines 887 * \param [in] sh_sand_cmd_a pointer to command list(array) to start from 888 * \param [in] sh_sys_cmd_a pointer to system command list(array) for specified root 889 * \param [in] legacy_list - list in which we'll look for legacy commands if none will be found on sh_sand_cmd_a 890 * \par DIRECT OUTPUT: 891 * \retval _SHR_E_NONE for success 892 * \retval _SHR_E_PARAM problem with input parameters, usage should be printed by calling procedure 893 * \retval other errors for other failure type 894 */ 895 shr_error_e sh_sand_act( 896 int unit, 897 args_t * args, 898 sh_sand_cmd_t * sh_sand_cmd_a, 899 sh_sand_cmd_t * sh_sys_cmd_a, 900 rhlist_t * legacy_list); 901 902 /** 903 * \brief 904 * Clean control structure from any allocation made in course on command processing 905 * \param [in] unit 906 * \param [in] sand_ctr - pointer to control structure used in command processing 907 * 908 * \remark 909 */ 910 void sh_sand_option_list_clean( 911 int unit, 912 sh_sand_control_t * sand_ctr); 913 914 /** 915 * \brief Fill args_list with options values or defaults 916 * \param [in] unit unit id 917 * \param [in] args pointer standard bcm shell argument structure, used by parse.h MACROS and routines 918 * \param [in] sh_sand_cmd - leaf command to obtain full command for 919 * \param [in] sand_ctr - pointer to control structure allocated by caller 920 * \param [in] flags - misc flags for different options 921 * \param [in] core - specify the core to execute. It will be used only if SH_CMD_EXEC_PER_CORE flag is set. 922 * \retval _SHR_E_NONE 923 * \remark 924 * Is called from regular tree processing or from executing examples 925 */ 926 shr_error_e sh_sand_option_list_process( 927 int unit, 928 int *core, 929 args_t * args, 930 sh_sand_cmd_t * sh_sand_cmd, 931 sh_sand_control_t * sand_ctr, 932 int flags); 933 934 /** 935 * \brief Return enum string for value for specific command and option 936 * \param [in] sand_control - control structure for command 937 * \param [in] arg_keyword - keyword for the command 938 * \param [in] enum_value - pointer to the string allocated by caller to be used as output location 939 * \retval pointer to string which is name of enum or printed value or error message 940 * \remark 941 * Routine (at least currently) does not return error, only success 942 */ 943 char *sh_sand_enum_value_text( 944 sh_sand_control_t * sand_control, 945 char *arg_keyword, 946 int enum_value); 947 948 shr_error_e sh_sand_cmd_traverse( 949 int unit, 950 args_t * args, 951 sh_sand_cmd_t * sh_sand_cmd_a, 952 sh_sand_traverse_cb_t sh_sand_action, 953 void *flex_ptr, 954 int flags, 955 char *label); 956 957 shr_error_e sys_usage_cmd( 958 int unit, 959 args_t * args, 960 sh_sand_control_t * sand_control); 961 962 shr_error_e sys_manual_cmd_internal( 963 int unit, 964 args_t * args, 965 sh_sand_control_t * sand_control, 966 char *introduction, 967 sh_manual_type_e manual_type); 968 969 shr_error_e sys_manual_label_match( 970 int unit, 971 char *label, 972 char **label_tokens, 973 uint32 tokens_count, 974 uint8 *match); 975 976 /** 977 * \brief Routine serves to execute certain framework command 978 * \param [in] unit - unit id 979 * \param [in] command - command to be executed under framework 980 * \return 981 * \retval _SHR_E_NONE for success 982 * \retval _SHR_E_PARAM problem with input parameters, usage should be printed by calling procedure 983 * \retval other errors for other failure type 984 */ 985 shr_error_e sh_sand_execute( 986 int unit, 987 char *command); 988 989 /** 990 * \brief Add example(arguments string) for shell command testing 991 * \param [in] unit - unit id 992 * \param [in] flags - flags - currently empty 993 * \param [in] sh_sand_cmd - shell command, which examples we are adding, taken from generate callback 994 * \param [in] examples_list - examples list, where all new examples will be added, there may be static examples already 995 * \param [in] arguments_str - parameter string as if it appear on command line 996 * \return 997 * \retval _SHR_E_NONE for success 998 * \retval _SHR_E_PARAM problem with input parameters, usage should be printed by calling procedure 999 * \retval other errors for other failure type 1000 */ 1001 shr_error_e sh_sand_example_add( 1002 int unit, 1003 int flags, 1004 sh_sand_cmd_t * sh_sand_cmd, 1005 rhlist_t * examples_list, 1006 char *arguments_str); 1007 1008 /** 1009 * \brief Routine serves to initialize shell command tree and verify requested resources 1010 * \param [in] unit - unit id 1011 * \param [in] sh_sand_cmd_a - array of commands under the root 1012 * \param [in] sh_sand_legacy_cmd_a - array of legacy commands under the root 1013 * \return 1014 * \retval _SHR_E_NONE for success 1015 * \retval _SHR_E_PARAM problem with input parameters, usage should be printed by calling procedure 1016 * \retval other errors for other failure type 1017 */ 1018 shr_error_e sh_sand_root_init( 1019 int unit, 1020 sh_sand_cmd_t * sh_sand_cmd_a, 1021 sh_sand_legacy_cmd_t * sh_sand_legacy_cmd_a); 1022 1023 /** 1024 * \brief Routine serves to deinitialize shell command tree and free resources 1025 * \param [in] unit - unit id 1026 * \return 1027 * \retval _SHR_E_NONE for success 1028 * \retval _SHR_E_PARAM problem with input parameters, usage should be printed by calling procedure 1029 * \retval other errors for other failure type 1030 */ 1031 shr_error_e sh_sand_root_deinit( 1032 int unit); 1033 1034 /** 1035 * \brief Return string for boolean value 1036 */ 1037 char *sh_sand_bool_str( 1038 int bool); 1039 1040 /** 1041 * \brief Return string for enum value 1042 * \param [in] enum_entry - pointer to enum array 1043 * \param [in] value - value which name we need 1044 * \return 1045 * \retval SUCCESS - string associated to value 1046 * \retval FAILURE - NULL 1047 */ 1048 char *sh_sand_enum_str( 1049 sh_sand_enum_t * enum_entry, 1050 int value); 1051 1052 /** 1053 * \brief Returns the number of cores for the device. 1054 * \param [in] unit unit id 1055 * \param [out] nof_cores - Number of cores 1056 * \retval _SHR_E_NONE 1057 */ 1058 shr_error_e sh_sand_nof_cores_get( 1059 int unit, 1060 int *nof_cores); 1061 1062 /** 1063 * \brief This macro is for local usage only to make external macros SH_SAND_GET* more transparent 1064 */ 1065 1066 /* 1067 * Set of MACROS for obtaining regular option values, not ranges and not masked 1068 * { 1069 */ 1070 /* 1071 * \brief - Fetches sand_arg as per option name and assigns value union ptr to "param" variable 1072 * \param [in] mc_arg_keyword - keyword for the argument 1073 * \remark 1074 * Strictly internal MACRO - to be used only by underlying ones, makes local assumptions 1075 */ 1076 #define _SH_SAND_GET(mc_arg_keyword) \ 1077 sh_sand_param_u *param = NULL; \ 1078 sal_field_type_e param_type = SAL_FIELD_TYPE_MAX; \ 1079 if(sand_control == NULL) \ 1080 { \ 1081 SHR_CLI_EXIT(_SHR_E_PARAM, "No command control for:%s\n", mc_arg_keyword); \ 1082 } \ 1083 else \ 1084 { \ 1085 sh_sand_arg_t *sand_arg; \ 1086 if((sand_arg = utilex_rhlist_entry_get_by_name(sand_control->stat_args_list, mc_arg_keyword)) == NULL) \ 1087 { \ 1088 if((sand_arg = utilex_rhlist_entry_get_by_name(sand_control->dyn_args_list, mc_arg_keyword)) == NULL) \ 1089 { \ 1090 SHR_CLI_EXIT(_SHR_E_PARAM, "command line option:%s is not supported\n", mc_arg_keyword); \ 1091 } \ 1092 } \ 1093 param_type = sand_arg->type; \ 1094 if(sand_arg->state & SH_SAND_ARG_RANGE) \ 1095 { \ 1096 SHR_CLI_EXIT(_SHR_E_PARAM, "GET MACRO does not suit range input for option:%s, use RANGE ones\n", \ 1097 mc_arg_keyword); \ 1098 } \ 1099 if(sand_arg->state & SH_SAND_ARG_MASKED) \ 1100 { \ 1101 SHR_CLI_EXIT(_SHR_E_PARAM, "GET MACRO does not suit masked input for option:%s, use MASKED ones\n", \ 1102 mc_arg_keyword); \ 1103 } \ 1104 if(sand_arg->state & SH_SAND_ARG_PRESENT) \ 1105 { \ 1106 param = &sand_arg->param1; \ 1107 } \ 1108 else \ 1109 { \ 1110 param = &sand_arg->def_param1; \ 1111 } \ 1112 } 1113 1114 /* 1115 * \brief - Fetches state of option - present or not present 1116 * \param [in] mc_arg_keyword - keyword for the argument 1117 * \param [in] mc_is_prsent - boolean value that will be assigned by TRUE if argument present 1118 * \remark 1119 * Should be used only when there is necessity to figure out that default value was assigned by user or not. 1120 * Otherwise default tells all the story 1121 */ 1122 #define SH_SAND_IS_PRESENT(mc_arg_keyword, mc_is_present) \ 1123 if(sand_control == NULL) \ 1124 { \ 1125 SHR_CLI_EXIT(_SHR_E_PARAM, "No command control for:%s\n", mc_arg_keyword); \ 1126 } \ 1127 else \ 1128 { \ 1129 sh_sand_arg_t *sand_arg; \ 1130 if((sand_arg = utilex_rhlist_entry_get_by_name(sand_control->stat_args_list, mc_arg_keyword)) == NULL) \ 1131 { \ 1132 if((sand_arg = utilex_rhlist_entry_get_by_name(sand_control->dyn_args_list, mc_arg_keyword)) == NULL) \ 1133 { \ 1134 SHR_CLI_EXIT(_SHR_E_PARAM, "command line option:%s is not supported\n", mc_arg_keyword); \ 1135 } \ 1136 } \ 1137 mc_is_present = (sand_arg->state & SH_SAND_ARG_PRESENT) ? TRUE : FALSE; \ 1138 } 1139 1140 /* 1141 * \brief - Verifies that GET macro is consistent wipe of option it requests, based on previously obtained param_type 1142 * \remark 1143 * Strictly internal MACRO - to be used only by underlying ones, makes local assumptions 1144 */ 1145 #define _SH_SAND_TYPE_VERIFY(arg_keyword, in_type) \ 1146 if(in_type != param_type) \ 1147 { \ 1148 SHR_CLI_EXIT(_SHR_E_PARAM, "option:\"%s\" - GET macro of type:%s not matching definition type:%s\n", \ 1149 arg_keyword, sal_field_type_str(in_type), sal_field_type_str(param_type)); \ 1150 } 1151 1152 /* 1153 * \brief - Fetches argument value of cli option 1154 * \param [in] arg_keyword - option name, exactly as defined in option list(sh_sand_option_t), case insensitive 1155 * \param [in] arg_value - variable for value assignment 1156 * \remark 1157 * 1. Valid only in the context of shell command framework, sand_control need to be defined. either via initial 1158 * framework callback or passed down as parameter 1159 * 2. Description valid for all SH_SAND_GET_* macros with the only difference being arg_value type, which will be 1160 * Specified explicitly before each macro 1161 * 3. Value assignment may be by value or pointer (see details per macro 1162 */ 1163 /** 1164 * 1. char *arg_value 1165 * 2. by pointer, pointer to the value string is assigned to 1166 */ 1167 #define SH_SAND_GET_STR(arg_keyword, arg_value) \ 1168 { \ 1169 _SH_SAND_GET(arg_keyword) \ 1170 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_STR) \ 1171 arg_value = param->val_str; \ 1172 } 1173 /** 1174 * 1. int arg_value 1175 * 2. by value, boolean value is assigned to 1176 * 3. See all details above in SH_SAND_GET_STR 1177 */ 1178 #define SH_SAND_GET_BOOL(arg_keyword, arg_value) \ 1179 { \ 1180 _SH_SAND_GET(arg_keyword) \ 1181 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_BOOL) \ 1182 arg_value = param->val_bool; \ 1183 } 1184 /** 1185 * 1. int arg_value 1186 * 2. by value, enum value is assigned to 1187 * 3. See all details above in SH_SAND_GET_STR 1188 */ 1189 #define SH_SAND_GET_ENUM(arg_keyword, arg_value) \ 1190 { \ 1191 _SH_SAND_GET(arg_keyword) \ 1192 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_ENUM) \ 1193 arg_value = param->val_enum; \ 1194 } 1195 /** 1196 * 1. int arg_value 1197 * 2. by value, enum value is assigned to 1198 * 3. See all details above in SH_SAND_GET_STR 1199 */ 1200 #define SH_SAND_GET_ENUM_STR(mc_arg_keyword, arg_value) sh_sand_enum_value_text(sand_control, mc_arg_keyword, arg_value) 1201 1202 /** 1203 * 1. int arg_value - 1204 * 2. by value 1205 * 3. See all details above in SH_SAND_GET_STR 1206 */ 1207 #define SH_SAND_GET_PORT(arg_keyword, arg_value) \ 1208 { \ 1209 _SH_SAND_GET(arg_keyword) \ 1210 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_PORT) \ 1211 arg_value = param->ports_bitmap; \ 1212 } 1213 /** 1214 * 1. int arg_value 1215 * 2. by value 1216 * 3. See all details above in SH_SAND_GET_STR 1217 */ 1218 #define SH_SAND_GET_INT32(arg_keyword, arg_value) \ 1219 { \ 1220 _SH_SAND_GET(arg_keyword) \ 1221 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_INT32) \ 1222 arg_value = param->val_int32; \ 1223 } 1224 /** 1225 * 1. uint32 arg_value 1226 * 2. by value 1227 * 3. See all details above in SH_SAND_GET_STR 1228 */ 1229 #define SH_SAND_GET_UINT32(arg_keyword, arg_value) \ 1230 { \ 1231 _SH_SAND_GET(arg_keyword) \ 1232 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_UINT32) \ 1233 arg_value = param->val_uint32; \ 1234 } 1235 /** 1236 * 1. uint32 *arg_value 1237 * 2. by pointer 1238 * 3. See all details above in SH_SAND_GET_STR 1239 */ 1240 #define SH_SAND_GET_ARRAY32(arg_keyword, arg_value) \ 1241 { \ 1242 _SH_SAND_GET(arg_keyword) \ 1243 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_ARRAY32) \ 1244 arg_value = param->array_uint32; \ 1245 } 1246 /** 1247 * 1. sal_ip_addr_t arg_value 1248 * 2. by value 1249 * 3. See all details above in SH_SAND_GET_STR 1250 */ 1251 #define SH_SAND_GET_IP4(arg_keyword, arg_value) \ 1252 { \ 1253 _SH_SAND_GET(arg_keyword) \ 1254 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_IP4) \ 1255 arg_value = param->ip4_addr; \ 1256 } 1257 /** 1258 * 1. sal_ip6_addr_t arg_value 1259 * 2. by value 1260 * 3. See all details above in SH_SAND_GET_STR 1261 */ 1262 #define SH_SAND_GET_IP6(arg_keyword, arg_value) \ 1263 { \ 1264 _SH_SAND_GET(arg_keyword) \ 1265 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_IP6) \ 1266 memcpy(arg_value, param->ip6_addr, sizeof(sal_ip6_addr_t)); \ 1267 } 1268 /** 1269 * 1. sal_mac_addr_t arg_value 1270 * 2. by value 1271 * 3. See all details above in SH_SAND_GET_STR 1272 */ 1273 #define SH_SAND_GET_MAC(arg_keyword, arg_value) \ 1274 { \ 1275 _SH_SAND_GET(arg_keyword) \ 1276 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_MAC) \ 1277 memcpy(arg_value, param->mac_addr, sizeof(sal_mac_addr_t)); \ 1278 } 1279 /* 1280 * End of regular options fetching MACROS 1281 * } 1282 */ 1283 1284 /* 1285 * Set of MACROS for obtaining range option values 1286 * { 1287 */ 1288 /* 1289 * \brief - Fetches sand_arg as per option name and assigns value union ptr to "param" variable, difference from regular 1290 * _SH_SAND_GET is that 2 params are fetched, and if there is no second pne on command line, first is assigned 1291 * to both 1292 * \param [in] mc_arg_keyword - keyword for the argument 1293 * \remark 1294 * Strictly internal MACRO - to be used only by underlying ones, makes local assumptions 1295 * Only certain FIELD_TYPES are eligible for range options, see below 1296 */ 1297 #define _SH_SAND_GET_RANGE(mc_arg_keyword) \ 1298 sh_sand_param_u *param_start = NULL; \ 1299 sh_sand_param_u *param_end = NULL; \ 1300 sal_field_type_e param_type = SAL_FIELD_TYPE_MAX; \ 1301 if(sand_control == NULL) \ 1302 { \ 1303 SHR_CLI_EXIT(_SHR_E_PARAM, "No command control for:%s\n", mc_arg_keyword); \ 1304 } \ 1305 else \ 1306 { \ 1307 sh_sand_arg_t *sand_arg; \ 1308 if((sand_arg = utilex_rhlist_entry_get_by_name(sand_control->stat_args_list, mc_arg_keyword)) == NULL) \ 1309 { \ 1310 if((sand_arg = utilex_rhlist_entry_get_by_name(sand_control->dyn_args_list, mc_arg_keyword)) == NULL) \ 1311 { \ 1312 SHR_CLI_EXIT(_SHR_E_PARAM, "command line option:%s is not supported\n", mc_arg_keyword); \ 1313 } \ 1314 } \ 1315 param_type = sand_arg->type; \ 1316 if(sand_arg->state & SH_SAND_ARG_MASKED) \ 1317 { \ 1318 SHR_CLI_EXIT(_SHR_E_PARAM, "RANGE MACRO does not suit masked input for option:%s, use MASKED ones\n", \ 1319 mc_arg_keyword);\ 1320 } \ 1321 if(sand_arg->state & SH_SAND_ARG_PRESENT) \ 1322 { \ 1323 param_start = &sand_arg->param1; \ 1324 if(sand_arg->state & SH_SAND_ARG_RANGE) \ 1325 param_end = &sand_arg->param2; \ 1326 else \ 1327 param_end = &sand_arg->param1; \ 1328 } \ 1329 else \ 1330 { \ 1331 param_start = &sand_arg->def_param1; \ 1332 if(sand_arg->def_state & SH_SAND_ARG_RANGE) \ 1333 param_end = &sand_arg->def_param2; \ 1334 else \ 1335 param_end = &sand_arg->def_param1; \ 1336 } \ 1337 } 1338 /** 1339 * All *_RANGE macros have in addition to first value, which will represent start of range second one that represents 1340 * end of range, if there is only one value on command line it will be considered range of one element start=end 1341 * Eligible types: INT32, UINT32, IP4, IP6, MAC 1342 */ 1343 #define SH_SAND_GET_INT32_RANGE(arg_keyword, arg_value_start, arg_value_end) \ 1344 { \ 1345 _SH_SAND_GET_RANGE(arg_keyword) \ 1346 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_INT32) \ 1347 arg_value_start = param_start->val_int32; \ 1348 arg_value_end = param_end->val_int32; \ 1349 } 1350 1351 #define SH_SAND_GET_UINT32_RANGE(arg_keyword, arg_value_start, arg_value_end) \ 1352 { \ 1353 _SH_SAND_GET_RANGE(arg_keyword) \ 1354 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_UINT32) \ 1355 arg_value_start = param_start->val_uint32; \ 1356 arg_value_end = param_end->val_uint32; \ 1357 } 1358 1359 #define SH_SAND_GET_IP4_RANGE(arg_keyword, arg_value_start, arg_value_end) \ 1360 { \ 1361 _SH_SAND_GET_RANGE(arg_keyword) \ 1362 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_IP4) \ 1363 arg_value_start = param_start->ip4_addr; \ 1364 arg_value_end = param_end->ip4_addr; \ 1365 } 1366 1367 #define SH_SAND_GET_IP6_RANGE(arg_keyword, arg_value_start, arg_value_end) \ 1368 { \ 1369 _SH_SAND_GET_RANGE(arg_keyword) \ 1370 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_IP6) \ 1371 memcpy(arg_value_start, param_start->ip6_addr, sizeof(sal_ip6_addr_t)); \ 1372 memcpy(arg_value_end, param_end->ip6_addr, sizeof(sal_ip6_addr_t)); \ 1373 } 1374 1375 #define SH_SAND_GET_MAC_RANGE(arg_keyword, arg_value_start, arg_value_end) \ 1376 { \ 1377 _SH_SAND_GET_RANGE(arg_keyword) \ 1378 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_MAC) \ 1379 memcpy(arg_value_start, param_start->mac_addr, sizeof(sal_mac_addr_t)); \ 1380 memcpy(arg_value_end, param_end->mac_addr, sizeof(sal_mac_addr_t)); \ 1381 } 1382 /* 1383 * End of range options fetching MACROS 1384 * } 1385 */ 1386 /* 1387 * Set of MACROS for obtaining masked option values 1388 * { 1389 */ 1390 /* 1391 * \brief - Fetches sand_arg as per option name and assigns value union ptr to "param" variable. It obtains 2 value, 1392 * where first is considered to be data, second mask. If there is no second, default value of all FF is 1393 * assigned to mask 1394 * \param [in] mc_arg_keyword - keyword for the argument 1395 * \remark 1396 * Strictly internal MACRO - to be used only by underlying ones, makes local assumptions 1397 */ 1398 #define _SH_SAND_GET_MASKED(mc_arg_keyword) \ 1399 sh_sand_param_u *param_data = NULL; \ 1400 sh_sand_param_u *param_mask = NULL; \ 1401 sal_field_type_e param_type = SAL_FIELD_TYPE_MAX; \ 1402 if(sand_control == NULL) \ 1403 { \ 1404 SHR_CLI_EXIT(_SHR_E_PARAM, "No command control for:%s\n", mc_arg_keyword); \ 1405 } \ 1406 else \ 1407 { \ 1408 sh_sand_arg_t *sand_arg; \ 1409 if((sand_arg = utilex_rhlist_entry_get_by_name(sand_control->stat_args_list, mc_arg_keyword)) == NULL) \ 1410 { \ 1411 if((sand_arg = utilex_rhlist_entry_get_by_name(sand_control->dyn_args_list, mc_arg_keyword)) == NULL) \ 1412 { \ 1413 SHR_CLI_EXIT(_SHR_E_PARAM, "command line option:%s is not supported\n", mc_arg_keyword); \ 1414 } \ 1415 } \ 1416 param_type = sand_arg->type; \ 1417 if(sand_arg->state & SH_SAND_ARG_RANGE) \ 1418 { \ 1419 SHR_CLI_EXIT(_SHR_E_PARAM, "MASKED MACRO does not suit range input for option:%s, use range ones\n", \ 1420 mc_arg_keyword);\ 1421 } \ 1422 if(sand_arg->state & SH_SAND_ARG_PRESENT) \ 1423 { \ 1424 param_data = &sand_arg->param1; \ 1425 if(sand_arg->state & SH_SAND_ARG_MASKED) \ 1426 param_mask = &sand_arg->param2; \ 1427 else \ 1428 param_mask = &sand_arg->param1; \ 1429 } \ 1430 else \ 1431 { \ 1432 param_data = &sand_arg->def_param1; \ 1433 if(sand_arg->def_state & SH_SAND_ARG_MASKED) \ 1434 param_mask = &sand_arg->def_param2; \ 1435 else \ 1436 param_mask = &full_param_mask; \ 1437 } \ 1438 } 1439 1440 /** 1441 * All *_RANGE macros have in addition to first value, which will represent data, second one that represents 1442 * mask. if there is only one value on command line it will be considered FULLY unmasked or the value of 1443 * 0xFF filled in mask 1444 * Eligible types: INT32, UINT32, IP4, IP6, MAC 1445 */ 1446 #define SH_SAND_GET_INT32_MASKED(arg_keyword, arg_value_data, arg_value_mask) \ 1447 { \ 1448 _SH_SAND_GET_MASKED(arg_keyword) \ 1449 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_INT32) \ 1450 arg_value_data = param_data->val_int32; \ 1451 arg_value_mask = param_mask->val_int32; \ 1452 } 1453 1454 #define SH_SAND_GET_UINT32_MASKED(arg_keyword, arg_value_data, arg_value_mask) \ 1455 { \ 1456 _SH_SAND_GET_MASKED(arg_keyword) \ 1457 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_UINT32) \ 1458 arg_value_data = param_data->val_uint32; \ 1459 arg_value_mask = param_mask->val_uint32; \ 1460 } 1461 1462 #define SH_SAND_GET_IP4_MASKED(arg_keyword, arg_value_data, arg_value_mask) \ 1463 { \ 1464 _SH_SAND_GET_MASKED(arg_keyword) \ 1465 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_IP4) \ 1466 arg_value_data = param_data->ip4_addr; \ 1467 arg_value_mask = param_mask->ip4_addr; \ 1468 } 1469 1470 #define SH_SAND_GET_IP6_MASKED(arg_keyword, arg_value_data, arg_value_mask) \ 1471 { \ 1472 _SH_SAND_GET_MASKED(arg_keyword) \ 1473 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_IP6) \ 1474 memcpy(arg_value_data, param_data->ip6_addr, sizeof(sal_ip6_addr_t)); \ 1475 memcpy(arg_value_mask, param_mask->ip6_addr, sizeof(sal_ip6_addr_t)); \ 1476 } 1477 1478 #define SH_SAND_GET_MAC_MASKED(arg_keyword, arg_value_data, arg_value_mask) \ 1479 { \ 1480 _SH_SAND_GET_MASKED(arg_keyword) \ 1481 _SH_SAND_TYPE_VERIFY(arg_keyword, SAL_FIELD_TYPE_MAC) \ 1482 memcpy(arg_value_data, param_data->mac_addr, sizeof(sal_mac_addr_t)); \ 1483 memcpy(arg_value_mask, param_mask->mac_addr, sizeof(sal_mac_addr_t)); \ 1484 } 1485 /* 1486 * End of masked options fetching MACROS 1487 * } 1488 */ 1489 /* 1490 * Set of MACROS for handling dynamic options and their values 1491 * { 1492 */ 1493 #define _SH_SAND_GET_DYN(mc_arg_keyword, mc_is_present) \ 1494 sh_sand_arg_t *sand_arg; \ 1495 if((sand_control == NULL) || (sand_control->dyn_args_list == NULL) || \ 1496 ((sand_arg = utilex_rhlist_entry_get_by_name(sand_control->dyn_args_list, mc_arg_keyword)) == NULL)) \ 1497 { \ 1498 mc_is_present = FALSE; \ 1499 } \ 1500 else \ 1501 { \ 1502 mc_is_present = TRUE; \ 1503 } \ 1504 1505 #define SH_SAND_GET_STR_DYN(arg_keyword, arg_value, is_present) \ 1506 { \ 1507 _SH_SAND_GET_DYN(arg_keyword, is_present); \ 1508 if(is_present == TRUE) \ 1509 arg_value = sand_arg->param1.val_str; \ 1510 } 1511 1512 #define SH_SAND_GET_BOOL_DYN(arg_keyword, arg_value, is_present) \ 1513 { \ 1514 _SH_SAND_GET_DYN(arg_keyword, is_present); \ 1515 if(is_present == TRUE) \ 1516 arg_value = sand_arg->param1.val_bool; \ 1517 } 1518 1519 #define SH_SAND_GET_ENUM_DYN(arg_keyword, arg_value, is_present) \ 1520 { \ 1521 _SH_SAND_GET_DYN(arg_keyword, is_present); \ 1522 if(is_present == TRUE) \ 1523 arg_value = sand_arg->param1.val_enum; \ 1524 } 1525 1526 #define SH_SAND_GET_INT32_DYN(arg_keyword, arg_value, is_present) \ 1527 { \ 1528 _SH_SAND_GET_DYN(arg_keyword, is_present); \ 1529 if(is_present == TRUE) \ 1530 arg_value = sand_arg->param1.val_int32; \ 1531 } 1532 1533 #define SH_SAND_GET_ARRAY32_DYN(arg_keyword, arg_value, is_present) \ 1534 { \ 1535 _SH_SAND_GET_DYN(arg_keyword, is_present); \ 1536 if(is_present == TRUE) \ 1537 arg_value = sand_arg->param1.array_uint32; \ 1538 } 1539 1540 #define SH_SAND_GET_UINT32_DYN(arg_keyword, arg_value, is_present) \ 1541 { \ 1542 _SH_SAND_GET_DYN(arg_keyword, is_present); \ 1543 if(is_present == TRUE) \ 1544 arg_value = sand_arg->param1.val_uint32; \ 1545 } 1546 1547 #define SH_SAND_GET_IP4_DYN(arg_keyword, arg_value, is_present) \ 1548 { \ 1549 _SH_SAND_GET_DYN(arg_keyword, is_present); \ 1550 if(is_present == TRUE) \ 1551 arg_value = sand_arg->param1.ip4_addr; \ 1552 } 1553 1554 #define SH_SAND_GET_IP6_DYN(arg_keyword, arg_value, is_present) \ 1555 { \ 1556 _SH_SAND_GET_DYN(arg_keyword, is_present); \ 1557 if(is_present == TRUE) \ 1558 memcpy(arg_value, sand_arg->param1.ip6_addr, sizeof(sal_ip6_addr_t)); \ 1559 } 1560 1561 #define SH_SAND_GET_MAC_DYN(arg_keyword, arg_value, is_present) \ 1562 { \ 1563 _SH_SAND_GET_DYN(arg_keyword, is_present); \ 1564 if(is_present == TRUE) \ 1565 memcpy(arg_value, sand_arg->param1.mac_addr, sizeof(sal_mac_addr_t)); \ 1566 } 1567 /* 1568 * End of dynamic options fetching MACROS 1569 * } 1570 */ 1571 1572 #define SH_SAND_GET_ITERATOR(mc_arg) \ 1573 for(mc_arg = utilex_rhlist_entry_get_first(sand_control->dyn_args_list); mc_arg; mc_arg = utilex_rhlist_entry_get_next(mc_arg)) 1574 1575 #define SH_SAND_GET_DYN_ARGS_NUM() (sand_control->dyn_args_list == NULL) ? 0 : RHLNUM(sand_control->dyn_args_list) 1576 #define SH_SAND_HAS_MASK(mc_arg) (mc_arg->state & SH_SAND_ARG_MASKED) 1577 1578 #define SH_SAND_GET_NAME(mc_arg) RHNAME(mc_arg) 1579 #define SH_SAND_GET_ID(mc_arg) RHID(mc_arg) 1580 #define SH_SAND_GET_TYPE(mc_arg) mc_arg->type 1581 #define SH_SAND_ARG_STR(mc_arg) mc_arg->param1.val_str 1582 #define SH_SAND_ARG_UINT32_DATA(mc_arg) mc_arg->param1.val_uint32 1583 #define SH_SAND_ARG_UINT32_MASK(mc_arg) mc_arg->param2.val_uint32 1584 #define SH_SAND_ARG_ARRAY_DATA(mc_arg) mc_arg->param1.array_uint32 1585 #define SH_SAND_ARG_ARRAY_MASK(mc_arg) mc_arg->param2.array_uint32 1586 #define SH_SAND_ARG_MAC_DATA(mc_arg) mc_arg->param1.mac_addr 1587 #define SH_SAND_ARG_MAC_MASK(mc_arg) mc_arg->param2.mac_addr 1588 #define SH_SAND_ARG_IP6_DATA(mc_arg) mc_arg->param1.ip6_addr 1589 #define SH_SAND_ARG_IP6_MASK(mc_arg) mc_arg->param2.ip6_addr 1590 1591 /** 1592 * \brief Callback in shell command framework allowing to enable command for DNX device 1593 * \param [in] unit - unit id 1594 * \param [in] list - unused here (keep callback type) 1595 * \return 1596 * \retval _SHR_E_NONE - If the device is DNX 1597 * \retval _SHR_E_NOT_FOUND - Otherwise 1598 * Flow goes to exit in any case of failure 1599 */ 1600 shr_error_e sh_cmd_is_dnx( 1601 int unit, 1602 rhlist_t * list); 1603 1604 /** 1605 * \brief Callback in shell command framework allowing to enable command for DNXF device 1606 * \param [in] unit - unit id 1607 * \param [in] list - unused here (keep callback type) 1608 * \return 1609 * \retval _SHR_E_NONE - If the device is DNX 1610 * \retval _SHR_E_NOT_FOUND - Otherwise 1611 * Flow goes to exit in any case of failure 1612 */ 1613 shr_error_e sh_cmd_is_dnxf( 1614 int unit, 1615 rhlist_t * list); 1616 /** 1617 * \brief Callback in shell command framework allowing to disable command for ADAPTER mode 1618 * \param [in] unit - unit id 1619 * \param [in] list - unused here (keep callback type) 1620 * \return 1621 * \retval _SHR_E_NONE - If the device is DNX 1622 * \retval _SHR_E_NOT_FOUND - Otherwise 1623 * Flow goes to exit in any case of failure 1624 */ 1625 shr_error_e sh_cmd_is_device( 1626 int unit, 1627 rhlist_t * list); 1628 1629 /** 1630 * \brief Initialize deinit_cb to this routine to avoid SW Recovery invocation 1631 * \param [in] unit - unit id 1632 * \return 1633 * \retval standard shr_error_e 1634 */ 1635 shr_error_e sh_deinit_cb_void( 1636 int unit); 1637 1638 /** 1639 * \brief Set root shell command pointer 1640 * \param [in] unit - unit id 1641 * \param [out] sh_sand_cmd_a_p - pointer to place were to assign root shell command pointer 1642 * \return 1643 * \retval _SHR_E_NONE - If the device is DNX 1644 * \retval _SHR_E_PARAM - If place were pointer should be assigned is NULL 1645 * \retval _SHR_E_INTERNAL - If root is NULL 1646 */ 1647 shr_error_e sh_sand_cmd_root_get( 1648 int unit, 1649 sh_sand_cmd_t ** sh_sand_cmd_a_p); 1650 1651 extern sh_sand_enum_t sh_enum_table_lag_pool[]; 1652 1653 extern sh_sand_man_t sh_sand_shell_man; 1654 extern sh_sand_cmd_t sh_sand_shell_cmds[]; 1655 1656 extern sh_sand_cmd_t sh_sand_sys_cmds[]; 1657 1658 extern sh_sand_man_t sys_usage_man; 1659 extern sh_sand_option_t sys_usage_arguments[]; 1660 1661 extern sh_sand_keyword_t sh_sand_keywords[]; 1662 extern sh_sand_param_u full_param_mask; 1663 1664 extern sh_sand_option_t sys_manual_arguments[]; 1665 1666 /** 1667 * \brief Routine serves to verify correctness of shell command tree and init requested resources 1668 * \par DIRECT INPUT: 1669 * \param [in] unit unit id 1670 * \param [in] sh_sand_cmd_parent - parent command to sh_sand_cmd_a array 1671 * \param [in] sh_sand_cmd_a pointer to command list to start from 1672 * \param [in] sh_sys_cmd_a pointer to array of system commands assigned per root command 1673 * \param [in] command accumulated from shell tree traversing, usually starts from NULL 1674 * \param [in] flags verification flags for shell command initialization 1675 * \par DIRECT OUTPUT: 1676 * \retval _SHR_E_NONE for success 1677 * \retval _SHR_E_PARAM problem with input parameters, usage should be printed by calling procedure 1678 * \retval other errors for other failure type 1679 */ 1680 shr_error_e sh_sand_init( 1681 int unit, 1682 sh_sand_cmd_t * sh_sand_cmd_parent, 1683 sh_sand_cmd_t * sh_sand_cmd_a, 1684 sh_sand_cmd_t * sh_sys_cmd_a, 1685 char *command, 1686 int flags); 1687 1688 /** 1689 * \brief Parse string to any given type 1690 * \param [in] unit - unit id 1691 * \param [in] type - The output type of the value 1692 * \param [in] source - input value to parse (string) 1693 * \param [in] target - Union of all kind of things allowing to get any format 1694 * \param [in] ext_ptr - use for ENUM type translation 1695 * \return 1696 * \retval _SHR_E_NONE - On success 1697 * \retval Other - Other errors as per shr_error_e 1698 * \remark 1699 */ 1700 shr_error_e sh_sand_value_get( 1701 int unit, 1702 sal_field_type_e type, 1703 char *source, 1704 sh_sand_param_u * target, 1705 void *ext_ptr); 1706 1707 /** 1708 * \brief * Checks existence of gold result for command 1709 * \param [in] unit - device id - important because path will depend on it 1710 * \param [in] command - command for which existence of gold is checked 1711 * 1712 * \remark 1713 */ 1714 shr_error_e sh_sand_gold_exists( 1715 int unit, 1716 char *command); 1717 1718 /** 1719 * \brief Recursive verification procedure for sand command array 1720 * \param [in] root_cmd - root command name for sh_sand_cmds, we need it to have full command line in output 1721 * \param [in] sh_sand_cmds - sh_sand_cmd_t * - pointer to command array for specific command 1722 * \param [out] cmd_result - variable that return status value will be saved in 1723 * \return 1724 * Flow goes to exit in any case of failure 1725 * \remark 1726 * Routine should have exit point 1727 * Should not be used in JR2 1728 * \see 1729 * sh_sand_init 1730 */ 1731 #define SH_SAND_VERIFY(root_cmd, sh_sand_cmds, cmd_result) \ 1732 { \ 1733 static int sh_sand_legacy_command_verified = FALSE; \ 1734 if(sh_sand_legacy_command_verified == FALSE) \ 1735 { \ 1736 char *command = sal_alloc(SH_SAND_MAX_TOKEN_SIZE, "sh_sand_command_verify"); \ 1737 if(command == NULL) \ 1738 { \ 1739 cli_out("Memory allocation failure\n"); \ 1740 cmd_result = CMD_FAIL; \ 1741 goto exit; \ 1742 } \ 1743 sal_strncpy(command, root_cmd, SH_SAND_MAX_TOKEN_SIZE -1); \ 1744 cmd_result = diag_sand_error_get(sh_sand_init(unit, NULL, sh_sand_cmds, \ 1745 sh_sand_sys_cmds, command, 0)); \ 1746 if(cmd_result == CMD_OK) \ 1747 { \ 1748 command[0] = 0; \ 1749 sh_sand_init(unit, NULL, sh_sand_sys_cmds, NULL, command, 0); \ 1750 sh_sand_legacy_command_verified = TRUE; \ 1751 } \ 1752 sal_free(command); \ 1753 } \ 1754 else \ 1755 { \ 1756 cmd_result = CMD_OK; \ 1757 } \ 1758 } 1759 1760 /** 1761 * \brief Fills string with formated time, oriented for log purposes mainly 1762 * \param [in,out] time_str - pointer to string where formatted time presentation will be copied 1763 * \remark 1764 * time_str should be at least SH_SAND_MAX_TIME_SIZE 1765 */ 1766 void sh_sand_time_get( 1767 char *time_str); 1768 1769 /** 1770 * \brief add option to dynamic argument list of sand control 1771 * \param [in] unit - unit ID 1772 * \param [in,out] sand_control - pointer for control structure for command 1773 * \param [in] option_name - the name of the option 1774 * \param [in] option_cb - callback for dynamic option 1775 */ 1776 shr_error_e sh_sand_add_option_dyn_args( 1777 int unit, 1778 sh_sand_control_t * sand_control, 1779 char *option_name, 1780 sh_sand_option_cb_t option_cb); 1781 1782 #endif /* DIAG_SAND_FRAMEWORK_H_INCLUDED */