allow flashing via net

This commit is contained in:
John
2022-04-10 17:19:42 +02:00
parent 92436474e1
commit 11e2a8ce0b
+62 -9
View File
@@ -21,6 +21,10 @@
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <dirent.h>
#include <time.h>
#include <termios.h>
@@ -41,7 +45,8 @@ const char *argp_program_version = "eBUS adapter PIC firmware loader";
/** the documentation of the program. */
static const char argpdoc[] =
"A tool for loading firmware to the eBUS adapter PIC."
"\vPORT is the serial port to use (e.g./dev/ttyUSB0) also supporting a trailing wildcard '*' for testing multiple ports.";
"\vPORT is either the serial port to use (e.g./dev/ttyUSB0) that also supports a trailing wildcard '*' for testing multiple ports,"
"or a network port as \"ip:port\" for use with e.g. socat.";
static const char argpargsdoc[] = "PORT";
@@ -256,6 +261,10 @@ typedef union
// size of boot block in bytes
#define END_BOOT_BYTES (END_BOOT*2)
static bool isSerial = true;
static int timeoutFactor = 1;
static int timeoutAddend = 0;
long long getTime() {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
@@ -267,7 +276,7 @@ ssize_t waitWrite(int fd, uint8_t *data, size_t len, int timeoutMillis) {
struct pollfd pfd;
pfd.fd = fd;
pfd.events = POLLOUT | POLLERR | POLLHUP;
ret = poll(&pfd, 1, timeoutMillis);
ret = poll(&pfd, 1, timeoutMillis*timeoutFactor + timeoutAddend);
if (ret >= 0 && pfd.revents & (POLLERR | POLLHUP)) {
return -1;
}
@@ -293,7 +302,7 @@ ssize_t waitRead(int fd, uint8_t *data, size_t len, int timeoutMillis) {
struct pollfd pfd;
pfd.fd = fd;
pfd.events = POLLIN | POLLERR | POLLHUP;
ret = poll(&pfd, 1, timeoutMillis);
ret = poll(&pfd, 1, timeoutMillis*timeoutFactor + timeoutAddend);
if (ret >= 0 && pfd.revents & (POLLERR | POLLHUP)) {
return -1;
}
@@ -618,7 +627,7 @@ struct termios termios_original;
int openSerial(std::string port) {
// open serial port
int fd = open(port.c_str(), O_RDWR | O_NOCTTY | O_NDELAY); // non-blocking IO: | O_NONBLOCK);
int fd = open(port.c_str(), O_RDWR | O_NOCTTY | O_NDELAY); // non-blocking IO
if (fd == -1) {
std::cerr << "unable to open " << port << std::endl;
return -1;
@@ -656,8 +665,38 @@ int openSerial(std::string port) {
return fd;
}
void closeSerial(int fd) {
tcsetattr(fd, TCSANOW, &termios_original);
int openNet(std::string host, uint16_t port) {
// open network port
struct sockaddr_in address;
memset(reinterpret_cast<char*>(&address), 0, sizeof(address));
if (inet_addr(host.c_str()) == INADDR_NONE) {
struct hostent* he;
he = gethostbyname(host.c_str());
if (he == nullptr) {
return -1;
}
memcpy(&address.sin_addr, he->h_addr_list[0], he->h_length);
} else if (inet_aton(host.c_str(), &address.sin_addr) == 0) {
return -1;
}
address.sin_family = AF_INET;
address.sin_port = (in_port_t)htons(port);
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
return -1;
}
if (connect(fd, (struct sockaddr *) &address, sizeof(address)) != 0) {
close(fd);
return -1;
}
fcntl(fd, F_SETFL, O_NONBLOCK); // set non-blocking
return fd;
}
void closeConnection(int fd) {
if (isSerial) {
tcsetattr(fd, TCSANOW, &termios_original);
}
close(fd);
}
@@ -954,7 +993,21 @@ int main(int argc, char* argv[]) {
std::string port = argv[arg_index];
std::string::size_type pos = port.find('*');
if (pos==std::string::npos || pos != port.length()-1) {
int fd = openSerial(argv[arg_index]);
int fd;
pos = port.find(':');
if (pos != std::string::npos) {
string host = port.substr(0, pos);
uint16_t portNum = 0;
if (!parseShort(port.substr(pos+1).c_str(), 1, 65535, &portNum)) {
exit(EXIT_FAILURE);
}
isSerial = false;
timeoutFactor = 2;
timeoutAddend = 100;
fd = openNet(host, portNum);
} else {
fd = openSerial(port);
}
if (fd < 0) {
exit(EXIT_FAILURE);
}
@@ -990,7 +1043,7 @@ int main(int argc, char* argv[]) {
int run(int fd) {
// read version
if (readVersion(fd, verbose) != 0) {
closeSerial(fd);
closeConnection(fd);
return EXIT_FAILURE;
}
uint8_t data[0x10];
@@ -1061,6 +1114,6 @@ int run(int fd) {
resetDevice(fd);
}
closeSerial(fd);
closeConnection(fd);
return 0;
}