Unfinished serial support in Windows

This commit is contained in:
Aaron Cook 2023-08-23 22:07:44 -05:00
commit be0e8a997c
8 changed files with 174 additions and 156 deletions

View file

@ -1,11 +1,14 @@
#ifdef __MINGW32__
# include <curses.h>
#else
# include <ncurses.h> # include <ncurses.h>
#endif
#include <pthread.h> #include <pthread.h>
#include <sched.h> #include <sched.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <termios.h>
#include <unistd.h> #include <unistd.h>
#include "bytenuts.h" #include "bytenuts.h"
@ -33,8 +36,6 @@ static int parse_args(int argc, char **argv);
static int load_configs(); static int load_configs();
static int read_state(); static int read_state();
static int load_state(); static int load_state();
static speed_t string_to_speed(const char *speed);
static const char *speed_to_string(speed_t speed);
static bytenuts_t bytenuts; static bytenuts_t bytenuts;
@ -61,11 +62,13 @@ bytenuts_run(int argc, char **argv)
return -1; return -1;
} }
#ifndef __MINGW32__
/* use pseudo-terminals for testing purposes */ /* use pseudo-terminals for testing purposes */
if (!strcmp(bytenuts.config.serial_path, "/dev/ptmx")) { if (!strcmp(bytenuts.config.serial_path, "/dev/ptmx")) {
grantpt(bytenuts.serial_fd); grantpt(bytenuts.serial_fd);
unlockpt(bytenuts.serial_fd); unlockpt(bytenuts.serial_fd);
} }
#endif
// Initialize ncurses // Initialize ncurses
initscr(); initscr();
@ -170,7 +173,7 @@ bytenuts_print_stats()
cheerios_insert(st_line, strlen(st_line)); cheerios_insert(st_line, strlen(st_line));
sprintf(st_line, "escape: %c\r\n", bytenuts.config.escape); sprintf(st_line, "escape: %c\r\n", bytenuts.config.escape);
cheerios_insert(st_line, strlen(st_line)); cheerios_insert(st_line, strlen(st_line));
sprintf(st_line, "baud: %s\r\n", speed_to_string(bytenuts.config.baud)); sprintf(st_line, "baud: %ld\r\n", bytenuts.config.baud);
cheerios_insert(st_line, strlen(st_line)); cheerios_insert(st_line, strlen(st_line));
sprintf(st_line, "config_path: %s\r\n", bytenuts.config.config_path); sprintf(st_line, "config_path: %s\r\n", bytenuts.config.config_path);
cheerios_insert(st_line, strlen(st_line)); cheerios_insert(st_line, strlen(st_line));
@ -316,7 +319,7 @@ parse_args(int argc, char **argv)
if (i == argc - 1) if (i == argc - 1)
return -1; return -1;
bytenuts.config.baud = string_to_speed(argv[i]); bytenuts.config.baud = strtol(argv[i], NULL, 10);
} }
else if (!strcmp(argv[i], "-l")) { else if (!strcmp(argv[i], "-l")) {
i++; i++;
@ -498,137 +501,3 @@ load_state()
return 0; return 0;
} }
static speed_t
string_to_speed(const char *speed)
{
if (!strcmp("50", speed))
return B50;
else if (!strcmp("75", speed))
return B75;
else if (!strcmp("110", speed))
return B110;
else if (!strcmp("134", speed))
return B134;
else if (!strcmp("150", speed))
return B150;
else if (!strcmp("200", speed))
return B200;
else if (!strcmp("300", speed))
return B300;
else if (!strcmp("600", speed))
return B600;
else if (!strcmp("1200", speed))
return B1200;
else if (!strcmp("1800", speed))
return B1800;
else if (!strcmp("2400", speed))
return B2400;
else if (!strcmp("4800", speed))
return B4800;
else if (!strcmp("9600", speed))
return B9600;
else if (!strcmp("19200", speed))
return B19200;
else if (!strcmp("38400", speed))
return B38400;
else if (!strcmp("57600", speed))
return B57600;
else if (!strcmp("115200", speed))
return B115200;
else if (!strcmp("230400", speed))
return B230400;
else if (!strcmp("460800", speed))
return B460800;
else if (!strcmp("500000", speed))
return B500000;
else if (!strcmp("576000", speed))
return B576000;
else if (!strcmp("921600", speed))
return B921600;
else if (!strcmp("1000000", speed))
return B1000000;
else if (!strcmp("1152000", speed))
return B1152000;
else if (!strcmp("1500000", speed))
return B1500000;
else if (!strcmp("2000000", speed))
return B2000000;
else if (!strcmp("2500000", speed))
return B2500000;
else if (!strcmp("3000000", speed))
return B3000000;
else if (!strcmp("3500000", speed))
return B3500000;
else if (!strcmp("4000000", speed))
return B4000000;
else
return B0;
}
static const char *
speed_to_string(speed_t speed)
{
if (speed == B50)
return "B50";
else if (speed == B75)
return "B75";
else if (speed == B110)
return "B110";
else if (speed == B134)
return "B134";
else if (speed == B150)
return "B150";
else if (speed == B200)
return "B200";
else if (speed == B300)
return "B300";
else if (speed == B600)
return "B600";
else if (speed == B1200)
return "B1200";
else if (speed == B1800)
return "B1800";
else if (speed == B2400)
return "B2400";
else if (speed == B4800)
return "B4800";
else if (speed == B9600)
return "B9600";
else if (speed == B19200)
return "B19200";
else if (speed == B38400)
return "B38400";
else if (speed == B57600)
return "B57600";
else if (speed == B115200)
return "B115200";
else if (speed == B230400)
return "B230400";
else if (speed == B460800)
return "B460800";
else if (speed == B500000)
return "B500000";
else if (speed == B576000)
return "B576000";
else if (speed == B921600)
return "B921600";
else if (speed == B1000000)
return "B1000000";
else if (speed == B1152000)
return "B1152000";
else if (speed == B1500000)
return "B1500000";
else if (speed == B2000000)
return "B2000000";
else if (speed == B2500000)
return "B2500000";
else if (speed == B3000000)
return "B3000000";
else if (speed == B3500000)
return "B3500000";
else if (speed == B4000000)
return "B4000000";
else
return "";
}

View file

@ -1,7 +1,11 @@
#ifndef _BYTENUTES_H_ #ifndef _BYTENUTES_H_
#define _BYTENUTES_H_ #define _BYTENUTES_H_
#ifdef __MINGW32__
# include <curses.h>
#else
# include <ncurses.h> # include <ncurses.h>
#endif
#include <pthread.h> #include <pthread.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
@ -24,7 +28,7 @@ typedef struct bytenuts_config_struct {
int echo; /* echo user input to the output window, default 0 */ int echo; /* echo user input to the output window, default 0 */
int no_crlf; /* only send LF line endings, not CRLF, default 0 */ int no_crlf; /* only send LF line endings, not CRLF, default 0 */
char escape; /* which character is used for escape sequence */ char escape; /* which character is used for escape sequence */
speed_t baud; /* baud rate */ long baud; /* baud rate */
char *config_path; /* config file path */ char *config_path; /* config file path */
char *log_path; /* path to the log file (if it exists) */ char *log_path; /* path to the log file (if it exists) */
char *serial_path; /* path to the target serial device */ char *serial_path; /* path to the target serial device */
@ -36,7 +40,7 @@ typedef struct bytenuts_config_struct {
.echo = 0, \ .echo = 0, \
.no_crlf = 0, \ .no_crlf = 0, \
.escape = 'b', \ .escape = 'b', \
.baud = B115200, \ .baud = 115200, \
.config_path = NULL, \ .config_path = NULL, \
.log_path = NULL, \ .log_path = NULL, \
.serial_path = NULL, \ .serial_path = NULL, \
@ -44,7 +48,7 @@ typedef struct bytenuts_config_struct {
} }
typedef struct bytenuts_struct { typedef struct bytenuts_struct {
int serial_fd; serial_t serial_fd;
bytenuts_config_t config; bytenuts_config_t config;
int config_overrides[5]; int config_overrides[5];
int resume; int resume;

View file

@ -1,4 +1,8 @@
#ifdef __MINGW32__
# include <curses.h>
#else
# include <ncurses.h> # include <ncurses.h>
#endif
#include <poll.h> #include <poll.h>
#include <pthread.h> #include <pthread.h>
#include <sched.h> #include <sched.h>

View file

@ -1,7 +1,11 @@
#ifndef _CHEERIOS_H_ #ifndef _CHEERIOS_H_
#define _CHEERIOS_H_ #define _CHEERIOS_H_
#ifdef __MINGW32__
# include <curses.h>
#else
# include <ncurses.h> # include <ncurses.h>
#endif
#include <pthread.h> #include <pthread.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
@ -33,7 +37,7 @@ typedef struct cheerios_struct {
pthread_t thr; pthread_t thr;
WINDOW *output; WINDOW *output;
pthread_mutex_t *term_lock; pthread_mutex_t *term_lock;
int ser_fd; serial_t ser_fd;
line_buffer_t lines; line_buffer_t lines;
FILE *log; /* log file which was opened with -l */ FILE *log; /* log file which was opened with -l */
char *backup_filename; /* realpath to the backup outbuf.pid.log */ char *backup_filename; /* realpath to the backup outbuf.pid.log */

View file

@ -1,5 +1,9 @@
#include <libgen.h> #include <libgen.h>
#ifdef __MINGW32__
# include <curses.h>
#else
# include <ncurses.h> # include <ncurses.h>
#endif
#include <pthread.h> #include <pthread.h>
#include <sched.h> #include <sched.h>
#include <stdio.h> #include <stdio.h>

View file

@ -1,7 +1,11 @@
#ifndef _INGEST_H_ #ifndef _INGEST_H_
#define _INGEST_H_ #define _INGEST_H_
#ifdef __MINGW32__
# include <curses.h>
#else
# include <ncurses.h> # include <ncurses.h>
#endif
#include <pthread.h> #include <pthread.h>
#include <stdio.h> #include <stdio.h>
#include <time.h> #include <time.h>

View file

@ -2,14 +2,44 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <termios.h>
#include <unistd.h> #include <unistd.h>
#include "serial.h" #include "serial.h"
int #ifdef __MINGW32__
serial_open(const char *path, speed_t bps) # include <windows.h>
serial_t
serial_open(const char *comport, long bps)
{ {
DCB dcb = { 0 };
HANDLE serial = CreateFile(
comport,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
0,
0
);
if (serial == INVALID_HANDLE_VALUE) {
return -1;
}
/* TODO
* reference: https://github.com/waynix/SPinGW/tree/master */
return serial;
}
#else
# include <termios.h>
# include <poll.h>
static speed_t long_to_speed(long bps);
serial_t
serial_open(const char *path, long bps)
{
speed_t speed = long_to_speed(bps);
int fd; int fd;
struct termios otio; struct termios otio;
struct termios ntio; struct termios ntio;
@ -22,8 +52,8 @@ serial_open(const char *path, speed_t bps)
tcgetattr(fd, &otio); tcgetattr(fd, &otio);
tcgetattr(fd, &ntio); tcgetattr(fd, &ntio);
cfsetispeed(&ntio, bps); cfsetispeed(&ntio, speed);
cfsetospeed(&ntio, bps); cfsetospeed(&ntio, speed);
/* https://www.cmrr.umn.edu/~strupp/serial.html */ /* https://www.cmrr.umn.edu/~strupp/serial.html */
/* 8N1 */ /* 8N1 */
@ -57,3 +87,95 @@ serial_open(const char *path, speed_t bps)
return fd; return fd;
} }
int
serial_read(serial_t serial, void *buf, size_t len)
{
struct pollfd fds;
fds.fd = serial;
fds.events = POLLIN;
fds.revents = 0;
if (poll(&fds, 1, 1) == 0) {
return 0;
}
return (int)read(serial, buf, len);
}
int
serial_write(serial_t serial, void *buf, size_t len)
{
return (int)write(serial, buf, len);
}
static speed_t
long_to_speed(long bps)
{
switch (bps) {
case 50:
return B50;
case 75:
return B75;
case 110:
return B110;
case 134:
return B134;
case 150:
return B150;
case 200:
return B200;
case 300:
return B300;
case 600:
return B600;
case 1200:
return B1200;
case 1800:
return B1800;
case 2400:
return B2400;
case 4800:
return B4800;
case 9600:
return B9600;
case 19200:
return B19200;
case 38400:
return B38400;
case 57600:
return B57600;
case 115200:
return B115200;
case 230400:
return B230400;
case 460800:
return B460800;
case 500000:
return B500000;
case 576000:
return B576000;
case 921600:
return B921600;
case 1000000:
return B1000000;
case 1152000:
return B1152000;
case 1500000:
return B1500000;
case 2000000:
return B2000000;
case 2500000:
return B2500000;
case 3000000:
return B3000000;
case 3500000:
return B3500000;
case 4000000:
return B4000000;
default:
return B0;
}
}
#endif /* __MINGW32__ */

View file

@ -1,8 +1,15 @@
#ifndef _SERIAL_H_ #ifndef _SERIAL_H_
#define _SERIAL_H_ #define _SERIAL_H_
#include <termios.h> #ifdef __MINGW32__
# include <windows.h>
typedef HANDLE serial_t;
#else
typedef int serial_t;
#endif
int serial_open(const char *path, speed_t bps); serial_t serial_open(const char *path, long bps);
int serial_read(serial_t serial, void *buf, size_t len);
int serial_write(serial_t serial, void *buf, size_t len);
#endif /* _SERIAL_H_ */ #endif /* _SERIAL_H_ */