fp@922: /***************************************************************************** fp@922: * fp@922: * $Id$ fp@922: * fp@922: ****************************************************************************/ fp@922: fp@922: #include fp@1118: #include // basename() fp@922: fp@922: #include fp@922: #include fp@956: #include fp@922: using namespace std; fp@922: fp@1122: #include "globals.h" fp@1122: fp@1122: /*****************************************************************************/ fp@1122: fp@1122: string binaryBaseName; fp@1122: unsigned int masterIndex = 0; fp@1122: int slavePosition = -1; fp@1122: int domainIndex = -1; fp@1122: string command; fp@956: vector commandArgs; fp@1122: Verbosity verbosity = Normal; fp@968: string dataTypeStr; fp@980: bool force = false; fp@1122: fp@1121: bool helpRequested = false; fp@922: fp@1122: MasterDevice masterDev; fp@1122: fp@1122: /*****************************************************************************/ fp@1122: fp@1122: struct Command { fp@1122: void (*func)(void); fp@1122: const char *helpString; fp@1122: fp@1122: int execute(void) const; fp@1122: void displayHelp(void) const; fp@1122: }; fp@1122: fp@1122: struct CommandAlias { fp@1122: const char *name; fp@1122: const Command *command; fp@1122: }; fp@1122: fp@1122: /*****************************************************************************/ fp@1122: fp@1122: #define COMMAND(name) \ fp@1122: void command_##name(void); \ fp@1122: extern const char *help_##name; \ fp@1122: const Command cmd_##name = {command_##name, help_##name}; fp@1122: fp@1122: COMMAND(alias); fp@1122: COMMAND(config); fp@1122: fp@1122: const CommandAlias commandAliases[] = { fp@1122: {"alias", &cmd_alias}, fp@1122: fp@1122: {"config", &cmd_config}, fp@1122: {"conf", &cmd_config}, fp@1122: {"cf", &cmd_config}, fp@1122: }; fp@1122: fp@1122: #if 0 fp@980: } else if (command == "data") { fp@949: master.outputData(domainIndex); fp@956: } else if (command == "debug") { fp@956: master.setDebug(commandArgs); fp@949: } else if (command == "domain") { fp@948: master.showDomains(domainIndex); fp@957: } else if (command == "master") { fp@957: master.showMaster(); fp@935: } else if (command == "pdos") { fp@1099: master.listPdos(slavePosition); fp@965: } else if (command == "sdos") { fp@1099: master.listSdos(slavePosition); fp@974: } else if (command == "sdo_download" || command == "sd") { fp@974: master.sdoDownload(slavePosition, dataTypeStr, commandArgs); fp@968: } else if (command == "sdo_upload" || command == "su") { fp@968: master.sdoUpload(slavePosition, dataTypeStr, commandArgs); fp@1065: } else if (command == "slave" || command == "slaves" fp@1065: || command == "list" || command == "ls") { fp@1099: master.showSlaves(slavePosition); fp@978: } else if (command == "sii_read" || command == "sr") { fp@978: master.siiRead(slavePosition); fp@980: } else if (command == "sii_write" || command == "sw") { fp@980: master.siiWrite(slavePosition, force, commandArgs); fp@960: } else if (command == "state") { fp@960: master.requestStates(slavePosition, commandArgs); fp@938: } else if (command == "xml") { fp@938: master.generateXml(slavePosition); fp@1122: #endif fp@1122: fp@1122: /*****************************************************************************/ fp@1122: fp@1122: void printUsage() fp@1122: { fp@1122: cerr fp@1122: << "Usage: " << binaryBaseName << " [OPTIONS]" << endl fp@1122: << "Commands:" << endl fp@1122: << " alias Write alias addresses." << endl fp@1122: << " config Show bus configuration." << endl fp@1122: << " data Output binary domain process data." << endl fp@1122: << " debug Set the master's debug level." << endl fp@1122: << " domain Show domain information." << endl fp@1122: << " master Show master information." << endl fp@1122: << " pdos List Pdo assignment/mapping." << endl fp@1122: << " sdo_download Write an Sdo entry." << endl fp@1122: << " sdos List Sdo dictionaries." << endl fp@1122: << " sdo_upload Read an Sdo entry." << endl fp@1122: << " sii_read Output a slave's SII contents." << endl fp@1122: << " sii_write Write slave's SII contents." << endl fp@1122: << " slaves Show slaves." << endl fp@1122: << " state Request slave states." << endl fp@1122: << " xml Generate slave information xmls." << endl fp@1122: << "Global options:" << endl fp@1122: << " --master -m Index of the master to use. Default: 0" fp@1122: << endl fp@1122: << " --slave -s Positive numerical ring position," fp@1122: << endl fp@1122: << " or 'all' for all slaves (default)." fp@1122: << endl fp@1122: << " --domain -d Positive numerical index," fp@1122: << endl fp@1122: << " or 'all' for all domains (default)." fp@1122: << endl fp@1122: << " --type -t Forced Sdo data type." << endl fp@1122: << " --force -f Force action." << endl fp@1122: << " --quiet -q Output less information." << endl fp@1122: << " --verbose -v Output more information." << endl fp@1122: << " --help -h Show this help." << endl fp@1122: << "Call '" << binaryBaseName fp@1122: << " --help' for command-specific help." << endl fp@1122: << "Send bug reports to " << PACKAGE_BUGREPORT << "." << endl; fp@1122: } fp@1122: fp@1122: /*****************************************************************************/ fp@1122: fp@1122: void getOptions(int argc, char **argv) fp@1122: { fp@1122: int c, argCount, optionIndex, number; fp@1122: char *remainder; fp@1122: fp@1122: static struct option longOptions[] = { fp@1122: //name, has_arg, flag, val fp@1122: {"master", required_argument, NULL, 'm'}, fp@1122: {"slave", required_argument, NULL, 's'}, fp@1122: {"domain", required_argument, NULL, 'd'}, fp@1122: {"type", required_argument, NULL, 't'}, fp@1122: {"force", no_argument, NULL, 'f'}, fp@1122: {"quiet", no_argument, NULL, 'q'}, fp@1122: {"verbose", no_argument, NULL, 'v'}, fp@1122: {"help", no_argument, NULL, 'h'}, fp@1122: {} fp@1122: }; fp@1122: fp@1122: do { fp@1122: c = getopt_long(argc, argv, "m:s:d:t:fqvh", longOptions, &optionIndex); fp@1122: fp@1122: switch (c) { fp@1122: case 'm': fp@1122: number = strtoul(optarg, &remainder, 0); fp@1122: if (remainder == optarg || *remainder || number < 0) { fp@1122: cerr << "Invalid master number " << optarg << "!" << endl; fp@1122: printUsage(); fp@1122: exit(1); fp@1122: } fp@1122: masterIndex = number; fp@1122: break; fp@1122: fp@1122: case 's': fp@1122: if (!strcmp(optarg, "all")) { fp@1122: slavePosition = -1; fp@1122: } else { fp@1122: number = strtoul(optarg, &remainder, 0); fp@1122: if (remainder == optarg || *remainder fp@1122: || number < 0 || number > 0xFFFF) { fp@1122: cerr << "Invalid slave position " fp@1122: << optarg << "!" << endl; fp@1122: printUsage(); fp@1122: exit(1); fp@1122: } fp@1122: slavePosition = number; fp@1122: } fp@1122: break; fp@1122: fp@1122: case 'd': fp@1122: if (!strcmp(optarg, "all")) { fp@1122: domainIndex = -1; fp@1122: } else { fp@1122: number = strtoul(optarg, &remainder, 0); fp@1122: if (remainder == optarg || *remainder || number < 0) { fp@1122: cerr << "Invalid domain index " fp@1122: << optarg << "!" << endl; fp@1122: printUsage(); fp@1122: exit(1); fp@1122: } fp@1122: domainIndex = number; fp@1122: } fp@1122: break; fp@1122: fp@1122: case 't': fp@1122: dataTypeStr = optarg; fp@1122: break; fp@1122: fp@1122: case 'f': fp@1122: force = true; fp@1122: break; fp@1122: fp@1122: case 'q': fp@1122: verbosity = Quiet; fp@1122: break; fp@1122: fp@1122: case 'v': fp@1122: verbosity = Verbose; fp@1122: break; fp@1122: fp@1122: case 'h': fp@1122: helpRequested = true; fp@1122: break; fp@1122: fp@1122: case '?': fp@1122: printUsage(); fp@1122: exit(1); fp@1122: fp@1122: default: fp@1122: break; fp@1122: } fp@1122: } fp@1122: while (c != -1); fp@1122: fp@1122: argCount = argc - optind; fp@1122: fp@1122: if (!argCount) { fp@1122: if (!helpRequested) { fp@1122: cerr << "Please specify a command!" << endl; fp@1122: } fp@1122: printUsage(); fp@1122: exit(!helpRequested); fp@1122: } fp@1122: fp@1122: command = argv[optind]; fp@1122: while (++optind < argc) fp@1122: commandArgs.push_back(string(argv[optind])); fp@1122: } fp@1122: fp@1122: /****************************************************************************/ fp@1122: fp@1122: int Command::execute() const fp@1122: { fp@1122: try { fp@1122: func(); fp@1122: } catch (InvalidUsageException &e) { fp@1122: cerr << e.what() << endl << endl; fp@1122: displayHelp(); fp@1122: return 1; fp@1122: } catch (ExecutionFailureException &e) { fp@1122: cerr << e.what() << endl; fp@1122: return 1; fp@1122: } catch (MasterDeviceException &e) { fp@1122: cerr << e.what() << endl; fp@1122: return 1; fp@1122: } fp@1122: fp@1122: return 0; fp@1122: } fp@1122: fp@1122: /****************************************************************************/ fp@1122: fp@1122: void Command::displayHelp() const fp@1122: { fp@1122: cerr << binaryBaseName << " " << command << " " << helpString; fp@1122: } fp@1122: fp@1122: /****************************************************************************/ fp@1122: fp@1122: int main(int argc, char **argv) fp@1122: { fp@1122: int retval = 0; fp@1122: const CommandAlias *alias; fp@1122: const CommandAlias *endAlias = fp@1122: commandAliases + sizeof(commandAliases) / sizeof(CommandAlias); fp@1122: fp@1122: binaryBaseName = basename(argv[0]); fp@1122: getOptions(argc, argv); fp@1122: fp@1122: // search command alias in alias map fp@1122: for (alias = commandAliases; alias < endAlias; alias++) { fp@1122: if (command == alias->name) fp@1122: break; fp@1122: } fp@1122: fp@1122: if (alias < endAlias) { // command alias found fp@1122: if (!helpRequested) { fp@1122: masterDev.setIndex(masterIndex); fp@1122: retval = alias->command->execute(); fp@935: } else { fp@1122: alias->command->displayHelp(); fp@935: } fp@1122: } else { // command not found fp@1122: cerr << "Unknown command " << command << "!" << endl << endl; fp@1122: printUsage(); fp@1122: retval = 1; fp@922: } fp@922: fp@1122: return retval; fp@922: } fp@922: fp@922: /****************************************************************************/