switched to argp
This commit is contained in:
+86
-30
@@ -21,60 +21,116 @@
|
|||||||
#include <config.h>
|
#include <config.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "appl.h"
|
#include <argp.h>
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <string.h>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Appl& A = Appl::Instance("/path/dumpfile");
|
/** A structure holding all program options. */
|
||||||
|
struct options
|
||||||
void define_args()
|
|
||||||
{
|
{
|
||||||
A.setVersion("ebusfeed is part of """PACKAGE_STRING"");
|
const char* device; //!< device to write to [/dev/ttyUSB60]
|
||||||
|
int time; //!< delay between bytes in us [10000]
|
||||||
|
|
||||||
A.addText(" 'ebusfeed' sends hex values from dump file to a pseudo terminal device (pty)\n\n"
|
const char* dumpFile; //!< dump file to read
|
||||||
" Usage: 1. 'socat -d -d pty,raw,echo=0 pty,raw,echo=0'\n"
|
};
|
||||||
|
|
||||||
|
/** the program options. */
|
||||||
|
static struct options opt = {
|
||||||
|
"/dev/ttyUSB60", // device
|
||||||
|
10000, // time
|
||||||
|
|
||||||
|
"/tmp/ebus_dump.bin", // dumpFile
|
||||||
|
};
|
||||||
|
|
||||||
|
/** the version string of the program. */
|
||||||
|
const char *argp_program_version = "ebusfeed of """PACKAGE_STRING"";
|
||||||
|
|
||||||
|
/** the report bugs to address of the program. */
|
||||||
|
const char *argp_program_bug_address = ""PACKAGE_BUGREPORT"";
|
||||||
|
|
||||||
|
/** the documentation of the program. */
|
||||||
|
static const char argpdoc[] =
|
||||||
|
"ebusfeed - feed data from an "PACKAGE" dump file to a pseudo serial device.\n\n"
|
||||||
|
" Setup: 1. 'socat -d -d pty,raw,echo=0 pty,raw,echo=0'\n"
|
||||||
" 2. create symbol links to appropriate devices\n"
|
" 2. create symbol links to appropriate devices\n"
|
||||||
" for example: 'ln -s /dev/pts/2 /dev/ttyUSB60'\n"
|
" for example: 'ln -s /dev/pts/2 /dev/ttyUSB60'\n"
|
||||||
" 'ln -s /dev/pts/3 /dev/ttyUSB20'\n"
|
" 'ln -s /dev/pts/3 /dev/ttyUSB20'\n"
|
||||||
" 3. start ebusd: 'ebusd -f -d /dev/ttyUSB20'\n"
|
" 3. start "PACKAGE": '"PACKAGE" -f -d /dev/ttyUSB20'\n"
|
||||||
" 4. start ebusfeed: 'ebusfeed /path/to/ebus_dump.bin'\n\n"
|
" 4. start ebusfeed: 'ebusfeed /path/to/ebus_dump.bin'\n\n";
|
||||||
"Options:\n");
|
|
||||||
|
|
||||||
A.addOption("device", "d", OptVal("/dev/ttyUSB60"), dt_string, ot_mandatory,
|
/** the description of the accepted arguments. */
|
||||||
"link on pseudo terminal device (/dev/ttyUSB60)");
|
static char argpargsdoc[] = "[DUMPFILE]";
|
||||||
|
|
||||||
A.addOption("time", "t", OptVal(10000), dt_long, ot_mandatory,
|
/** the definition of the known program arguments. */
|
||||||
"delay between 2 bytes in 'us' (10000)");
|
static const struct argp_option argpoptions[] = {
|
||||||
|
{"device", 'd', "DEV", 0, "Write to DEV (pseudo serial device) [/dev/ttyUSB60]", 0 },
|
||||||
|
{"time", 't', "USEC", 0, "Delay each byte by USEC us [10000]", 0 },
|
||||||
|
{NULL, 0, NULL, 0, NULL, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The program argument parsing function.
|
||||||
|
* @param key the key from @a argpoptions.
|
||||||
|
* @param arg the option argument, or NULL.
|
||||||
|
* @param state the parsing state.
|
||||||
|
*/
|
||||||
|
error_t parse_opt(int key, char *arg, struct argp_state *state)
|
||||||
|
{
|
||||||
|
struct options *opt = (struct options*)state->input;
|
||||||
|
char* strEnd = NULL;
|
||||||
|
switch (key) {
|
||||||
|
// Device settings:
|
||||||
|
case 'd': // --device=/dev/ttyUSB60
|
||||||
|
if (arg == NULL || arg[0] == 0) {
|
||||||
|
argp_error(state, "invalid device");
|
||||||
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
opt->device = arg;
|
||||||
|
break;
|
||||||
|
case 't': // --time=10000
|
||||||
|
opt->time = strtol(arg, &strEnd, 10);
|
||||||
|
if (strEnd == NULL || *strEnd != 0 || opt->time < 1000 || opt->time > 100000000) {
|
||||||
|
argp_error(state, "invalid time");
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ARGP_KEY_ARG:
|
||||||
|
if (state->arg_num == 0) {
|
||||||
|
if (arg == NULL || arg[0] == 0 || strcmp("/", arg) == 0) {
|
||||||
|
argp_error(state, "invalid dumpfile");
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
opt->dumpFile = arg;
|
||||||
|
} else
|
||||||
|
return ARGP_ERR_UNKNOWN;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return ARGP_ERR_UNKNOWN;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
// define arguments and application variables
|
struct argp argp = { argpoptions, parse_opt, argpargsdoc, argpdoc, NULL, NULL, NULL };
|
||||||
define_args();
|
if (argp_parse(&argp, argc, argv, ARGP_IN_ORDER, NULL, &opt) != 0)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
// parse arguments
|
string dev(opt.device);
|
||||||
if (A.parseArgs(argc, argv) == false)
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
|
|
||||||
if (A.missingCommand() == true) {
|
|
||||||
cout << "ebus dump file is required." << endl;
|
|
||||||
exit(EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
string dev(A.getOptVal<const char*>("device"));
|
|
||||||
Port port(dev, true, false, NULL, false, "", 1);
|
Port port(dev, true, false, NULL, false, "", 1);
|
||||||
|
|
||||||
port.open();
|
port.open();
|
||||||
if(port.isOpen() == true) {
|
if(port.isOpen() == true) {
|
||||||
cout << "openPort successful." << endl;
|
cout << "openPort successful." << endl;
|
||||||
|
|
||||||
fstream file(A.getCommand().c_str(), ios::in | ios::binary);
|
fstream file(opt.dumpFile, ios::in | ios::binary);
|
||||||
|
|
||||||
if (file.is_open() == true) {
|
if (file.is_open() == true) {
|
||||||
|
|
||||||
@@ -84,20 +140,20 @@ int main(int argc, char* argv[])
|
|||||||
<< static_cast<unsigned>(byte) << endl;
|
<< static_cast<unsigned>(byte) << endl;
|
||||||
|
|
||||||
port.send(byte);
|
port.send(byte);
|
||||||
usleep(A.getOptVal<long>("time"));
|
usleep(opt.time);
|
||||||
}
|
}
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cout << "error opening file " << A.getOptVal<const char*>("file") << endl;
|
cout << "error opening file " << opt.dumpFile << endl;
|
||||||
|
|
||||||
port.close();
|
port.close();
|
||||||
if(port.isOpen() == false)
|
if(port.isOpen() == false)
|
||||||
cout << "closePort successful." << endl;
|
cout << "closePort successful." << endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cout << "error opening device " << A.getOptVal<const char*>("device") << endl;
|
cout << "error opening device " << opt.device << endl;
|
||||||
|
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
|
|||||||
Reference in New Issue
Block a user