Logging and warning cleanup. Fully start program with Noshell!

This commit is contained in:
Empathic Qubit 2022-12-27 23:35:23 +01:00
parent 8f0f9dbc3c
commit ea7adeb30f
4 changed files with 165 additions and 45 deletions

View file

@ -17,7 +17,7 @@ file(GLOB TIBRIDGE_SRC src/tibridge.c)
add_executable(tibridge ${COMMON_SRC} ${TIBRIDGE_SRC}) add_executable(tibridge ${COMMON_SRC} ${TIBRIDGE_SRC})
target_compile_options(tibridge PRIVATE -Werror) target_compile_options(tibridge PRIVATE -Wall -Wno-format-security)
target_include_directories(tibridge target_include_directories(tibridge
PRIVATE src/include/ PRIVATE src/include/
@ -39,7 +39,7 @@ file(GLOB TIKEYS_SRC src/tikeys.c)
add_executable(tikeys ${COMMON_SRC} ${TIKEYS_SRC}) add_executable(tikeys ${COMMON_SRC} ${TIKEYS_SRC})
target_compile_options(tikeys PRIVATE -Werror) target_compile_options(tikeys PRIVATE -Wall -Wno-format-security)
target_include_directories(tikeys target_include_directories(tikeys
PRIVATE src/include/ PRIVATE src/include/

View file

@ -3,6 +3,8 @@
#include <stdio.h> #include <stdio.h>
#include <tilp2/ticables.h> #include <tilp2/ticables.h>
#include <stdlib.h>
#include <string.h>
typedef enum { typedef enum {
LEVEL_ERROR, LEVEL_ERROR,
@ -12,7 +14,48 @@ typedef enum {
LEVEL_TRACE, LEVEL_TRACE,
} LOG_LEVEL; } LOG_LEVEL;
#define log(level, fmt, values...) if(level <= current_log_level) { fprintf(stderr, fmt, ## values); fflush(stderr); } #define COLOR_RESET "\x1b[00m"
#define COLOR_BLACK "\x1b[30m"
#define COLOR_RED "\x1b[31m"
#define COLOR_GREEN "\x1b[32m"
#define COLOR_YELLOW "\x1b[33m"
#define COLOR_BLUE "\x1b[34m"
#define COLOR_MAGENTA "\x1b[35m"
#define COLOR_CYAN "\x1b[36m"
#define COLOR_WHITE "\x1b[37m"
static char* get_fullfmt(LOG_LEVEL level, const char* fmt) {
char* color;
if(level == LEVEL_ERROR) {
color = COLOR_RED;
}
else if(level == LEVEL_WARN) {
color = COLOR_YELLOW;
}
else if(level == LEVEL_DEBUG) {
color = COLOR_MAGENTA;
}
else if(level == LEVEL_TRACE) {
color = COLOR_CYAN;
}
else {
color = COLOR_RESET;
}
char *fullfmt = malloc(10 + strlen(fmt)); \
sprintf(fullfmt, "%s%s%s", color, fmt, COLOR_RESET); \
return fullfmt;
}
#define log(level, fmt, values...) { \
if(level <= current_log_level) { \
char *fullfmt = get_fullfmt(level, fmt ""); \
fprintf(stderr, fullfmt , ## values); \
fflush(stderr); \
free(fullfmt); \
} \
}
extern LOG_LEVEL current_log_level; extern LOG_LEVEL current_log_level;

View file

@ -9,8 +9,6 @@
#include "common/utils.h" #include "common/utils.h"
static pthread_t tid;
static CableHandle* cable_handle; static CableHandle* cable_handle;
void show_help() { void show_help() {
@ -32,7 +30,7 @@ int hex(char ch) {
return (-1); return (-1);
} }
uint8_t *hex2mem(const char *buf, uint8_t *mem, uint32_t count) { char *hex2mem(const char *buf, char *mem, uint32_t count) {
unsigned char ch; unsigned char ch;
for (int i = 0; i < count; i++) for (int i = 0; i < count; i++)
{ {
@ -56,30 +54,30 @@ void reset_cable(void) {
ticables_options_set_delay(cable_handle, 1); ticables_options_set_delay(cable_handle, 1);
ticables_options_set_timeout(cable_handle, 5); ticables_options_set_timeout(cable_handle, 5);
while(err = ticables_cable_open(cable_handle)) { while((err = ticables_cable_open(cable_handle))) {
log(LEVEL_ERROR, "Could not open cable: %d\n", err); log(LEVEL_ERROR, "Could not open cable: %d\n", err);
} }
} }
void retry_send(unsigned char* send, int sendCount) { void retry_send(uint8_t* send, int sendCount) {
unsigned char err = 0; unsigned char err = 0;
log(LEVEL_DEBUG, "%d->", sendCount); log(LEVEL_DEBUG, "%d->", sendCount);
log(LEVEL_TRACE, "%.*s\n", sendCount, send); log(LEVEL_TRACE, "%.*s\n", sendCount, send);
while(err = ticables_cable_send(cable_handle, send, sendCount)) { while((err = ticables_cable_send(cable_handle, send, sendCount))) {
log(LEVEL_ERROR, "Error sending: %d", err); log(LEVEL_ERROR, "Error sending: %d", err);
reset_cable(); reset_cable();
} }
} }
void ack() { void ack() {
retry_send("+", 1); retry_send((uint8_t*)"+", 1);
} }
void nack() { void nack() {
retry_send("-", 1); retry_send((uint8_t*)"-", 1);
} }
void retry_recv(unsigned char* recv, int recvCount) { void retry_recv(uint8_t* recv, int recvCount) {
log(LEVEL_DEBUG, "%d<-", recvCount); log(LEVEL_DEBUG, "%d<-", recvCount);
log(LEVEL_TRACE, "%.*s\n", recvCount, recv) log(LEVEL_TRACE, "%.*s\n", recvCount, recv)
int c = 0; int c = 0;
@ -150,7 +148,7 @@ int main(int argc, char *argv[]) {
bool handled_first_recv = false; bool handled_first_recv = false;
while(true) { while(true) {
unsigned char recv[1023]; uint8_t recv[1023];
unsigned char current = 0; unsigned char current = 0;
int recvCount = 0; int recvCount = 0;
int c; int c;
@ -159,7 +157,7 @@ int main(int argc, char *argv[]) {
log(LEVEL_DEBUG, "RECEIVE PHASE\n"); log(LEVEL_DEBUG, "RECEIVE PHASE\n");
while(true) { while(true) {
do { do {
if(err = ticables_cable_recv(cable_handle, &recv[recvCount], 1)) { if((err = ticables_cable_recv(cable_handle, &recv[recvCount], 1))) {
log(LEVEL_ERROR, "error receiving: %d\n", err); log(LEVEL_ERROR, "error receiving: %d\n", err);
} }
} while(err); } while(err);
@ -167,7 +165,7 @@ int main(int argc, char *argv[]) {
recvCount++; recvCount++;
if(current == '#') { if(current == '#') {
do { do {
if(err = ticables_cable_recv(cable_handle, &recv[recvCount], 2)) { if((err = ticables_cable_recv(cable_handle, &recv[recvCount], 2))) {
log(LEVEL_ERROR, "error receiving: %d\n", err); log(LEVEL_ERROR, "error receiving: %d\n", err);
} }
} while(err); } while(err);
@ -182,7 +180,7 @@ int main(int argc, char *argv[]) {
log(LEVEL_DEBUG, "Discarded the first packet\n"); log(LEVEL_DEBUG, "Discarded the first packet\n");
} }
char *packet_char = strchr(recv, '$'); char *packet_char = strchr((const char*)recv, '$');
if(packet_char) { if(packet_char) {
packet_char++; packet_char++;
@ -227,12 +225,11 @@ int main(int argc, char *argv[]) {
fd_set set; fd_set set;
FD_ZERO(&set); FD_ZERO(&set);
FD_SET(0, &set); FD_SET(0, &set);
struct timeval timeout = { 1, 0 };
log(LEVEL_INFO, ">"); log(LEVEL_INFO, ">");
log(LEVEL_DEBUG, "SEND PHASE\n"); log(LEVEL_DEBUG, "SEND PHASE\n");
while(true) { while(true) {
unsigned char send[255]; uint8_t send[255];
int sendCount = 0; int sendCount = 0;
while(true) { while(true) {

View file

@ -9,25 +9,42 @@
#include <tilp2/ticalcs.h> #include <tilp2/ticalcs.h>
#include <tilp2/tifiles.h> #include <tilp2/tifiles.h>
#include <tilp2/keys83p.h> #include <tilp2/keys83p.h>
#include <stdbool.h>
#include "common/utils.h" #include "common/utils.h"
#define CABLE_TIMEOUT 20
#define CABLE_FAST_TIMEOUT 2
static char *subtype = ""; static char *subtype = "";
static char *program = ""; static char *program = "";
static char *keys = ""; static char *keys = "";
static int reset_ram = 0; static int reset_ram = 0;
static CalcHandle *calc_handle = NULL; static CalcHandle *calc_handle = NULL;
static CableHandle *cable_handle = NULL;
static CalcModel model = CALC_NONE; static CalcModel model = CALC_NONE;
void show_help() { void show_help() {
log(LEVEL_INFO, "Syntax: tikeys [--reset-ram] [--keys=ABCDEFG123456789] [--subtype=mirage --program=PROGNAME]\n"); log(LEVEL_INFO, "Syntax: tikeys [--reset-ram] [--keys=ABCDEFG123456789] [--subtype=mirage --program=PROGNAME]\n");
} }
void cleanup() {
if(calc_handle) {
ticalcs_cable_detach(calc_handle);
ticalcs_handle_del(calc_handle);
}
if(cable_handle) {
ticables_cable_close(cable_handle);
ticables_handle_del(cable_handle);
}
ticables_library_exit();
}
static void send_key(uint32_t key, int retry) { static void send_key(uint32_t key, int retry) {
usleep(100000); usleep(100000);
int err; int err;
while(err = ticalcs_calc_send_key(calc_handle, key) && retry); while((err = ticalcs_calc_send_key(calc_handle, key) && retry));
} }
static int compare(const void *a, const void *b) { static int compare(const void *a, const void *b) {
@ -37,8 +54,8 @@ static int compare(const void *a, const void *b) {
static int get_program_index(GNode *tree, char* program) { static int get_program_index(GNode *tree, char* program) {
char *names[1024]; char *names[1024];
int n = 0; int n = 0;
bool has_program = false;
TreeInfo *info = tree->data;
for (int i = 0; i < (int)g_node_n_children(tree); i++) { for (int i = 0; i < (int)g_node_n_children(tree); i++) {
GNode *parent = g_node_nth_child(tree, i); GNode *parent = g_node_nth_child(tree, i);
VarEntry *ve = parent->data; VarEntry *ve = parent->data;
@ -50,29 +67,72 @@ static int get_program_index(GNode *tree, char* program) {
if(ve != NULL) { if(ve != NULL) {
const char *str_type = tifiles_vartype2string(model, ve->type); const char *str_type = tifiles_vartype2string(model, ve->type);
bool is_program = strcmp(&str_type[strlen(str_type) - 4], "PRGM") == 0;
if (strlen(str_type) >= 4 if (strlen(str_type) >= 4
&& ( && (
strcmp(&str_type[strlen(str_type) - 4], "PRGM") == 0 is_program || strcmp(str_type, "APPL") == 0
|| strcmp(str_type, "APPL") == 0
) )
) { ) {
if(is_program && strcmp(ve->name, program) == 0) {
has_program = true;
}
names[n++] = ve->name; names[n++] = ve->name;
log(LEVEL_TRACE, "%s\n", names[n-1]);
} }
} }
} }
} }
log(LEVEL_TRACE, "Sorting\n");
qsort(names, n, sizeof(names[0]), compare); qsort(names, n, sizeof(names[0]), compare);
for(int i = 0; i < n; i++) { for(int i = 0; i < n; i++) {
log(LEVEL_TRACE, "%s\n", names[i]);
if(strcmp(names[i], program) == 0) { if(strcmp(names[i], program) == 0) {
return i+1; // Finance is always at the beginning // Finance is always at the beginning for apps
return has_program ? i : i+1;
} }
} }
return -1; return -1;
} }
int start_app(GNode *apps, char *app_name, int is_program) {
int noshell_idx = get_program_index(apps, app_name);
if(noshell_idx == -1) {
log(LEVEL_ERROR, "Could not find %s.\n", app_name);
return 1;
}
if(is_program) {
send_key(KEY83P_Prgm, 1);
}
else {
send_key(KEY83P_AppsMenu, 1);
}
for(int i = 0; i < noshell_idx; i++) {
send_key(KEY83P_Down, 1);
}
send_key(KEY83P_Enter, 0);
if(is_program) {
send_key(KEY83P_Enter, 0);
}
return 0;
}
void handle_sigint(int code) {
cleanup();
}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
struct sigaction sa;
sa.sa_handler = handle_sigint;
sigaction(SIGINT, &sa, NULL);
utils_parse_args(argc, argv); utils_parse_args(argc, argv);
const struct option long_opts[] = { const struct option long_opts[] = {
@ -106,22 +166,29 @@ int main(int argc, char *argv[]) {
} }
else if(opt == 'h') { else if(opt == 'h') {
show_help(); show_help();
cleanup();
return 0; return 0;
} }
} }
log(LEVEL_TRACE, "Subtype: %s\n", subtype);
log(LEVEL_TRACE, "Keys: %s\n", keys);
log(LEVEL_TRACE, "Reset RAM: %d\n", reset_ram);
int err; int err;
ticables_library_init(); ticables_library_init();
CableHandle *cable_handle = utils_setup_cable(); cable_handle = utils_setup_cable();
if(cable_handle == NULL) { if(cable_handle == NULL) {
log(LEVEL_ERROR, "Cable not found!\n"); log(LEVEL_ERROR, "Cable not found!\n");
cleanup();
return 1; return 1;
} }
err = ticables_cable_open(cable_handle); err = ticables_cable_open(cable_handle);
if(err) { if(err) {
log(LEVEL_ERROR, "Could not open cable: %d\n", err); log(LEVEL_ERROR, "Could not open cable: %d\n", err);
cleanup();
return 1; return 1;
} }
@ -129,12 +196,14 @@ int main(int argc, char *argv[]) {
err = ticables_cable_get_device_info(cable_handle, &info); err = ticables_cable_get_device_info(cable_handle, &info);
if(err) { if(err) {
log(LEVEL_ERROR, "Could not read device info: %d\n", err); log(LEVEL_ERROR, "Could not read device info: %d\n", err);
cleanup();
return 1; return 1;
} }
err = ticables_cable_close(cable_handle); err = ticables_cable_close(cable_handle);
if(err) { if(err) {
log(LEVEL_ERROR, "Could not close cable: %d\n", err); log(LEVEL_ERROR, "Could not close cable: %d\n", err);
cleanup();
return 1; return 1;
} }
@ -142,7 +211,7 @@ int main(int argc, char *argv[]) {
cable_handle = utils_setup_cable(); cable_handle = utils_setup_cable();
ticables_options_set_timeout(cable_handle, 20); ticables_options_set_timeout(cable_handle, CABLE_TIMEOUT);
model = CALC_TI83P; model = CALC_TI83P;
@ -164,15 +233,19 @@ int main(int argc, char *argv[]) {
} }
if(strlen(subtype) > 0 || strlen(program) > 0) { if(strlen(subtype) > 0 || strlen(program) > 0) {
log(LEVEL_DEBUG, "Got a program startup request.\n");
send_key(KEY83P_Quit, 1); send_key(KEY83P_Quit, 1);
send_key(KEY83P_Clear, 1); send_key(KEY83P_Clear, 1);
if(strcmp(subtype, "asm") == 0) { if(strcmp(subtype, "asm") == 0) {
log(LEVEL_ERROR, "asm is not supported! Start it manually!\n"); log(LEVEL_ERROR, "asm is not supported! Start it manually!\n");
cleanup();
return 1; return 1;
} }
else if(strcmp(subtype, "tse") == 0) { else if(strcmp(subtype, "tse") == 0) {
log(LEVEL_ERROR, "tse is not supported! Start it manually!\n"); log(LEVEL_ERROR, "tse is not supported! Start it manually!\n");
cleanup();
return 1; return 1;
} }
else if(strcmp(subtype, "ion") == 0) { else if(strcmp(subtype, "ion") == 0) {
@ -184,9 +257,17 @@ int main(int argc, char *argv[]) {
} }
else if(strcmp(subtype, "mirage") == 0) { else if(strcmp(subtype, "mirage") == 0) {
log(LEVEL_WARN, "Mirage will be started, but you still need to start the program yourself.\n"); 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); GNode *vars, *apps;
send_key(KEY83P_Enter, 0); while((err = ticalcs_calc_get_dirlist(calc_handle, &vars, &apps)));
log(LEVEL_DEBUG, "Got dirlist\n");
if((err = start_app(apps, "MirageOS", 0))) {
log(LEVEL_ERROR, "Could not start MirageOS. Is it installed?\n");
cleanup();
return 1;
}
} }
else if(strlen(program) > 0) { else if(strlen(program) > 0) {
if(strcmp(subtype, "noshell") != 0) { if(strcmp(subtype, "noshell") != 0) {
@ -195,28 +276,32 @@ int main(int argc, char *argv[]) {
log(LEVEL_INFO, "Verifying that noshell is correctly hooked.\n"); log(LEVEL_INFO, "Verifying that noshell is correctly hooked.\n");
int err;
GNode *vars, *apps; GNode *vars, *apps;
while(err = ticalcs_calc_get_dirlist(calc_handle, &vars, &apps)); while((err = ticalcs_calc_get_dirlist(calc_handle, &vars, &apps)));
log(LEVEL_DEBUG, "Got dirlist\n"); log(LEVEL_DEBUG, "Got dirlist\n");
int noshell_idx = get_program_index(apps, "Noshell "); if((err = start_app(apps, "Noshell ", 0))) {
if(noshell_idx == -1) { log(LEVEL_ERROR, "Could not start Noshell. Is it installed?\n");
log(LEVEL_ERROR, "Could not find noshell. Exiting\n"); cleanup();
return 1; return 1;
} }
send_key(KEY83P_AppsMenu, 1); ticables_options_set_timeout(cable_handle, CABLE_FAST_TIMEOUT);
for(int i = 0; i < noshell_idx; i++) { send_key(ticalcs_keys_83p('1')->normal.value, 0);
send_key(KEY83P_Down, 1); send_key(KEY83P_Enter, 0);
send_key(ticalcs_keys_83p('6')->normal.value, 0);
ticables_options_set_timeout(cable_handle, CABLE_TIMEOUT);
if((err = start_app(vars, program, 1))) {
log(LEVEL_ERROR, "Could not start %s. Is it installed?\n", program);
cleanup();
return 1;
} }
//send_key(KEY83P_Enter, 0);
cleanup();
return 1; return 1;
get_program_index(vars, program);
// There has to be a better way to do this... // There has to be a better way to do this...
// Select a program then delete the name, // Select a program then delete the name,
// keeping only the pgrm token // keeping only the pgrm token
@ -236,11 +321,6 @@ int main(int argc, char *argv[]) {
} }
} }
ticalcs_cable_detach(calc_handle); cleanup();
ticalcs_handle_del(calc_handle);
ticables_cable_close(cable_handle);
ticables_handle_del(cable_handle);
ticables_library_exit();
return 0; return 0;
} }