mirror of
https://git.planet-casio.com/Lephenixnoir/fxsdk.git
synced 2025-07-05 03:36: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
|
#pragma once
|
||||||
#include <fxlink/filter.h>
|
#include <fxlink/filter.h>
|
||||||
#include <libusb.h>
|
#include <libusb.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
|
||||||
/* Global and command-line options. */
|
/* Global and command-line options. */
|
||||||
struct fxlink_options {
|
struct fxlink_options {
|
||||||
|
@ -33,7 +34,9 @@ int main_send(struct fxlink_filter *filter, delay_t *delay, char **files,
|
||||||
|
|
||||||
/* Main function for -i */
|
/* Main function for -i */
|
||||||
int main_interactive(struct fxlink_filter *filter, delay_t *delay,
|
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 */
|
/* Main function for -t */
|
||||||
int main_tui_interactive(libusb_context *context);
|
int main_tui_interactive(libusb_context *context);
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <locale.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"
|
" --fxlink-log[=FILE] -i: Append fxlink text messages to FILE. Without\n"
|
||||||
" argument, a unique name is generated.\n"
|
" argument, a unique name is generated.\n"
|
||||||
" -r, --repeat -i: Reconnect if the calc disconnects (implies -w)\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"
|
" --folder=FOLDER -s: Select destination folder for files\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Device filters:\n"
|
"Device filters:\n"
|
||||||
|
@ -69,6 +75,8 @@ int main(int argc, char **argv)
|
||||||
struct fxlink_filter *filter = NULL;
|
struct fxlink_filter *filter = NULL;
|
||||||
bool repeat = false;
|
bool repeat = false;
|
||||||
char *outfolder = NULL;
|
char *outfolder = NULL;
|
||||||
|
struct sockaddr_un sockin_addr = { AF_UNSPEC };
|
||||||
|
struct sockaddr_un sockout_addr = { AF_UNSPEC };
|
||||||
|
|
||||||
options.log_file = NULL;
|
options.log_file = NULL;
|
||||||
options.verbose = false;
|
options.verbose = false;
|
||||||
|
@ -79,7 +87,7 @@ int main(int argc, char **argv)
|
||||||
// Command-line argument parsing
|
// 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[] = {
|
const struct option longs[] = {
|
||||||
{ "help", no_argument, NULL, 'h' },
|
{ "help", no_argument, NULL, 'h' },
|
||||||
{ "list", no_argument, NULL, 'l' },
|
{ "list", no_argument, NULL, 'l' },
|
||||||
|
@ -93,6 +101,8 @@ int main(int argc, char **argv)
|
||||||
{ "repeat", no_argument, NULL, 'r' },
|
{ "repeat", no_argument, NULL, 'r' },
|
||||||
{ "verbose", no_argument, NULL, 'v' },
|
{ "verbose", no_argument, NULL, 'v' },
|
||||||
{ "folder", required_argument, NULL, OUT_FOLDER },
|
{ "folder", required_argument, NULL, OUT_FOLDER },
|
||||||
|
{ "sockin", required_argument, NULL, SOCKIN },
|
||||||
|
{ "sockout", required_argument, NULL, SOCKOUT },
|
||||||
/* Deprecated options ignored for compatibility: */
|
/* Deprecated options ignored for compatibility: */
|
||||||
{ "quiet", no_argument, NULL, 'q' },
|
{ "quiet", no_argument, NULL, 'q' },
|
||||||
{ "unmount", no_argument, NULL, 'u' },
|
{ "unmount", no_argument, NULL, 'u' },
|
||||||
|
@ -171,6 +181,14 @@ int main(int argc, char **argv)
|
||||||
case OUT_FOLDER:
|
case OUT_FOLDER:
|
||||||
outfolder = strdup(optarg);
|
outfolder = strdup(optarg);
|
||||||
break;
|
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 '?':
|
case '?':
|
||||||
error = 1;
|
error = 1;
|
||||||
}
|
}
|
||||||
|
@ -232,7 +250,9 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
else if(mode == 'i') {
|
else if(mode == 'i') {
|
||||||
do {
|
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);
|
while(repeat);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,15 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.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,
|
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 = ".";
|
char const *path = ".";
|
||||||
|
|
||||||
|
@ -41,6 +47,11 @@ static void handle_new_message(struct fxlink_device *fdev,
|
||||||
if(fxlink_message_is_fxlink_text(msg)) {
|
if(fxlink_message_is_fxlink_text(msg)) {
|
||||||
char const *str = msg->data;
|
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)
|
if(options.verbose)
|
||||||
printf("------------------\n");
|
printf("------------------\n");
|
||||||
fwrite(str, 1, msg->size, stdout);
|
fwrite(str, 1, msg->size, stdout);
|
||||||
|
@ -95,8 +106,77 @@ static void handle_new_message(struct fxlink_device *fdev,
|
||||||
free(filename);
|
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,
|
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 */
|
/* Wait for a device to be connected */
|
||||||
fxlink_filter_clean_libusb(filter);
|
fxlink_filter_clean_libusb(filter);
|
||||||
|
@ -113,6 +193,14 @@ int main_interactive(struct fxlink_filter *filter, delay_t *delay,
|
||||||
return 1;
|
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");
|
hlog("interactive");
|
||||||
log_("connected to %s\n", fxlink_device_id(fdev));
|
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) {
|
while(1) {
|
||||||
fxlink_sdl2_handle_events();
|
fxlink_sdl2_handle_events();
|
||||||
|
|
||||||
|
handle_input_socket(fdev, socket_fd);
|
||||||
|
|
||||||
int transferred = -1;
|
int transferred = -1;
|
||||||
int rc = libusb_bulk_transfer(fdev->dh, fdev->comm->ep_bulk_IN, buffer,
|
int rc = libusb_bulk_transfer(fdev->dh, fdev->comm->ep_bulk_IN, buffer,
|
||||||
sizeof buffer, &transferred, 500 /* ms */);
|
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)) {
|
if(tr && fxlink_transfer_complete(tr)) {
|
||||||
struct fxlink_message *msg = fxlink_transfer_finish_IN(tr);
|
struct fxlink_message *msg = fxlink_transfer_finish_IN(tr);
|
||||||
if(msg) {
|
if(msg) {
|
||||||
handle_new_message(fdev, msg);
|
handle_new_message(fdev, msg, socket_fd, sockout_addr);
|
||||||
fxlink_message_free(msg, true);
|
fxlink_message_free(msg, true);
|
||||||
}
|
}
|
||||||
tr = NULL;
|
tr = NULL;
|
||||||
|
@ -163,6 +253,10 @@ int main_interactive(struct fxlink_filter *filter, delay_t *delay,
|
||||||
fxlink_transfer_free(tr);
|
fxlink_transfer_free(tr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(socket_fd >= 0) {
|
||||||
|
close(socket_fd);
|
||||||
|
}
|
||||||
|
|
||||||
fxlink_device_cleanup(fdev);
|
fxlink_device_cleanup(fdev);
|
||||||
free(fdev);
|
free(fdev);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Add table
Reference in a new issue