diff --git a/CMakeLists.txt b/CMakeLists.txt index f738a90..6a8f54f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.0) set(PROJ tty_term) -set(MINOR_VERSION "3") -set(MID_VERSION "1") +set(MINOR_VERSION "1") +set(MID_VERSION "2") set(MAJOR_VERSION "0") set(VERSION "${MAJOR_VERSION}.${MID_VERSION}.${MINOR_VERSION}") @@ -36,7 +36,7 @@ endif() ###### pkgconfig ###### # pkg-config modules (for pkg-check-modules) -set(MODULES ncurses readline usefull_macros) +set(MODULES ncurses readline usefull_macros>=0.3.2) # find packages: find_package(PkgConfig REQUIRED) @@ -67,9 +67,10 @@ message("Install dir prefix: ${CMAKE_INSTALL_PREFIX}") # exe file add_executable(${PROJ} ${SOURCES}) # -I -include_directories(${${PROJ}_INCLUDE_DIRS}) +target_include_directories(${PROJ} PUBLIC ${${PROJ}_INCLUDE_DIRS}) # -L -link_directories(${${PROJ}_LIBRARY_DIRS}) +target_link_directories(${PROJ} PUBLIC ${${PROJ}_LIBRARY_DIRS}) + # -D add_definitions(${CFLAGS} -DLOCALEDIR=\"${LOCALEDIR}\" -DPROJECT=\"${PROJ}\" -DPACKAGE_VERSION=\"${VERSION}\" -DGETTEXT_PACKAGE=\"${PROJ}\" diff --git a/Changelog b/Changelog new file mode 100644 index 0000000..603aaf7 --- /dev/null +++ b/Changelog @@ -0,0 +1,3 @@ +Mon Apr 28 12:33:57 MSK 2025 + +Changed to libusefull_macros v.0.3.2. diff --git a/cmdlnopts.c b/cmdlnopts.c index 65530c3..1468e2b 100644 --- a/cmdlnopts.c +++ b/cmdlnopts.c @@ -43,7 +43,7 @@ glob_pars const Gdefault = { * Define command line options by filling structure: * name has_arg flag val type argptr help */ -static myoption cmdlnopts[] = { +static sl_option_t cmdlnopts[] = { // set 1 to param despite of its repeating number: {"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), _("show this help")}, {"speed", NEED_ARG, NULL, 's', arg_int, APTR(&G.speed), _("baudrate (default: 9600)")}, @@ -54,6 +54,7 @@ static myoption cmdlnopts[] = { {"socket", NO_ARGS, NULL, 'S', arg_int, APTR(&G.socket), _("open socket")}, {"dumpfile",NEED_ARG, NULL, 'd', arg_string, APTR(&G.dumpfile), _("dump data to this file")}, {"format", NEED_ARG, NULL, 'f', arg_string, APTR(&G.serformat), _("tty format (default: 8N1)")}, + {"exclusive",NO_ARGS, NULL, 'x', arg_int, APTR(&G.exclusive), _("open serial in exclusive mode")}, end_option }; @@ -67,10 +68,10 @@ static myoption cmdlnopts[] = { glob_pars *parse_args(int argc, char **argv){ void *ptr = memcpy(&G, &Gdefault, sizeof(G)); assert(ptr); // format of help: "Usage: progname [args]\n" - change_helpstring(_(PROJECT " version " PACKAGE_VERSION "\nUsage: %s [args]\n\n\tWhere args are:\n")); + sl_helpstring(_(PROJECT " version " PACKAGE_VERSION "\nUsage: %s [args]\n\n\tWhere args are:\n")); // parse arguments - parseargs(&argc, &argv, cmdlnopts); - if(help) showhelp(-1, cmdlnopts); + sl_parseargs(&argc, &argv, cmdlnopts); + if(help) sl_showhelp(-1, cmdlnopts); if(argc > 0){ WARNX("Wrong arguments:\n"); for(int i = 0; i < argc; i++) diff --git a/cmdlnopts.h b/cmdlnopts.h index 44a4219..e01b252 100644 --- a/cmdlnopts.h +++ b/cmdlnopts.h @@ -27,6 +27,7 @@ typedef struct{ int speed; // baudrate int tmoutms; // timeout for select() in ms int socket; // open socket + int exclusive; // open serial in exclusive mode char *dumpfile; // file to save dump char *ttyname; // device name char *eol; // end of line: \r (CR), \rn (CR+LF) or \n (LF): "r", "rn", "n" diff --git a/main.c b/main.c index 7800e0d..9a9bedc 100644 --- a/main.c +++ b/main.c @@ -38,7 +38,7 @@ void signals(int signo){ int main(int argc, char **argv){ glob_pars *G = NULL; // default parameters see in cmdlnopts.c - initial_setup(); + sl_init(); #ifdef EBUG OPENLOG("debug.log", LOGLEVEL_ANY, 1); #endif @@ -71,6 +71,7 @@ int main(int argc, char **argv){ conndev.speed = G->speed; conndev.port = strdup(G->serformat); // `port` of tty is serial format DBG("speed=%d, format=%s", conndev.speed, conndev.port); + conndev.exclusive = G->exclusive; } if(!opendev(&conndev, G->dumpfile)){ signals(0); diff --git a/popup_msg.h b/popup_msg.h index ff5e031..bcc94d4 100644 --- a/popup_msg.h +++ b/popup_msg.h @@ -18,6 +18,7 @@ #pragma once #include +#include #define QUIT CTRL('Q') #define ESCAPE CTRL('[') diff --git a/ttysocket.c b/ttysocket.c index 0d86848..710a79c 100644 --- a/ttysocket.c +++ b/ttysocket.c @@ -81,11 +81,11 @@ static int waittoread(int fd){ // get data drom TTY static uint8_t *getttydata(int *len){ if(!device || !device->dev) return NULL; - TTY_descr2 *D = device->dev; + sl_tty_t *D = device->dev; if(D->comfd < 0) return NULL; int L = 0; int length = D->bufsz - 1; // -1 for terminating zero - uint8_t *ptr = D->buf; + uint8_t *ptr = (uint8_t*)D->buf; int s = 0; do{ if(!(s = waittoread(D->comfd))) break; @@ -106,19 +106,19 @@ static uint8_t *getttydata(int *len){ if(len) *len = L; if(!L) return NULL; DBG("buffer len: %zd, content: =%s=", D->buflen, D->buf); - return D->buf; + return (uint8_t*)D->buf; } static uint8_t *getsockdata(int *len){ if(!device || !device->dev) return NULL; - TTY_descr2 *D = device->dev; + sl_tty_t *D = device->dev; if(D->comfd < 0) return NULL; uint8_t *ptr = NULL; int n = waittoread(D->comfd); if(n == 1){ n = read(D->comfd, D->buf, D->bufsz-1); if(n > 0){ - ptr = D->buf; + ptr = (uint8_t*)D->buf; ptr[n] = 0; D->buflen = n; DBG("got %d: ..%s..", n, ptr); @@ -173,7 +173,7 @@ int SendData(const uint8_t *data, size_t len){ if(0 == pthread_mutex_lock(&device->mutex)){ switch(device->type){ case DEV_TTY: - if(write_tty(device->dev->comfd, (const char*)data, len)) ret = 0; + if(sl_tty_write(device->dev->comfd, (const char*)data, len)) ret = 0; else ret = len; break; case DEV_NETSOCKET: @@ -197,10 +197,10 @@ int SendData(const uint8_t *data, size_t len){ static const int socktypes[] = {SOCK_STREAM, SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET, SOCK_DCCP, SOCK_PACKET, SOCK_DGRAM, 0}; -static TTY_descr2* opensocket(){ +static sl_tty_t* opensocket(){ if(!device) return FALSE; - TTY_descr2 *descr = MALLOC(TTY_descr2, 1); // only for `buf` and bufsz/buflen - descr->buf = MALLOC(uint8_t, BUFSIZ); + sl_tty_t *descr = MALLOC(sl_tty_t, 1); // only for `buf` and bufsz/buflen + descr->buf = MALLOC(char, BUFSIZ); descr->bufsz = BUFSIZ; // now try to open a socket descr->comfd = -1; @@ -266,108 +266,20 @@ static TTY_descr2* opensocket(){ return descr; } -static char *parse_format(const char *iformat, tcflag_t *flags){ - tcflag_t f = 0; - if(!iformat){ // default - *flags = CS8; - return strdup("8N1"); - } - if(strlen(iformat) != 3) goto someerr; - switch(iformat[0]){ - case '5': - f |= CS5; - break; - case '6': - f |= CS6; - break; - case '7': - f |= CS7; - break; - case '8': - f |= CS8; - break; - default: - goto someerr; - } - switch(iformat[1]){ - case '0': // always 0 - f |= PARENB | CMSPAR; - break; - case '1': // always 1 - f |= PARENB | CMSPAR | PARODD; - break; - case 'E': // even - f |= PARENB; - break; - case 'N': // none - break; - case 'O': // odd - f |= PARENB | PARODD; - break; - default: - goto someerr; - } - switch(iformat[2]){ - case '1': - break; - case '2': - f |= CSTOPB; - break; - default: - goto someerr; - } - *flags = f; - return strdup(iformat); -someerr: - WARNX(_("Wrong USART format \"%s\"; use NPS, where N: 5..8; P: N/E/O/1/0, S: 1/2"), iformat); - return NULL; -} - -static TTY_descr2* opentty(){ +static sl_tty_t* opentty(){ if(!device->name){ /// Отсутствует имя порта WARNX(_("Port name is missing")); return NULL; } - TTY_descr2 *descr = MALLOC(TTY_descr2, 1); - descr->portname = strdup(device->name); - descr->speed = device->speed; - tcflag_t flags; - descr->format = parse_format(device->port, &flags); - if(!descr->format) goto someerr; - descr->buf = MALLOC(uint8_t, 512); - descr->bufsz = 511; - if((descr->comfd = open(descr->portname, O_RDWR|O_NOCTTY)) < 0){ - WARN(_("Can't use port %s"), descr->portname); - goto someerr; + sl_tty_t *descr = sl_tty_new(device->name, device->speed, 4096); + if(!descr){ + WARN("Can't init %s", device->name); + return NULL; } - if(ioctl(descr->comfd, TCGETS2, &descr->oldtty)){ - WARN(_("Can't get port config")); - goto someerr; - } - descr->tty = descr->oldtty; - descr->tty.c_lflag = 0; // ~(ICANON | ECHO | ECHOE | ISIG) - descr->tty.c_iflag = 0; // don't do any changes in input stream - descr->tty.c_oflag = 0; // don't do any changes in output stream - descr->tty.c_cflag = BOTHER | flags |CREAD|CLOCAL; - descr->tty.c_ispeed = device->speed; - descr->tty.c_ospeed = device->speed; - if(ioctl(descr->comfd, TCSETS2, &descr->tty)){ - WARN(_("Can't set new port config")); - goto someerr; - } - ioctl(descr->comfd, TCGETS2, &descr->tty); - if(descr->tty.c_ispeed != (speed_t)device->speed || descr->tty.c_ospeed != (speed_t)device->speed){ - WARN(_("Can't set speed %d, got ispeed=%d, ospeed=%d"), device->speed, descr->tty.c_ispeed, descr->tty.c_ospeed); - //goto someerr; - } - device->speed = descr->tty.c_ispeed; + descr->format = device->port; + descr = sl_tty_open(descr, device->exclusive); return descr; -someerr: - FREE(descr->format); - FREE(descr->buf); - FREE(descr); - return NULL; } /** @@ -430,7 +342,7 @@ void closedev(){ switch(device->type){ case DEV_TTY: if(device->dev){ - TTY_descr2 *t = device->dev; + sl_tty_t *t = device->dev; ioctl(t->comfd, TCSETS2, &t->oldtty); // return TTY to previous state close(t->comfd); } diff --git a/ttysocket.h b/ttysocket.h index 39cb81f..3e07bc2 100644 --- a/ttysocket.h +++ b/ttysocket.h @@ -24,7 +24,7 @@ #include #include #include -//#include "dbg.h" +#include typedef enum{ // device: tty terminal, network socket or UNIX socket DEV_TTY, @@ -32,27 +32,16 @@ typedef enum{ // device: tty terminal, network socket or UNIX socket DEV_UNIXSOCKET, } devtype; -typedef struct { - char *portname; // device filename (should be freed before structure freeing) - int speed; // baudrate in human-readable format - char *format; // format like 8N1 - struct termios2 oldtty; // TTY flags for previous port settings - struct termios2 tty; // TTY flags for current settings - int comfd; // TTY file descriptor - uint8_t *buf; // buffer for data read - size_t bufsz; // size of buf - size_t buflen; // length of data read into buf -} TTY_descr2; - typedef struct{ devtype type; // type char *name; // filename (dev or UNIX socket) or server name/IP - TTY_descr2 *dev; // tty serial device + sl_tty_t *dev; // tty serial device char *port; // port to connect int speed; // tty speed pthread_mutex_t mutex; // reading/writing mutex char eol[3]; // end of line char seol[5]; // `eol` with doubled backslash (for print @ screen) + int exclusive; } chardevice; uint8_t *ReadData(int *l);