mirror of
https://github.com/eddyem/tty_term.git
synced 2025-12-06 02:25:11 +03:00
add various speeds and uart format selection
This commit is contained in:
parent
c3f6a033fb
commit
08e99e0063
@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
set(PROJ tty_term)
|
set(PROJ tty_term)
|
||||||
set(MINOR_VERSION "0")
|
set(MINOR_VERSION "1")
|
||||||
set(MID_VERSION "1")
|
set(MID_VERSION "1")
|
||||||
set(MAJOR_VERSION "0")
|
set(MAJOR_VERSION "0")
|
||||||
set(VERSION "${MAJOR_VERSION}.${MID_VERSION}.${MINOR_VERSION}")
|
set(VERSION "${MAJOR_VERSION}.${MID_VERSION}.${MINOR_VERSION}")
|
||||||
@ -67,7 +67,7 @@ include_directories(${${PROJ}_INCLUDE_DIRS})
|
|||||||
# -L
|
# -L
|
||||||
link_directories(${${PROJ}_LIBRARY_DIRS})
|
link_directories(${${PROJ}_LIBRARY_DIRS})
|
||||||
# -D
|
# -D
|
||||||
add_definitions(${CFLAGS} -DLOCALEDIR=\"${LOCALEDIR}\"
|
add_definitions(${CFLAGS} -DLOCALEDIR=\"${LOCALEDIR}\" -DPROJECT=\"${PROJ}\"
|
||||||
-DPACKAGE_VERSION=\"${VERSION}\" -DGETTEXT_PACKAGE=\"${PROJ}\"
|
-DPACKAGE_VERSION=\"${VERSION}\" -DGETTEXT_PACKAGE=\"${PROJ}\"
|
||||||
-DMINOR_VERSION=\"${MINOR_VERSION}\" -DMID_VERSION=\"${MID_VERSION}\"
|
-DMINOR_VERSION=\"${MINOR_VERSION}\" -DMID_VERSION=\"${MID_VERSION}\"
|
||||||
-DMAJOR_VERSION=\"${MAJOR_VESION}\")
|
-DMAJOR_VERSION=\"${MAJOR_VESION}\")
|
||||||
|
|||||||
@ -46,12 +46,13 @@ static myoption cmdlnopts[] = {
|
|||||||
// set 1 to param despite of its repeating number:
|
// set 1 to param despite of its repeating number:
|
||||||
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), _("show this help")},
|
{"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)")},
|
{"speed", NEED_ARG, NULL, 's', arg_int, APTR(&G.speed), _("baudrate (default: 9600)")},
|
||||||
{"name", NEED_ARG, NULL, 'n', arg_string, APTR(&G.ttyname), _("serial device path or server name/IP")},
|
{"name", NEED_ARG, NULL, 'n', arg_string, APTR(&G.ttyname), _("serial device path or server name/IP or socket path")},
|
||||||
{"eol", NEED_ARG, NULL, 'e', arg_string, APTR(&G.eol), _("end of line: n (default), r, nr or rn")},
|
{"eol", NEED_ARG, NULL, 'e', arg_string, APTR(&G.eol), _("end of line: n (default), r, nr or rn")},
|
||||||
{"timeout", NEED_ARG, NULL, 't', arg_int, APTR(&G.tmoutms), _("timeout for select() in ms (default: 100)")},
|
{"timeout", NEED_ARG, NULL, 't', arg_int, APTR(&G.tmoutms), _("timeout for select() in ms (default: 100)")},
|
||||||
{"port", NEED_ARG, NULL, 'p', arg_string, APTR(&G.port), _("socket port (none for UNIX)")},
|
{"port", NEED_ARG, NULL, 'p', arg_string, APTR(&G.port), _("socket port (none for UNIX)")},
|
||||||
{"socket", NO_ARGS, NULL, 'S', arg_int, APTR(&G.socket), _("open socket")},
|
{"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")},
|
{"dumpfile",NEED_ARG, NULL, 'd', arg_string, APTR(&G.dumpfile), _("dump data to this file")},
|
||||||
|
{"format", NEED_ARG, NULL, 'f', arg_string, APTR(&G.port), _("tty format (default: 8N1)")},
|
||||||
end_option
|
end_option
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -65,7 +66,7 @@ static myoption cmdlnopts[] = {
|
|||||||
glob_pars *parse_args(int argc, char **argv){
|
glob_pars *parse_args(int argc, char **argv){
|
||||||
void *ptr = memcpy(&G, &Gdefault, sizeof(G)); assert(ptr);
|
void *ptr = memcpy(&G, &Gdefault, sizeof(G)); assert(ptr);
|
||||||
// format of help: "Usage: progname [args]\n"
|
// format of help: "Usage: progname [args]\n"
|
||||||
change_helpstring(_("Usage: %s [args]\n\n\tWhere args are:\n"));
|
change_helpstring(_(PROJECT " version " PACKAGE_VERSION "\nUsage: %s [args]\n\n\tWhere args are:\n"));
|
||||||
// parse arguments
|
// parse arguments
|
||||||
parseargs(&argc, &argv, cmdlnopts);
|
parseargs(&argc, &argv, cmdlnopts);
|
||||||
if(help) showhelp(-1, cmdlnopts);
|
if(help) showhelp(-1, cmdlnopts);
|
||||||
|
|||||||
9
dbg.h
9
dbg.h
@ -20,7 +20,10 @@
|
|||||||
#ifndef DBG_H__
|
#ifndef DBG_H__
|
||||||
#define DBG_H__
|
#define DBG_H__
|
||||||
|
|
||||||
|
// dirty trick
|
||||||
|
#define termios xxtermios
|
||||||
#include <usefull_macros.h>
|
#include <usefull_macros.h>
|
||||||
|
#undef termios
|
||||||
|
|
||||||
#ifdef EBUG
|
#ifdef EBUG
|
||||||
#undef DBG
|
#undef DBG
|
||||||
@ -32,10 +35,10 @@
|
|||||||
#define FNAME() do{LOGDBG("%s (%s, line %d)", __func__, __FILE__, __LINE__);}while(0)
|
#define FNAME() do{LOGDBG("%s (%s, line %d)", __func__, __FILE__, __LINE__);}while(0)
|
||||||
#define DBG(...) do{LOGDBG("%s (%s, line %d):", __func__, __FILE__, __LINE__); \
|
#define DBG(...) do{LOGDBG("%s (%s, line %d):", __func__, __FILE__, __LINE__); \
|
||||||
LOGDBGADD(__VA_ARGS__);} while(0)
|
LOGDBGADD(__VA_ARGS__);} while(0)
|
||||||
#define ERR(...) do{LOGERR(__VA_ARGS__); signals(9);}while(0)
|
#define ERR(...) do{red(__VA_ARGS__); printf("\n"); LOGERR(__VA_ARGS__); signals(9);}while(0)
|
||||||
#define ERRX(...) do{LOGERR(__VA_ARGS__); signals(9);}while(0)
|
#define ERRX(...) do{red(__VA_ARGS__); printf("\n"); LOGERR(__VA_ARGS__); signals(9);}while(0)
|
||||||
//#define WARN(...) do{LOGWARN(__VA_ARGS__);}while(0)
|
//#define WARN(...) do{LOGWARN(__VA_ARGS__);}while(0)
|
||||||
#define WARNX(...) do{LOGWARN(__VA_ARGS__);}while(0)
|
#define WARNX(...) do{red(__VA_ARGS__); printf("\n"); LOGWARN(__VA_ARGS__);}while(0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // DBG_H__
|
#endif // DBG_H__
|
||||||
|
|||||||
9
main.c
9
main.c
@ -61,13 +61,12 @@ int main(int argc, char **argv){
|
|||||||
signals(0);
|
signals(0);
|
||||||
}
|
}
|
||||||
conndev.name = strdup(G->ttyname);
|
conndev.name = strdup(G->ttyname);
|
||||||
conndev.speed = G->speed;
|
conndev.port = strdup(G->port);
|
||||||
if(G->socket){
|
if(G->socket){
|
||||||
if(!G->port) conndev.type = DEV_UNIXSOCKET;
|
if(!G->port) conndev.type = DEV_UNIXSOCKET;
|
||||||
else{
|
else conndev.type = DEV_NETSOCKET;
|
||||||
conndev.type = DEV_NETSOCKET;
|
}else{
|
||||||
conndev.port = strdup(G->port);
|
conndev.speed = G->speed;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(!opendev(&conndev, G->dumpfile)){
|
if(!opendev(&conndev, G->dumpfile)){
|
||||||
signals(0);
|
signals(0);
|
||||||
|
|||||||
@ -155,8 +155,8 @@ static void show_mode(bool for_resize){
|
|||||||
dtty->name+1, dtty->seol);
|
dtty->name+1, dtty->seol);
|
||||||
break;
|
break;
|
||||||
case DEV_TTY:
|
case DEV_TTY:
|
||||||
snprintf(buf, 127, "INSERT (TAB to switch, ctrl+D to quit) DEV: %s, ENDLINE: %s, SPEED: %d",
|
snprintf(buf, 127, "INSERT (TAB to switch, ctrl+D to quit) DEV: %s, ENDLINE: %s, SPEED: %d, FORMAT: %s",
|
||||||
dtty->name, dtty->seol, dtty->speed);
|
dtty->name, dtty->seol, dtty->speed, dtty->port);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
134
ttysocket.c
134
ttysocket.c
@ -17,11 +17,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <stdio.h> // getchar
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/un.h> // unix socket
|
#include <sys/un.h> // unix socket
|
||||||
|
|
||||||
@ -78,7 +81,7 @@ static size_t rmeols(chardevice *d){
|
|||||||
DBG("d is NULL");
|
DBG("d is NULL");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
TTY_descr *D = d->dev;
|
TTY_descr2 *D = d->dev;
|
||||||
if(!D || D->comfd < 0){
|
if(!D || D->comfd < 0){
|
||||||
DBG("D bad");
|
DBG("D bad");
|
||||||
return 0;
|
return 0;
|
||||||
@ -108,7 +111,7 @@ static size_t rmeols(chardevice *d){
|
|||||||
// get data drom TTY
|
// get data drom TTY
|
||||||
static char *getttydata(chardevice *d, int *len){
|
static char *getttydata(chardevice *d, int *len){
|
||||||
if(!d || !d->dev) return NULL;
|
if(!d || !d->dev) return NULL;
|
||||||
TTY_descr *D = d->dev;
|
TTY_descr2 *D = d->dev;
|
||||||
if(D->comfd < 0) return NULL;
|
if(D->comfd < 0) return NULL;
|
||||||
int L = 0;
|
int L = 0;
|
||||||
int length = D->bufsz;
|
int length = D->bufsz;
|
||||||
@ -136,12 +139,13 @@ static char *getttydata(chardevice *d, int *len){
|
|||||||
if(len) *len = L;
|
if(len) *len = L;
|
||||||
if(!L) return NULL;
|
if(!L) return NULL;
|
||||||
rmeols(d);
|
rmeols(d);
|
||||||
|
DBG("buffer len: %zd, content: =%s=", D->buflen, D->buf);
|
||||||
return D->buf;
|
return D->buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *getsockdata(chardevice *d, int *len){
|
static char *getsockdata(chardevice *d, int *len){
|
||||||
if(!d || !d->dev) return NULL;
|
if(!d || !d->dev) return NULL;
|
||||||
TTY_descr *D = d->dev;
|
TTY_descr2 *D = d->dev;
|
||||||
if(D->comfd < 0) return NULL;
|
if(D->comfd < 0) return NULL;
|
||||||
char *ptr = NULL;
|
char *ptr = NULL;
|
||||||
int n = waittoread(D->comfd);
|
int n = waittoread(D->comfd);
|
||||||
@ -233,9 +237,9 @@ int SendData(chardevice *d, char *str){
|
|||||||
|
|
||||||
static const int socktypes[] = {SOCK_STREAM, SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET, SOCK_DCCP, SOCK_PACKET, SOCK_DGRAM, 0};
|
static const int socktypes[] = {SOCK_STREAM, SOCK_RAW, SOCK_RDM, SOCK_SEQPACKET, SOCK_DCCP, SOCK_PACKET, SOCK_DGRAM, 0};
|
||||||
|
|
||||||
static TTY_descr* opensocket(chardevice *d){
|
static TTY_descr2* opensocket(chardevice *d){
|
||||||
if(!d) return FALSE;
|
if(!d) return FALSE;
|
||||||
TTY_descr *descr = MALLOC(TTY_descr, 1); // only for `buf` and bufsz/buflen
|
TTY_descr2 *descr = MALLOC(TTY_descr2, 1); // only for `buf` and bufsz/buflen
|
||||||
descr->buf = MALLOC(char, BUFSIZ);
|
descr->buf = MALLOC(char, BUFSIZ);
|
||||||
descr->bufsz = BUFSIZ;
|
descr->bufsz = BUFSIZ;
|
||||||
// now try to open a socket
|
// now try to open a socket
|
||||||
@ -302,6 +306,109 @@ static TTY_descr* opensocket(chardevice *d){
|
|||||||
return descr;
|
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
|
||||||
|
f |= PARENB | PARODD;
|
||||||
|
break;
|
||||||
|
case 'O': // odd
|
||||||
|
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(chardevice *d){
|
||||||
|
if(!d->name){
|
||||||
|
/// ïÔÓÕÔÓÔ×ÕÅÔ ÉÍÑ ÐÏÒÔÁ
|
||||||
|
WARNX(_("Port name is missing"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
TTY_descr2 *descr = MALLOC(TTY_descr2, 1);
|
||||||
|
descr->portname = strdup(d->name);
|
||||||
|
descr->speed = d->speed;
|
||||||
|
tcflag_t flags;
|
||||||
|
descr->format = parse_format(d->port, &flags);
|
||||||
|
if(!descr->format) goto someerr;
|
||||||
|
descr->buf = MALLOC(char, BUFSIZ);
|
||||||
|
descr->bufsz = BUFSIZ-1;
|
||||||
|
if((descr->comfd = open(descr->portname, O_RDWR|O_NOCTTY)) < 0){
|
||||||
|
WARN(_("Can't use port %s"), descr->portname);
|
||||||
|
goto someerr;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
descr->tty.c_cflag = BOTHER | flags |CREAD|CLOCAL;
|
||||||
|
descr->tty.c_ispeed = d->speed;
|
||||||
|
descr->tty.c_ospeed = d->speed;
|
||||||
|
if(ioctl(descr->comfd, TCSETS2, &descr->tty)){
|
||||||
|
WARN(_("Can't set new port config"));
|
||||||
|
goto someerr;
|
||||||
|
}
|
||||||
|
ioctl(descr->comfd, TCGETS2, &descr->tty);
|
||||||
|
d->speed = descr->tty.c_ispeed;
|
||||||
|
#ifdef EBUG
|
||||||
|
printf("ispeed: %d, ospeed: %d, cflag=%d (BOTHER=%d)\n", descr->tty.c_ispeed, descr->tty.c_ospeed, descr->tty.c_cflag&CBAUD, BOTHER);
|
||||||
|
if(system("stty -F /dev/ttyUSB0")) WARN("system()");
|
||||||
|
#endif
|
||||||
|
return descr;
|
||||||
|
someerr:
|
||||||
|
FREE(descr->format);
|
||||||
|
FREE(descr->buf);
|
||||||
|
FREE(descr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief opendev - open TTY or socket output device
|
* @brief opendev - open TTY or socket output device
|
||||||
* @param d - device type
|
* @param d - device type
|
||||||
@ -313,8 +420,8 @@ int opendev(chardevice *d, char *path){
|
|||||||
switch(d->type){
|
switch(d->type){
|
||||||
case DEV_TTY:
|
case DEV_TTY:
|
||||||
DBG("Serial");
|
DBG("Serial");
|
||||||
d->dev = new_tty(d->name, d->speed, BUFSIZ);
|
d->dev = opentty(d);
|
||||||
if(!d->dev || !(d->dev = tty_open(d->dev, 1))){
|
if(!d->dev){
|
||||||
WARN("Can't open device %s", d->name);
|
WARN("Can't open device %s", d->name);
|
||||||
DBG("CANT OPEN");
|
DBG("CANT OPEN");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -354,7 +461,9 @@ void closedev(chardevice *d){
|
|||||||
switch(d->type){
|
switch(d->type){
|
||||||
case DEV_TTY:
|
case DEV_TTY:
|
||||||
if(d->dev){
|
if(d->dev){
|
||||||
close_tty(&d->dev);
|
TTY_descr2 *t = d->dev;
|
||||||
|
ioctl(t->comfd, TCSETS2, &t->oldtty); // return TTY to previous state
|
||||||
|
close(t->comfd);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DEV_NETSOCKET:
|
case DEV_NETSOCKET:
|
||||||
@ -366,5 +475,12 @@ void closedev(chardevice *d){
|
|||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if(d->dev){
|
||||||
|
FREE(d->dev->format);
|
||||||
|
FREE(d->dev->portname);
|
||||||
|
FREE(d->dev->buf);
|
||||||
|
FREE(d->dev);
|
||||||
|
}
|
||||||
FREE(d->name);
|
FREE(d->name);
|
||||||
|
DBG("Device closed");
|
||||||
}
|
}
|
||||||
|
|||||||
18
ttysocket.h
18
ttysocket.h
@ -21,7 +21,9 @@
|
|||||||
#define TTY_H__
|
#define TTY_H__
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "dbg.h"
|
#include <asm-generic/termbits.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
//#include "dbg.h"
|
||||||
|
|
||||||
typedef enum{
|
typedef enum{
|
||||||
DEV_TTY,
|
DEV_TTY,
|
||||||
@ -29,10 +31,22 @@ typedef enum{
|
|||||||
DEV_UNIXSOCKET,
|
DEV_UNIXSOCKET,
|
||||||
} devtype;
|
} 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
|
||||||
|
char *buf; // buffer for data read
|
||||||
|
size_t bufsz; // size of buf
|
||||||
|
size_t buflen; // length of data read into buf
|
||||||
|
} TTY_descr2;
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
devtype type; // type
|
devtype type; // type
|
||||||
char *name; // filename (dev or UNIX socket) or server name/IP
|
char *name; // filename (dev or UNIX socket) or server name/IP
|
||||||
TTY_descr *dev; // tty serial device
|
TTY_descr2 *dev; // tty serial device
|
||||||
char *port; // port to connect
|
char *port; // port to connect
|
||||||
int speed; // tty speed
|
int speed; // tty speed
|
||||||
pthread_mutex_t mutex; // reading/writing mutex
|
pthread_mutex_t mutex; // reading/writing mutex
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user