mirror of
https://git.planet-casio.com/Lephenixnoir/fxsdk.git
synced 2024-12-28 04:23:37 +01:00
gdb: style, messages, add option to wait for gdb:start
This commit is contained in:
parent
87a2feff15
commit
056ce41c9e
1 changed files with 124 additions and 86 deletions
|
@ -12,32 +12,62 @@
|
||||||
#include <fxlink/filter.h>
|
#include <fxlink/filter.h>
|
||||||
#include <fxlink/logging.h>
|
#include <fxlink/logging.h>
|
||||||
|
|
||||||
static struct fxlink_device* setup_calc(libusb_context* context) {
|
/* Establish a connection to the calculator. If nostart is set, assume the
|
||||||
struct fxlink_filter filter = {
|
calculator is ready immediately; otherwise, wait for a message of type
|
||||||
.intf_fxlink = true,
|
gdb:start. The latter can be useful is the calculator is using USB prior to
|
||||||
};
|
starting a debugging session. */
|
||||||
delay_t delay = delay_infinite();
|
static struct fxlink_device *setup_calc(libusb_context *context, bool nostart)
|
||||||
|
{
|
||||||
|
struct fxlink_filter filter = { 0 };
|
||||||
|
filter.intf_fxlink = true;
|
||||||
fxlink_filter_clean_libusb(&filter);
|
fxlink_filter_clean_libusb(&filter);
|
||||||
|
|
||||||
hlog("calculators");
|
hlog("calculators");
|
||||||
log_("wating for fxlink capable device...\n");
|
log_("waiting for calculator to connect...\n");
|
||||||
struct fxlink_device* dev = fxlink_device_find_wait(context, &filter, &delay);
|
delay_t delay = delay_infinite();
|
||||||
if (!dev) {
|
struct fxlink_device *fdev =
|
||||||
elog("unable to open fxlink_device\n");
|
fxlink_device_find_wait(context, &filter, &delay);
|
||||||
|
|
||||||
|
if(!fdev) {
|
||||||
|
elog("unable to open calculator\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(!fxlink_device_claim_fxlink(fdev)) {
|
||||||
|
elog("unable to claim fxlink interface\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fxlink_device_claim_fxlink(dev)) {
|
fxlink_device_start_bulk_IN(fdev);
|
||||||
elog("unable to claim fxlink\n");
|
|
||||||
return NULL;
|
if(nostart)
|
||||||
|
return fdev;
|
||||||
|
|
||||||
|
hlog("gdb");
|
||||||
|
log_("waiting for gdb init message...\n");
|
||||||
|
while(true) {
|
||||||
|
libusb_handle_events(context);
|
||||||
|
|
||||||
|
struct fxlink_message *msg = fxlink_device_finish_bulk_IN(fdev);
|
||||||
|
if(!msg)
|
||||||
|
continue;
|
||||||
|
if(fxlink_message_is_apptype(msg, "gdb", "start")) {
|
||||||
|
hlog("gdb");
|
||||||
|
log_("got start message\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
wlog("dropped a message of type %.16s:%.16s\n",
|
||||||
|
msg->application, msg->type);
|
||||||
|
|
||||||
|
fxlink_device_start_bulk_IN(fdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
return dev;
|
return fdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int setup_socket(const char* listen_path) {
|
static int setup_socket(char const *listen_path)
|
||||||
|
{
|
||||||
int listen_socket = socket(AF_UNIX, SOCK_STREAM, 0);
|
int listen_socket = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
if (listen_socket < 0) {
|
if(listen_socket < 0) {
|
||||||
perror("socket");
|
perror("socket");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -46,23 +76,24 @@ static int setup_socket(const char* listen_path) {
|
||||||
.sun_family = AF_UNIX,
|
.sun_family = AF_UNIX,
|
||||||
.sun_path = {0},
|
.sun_path = {0},
|
||||||
};
|
};
|
||||||
strncpy(listen_address.sun_path, listen_path, sizeof(listen_address.sun_path) - 1);
|
strncpy(listen_address.sun_path, listen_path,
|
||||||
if (bind(listen_socket, (struct sockaddr*)&listen_address, sizeof(listen_address)) < 0) {
|
sizeof(listen_address.sun_path) - 1);
|
||||||
|
if(bind(listen_socket, (struct sockaddr *)&listen_address, sizeof(listen_address)) < 0) {
|
||||||
close(listen_socket);
|
close(listen_socket);
|
||||||
perror("bind");
|
perror("bind");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen(listen_socket, 1024) < 0) {
|
if(listen(listen_socket, 1024) < 0) {
|
||||||
close(listen_socket);
|
close(listen_socket);
|
||||||
perror("listen");
|
perror("listen");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
hlog("socket");
|
hlog("socket");
|
||||||
log_("wating for client on \"%s\"...\n", listen_address.sun_path);
|
log_("waiting for client on \"%s\"...\n", listen_address.sun_path);
|
||||||
int client_socket = accept(listen_socket, NULL, NULL);
|
int client_socket = accept(listen_socket, NULL, NULL);
|
||||||
if (client_socket < 0) {
|
if(client_socket < 0) {
|
||||||
close(listen_socket);
|
close(listen_socket);
|
||||||
perror("accept");
|
perror("accept");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -71,100 +102,107 @@ static int setup_socket(const char* listen_path) {
|
||||||
return client_socket;
|
return client_socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char *argv[])
|
||||||
if (argc != 2) {
|
{
|
||||||
|
libusb_context *context = NULL;
|
||||||
|
struct fxlink_device *fdev = NULL;
|
||||||
|
struct fxlink_pollfds fxlink_polled_fds = { 0 };
|
||||||
|
int ret = 1;
|
||||||
|
|
||||||
|
if(argc != 2) {
|
||||||
elog("Usage : %s [listen path]\n", argv[0]);
|
elog("Usage : %s [listen path]\n", argv[0]);
|
||||||
return -1;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
libusb_context* context = NULL;
|
|
||||||
int err = libusb_init(&context);
|
int err = libusb_init(&context);
|
||||||
if (err != 0) {
|
if(err != 0) {
|
||||||
elog_libusb(err, "libusb_init");
|
elog_libusb(err, "libusb_init");
|
||||||
return -1;
|
goto end;
|
||||||
}
|
|
||||||
struct fxlink_device* dev = setup_calc(context);
|
|
||||||
if (dev == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int client_socket = setup_socket(argv[1]);
|
|
||||||
if (client_socket < 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
bool nostart = true;
|
||||||
|
fdev = setup_calc(context, nostart);
|
||||||
|
if(!fdev)
|
||||||
|
goto end;
|
||||||
|
|
||||||
struct pollfd client_socket_pollfd = {.fd = client_socket, .events = POLLIN};
|
int client_socket = setup_socket(argv[1]);
|
||||||
struct fxlink_pollfds fxlink_polled_fds;
|
if(client_socket < 0)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* Track libusb fds as an indirect way to watch the calculator itself */
|
||||||
|
struct pollfd client_socket_pollfd = {
|
||||||
|
.fd = client_socket, .events = POLLIN
|
||||||
|
};
|
||||||
fxlink_pollfds_track(&fxlink_polled_fds, context);
|
fxlink_pollfds_track(&fxlink_polled_fds, context);
|
||||||
|
|
||||||
if (!fxlink_device_start_bulk_IN(dev)) {
|
while(true) {
|
||||||
elog("unable to start bulk IN trasfer\n");
|
int err = fxlink_multipoll(-1,
|
||||||
return -1;
|
fxlink_polled_fds.fds, fxlink_polled_fds.count,
|
||||||
}
|
&client_socket_pollfd, 1,
|
||||||
|
NULL);
|
||||||
// TODO : find a way to properly close socket or USB interface when the other side is disconnected
|
|
||||||
int ret = 0;
|
|
||||||
while (1) {
|
|
||||||
int err = fxlink_multipoll(-1, fxlink_polled_fds.fds, fxlink_polled_fds.count,
|
|
||||||
&client_socket_pollfd, 1,
|
|
||||||
NULL);
|
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
perror("poll");
|
perror("poll");
|
||||||
ret = -1;
|
goto end;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct timeval zero = {0};
|
struct timeval zero = {0};
|
||||||
libusb_handle_events_timeout(context, &zero);
|
libusb_handle_events_timeout(context, &zero);
|
||||||
struct fxlink_message* msg;
|
|
||||||
while ((msg = fxlink_device_finish_bulk_IN(dev)) != NULL) {
|
struct fxlink_message *msg;
|
||||||
if (!fxlink_message_is_apptype(msg, "gdb", "remote")) {
|
while((msg = fxlink_device_finish_bulk_IN(fdev)) != NULL) {
|
||||||
elog("unknown fxlink message type\n");
|
if(!fxlink_message_is_apptype(msg, "gdb", "remote")) {
|
||||||
ret = -1;
|
wlog("dropped a message of type %.16s:%.16s\n",
|
||||||
break;
|
msg->application, msg->type);
|
||||||
|
fxlink_device_start_bulk_IN(fdev);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
printf("CAL> %.*s\n", msg->size, (char *)msg->data);
|
||||||
ssize_t send_ret = send(client_socket, msg->data, msg->size, 0);
|
ssize_t send_ret = send(client_socket, msg->data, msg->size, 0);
|
||||||
if (send_ret != msg->size) {
|
if(send_ret != msg->size) {
|
||||||
perror("send");
|
perror("send");
|
||||||
ret = -1;
|
goto end;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
fxlink_message_free(msg, true);
|
fxlink_message_free(msg, true);
|
||||||
|
|
||||||
fxlink_device_start_bulk_IN(dev);
|
fxlink_device_start_bulk_IN(fdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret != 0) {
|
/* Don't start an OUT transfer if there's one in progress */
|
||||||
break;
|
if(fdev->comm->ftransfer_OUT)
|
||||||
}
|
continue;
|
||||||
|
|
||||||
// We don't want to start a new OUT transfer if another one is still in progress
|
int bytes_socket;
|
||||||
if (!dev->comm->ftransfer_OUT) {
|
if(ioctl(client_socket, FIONREAD, &bytes_socket) < 0) {
|
||||||
int bytes_socket;
|
perror("ioctl");
|
||||||
if (ioctl(client_socket, FIONREAD, &bytes_socket) < 0) {
|
goto end;
|
||||||
perror("ioctl");
|
}
|
||||||
ret = -1;
|
if(bytes_socket > 0) {
|
||||||
break;
|
char buf[1024];
|
||||||
|
ssize_t recv_ret = recv(client_socket, buf, sizeof(buf), 0);
|
||||||
|
if(recv_ret < 0) {
|
||||||
|
perror("recv");
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
if (bytes_socket > 0) {
|
printf("GDB> %.*s\n", (int)recv_ret, buf);
|
||||||
char buf[1024];
|
if(!fxlink_device_start_bulk_OUT(fdev, "gdb", "remote", buf, recv_ret, false)) {
|
||||||
ssize_t recv_ret = recv(client_socket, buf, sizeof(buf), 0);
|
elog("unable to start bulk OUT transfer\n");
|
||||||
if (recv_ret < 0) {
|
goto end;
|
||||||
perror("recv");
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!fxlink_device_start_bulk_OUT(dev, "gdb", "remote", buf, recv_ret, false)) {
|
|
||||||
elog("unable to start bulk OUT trasfer\n");
|
|
||||||
ret = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fxlink_pollfds_stop(&fxlink_polled_fds);
|
ret = 0;
|
||||||
fxlink_device_cleanup(dev);
|
|
||||||
free(dev);
|
end:
|
||||||
libusb_exit(context);
|
/* TODO: Close socket at end, including after ^C */
|
||||||
|
|
||||||
|
if(fxlink_polled_fds.ctx)
|
||||||
|
fxlink_pollfds_stop(&fxlink_polled_fds);
|
||||||
|
if(fdev) {
|
||||||
|
fxlink_device_interrupt_transfers(fdev);
|
||||||
|
fxlink_device_cleanup(fdev);
|
||||||
|
free(fdev);
|
||||||
|
}
|
||||||
|
if(context)
|
||||||
|
libusb_exit(context);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue