mirror of
https://git.planet-casio.com/Lephenixnoir/fxsdk.git
synced 2024-12-29 13:03:37 +01:00
fxlink: basic TUI commands
This commit is contained in:
parent
c7c1ec35f7
commit
0a61ffc523
5 changed files with 87 additions and 29 deletions
|
@ -490,7 +490,6 @@ struct fxlink_message *fxlink_device_finish_bulk_IN(struct fxlink_device *fdev)
|
||||||
version_major, version_minor,
|
version_major, version_minor,
|
||||||
msg->application, msg->type, fxlink_size_string(msg->size));
|
msg->application, msg->type, fxlink_size_string(msg->size));
|
||||||
|
|
||||||
fxlink_transfer_free(comm->ftransfer_IN);
|
|
||||||
comm->ftransfer_IN = NULL;
|
comm->ftransfer_IN = NULL;
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
@ -554,13 +553,15 @@ static void bulk_OUT_callback(struct libusb_transfer *transfer)
|
||||||
}
|
}
|
||||||
|
|
||||||
void fxlink_device_start_bulk_OUT(struct fxlink_device *fdev,
|
void fxlink_device_start_bulk_OUT(struct fxlink_device *fdev,
|
||||||
char const *app, char const *type, void const *data, int size)
|
char const *app, char const *type, void const *data, int size,
|
||||||
|
bool own_data)
|
||||||
{
|
{
|
||||||
struct fxlink_comm *comm = fdev->comm;
|
struct fxlink_comm *comm = fdev->comm;
|
||||||
if(!comm || !comm->claimed || comm->ftransfer_OUT)
|
if(!comm || !comm->claimed || comm->ftransfer_OUT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
comm->ftransfer_OUT = fxlink_transfer_make_OUT(app, type, data, size);
|
comm->ftransfer_OUT =
|
||||||
|
fxlink_transfer_make_OUT(app, type, data, size, own_data);
|
||||||
if(!comm->ftransfer_OUT) {
|
if(!comm->ftransfer_OUT) {
|
||||||
elog("allocation of OUT transfer (protocol) failed\n");
|
elog("allocation of OUT transfer (protocol) failed\n");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -210,9 +210,11 @@ void fxlink_device_start_bulk_IN(struct fxlink_device *fdev);
|
||||||
struct fxlink_message *fxlink_device_finish_bulk_IN(
|
struct fxlink_message *fxlink_device_finish_bulk_IN(
|
||||||
struct fxlink_device *fdev);
|
struct fxlink_device *fdev);
|
||||||
|
|
||||||
/* Start an OUT transfer on the device. */
|
/* Start an OUT transfer on the device. If `own_data` is set, the transfer will
|
||||||
|
free(data) when it completes. */
|
||||||
void fxlink_device_start_bulk_OUT(struct fxlink_device *fdev,
|
void fxlink_device_start_bulk_OUT(struct fxlink_device *fdev,
|
||||||
char const *app, char const *type, void const *data, int size);
|
char const *app, char const *type, void const *data, int size,
|
||||||
|
bool own_data);
|
||||||
|
|
||||||
/* Interrupt any active transfers on the device. */
|
/* Interrupt any active transfers on the device. */
|
||||||
void fxlink_device_interrupt_transfers(struct fxlink_device *fdev);
|
void fxlink_device_interrupt_transfers(struct fxlink_device *fdev);
|
||||||
|
|
|
@ -113,6 +113,8 @@ struct fxlink_transfer {
|
||||||
uint8_t direction;
|
uint8_t direction;
|
||||||
/* Size of data sent or received so far */
|
/* Size of data sent or received so far */
|
||||||
int processed_size;
|
int processed_size;
|
||||||
|
/* Whether we own msg.data and should free(3) it */
|
||||||
|
bool own_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -130,7 +132,8 @@ enum {
|
||||||
struct fxlink_transfer *fxlink_transfer_make_IN(void *data, int size);
|
struct fxlink_transfer *fxlink_transfer_make_IN(void *data, int size);
|
||||||
|
|
||||||
/* If the provided IN transfer is finished, extract the message and free the
|
/* If the provided IN transfer is finished, extract the message and free the
|
||||||
transfer pointer. Otherwise, return NULL. */
|
transfer (do not fxlink_transfer_free(tr) later!). Returns NULL if the
|
||||||
|
transfer isn't finished yet. */
|
||||||
struct fxlink_message *fxlink_transfer_finish_IN(struct fxlink_transfer *tr);
|
struct fxlink_message *fxlink_transfer_finish_IN(struct fxlink_transfer *tr);
|
||||||
|
|
||||||
/* Append data to a previously-initialized inbound transfer. */
|
/* Append data to a previously-initialized inbound transfer. */
|
||||||
|
@ -138,7 +141,7 @@ void fxlink_transfer_receive(struct fxlink_transfer *tr, void *data, int size);
|
||||||
|
|
||||||
/* Make an outbound transfer structure. */
|
/* Make an outbound transfer structure. */
|
||||||
struct fxlink_transfer *fxlink_transfer_make_OUT(char const *application,
|
struct fxlink_transfer *fxlink_transfer_make_OUT(char const *application,
|
||||||
char const *type, void const *data, int size);
|
char const *type, void const *data, int size, bool own_data);
|
||||||
|
|
||||||
/* Check whether a transfer is complete. */
|
/* Check whether a transfer is complete. */
|
||||||
bool fxlink_transfer_complete(struct fxlink_transfer const *tr);
|
bool fxlink_transfer_complete(struct fxlink_transfer const *tr);
|
||||||
|
|
|
@ -21,6 +21,25 @@
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Plan for the TUI command set.
|
||||||
|
|
||||||
|
fxlink commands:
|
||||||
|
select Select the calculator we're talking to
|
||||||
|
remote-control Enable/disable/setup remote calculator control
|
||||||
|
|
||||||
|
Protocol commands (executed by the calculator):
|
||||||
|
/identify Send calculator identification information
|
||||||
|
/echo Echo a message
|
||||||
|
/screenshot Take a screenshot
|
||||||
|
/video Enable/disable video capture
|
||||||
|
|
||||||
|
Application-specific commands:
|
||||||
|
gintctl read-long Transmission tests (long messages)
|
||||||
|
gintctl read-alignment Pipe reading alignment
|
||||||
|
gintctl bench USB transfer speed benchmark
|
||||||
|
*/
|
||||||
|
|
||||||
static struct TUIData {
|
static struct TUIData {
|
||||||
/* SIGWINCH flag */
|
/* SIGWINCH flag */
|
||||||
bool resize_needed;
|
bool resize_needed;
|
||||||
|
@ -402,6 +421,50 @@ static void handle_fxlink_log(int display_fmt, char const *str)
|
||||||
wattroff(TUI.wLogs, attr);
|
wattroff(TUI.wLogs, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void execute_command(char const *command)
|
||||||
|
{
|
||||||
|
/* Connected device (TODO: Use the "selected" device) */
|
||||||
|
struct fxlink_device *fdev = NULL;
|
||||||
|
for(int i = 0; i < TUI.devices.count; i++) {
|
||||||
|
if(TUI.devices.devices[i].status == FXLINK_FDEV_STATUS_CONNECTED) {
|
||||||
|
fdev = &TUI.devices.devices[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The following commands require a connected device */
|
||||||
|
if(!fdev) {
|
||||||
|
print(TUI.wConsole, "no connected device!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
print(TUI.wConsole, "using device %s (%s)\n",
|
||||||
|
fxlink_device_id(fdev), fdev->calc->serial);
|
||||||
|
|
||||||
|
if(!strncmp(command, "/echo", 5)) {
|
||||||
|
int len = strlen(command+1);
|
||||||
|
fxlink_device_start_bulk_OUT(fdev,
|
||||||
|
"fxlink", "command", strdup(command+1), len, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(!strcmp(command, "/identify")) {
|
||||||
|
fxlink_device_start_bulk_OUT(fdev,
|
||||||
|
"fxlink", "command", "identify", 8, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(!strcmp(command, "gintctl read-long")) {
|
||||||
|
int count = 128; // 2048;
|
||||||
|
uint32_t *data = malloc(count * 4);
|
||||||
|
for(int i = 0; i < count; i++)
|
||||||
|
data[i] = i;
|
||||||
|
fxlink_device_start_bulk_OUT(fdev,
|
||||||
|
"gintctl", "echo-bounds", data, count * 4, true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprint(TUI.wConsole, FMT_RED, "error: ");
|
||||||
|
print(TUI.wConsole, "unrecognized command '%s'\n", command);
|
||||||
|
}
|
||||||
|
|
||||||
int main_tui_interactive(libusb_context *ctx)
|
int main_tui_interactive(libusb_context *ctx)
|
||||||
{
|
{
|
||||||
if(!TUI_setup())
|
if(!TUI_setup())
|
||||||
|
@ -480,27 +543,12 @@ int main_tui_interactive(libusb_context *ctx)
|
||||||
char *command = input.data;
|
char *command = input.data;
|
||||||
if(command[0] != 0)
|
if(command[0] != 0)
|
||||||
log_("command: '%s'\n", command);
|
log_("command: '%s'\n", command);
|
||||||
if(!strcmp(command, "q"))
|
if(!strcmp(command, ""))
|
||||||
|
{}
|
||||||
|
else if(!strcmp(command, "q") || !strcmp(command, "quit"))
|
||||||
break;
|
break;
|
||||||
if(!strcmp(command, "test")) {
|
else
|
||||||
/* Find a device */
|
execute_command(command);
|
||||||
struct fxlink_device *fdev = NULL;
|
|
||||||
for(int i = 0; i < TUI.devices.count; i++) {
|
|
||||||
fdev = &TUI.devices.devices[i];
|
|
||||||
if(fdev->status == FXLINK_FDEV_STATUS_CONNECTED)
|
|
||||||
break;
|
|
||||||
else fdev = NULL;
|
|
||||||
}
|
|
||||||
if(fdev) {
|
|
||||||
print(TUI.wConsole, "using device %s (%s)\n",
|
|
||||||
fxlink_device_id(fdev), fdev->calc->serial);
|
|
||||||
fxlink_device_start_bulk_OUT(fdev,
|
|
||||||
"fxlink", "command", "test", 4);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
print(TUI.wConsole, "no connected device!\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fxlink_TUI_input_free(&input);
|
fxlink_TUI_input_free(&input);
|
||||||
print(TUI.wConsole, "%s", prompt);
|
print(TUI.wConsole, "%s", prompt);
|
||||||
fxlink_TUI_input_init(&input, TUI.wConsole, 16);
|
fxlink_TUI_input_init(&input, TUI.wConsole, 16);
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <assert.h>
|
||||||
#include "fxlink.h"
|
#include "fxlink.h"
|
||||||
|
|
||||||
bool fxlink_message_is_apptype(struct fxlink_message const *msg,
|
bool fxlink_message_is_apptype(struct fxlink_message const *msg,
|
||||||
|
@ -236,6 +237,7 @@ struct fxlink_transfer *fxlink_transfer_make_IN(void *data, int size)
|
||||||
tr->msg.data = malloc(tr->msg.size);
|
tr->msg.data = malloc(tr->msg.size);
|
||||||
tr->direction = FXLINK_TRANSFER_IN;
|
tr->direction = FXLINK_TRANSFER_IN;
|
||||||
tr->processed_size = 0;
|
tr->processed_size = 0;
|
||||||
|
tr->own_data = true;
|
||||||
|
|
||||||
if(!tr->msg.data) {
|
if(!tr->msg.data) {
|
||||||
elog("cannot allocate buffer for %d bytes\n", tr->msg.size);
|
elog("cannot allocate buffer for %d bytes\n", tr->msg.size);
|
||||||
|
@ -262,6 +264,7 @@ struct fxlink_message *fxlink_transfer_finish_IN(struct fxlink_transfer *tr)
|
||||||
log_("extracting completed message (%d bytes)\n", tr->msg.size);
|
log_("extracting completed message (%d bytes)\n", tr->msg.size);
|
||||||
|
|
||||||
/* Shallow copy the malloc()'d data pointer */
|
/* Shallow copy the malloc()'d data pointer */
|
||||||
|
assert(tr->own_data && "Can't shallow copy data if we don't own it!");
|
||||||
memcpy(msg, &tr->msg, sizeof *msg);
|
memcpy(msg, &tr->msg, sizeof *msg);
|
||||||
free(tr);
|
free(tr);
|
||||||
return msg;
|
return msg;
|
||||||
|
@ -283,7 +286,7 @@ void fxlink_transfer_receive(struct fxlink_transfer *tr, void *data, int size)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fxlink_transfer *fxlink_transfer_make_OUT(char const *application,
|
struct fxlink_transfer *fxlink_transfer_make_OUT(char const *application,
|
||||||
char const *type, void const *data, int size)
|
char const *type, void const *data, int size, bool own_data)
|
||||||
{
|
{
|
||||||
struct fxlink_transfer *tr = calloc(1, sizeof *tr);
|
struct fxlink_transfer *tr = calloc(1, sizeof *tr);
|
||||||
if(!tr)
|
if(!tr)
|
||||||
|
@ -297,6 +300,7 @@ struct fxlink_transfer *fxlink_transfer_make_OUT(char const *application,
|
||||||
tr->msg.data = (void *)data;
|
tr->msg.data = (void *)data;
|
||||||
tr->direction = FXLINK_TRANSFER_OUT;
|
tr->direction = FXLINK_TRANSFER_OUT;
|
||||||
tr->processed_size = -1;
|
tr->processed_size = -1;
|
||||||
|
tr->own_data = own_data;
|
||||||
return tr;
|
return tr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,7 +311,7 @@ bool fxlink_transfer_complete(struct fxlink_transfer const *tr)
|
||||||
|
|
||||||
void fxlink_transfer_free(struct fxlink_transfer *tr)
|
void fxlink_transfer_free(struct fxlink_transfer *tr)
|
||||||
{
|
{
|
||||||
if(tr->direction == FXLINK_TRANSFER_IN)
|
if(tr->own_data)
|
||||||
free(tr->msg.data);
|
free(tr->msg.data);
|
||||||
free(tr);
|
free(tr);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue