mirror of
https://git.planet-casio.com/Lephenixnoir/fxsdk.git
synced 2025-07-05 11:46:36 +02:00
fxlink: add --sockin and --sockout options to fxlink -i
This commit is contained in:
parent
e201304423
commit
c8afb9acb5
3 changed files with 123 additions and 6 deletions
|
@ -8,6 +8,7 @@
|
|||
#pragma once
|
||||
#include <fxlink/filter.h>
|
||||
#include <libusb.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
/* Global and command-line options. */
|
||||
struct fxlink_options {
|
||||
|
@ -33,7 +34,9 @@ int main_send(struct fxlink_filter *filter, delay_t *delay, char **files,
|
|||
|
||||
/* Main function for -i */
|
||||
int main_interactive(struct fxlink_filter *filter, delay_t *delay,
|
||||
libusb_context *context);
|
||||
libusb_context *context,
|
||||
const struct sockaddr_un *sockin_addr,
|
||||
const struct sockaddr_un *sockout_addr);
|
||||
|
||||
/* Main function for -t */
|
||||
int main_tui_interactive(libusb_context *context);
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <errno.h>
|
||||
#include <locale.h>
|
||||
|
||||
|
@ -47,6 +49,10 @@ static const char *help_string =
|
|||
" --fxlink-log[=FILE] -i: Append fxlink text messages to FILE. Without\n"
|
||||
" argument, a unique name is generated.\n"
|
||||
" -r, --repeat -i: Reconnect if the calc disconnects (implies -w)\n"
|
||||
" --sockin=SOCKET -i: Send messages read from the datagram Unix socket\n"
|
||||
" SOCKET to the calculator as fxlink text messages.\n"
|
||||
" --sockout=SOCKET -i: Send fxlink text messages read from the calculator\n"
|
||||
" to the datagram Unix socket SOCKET.\n"
|
||||
" --folder=FOLDER -s: Select destination folder for files\n"
|
||||
"\n"
|
||||
"Device filters:\n"
|
||||
|
@ -69,6 +75,8 @@ int main(int argc, char **argv)
|
|||
struct fxlink_filter *filter = NULL;
|
||||
bool repeat = false;
|
||||
char *outfolder = NULL;
|
||||
struct sockaddr_un sockin_addr = { AF_UNSPEC };
|
||||
struct sockaddr_un sockout_addr = { AF_UNSPEC };
|
||||
|
||||
options.log_file = NULL;
|
||||
options.verbose = false;
|
||||
|
@ -79,7 +87,7 @@ int main(int argc, char **argv)
|
|||
// Command-line argument parsing
|
||||
//---
|
||||
|
||||
enum { LIBUSB_LOG=1, LOG_TO_FILE=2, OUT_FOLDER=3 };
|
||||
enum { LIBUSB_LOG=1, LOG_TO_FILE=2, OUT_FOLDER=3, SOCKIN=4, SOCKOUT=5 };
|
||||
const struct option longs[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "list", no_argument, NULL, 'l' },
|
||||
|
@ -93,6 +101,8 @@ int main(int argc, char **argv)
|
|||
{ "repeat", no_argument, NULL, 'r' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "folder", required_argument, NULL, OUT_FOLDER },
|
||||
{ "sockin", required_argument, NULL, SOCKIN },
|
||||
{ "sockout", required_argument, NULL, SOCKOUT },
|
||||
/* Deprecated options ignored for compatibility: */
|
||||
{ "quiet", no_argument, NULL, 'q' },
|
||||
{ "unmount", no_argument, NULL, 'u' },
|
||||
|
@ -171,6 +181,14 @@ int main(int argc, char **argv)
|
|||
case OUT_FOLDER:
|
||||
outfolder = strdup(optarg);
|
||||
break;
|
||||
case SOCKIN:
|
||||
sockin_addr.sun_family = AF_UNIX;
|
||||
strncpy(sockin_addr.sun_path, optarg, sizeof(sockin_addr.sun_path) - 1);
|
||||
break;
|
||||
case SOCKOUT:
|
||||
sockout_addr.sun_family = AF_UNIX;
|
||||
strncpy(sockout_addr.sun_path, optarg, sizeof(sockout_addr.sun_path) - 1);
|
||||
break;
|
||||
case '?':
|
||||
error = 1;
|
||||
}
|
||||
|
@ -232,7 +250,9 @@ int main(int argc, char **argv)
|
|||
}
|
||||
else if(mode == 'i') {
|
||||
do {
|
||||
rc = main_interactive(filter, &delay, context);
|
||||
rc = main_interactive(filter, &delay, context,
|
||||
sockin_addr.sun_family == AF_UNSPEC ? NULL : &sockin_addr,
|
||||
sockout_addr.sun_family == AF_UNSPEC ? NULL : &sockout_addr);
|
||||
}
|
||||
while(repeat);
|
||||
}
|
||||
|
|
|
@ -15,9 +15,15 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static void handle_new_message(struct fxlink_device *fdev,
|
||||
struct fxlink_message *msg)
|
||||
struct fxlink_message *msg,
|
||||
int socket_fd,
|
||||
const struct sockaddr_un *sockout_addr)
|
||||
{
|
||||
char const *path = ".";
|
||||
|
||||
|
@ -41,6 +47,11 @@ static void handle_new_message(struct fxlink_device *fdev,
|
|||
if(fxlink_message_is_fxlink_text(msg)) {
|
||||
char const *str = msg->data;
|
||||
|
||||
if(socket_fd >= 0 && sockout_addr != NULL &&
|
||||
sendto(socket_fd, msg->data, msg->size, 0, sockout_addr, sizeof(*sockout_addr)) < 0) {
|
||||
perror("sendto");
|
||||
}
|
||||
|
||||
if(options.verbose)
|
||||
printf("------------------\n");
|
||||
fwrite(str, 1, msg->size, stdout);
|
||||
|
@ -95,8 +106,77 @@ static void handle_new_message(struct fxlink_device *fdev,
|
|||
free(filename);
|
||||
}
|
||||
|
||||
static int setup_socket(const struct sockaddr_un *sockin_addr,
|
||||
const struct sockaddr_un *sockout_addr)
|
||||
{
|
||||
if(sockin_addr == NULL && sockout_addr == NULL) {
|
||||
/* -1 is used to indicate that no fd were opened but it's not a fatal error */
|
||||
return -1;
|
||||
}
|
||||
|
||||
int socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0);
|
||||
if(socket_fd < 0) {
|
||||
perror("socket");
|
||||
/* -2 is used to indicate an error */
|
||||
return -2;
|
||||
}
|
||||
|
||||
if(sockin_addr != NULL) {
|
||||
unlink(sockin_addr->sun_path);
|
||||
|
||||
if (bind(socket_fd, (struct sockaddr*)sockin_addr, sizeof(*sockin_addr)) < 0) {
|
||||
perror("bind");
|
||||
close(socket_fd);
|
||||
/* -2 is used to indicate an error */
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
||||
return socket_fd;
|
||||
}
|
||||
|
||||
static void handle_input_socket(struct fxlink_device *fdev, int socket_fd)
|
||||
{
|
||||
if(socket_fd < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Don't start an OUT transfer if there's one in progress */
|
||||
if(fdev->comm->ftransfer_OUT) {
|
||||
return;
|
||||
}
|
||||
|
||||
int dgram_len;
|
||||
if(ioctl(socket_fd, FIONREAD, &dgram_len) < 0) {
|
||||
perror("ioctl");
|
||||
return;
|
||||
}
|
||||
if(dgram_len <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* We need to use a static buffer as libfxlink will use it in it's main loop,
|
||||
* outside of this stack frame
|
||||
*/
|
||||
static uint8_t* dgram_buf = NULL;
|
||||
static ssize_t dgram_buf_len = 0;
|
||||
if (dgram_buf_len < dgram_len) {
|
||||
dgram_buf = realloc(dgram_buf, dgram_len);
|
||||
dgram_buf_len = dgram_len;
|
||||
}
|
||||
|
||||
ssize_t recv_ret = recvfrom(socket_fd, dgram_buf, dgram_buf_len, 0, NULL, NULL);
|
||||
if(recv_ret < 0) {
|
||||
perror("recvfrom");
|
||||
} else if(recv_ret > 0) {
|
||||
fxlink_device_start_bulk_OUT(fdev, "fxlink", "text", dgram_buf, recv_ret, false);
|
||||
}
|
||||
}
|
||||
|
||||
int main_interactive(struct fxlink_filter *filter, delay_t *delay,
|
||||
libusb_context *ctx)
|
||||
libusb_context *ctx,
|
||||
const struct sockaddr_un *sockin_addr,
|
||||
const struct sockaddr_un *sockout_addr)
|
||||
{
|
||||
/* Wait for a device to be connected */
|
||||
fxlink_filter_clean_libusb(filter);
|
||||
|
@ -113,6 +193,14 @@ int main_interactive(struct fxlink_filter *filter, delay_t *delay,
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* socket used by sockin and sockout options */
|
||||
int socket_fd = setup_socket(sockin_addr, sockout_addr);
|
||||
if(socket_fd <= -2) {
|
||||
fxlink_device_cleanup(fdev);
|
||||
free(fdev);
|
||||
return 1;
|
||||
}
|
||||
|
||||
hlog("interactive");
|
||||
log_("connected to %s\n", fxlink_device_id(fdev));
|
||||
|
||||
|
@ -124,6 +212,8 @@ int main_interactive(struct fxlink_filter *filter, delay_t *delay,
|
|||
while(1) {
|
||||
fxlink_sdl2_handle_events();
|
||||
|
||||
handle_input_socket(fdev, socket_fd);
|
||||
|
||||
int transferred = -1;
|
||||
int rc = libusb_bulk_transfer(fdev->dh, fdev->comm->ep_bulk_IN, buffer,
|
||||
sizeof buffer, &transferred, 500 /* ms */);
|
||||
|
@ -150,7 +240,7 @@ int main_interactive(struct fxlink_filter *filter, delay_t *delay,
|
|||
if(tr && fxlink_transfer_complete(tr)) {
|
||||
struct fxlink_message *msg = fxlink_transfer_finish_IN(tr);
|
||||
if(msg) {
|
||||
handle_new_message(fdev, msg);
|
||||
handle_new_message(fdev, msg, socket_fd, sockout_addr);
|
||||
fxlink_message_free(msg, true);
|
||||
}
|
||||
tr = NULL;
|
||||
|
@ -163,6 +253,10 @@ int main_interactive(struct fxlink_filter *filter, delay_t *delay,
|
|||
fxlink_transfer_free(tr);
|
||||
}
|
||||
|
||||
if(socket_fd >= 0) {
|
||||
close(socket_fd);
|
||||
}
|
||||
|
||||
fxlink_device_cleanup(fdev);
|
||||
free(fdev);
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue