Add keypressing program to automatically start different shells

This commit is contained in:
Empathic Qubit 2022-12-25 22:10:07 +01:00
parent 52e3f1630d
commit c97fa6d38b
6 changed files with 272 additions and 67 deletions

27
.vscode/launch.json vendored
View file

@ -4,13 +4,34 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Starten",
"name": "tibridge",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/ticat",
"program": "${workspaceFolder}/build/tibridge",
"args": [],
"stopAtEntry": false,
"stopAtEntry": true,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"preLaunchTask": "build",
"setupCommands": [
{
"description": "Automatische Strukturierung und Einrückung für \"gdb\" aktivieren",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},
{
"name": "tikeys",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/tikeys",
"args": ["--subtype=mirage", "--log-level=trace"],
"stopAtEntry": true,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,

View file

@ -1,6 +1,55 @@
cmake_minimum_required(VERSION 3.16)
find_package (ticables2)
find_package (pthread)
add_executable (tibridge main.c)
target_link_libraries (tibridge LINK_PUBLIC ticables2)
target_link_libraries (tibridge LINK_PUBLIC pthread)
project(tibridge)
cmake_minimum_required(VERSION 3.1.0)
find_package(PkgConfig REQUIRED)
PKG_CHECK_MODULES(GLIB REQUIRED glib-2.0)
PKG_CHECK_MODULES(TICABLES REQUIRED ticables2)
PKG_CHECK_MODULES(TICALCS REQUIRED ticalcs2)
file(GLOB COMMON_SRC src/common/*.c)
file(GLOB TIBRIDGE_SRC src/tibridge.c)
add_executable(tibridge ${COMMON_SRC} ${TIBRIDGE_SRC})
target_compile_options(tibridge PRIVATE -Werror)
target_include_directories(tibridge
PRIVATE src/include/
PRIVATE ${GLIB_INCLUDE_DIRS}
PRIVATE ${TICABLES_INCLUDE_DIRS}
)
target_link_libraries(tibridge PRIVATE ${GLIB_LIBRARIES})
target_link_libraries(tibridge PRIVATE ${TICABLES_LIBRARIES})
target_link_directories(tibridge PRIVATE ${GLIB_LIBRARY_DIRS})
target_link_directories(tibridge PRIVATE ${TICABLES_LIBRARIES})
PKG_CHECK_MODULES(READLINE REQUIRED readline)
file(GLOB TIKEYS_SRC src/tikeys.c)
add_executable(tikeys ${COMMON_SRC} ${TIKEYS_SRC})
target_compile_options(tikeys PRIVATE -Werror)
target_include_directories(tikeys
PRIVATE src/include/
PRIVATE ${GLIB_INCLUDE_DIRS}
PRIVATE ${TICABLES_INCLUDE_DIRS}
PRIVATE ${TICALCS_INCLUDE_DIRS}
PRIVATE ${READLINE_INCLUDE_DIRS}
)
target_link_libraries(tikeys PRIVATE ${GLIB_LIBRARIES})
target_link_libraries(tikeys PRIVATE ${TICABLES_LIBRARIES})
target_link_libraries(tikeys PRIVATE ${TICALCS_LIBRARIES})
target_link_libraries(tikeys PRIVATE ${READLINE_LIBRARIES})
target_link_directories(tikeys PRIVATE ${GLIB_LIBRARY_DIRS})
target_link_directories(tikeys PRIVATE ${TICABLES_LIBRARIES})
target_link_directories(tikeys PRIVATE ${TICALCS_LIBRARIES})
target_link_directories(tikeys PRIVATE ${READLINE_LIBRARIES})

66
src/common/utils.c Normal file
View file

@ -0,0 +1,66 @@
#include "utils.h"
#include <string.h>
#include <getopt.h>
LOG_LEVEL current_log_level = LEVEL_INFO;
CableHandle* utils_setup_cable() {
// search for all USB cables (faster)
log(LEVEL_INFO, "Searching for link cables...\n");
int **cables = NULL;
int err = ticables_probing_do(&cables, 5, PROBE_ALL);
if(err) {
log(LEVEL_ERROR, "Could not probe cable: %d\n", err);
ticables_probing_finish(&cables);
return NULL;
}
CableModel model;
int port;
for(model = CABLE_NUL; model < CABLE_MAX ; model++) {
int *ports = cables[model];
int i;
for(i = 0; !ports[i] && i < 5; i++);
port = ports[i];
if(port) {
log(LEVEL_DEBUG, "Cable Model: %d, Port: %d\n", model, i);
break;
}
}
CableHandle *handle = ticables_handle_new(model, port);
ticables_options_set_delay(handle, 1);
ticables_options_set_timeout(handle, 5);
return handle;
}
void utils_parse_args(int argc, char *argv[]) {
const struct option long_opts[] = {
{"log-level", required_argument, 0, 'L'},
{0,0,0,0}
};
int opt_index = 0;
int opt;
while((opt = getopt_long(argc, argv, "L:", long_opts, &opt_index)) != -1) {
if(opt == 'L') {
if(strcmp(optarg, "warn") == 0) {
current_log_level = LEVEL_WARN;
}
else if(strcmp(optarg, "error") == 0) {
current_log_level = LEVEL_ERROR;
}
else if(strcmp(optarg, "debug") == 0) {
current_log_level = LEVEL_DEBUG;
}
else if(strcmp(optarg, "trace") == 0) {
current_log_level = LEVEL_TRACE;
}
else if(strcmp(optarg, "info") == 0) {
current_log_level = LEVEL_INFO;
}
}
}
}

23
src/common/utils.h Normal file
View file

@ -0,0 +1,23 @@
#ifndef __COMMON_UTILS_H__
#define __COMMON_UTILS_H__
#include <stdio.h>
#include <tilp2/ticables.h>
typedef enum {
LEVEL_ERROR,
LEVEL_WARN,
LEVEL_INFO,
LEVEL_DEBUG,
LEVEL_TRACE,
} LOG_LEVEL;
#define log(level, fmt, values...) if(level <= current_log_level) { fprintf(stderr, fmt, ## values); fflush(stderr); }
extern LOG_LEVEL current_log_level;
CableHandle* utils_setup_cable();
void utils_parse_args(int argc, char *argv[]);
#endif

View file

@ -8,22 +8,23 @@
#include <unistd.h>
#include <signal.h>
#include "common/utils.h"
static CableDeviceInfo EmptyInfo;
static pthread_t tid;
static CableHandle* handle;
static pthread_mutex_t lock;
static CablePort port;
static CableModel model;
void reset_cable(void) {
unsigned char err;
ticables_cable_reset(handle);
ticables_cable_close(handle);
ticables_handle_del(handle);
handle = ticables_handle_new(CABLE_SLV, port);
handle = ticables_handle_new(model, port);
ticables_options_set_delay(handle, 1);
ticables_options_set_timeout(handle, 5);
@ -32,21 +33,9 @@ void reset_cable(void) {
}
}
typedef enum {
LEVEL_ERROR,
LEVEL_WARN,
LEVEL_INFO,
LEVEL_DEBUG,
LEVEL_TRACE,
} LOG_LEVEL;
static LOG_LEVEL current_log_level = LEVEL_TRACE;
#define log(level, fmt, values...) if(level <= current_log_level) { fprintf(stderr, fmt, ## values); fflush(stderr); }
void retry_send(unsigned char* send, int sendCount) {
unsigned char err = 0;
log(LEVEL_DEBUG, "SENDING %d BYTES \n", sendCount);
log(LEVEL_DEBUG, "%d->", sendCount);
log(LEVEL_TRACE, "%.*s\n", sendCount, send);
while(err = ticables_cable_send(handle, send, sendCount)) {
log(LEVEL_ERROR, "Error sending: %d", err);
@ -63,63 +52,32 @@ void nack() {
}
void retry_recv(unsigned char* recv, int recvCount) {
log(LEVEL_DEBUG, "RECEIVED %d BYTES\n", recvCount);
log(LEVEL_DEBUG, "%d<-", recvCount);
log(LEVEL_TRACE, "%.*s\n", recvCount, recv)
int c = 0;
while((c += fwrite(&recv[c], 1, recvCount - c, stdout)) < recvCount);
fflush(stdout);
}
void INThandler(int sig) {
signal(sig, SIG_IGN);
char rest[1024];
int count = read(0, rest, sizeof(rest));
fwrite(rest, count, 1, stderr);
fflush(stderr);
}
int main(void) {
int **cables = NULL;
int main(int argc, char *argv[]) {
int err;
/*
signal(SIGINT, INThandler);
signal(SIGSTOP, INThandler);
signal(SIGTERM, INThandler);
signal(SIGQUIT, INThandler);
*/
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stdin, NULL, _IONBF, 0);
log(LEVEL_INFO, "PROCESS ID: %d\n", getpid());
if (pthread_mutex_init(&lock, NULL) != 0) {
fprintf(stderr, "mutex init has failed\n");
return 1;
}
utils_parse_args(argc, argv);
ticables_library_init();
// search for all USB cables (faster)
log(LEVEL_INFO, "Searching for link cables...\n");
err = ticables_probing_do(&cables, 5, PROBE_USB | PROBE_FIRST);
if(err)
{
log(LEVEL_ERROR, "Could not probe cable: %d\n", err);
ticables_probing_finish(&cables);
return 1;
}
log(LEVEL_INFO, "PROCESS ID: %d\n", getpid());
int *ports = cables[CABLE_SLV];
int i;
for(i = 0; !ports[i] && i < 5; i++);
port = ports[i];
handle = ticables_handle_new(CABLE_SLV, port);
ticables_options_set_delay(handle, 1);
ticables_options_set_timeout(handle, 5);
handle = utils_setup_cable();
if(handle == NULL) {
log(LEVEL_ERROR, "Cable not found!\n");
return 1;
}
// BEGIN DON'T DO THIS FOR TICALCS
err = ticables_cable_open(handle);
if(err) {
log(LEVEL_ERROR, "Could not open cable: %d\n", err);
@ -133,7 +91,8 @@ int main(void) {
return 1;
}
log(LEVEL_INFO, "INFO: Family %d, Variant %d\n", info.family, info.variant);
log(LEVEL_INFO, "INFO: Model %d, Port:%d, Family %d, Variant %d\n", model, port, info.family, info.variant);
// END DON'T DO THIS FOR TICALCS
bool handle_acks = true;
bool handled_first_recv = false;
@ -144,6 +103,7 @@ int main(void) {
int recvCount = 0;
int c;
log(LEVEL_INFO, "<");
log(LEVEL_DEBUG, "RECEIVE PHASE\n");
while(true) {
do {
@ -201,6 +161,7 @@ int main(void) {
FD_SET(0, &set);
struct timeval timeout = { 1, 0 };
log(LEVEL_INFO, ">");
log(LEVEL_DEBUG, "SEND PHASE\n");
while(true) {
unsigned char send[255];
@ -225,3 +186,5 @@ int main(void) {
}
}
}
void utils_parse_args(int argc, char *argv[]);

83
src/tikeys.c Normal file
View file

@ -0,0 +1,83 @@
#include <tilp2/ticables.h>
#include <tilp2/ticalcs.h>
#include "common/utils.h"
#include <readline/readline.h>
#include <tilp2/keys83p.h>
#include <getopt.h>
#include <unistd.h>
static char *subtype = "mirage";
static CalcHandle *calc_handle = NULL;
void send_key(uint32_t key, int retry) {
usleep(250000);
int err;
while(err = ticalcs_calc_send_key(calc_handle, key) && retry);
}
int main(int argc, char *argv[]) {
utils_parse_args(argc, argv);
const struct option long_opts[] = {
//{name,arg,flag,val}
{"subtype", required_argument, 0, 's'},
{0,0,0,0}
};
optind = 0;
int opt_index = 0;
int opt;
while((opt = getopt_long(argc, argv, "s:", long_opts, &opt_index)) != -1) {
if(opt == 's') {
subtype = optarg;
}
}
ticables_library_init();
CableHandle *cable_handle = utils_setup_cable();
if(cable_handle == NULL) {
log(LEVEL_ERROR, "Cable not found!\n");
return 1;
}
ticables_options_set_timeout(cable_handle, 20);
calc_handle = ticalcs_handle_new(CALC_TI83P);
ticalcs_cable_attach(calc_handle, cable_handle);
send_key(KEY83P_Quit, 1);
send_key(KEY83P_Clear, 1);
int err;
if(strcmp(subtype, "asm") == 0) {
log(LEVEL_ERROR, "asm is not supported! Start it manually!\n");
return 1;
}
else if(strcmp(subtype, "tse") == 0) {
log(LEVEL_ERROR, "tse is not supported! Start it manually!\n");
return 1;
}
else if(strcmp(subtype, "ion") == 0) {
log(LEVEL_WARN, "ion will be started, but you still need to start the program yourself.\n");
send_key(KEY83P_Prgm, 1);
send_key(ticalcs_keys_83p('A')->normal.value, 1);
send_key(KEY83P_Enter, 1);
send_key(KEY83P_Enter, 0);
}
else if(strcmp(subtype, "mirage") == 0) {
log(LEVEL_WARN, "Mirage will be started, but you still need to start the program yourself.\n");
send_key(KEY83P_AppsMenu, 1);
send_key(ticalcs_keys_83p('M')->normal.value, 1);
send_key(KEY83P_Enter, 0);
}
else {
log(LEVEL_WARN, "Subtype was not recognized! Start it manually!\n");
}
ticalcs_cable_detach(calc_handle);
ticables_cable_close(cable_handle);
return 0;
}