mirror of
https://git.planet-casio.com/Lephenixnoir/fxsdk.git
synced 2024-12-29 13:03:37 +01:00
fxlink: basic writing logic and 'test' command
This commit is contained in:
parent
9d30377d90
commit
3dc9f06219
6 changed files with 154 additions and 6 deletions
|
@ -460,7 +460,7 @@ void fxlink_device_start_bulk_IN(struct fxlink_device *fdev)
|
||||||
|
|
||||||
int rc = libusb_submit_transfer(fdev->comm->tr_bulk_IN);
|
int rc = libusb_submit_transfer(fdev->comm->tr_bulk_IN);
|
||||||
if(rc < 0) {
|
if(rc < 0) {
|
||||||
elog("bulk IN transfer failed to submit: %s\n", libusb_strerror(rc));
|
elog_libusb(rc, "bulk IN transfer failed to submit");
|
||||||
fdev->status = FXLINK_FDEV_STATUS_ERROR;
|
fdev->status = FXLINK_FDEV_STATUS_ERROR;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -489,10 +489,104 @@ struct fxlink_message *fxlink_device_finish_bulk_IN(struct fxlink_device *fdev)
|
||||||
log_("new message (v%d.%d): %.16s:%.16s, %s\n",
|
log_("new message (v%d.%d): %.16s:%.16s, %s\n",
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Note: this function is run by the even handler and can't do any crazy libusb
|
||||||
|
stuff like sync I/O or getting descriptors. */
|
||||||
|
static void bulk_OUT_callback(struct libusb_transfer *transfer)
|
||||||
|
{
|
||||||
|
struct fxlink_device *fdev = transfer->user_data;
|
||||||
|
struct fxlink_comm *comm = fdev->comm;
|
||||||
|
|
||||||
|
int data_size = transfer->actual_length;
|
||||||
|
bool send_more = true;
|
||||||
|
struct fxlink_transfer *tr = comm->ftransfer_OUT;
|
||||||
|
|
||||||
|
if(transfer->status != LIBUSB_TRANSFER_COMPLETED)
|
||||||
|
hlog("calculators %s", fxlink_device_id(fdev));
|
||||||
|
|
||||||
|
switch(transfer->status) {
|
||||||
|
case LIBUSB_TRANSFER_COMPLETED:
|
||||||
|
if(tr->processed_size < 0) {
|
||||||
|
if(data_size != FXLINK_MESSAGE_HEADER_SIZE) {
|
||||||
|
elog("OUT for header only partially completed");
|
||||||
|
send_more = false;
|
||||||
|
}
|
||||||
|
tr->processed_size = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tr->processed_size += data_size;
|
||||||
|
if(fxlink_transfer_complete(tr))
|
||||||
|
send_more = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(send_more) {
|
||||||
|
libusb_fill_bulk_transfer(comm->tr_bulk_OUT, fdev->dh,
|
||||||
|
comm->ep_bulk_OUT, /* Endpoint */
|
||||||
|
tr->msg.data + tr->processed_size, /* Buffer */
|
||||||
|
tr->msg.size - tr->processed_size, /* Buffer size */
|
||||||
|
bulk_OUT_callback, fdev, -1); /* Callback and timeout */
|
||||||
|
libusb_submit_transfer(comm->tr_bulk_OUT);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
libusb_free_transfer(comm->tr_bulk_OUT);
|
||||||
|
comm->tr_bulk_OUT = NULL;
|
||||||
|
fxlink_transfer_free(comm->ftransfer_OUT);
|
||||||
|
comm->ftransfer_OUT = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Typical errors */
|
||||||
|
case LIBUSB_TRANSFER_ERROR: log_("transfer error\n"); break;
|
||||||
|
case LIBUSB_TRANSFER_TIMED_OUT: log_("transfer timed out\n"); break;
|
||||||
|
case LIBUSB_TRANSFER_CANCELLED: log_("transfer cancelled\n"); break;
|
||||||
|
case LIBUSB_TRANSFER_STALL: log_("transfer stalled\n"); break;
|
||||||
|
case LIBUSB_TRANSFER_OVERFLOW: log_("transfer overflowed\n"); break;
|
||||||
|
/* No device: this is normal */
|
||||||
|
case LIBUSB_TRANSFER_NO_DEVICE:
|
||||||
|
log_("stop listening (calculator disconnected)\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fxlink_device_start_bulk_OUT(struct fxlink_device *fdev,
|
||||||
|
char const *app, char const *type, void const *data, int size)
|
||||||
|
{
|
||||||
|
struct fxlink_comm *comm = fdev->comm;
|
||||||
|
if(!comm || !comm->claimed || comm->ftransfer_OUT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
comm->ftransfer_OUT = fxlink_transfer_make_OUT(app, type, data, size);
|
||||||
|
if(!comm->ftransfer_OUT) {
|
||||||
|
elog("allocation of OUT transfer (protocol) failed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
comm->tr_bulk_OUT = libusb_alloc_transfer(0);
|
||||||
|
if(!comm->tr_bulk_OUT) {
|
||||||
|
elog("allocation of bulk OUT transfer (libusb) failed\n");
|
||||||
|
free(comm->ftransfer_OUT);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
libusb_fill_bulk_transfer(comm->tr_bulk_OUT, fdev->dh,
|
||||||
|
comm->ep_bulk_OUT, /* Endpoint */
|
||||||
|
(void *)&comm->ftransfer_OUT->msg, /* Buffer */
|
||||||
|
FXLINK_MESSAGE_HEADER_SIZE, /* Buffer size */
|
||||||
|
bulk_OUT_callback, fdev, -1); /* Callback and timeout */
|
||||||
|
|
||||||
|
int rc = libusb_submit_transfer(comm->tr_bulk_OUT);
|
||||||
|
if(rc < 0) {
|
||||||
|
elog_libusb(rc, "bulk OUT transfer failed to submit");
|
||||||
|
fdev->status = FXLINK_FDEV_STATUS_ERROR;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//---
|
//---
|
||||||
// Polled file descriptor tracking
|
// Polled file descriptor tracking
|
||||||
//---
|
//---
|
||||||
|
|
|
@ -210,6 +210,10 @@ 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. */
|
||||||
|
void fxlink_device_start_bulk_OUT(struct fxlink_device *fdev,
|
||||||
|
char const *app, char const *type, void const *data, int size);
|
||||||
|
|
||||||
/* 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);
|
||||||
|
|
||||||
|
|
|
@ -112,7 +112,7 @@ struct fxlink_transfer {
|
||||||
/* Transfer direction (FXLINK_TRANSFER_{IN,OUT}) */
|
/* Transfer direction (FXLINK_TRANSFER_{IN,OUT}) */
|
||||||
uint8_t direction;
|
uint8_t direction;
|
||||||
/* Size of data sent or received so far */
|
/* Size of data sent or received so far */
|
||||||
uint32_t processed_size;
|
int processed_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -136,5 +136,12 @@ 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. */
|
||||||
void fxlink_transfer_receive(struct fxlink_transfer *tr, void *data, int size);
|
void fxlink_transfer_receive(struct fxlink_transfer *tr, void *data, int size);
|
||||||
|
|
||||||
|
/* Make an outbound transfer structure. */
|
||||||
|
struct fxlink_transfer *fxlink_transfer_make_OUT(char const *application,
|
||||||
|
char const *type, void const *data, int size);
|
||||||
|
|
||||||
/* 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);
|
||||||
|
|
||||||
|
/* Free a transfer structure and associated data. */
|
||||||
|
void fxlink_transfer_free(struct fxlink_transfer *tr);
|
||||||
|
|
|
@ -158,8 +158,7 @@ int main_interactive(struct fxlink_filter *filter, delay_t *delay,
|
||||||
/* Warning for unfinished transfer */
|
/* Warning for unfinished transfer */
|
||||||
if(tr) {
|
if(tr) {
|
||||||
wlog("unfinished transfer interrupted by disconnection\n");
|
wlog("unfinished transfer interrupted by disconnection\n");
|
||||||
// TODO: Proper way to free a transfer without finishing it
|
fxlink_transfer_free(tr);
|
||||||
free(tr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fxlink_device_cleanup(fdev);
|
fxlink_device_cleanup(fdev);
|
||||||
|
|
|
@ -221,7 +221,7 @@ static void TUI_render_transfers(void)
|
||||||
if(OUT) {
|
if(OUT) {
|
||||||
mvwaddstr(win, y, 1, fxlink_device_id(fdev));
|
mvwaddstr(win, y, 1, fxlink_device_id(fdev));
|
||||||
mvwaddstr(win, y, 10, "OUT");
|
mvwaddstr(win, y, 10, "OUT");
|
||||||
mvwaddstr(win, y, 16, fxlink_size_string(IN->msg.size));
|
mvwaddstr(win, y, 16, fxlink_size_string(OUT->msg.size));
|
||||||
has_transfers = true;
|
has_transfers = true;
|
||||||
y++;
|
y++;
|
||||||
}
|
}
|
||||||
|
@ -482,6 +482,25 @@ int main_tui_interactive(libusb_context *ctx)
|
||||||
log_("command: '%s'\n", command);
|
log_("command: '%s'\n", command);
|
||||||
if(!strcmp(command, "q"))
|
if(!strcmp(command, "q"))
|
||||||
break;
|
break;
|
||||||
|
if(!strcmp(command, "test")) {
|
||||||
|
/* Find a device */
|
||||||
|
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);
|
||||||
|
|
|
@ -282,7 +282,32 @@ void fxlink_transfer_receive(struct fxlink_transfer *tr, void *data, int size)
|
||||||
tr->processed_size += size;
|
tr->processed_size += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct fxlink_transfer *fxlink_transfer_make_OUT(char const *application,
|
||||||
|
char const *type, void const *data, int size)
|
||||||
|
{
|
||||||
|
struct fxlink_transfer *tr = calloc(1, sizeof *tr);
|
||||||
|
if(!tr)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
tr->msg.version = 0x00000100;
|
||||||
|
tr->msg.size = size;
|
||||||
|
tr->msg.transfer_size = 0;
|
||||||
|
strncpy(tr->msg.application, application, 16);
|
||||||
|
strncpy(tr->msg.type, type, 16);
|
||||||
|
tr->msg.data = (void *)data;
|
||||||
|
tr->direction = FXLINK_TRANSFER_OUT;
|
||||||
|
tr->processed_size = -1;
|
||||||
|
return tr;
|
||||||
|
}
|
||||||
|
|
||||||
bool fxlink_transfer_complete(struct fxlink_transfer const *tr)
|
bool fxlink_transfer_complete(struct fxlink_transfer const *tr)
|
||||||
{
|
{
|
||||||
return tr->processed_size >= tr->msg.size;
|
return tr->processed_size >= (int)tr->msg.size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fxlink_transfer_free(struct fxlink_transfer *tr)
|
||||||
|
{
|
||||||
|
if(tr->direction == FXLINK_TRANSFER_IN)
|
||||||
|
free(tr->msg.data);
|
||||||
|
free(tr);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue