// ------------------------------------------------------------------------------------------- // Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. // This file is part of the AWS CDI-SDK, licensed under the BSD 2-Clause "Simplified" License. // License details at: https://github.com/aws/aws-cdi-sdk/blob/mainline/LICENSE // ------------------------------------------------------------------------------------------- /** * @file * @brief * This file contains the definitions of the functions used for capturing command line arguments and sanitizing them and * converting them to cdi_test program test settings. */ // Include headers in the following order: Related header, C system headers, other libraries' headers, your project's // headers. #include "test_args.h" #include #include #include #include #include #include // The configuration.h file must be included first since it can have defines which affect subsequent files. #include "configuration.h" #include "cdi_log_enums.h" #include "cdi_logger_api.h" #include "cdi_os_api.h" #include "cdi_test.h" #include "cdi_utility_api.h" #include "optarg.h" #include "riff.h" #include "test_common.h" #include "test_console.h" #include "utilities_api.h" //********************************************************************************************************************* //***************************************** START OF DEFINITIONS AND TYPES ******************************************** //********************************************************************************************************************* /** * Enum for max and min IP port numbers. **/ enum PortNumLimits { kPortNumMin = 1, kPortNumMax = UINT16_MAX }; //********************************************************************************************************************* //*********************************************** START OF VARIABLES ************************************************** //********************************************************************************************************************* /** * Enum/String array that contains valid test pattern modes. */ static const CdiEnumStringKey patterns_key_array[] = { /// SAME pattern stores uses the pattern_start value unmodified for every pattern word. { kTestPatternSame, "SAME" }, /// INC pattern will start at pattern_start and increment the value by one for every pattern word. { kTestPatternInc, "INC" }, /// SHR pattern starts at pattern_start and does a circular right shift by one for every pattern word. { kTestPatternSHR, "SHR" }, /// SHL pattern starts at pattern_start and does a circular left shift by one for every pattern word. { kTestPatternSHL, "SHL" }, /// NONE pattern means pattern is not set and either file_read is being used or on rx there is no payload data /// checking. { kTestPatternNone, "NONE" }, /// IGNORE pattern means pattern is not set and either file_read is being used or on rx there is no payload /// validation (no payload data checking). { kTestPatternIgnore, "IGNORE" }, { CDI_INVALID_ENUM_VALUE, NULL } // End of the array }; //********************************************************************************************************************* //******************************************* START OF STATIC FUNCTIONS *********************************************** //********************************************************************************************************************* /** * @brief Function used to convert a test pattern enum value to a string. * * @param enum_value Value to convert to a string. * * @return Pointer to returned string. If no match was found, NULL is returned. */ static const char* TestPatternEnumToString(TestPatternType enum_value) { return CdiUtilityEnumValueToString(patterns_key_array, enum_value); } /** * @brief Function used to convert a test protocol enum value to a string. * * @param enum_value Value to convert to a string. * * @return Pointer to returned string. If no match was found, NULL is returned. */ static const char* TestProtocolEnumToString(CdiConnectionProtocolType enum_value) { return CdiUtilityEnumValueToString(CdiUtilityKeyGetArray(kKeyConnectionProtocolType), enum_value); } /** * @brief Function used to convert a test pattern string to a matching enum value. * * @param name_str Pointer to string name of enumerated value. * * @return Returned enumerated value. If no match was found, CDI_INVALID_ENUM_VALUE is returned. */ static TestPatternType TestPatternStringToEnum(const char* name_str) { return CdiUtilityStringToEnumValue(patterns_key_array, name_str); } /** * @brief Function used to convert a test protocol string to a matching enum value. * * @param name_str Pointer to string name of enumerated value. * * @return Returned enumerated value. If no match was found, CDI_INVALID_ENUM_VALUE is returned. */ static CdiConnectionProtocolType TestProtocolStringToEnum(const char* name_str) { return CdiUtilityStringToEnumValue(CdiUtilityKeyGetArray(kKeyConnectionProtocolType), name_str); } /** * @brief Prints the main usage message. * * @param opt_array_ptr Pointer to the options array, where all usage information is stored. * @param opt_ptr Pointer to optional argument. */ static void PrintUsageVideo(const OptDef* opt_array_ptr, const OptArg* opt_ptr) { CdiAvmBaselineProfileVersion version = { .major = 1, .minor = 0 }; if (opt_ptr->num_args) { if (kCdiStatusOk != CdiAvmValidateBaselineVersionString(kCdiAvmVideo, opt_ptr->args_array[0], &version)) { TestConsoleLog(kLogError, "Invalid --help_video version [%s].", opt_ptr->args_array[0]); return; } } TestConsoleLog(kLogInfo, "Usage for --avm_video option:"); PrintOption(&opt_array_ptr[kTestOptionAVMVideo]); TestConsoleLog(kLogInfo, ""); TestConsoleLog(kLogInfo, "Choices for each argument:"); TestConsoleLog(kLogInfo, " [version] - xx.xx (Optional AVM profile version)"); TestConsoleLog(kLogInfo, ""); TestConsoleLog(kLogInfo, " Data shown for AVM version %02d.%02d:", version.major, version.minor); TestConsoleLog(kLogInfo, " - any integer"); TestConsoleLog(kLogInfo, " - any integer"); TestConsoleLog(kLogInfo, " - any of the following strings:"); PrintKeyArrayNames(CdiAvmKeyGetArray(kKeyAvmVideoSamplingType, &version), OPTARG_AVM_USAGE_LIST_INDENT); TestConsoleLog(kLogInfo, " - any of the following strings:"); PrintKeyArrayNames(CdiAvmKeyGetArray(kKeyAvmVideoAlphaChannelType, &version), OPTARG_AVM_USAGE_LIST_INDENT); TestConsoleLog(kLogInfo, " - any of the following strings:"); PrintKeyArrayNames(CdiAvmKeyGetArray(kKeyAvmVideoBitDepthType, &version), OPTARG_AVM_USAGE_LIST_INDENT); TestConsoleLog(kLogInfo, " - any integer"); TestConsoleLog(kLogInfo, " - any integer"); TestConsoleLog(kLogInfo, " - any of the following strings:"); PrintKeyArrayNames(CdiAvmKeyGetArray(kKeyAvmVideoColorimetryType, &version), OPTARG_AVM_USAGE_LIST_INDENT); TestConsoleLog(kLogInfo, " - true or false"); TestConsoleLog(kLogInfo, " - true or false"); TestConsoleLog(kLogInfo, " - any of the following strings:"); PrintKeyArrayNames(CdiAvmKeyGetArray(kKeyAvmVideoTcsType, &version), OPTARG_AVM_USAGE_LIST_INDENT); TestConsoleLog(kLogInfo, " - any of the following strings:"); PrintKeyArrayNames(CdiAvmKeyGetArray(kKeyAvmVideoRangeType, &version), OPTARG_AVM_USAGE_LIST_INDENT); TestConsoleLog(kLogInfo, " - any integer"); TestConsoleLog(kLogInfo, " - any integer"); TestConsoleLog(kLogInfo, " - any integer"); TestConsoleLog(kLogInfo, " - any integer"); TestConsoleLog(kLogInfo, " - any integer"); TestConsoleLog(kLogInfo, " - any integer"); TestConsoleLog(kLogInfo, ""); TestConsoleLog(kLogInfo, "Example:"); TestConsoleLog(kLogInfo, " --avm_video 1920 1080 YCbCr422 Unused 10bit 30 1 BT2020 true false PQ Narrow 3 4 21 " "1059 100 1820"); TestConsoleLog(kLogInfo, ""); } /** * @brief Prints the audio usage message. * * @param opt_array_ptr Pointer to the options array, where all usage information is stored. * @param opt_ptr Pointer to option argument. */ static void PrintUsageAudio(const OptDef* opt_array_ptr, const OptArg* opt_ptr) { CdiAvmBaselineProfileVersion version = { .major = 1, .minor = 0 }; if (opt_ptr->num_args) { if (kCdiStatusOk != CdiAvmValidateBaselineVersionString(kCdiAvmAudio, opt_ptr->args_array[0], &version)) { TestConsoleLog(kLogError, "Invalid --help_audio version [%s].", opt_ptr->args_array[0]); return; } } TestConsoleLog(kLogInfo, ""); TestConsoleLog(kLogInfo, "Usage for --avm_audio option:"); PrintOption(&opt_array_ptr[kTestOptionAVMAudio]); TestConsoleLog(kLogInfo, ""); TestConsoleLog(kLogInfo, "Choices for each argument:"); TestConsoleLog(kLogInfo, " [version] - xx.xx (Optional AVM profile version)"); TestConsoleLog(kLogInfo, ""); TestConsoleLog(kLogInfo, " Data shown for AVM version %02d.%02d:", version.major, version.minor); TestConsoleLog(kLogInfo, " - Any of the following strings:"); PrintKeyArrayNames(CdiAvmKeyGetArray(kKeyAvmAudioChannelGroupingType, &version), OPTARG_AVM_USAGE_LIST_INDENT); TestConsoleLog(kLogInfo, " - Any of the following strings:"); PrintKeyArrayNames(CdiAvmKeyGetArray(kKeyAvmAudioSampleRateType, &version), OPTARG_AVM_USAGE_LIST_INDENT); TestConsoleLog(kLogInfo, " - Any two or three character string or \"none\"."); TestConsoleLog(kLogInfo, ""); TestConsoleLog(kLogInfo, "Examples:"); TestConsoleLog(kLogInfo, " --avm_audio 51 48kHz none"); TestConsoleLog(kLogInfo, " --avm_audio M 96kHz fr"); } /** * @brief Prints help on RIFF format and usage in cdi_test. * * @param opt_ptr Pointer to option argument. */ static void PrintRiffHelp(const OptArg* opt_ptr) { if (opt_ptr->num_args) { ReportRiffFileContents(opt_ptr->args_array[0], 100, kRiffDumpRaw); return; } TestConsoleLog(kLogInfo, ""); TestConsoleLog(kLogInfo, "The RIFF file format is made up of chunks. Every chunk consists of a"); TestConsoleLog(kLogInfo, "four character code followed by a 32 bit integer that indicates the"); TestConsoleLog(kLogInfo, "size in bytes of the chunk data. The first chunk is the RIFF chunk"); TestConsoleLog(kLogInfo, "which also has a form type. For cdi_test the only currently"); TestConsoleLog(kLogInfo, "supported form type is 'CDI '. The RIFF chunk data is made of a"); TestConsoleLog(kLogInfo, "subchunk for each payload to be sent. Each subchunk header is"); TestConsoleLog(kLogInfo, "identified with a four character code 'ANC '."); TestConsoleLog(kLogInfo, ""); TestConsoleLog(kLogInfo, " RIFF format"); TestConsoleLog(kLogInfo, " bytes"); TestConsoleLog(kLogInfo, " 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15"); TestConsoleLog(kLogInfo, " 'R' 'I' 'F' 'F'
"); TestConsoleLog(kLogInfo, " "); TestConsoleLog(kLogInfo, " "); TestConsoleLog(kLogInfo, " ..............................................................."); TestConsoleLog(kLogInfo, ""); TestConsoleLog(kLogInfo, "NOTE: If the transmitter is sending RIFF payloads the receiver must also use"); TestConsoleLog(kLogInfo, " the --riff option or payload size errors could be generated."); TestConsoleLog(kLogInfo, ""); TestConsoleLog(kLogInfo, "For additional RIFF file information please see " "https://johnloomis.org/cpe102/asgn/asgn1/riff.html."); TestConsoleLog(kLogInfo, ""); } #ifndef CDI_NO_MONITORING /** * @brief Prints the statistics help message. */ static void PrintStatsHelp(const OptDef* opt_array_ptr) { TestConsoleLog(kLogInfo, ""); TestConsoleLog(kLogInfo, "Usage for --stats_... options:"); PrintOption(&opt_array_ptr[kTestOptionStatsConfigCloudWatch]); TestConsoleLog(kLogInfo, ""); TestConsoleLog(kLogInfo, "To specify the stats gathering period for a connection, use the --stats_period option."); TestConsoleLog(kLogInfo, ""); TestConsoleLog(kLogInfo, "To enable CloudWatch use the global --stats_cloudwatch option. Choices for each argument:"); TestConsoleLog(kLogInfo, " - Name of CloudWatch namespace. If \"NULL\", \"%s\" is used.", CLOUDWATCH_DEFAULT_NAMESPACE_STRING); TestConsoleLog(kLogInfo, " - Name of CloudWatch region. If \"NULL\", region where test is"); TestConsoleLog(kLogInfo, " running is used."); TestConsoleLog(kLogInfo, " - Name of CloudWatch dimension called \"Domain\"."); TestConsoleLog(kLogInfo, "Examples:"); TestConsoleLog(kLogInfo, " --stats_period 60"); TestConsoleLog(kLogInfo, " --stats_cloudwatch MyNameSpace us-west-2 MyStream"); TestConsoleLog(kLogInfo, " --stats_cloudwatch NULL NULL MyStream"); } #else static void PrintStatsHelp(const OptDef* unused) { (void)unused; TestConsoleLog(kLogInfo, "CloudWatch statistics gathering is not available."); } #endif /** * User-defined command-line options. These are the short options and the long options for our command line arguments. * Keep these organized, so they're easy to change and also easy to debug. The last element is required to be 0's. * * NOTE: Must keep this table in sync with typedef enum TestOptionNames in test_args.h. */ static OptDef my_options[] = { // Fields: // short option (required), long option (optional), number of arguments (required), // argument string (required), pointer to array of strings of arg choices (optional), // description string (required) { "l", "log", 1, "", NULL, "Global option. The base file name and path used for logging. This test application uses\n" "one log file and the SDK uses one log file. Only one of --log or --logs options\n" "can be used. If no log file is specified, all output goes to stdout."}, { "L", "logs", 1, "", NULL, "Global option. The base file name and path used for logging. In addition to two global\n" "log files (one for this test app and one for the SDK), each connection uses\n" "unique log files (one for this test app and one for the SDK). Only one of --log\n" "and --logs options can be used. If no log file is specified, all output goes to\n" "stdout."}, { "err", "stderr", 0, NULL, NULL, "Global option. Cause errors to be sent to stderr in addition to log files."}, { "mwin", "multiwindow", 0, NULL, NULL, "Global option. Enable multi-window console mode. Uses the callback log."}, { "name", "connection_name", 1, "", NULL, "Assign a connection a unique connection name string."}, { "tx", "tx", 1, "", NULL, "Choose transmitter mode (default RAW) for this connection. AVM mode requires one\n" "of --avm_video, --avm_audio, or --avm_anc options also be used."}, { "rx", "rx", 1, "", NULL, "Choose receiver mode (default RAW) for this connection. AVM mode requires one of\n" "avm_video, --avm_audio, or --avm_anc options also be used."}, { "vid", "avm_video", 18, "