Permalink
Browse files

Network protocol improvements #355

  • Loading branch information...
matlo committed Apr 3, 2017
1 parent 46b0632 commit c428fe564cf64b2e313b3ea745e2f5f2857bdf9f
Showing with 65 additions and 26 deletions.
  1. +3 −0 .gitmodules
  2. +8 −8 core/connectors/udp_con.c
  3. +46 −18 core/controller.c
  4. +7 −0 core/include/controller.h
  5. +1 −0 shared/gimx-network-protocol
View
@@ -28,3 +28,6 @@
[submodule "shared/gimxcommon"]
path = shared/gimxcommon
url = https://github.com/matlo/gimxcommon.git
[submodule "shared/gimx-network-protocol"]
path = shared/gimx-network-protocol
url = https://github.com/matlo/gimx-network-protocol.git
View
@@ -4,7 +4,7 @@
*/
#include <connectors/udp_con.h>
#include <connectors/protocol.h>
#include <gimx-network-protocol/protocol.h>
#ifndef WIN32
#include <arpa/inet.h>
#endif
@@ -87,7 +87,7 @@ int udp_connect(unsigned int ip, unsigned short port, int* type)
{
//request the controller type from the remote gimx
unsigned char request[] = {BYTE_TYPE, BYTE_LEN_0_BYTE};
unsigned char request[] = { E_NETWORK_PACKET_CONTROLLER };
if(udp_send(fd, request, sizeof(request)) > 0)
{
@@ -104,18 +104,18 @@ int udp_connect(unsigned int ip, unsigned short port, int* type)
}
else
{
unsigned char answer[3];
s_network_packet_controller controller;
socklen_t salen = sizeof(sa);
int ret = udp_recvfrom(fd, answer, sizeof(answer), (struct sockaddr *) &sa, &salen);
if(ret == sizeof(answer))
int ret = udp_recvfrom(fd, (void *) &controller, sizeof(controller), (struct sockaddr *) &sa, &salen);
if(ret == sizeof(controller))
{
if(answer[0] == BYTE_TYPE && answer[1] == BYTE_LEN_1_BYTE)
if(controller.packet_type == E_NETWORK_PACKET_CONTROLLER)
{
*type = answer[2];
*type = controller.controller_type;
}
else
{
fprintf(stderr, "invalid reply from remote gimx (type=%d, length=%d)\n", answer[0], answer[1]);
fprintf(stderr, "invalid reply from remote gimx type=%hu\n", controller.packet_type);
error = 1;
}
}
View
@@ -162,7 +162,7 @@ static void adapter_dump_state(int adapter)
*/
static int network_read_callback(int adapter)
{
static unsigned char buf[256+2];
static unsigned char buf[sizeof(s_network_packet_in_report) + AXIS_MAX * sizeof(* ((s_network_packet_in_report *) NULL)->axes)];
int nread = 0;
struct sockaddr_in sa;
socklen_t salen = sizeof(sa);
@@ -171,33 +171,52 @@ static int network_read_callback(int adapter)
{
return 0;
}
if(nread < 2)
if(nread < 1)
{
gwarn("invalid packet size: %d\n", nread);
return 0;
}
switch(buf[0])
{
case BYTE_TYPE:
case E_NETWORK_PACKET_CONTROLLER:
{
// send the answer
unsigned char answer[3] = {BYTE_TYPE, BYTE_LEN_1_BYTE, adapters[adapter].ctype};
if (udp_sendto(adapters[adapter].src_fd, answer, sizeof(answer), (struct sockaddr*) &sa, salen) < 0)
s_network_packet_controller ctype =
{
gwarn("adapter_network_read: can't send controller type\n");
.packet_type = E_NETWORK_PACKET_CONTROLLER,
.controller_type = adapters[adapter].ctype
};
if (udp_sendto(adapters[adapter].src_fd, (void *)&ctype, sizeof(ctype), (struct sockaddr*) &sa, salen) < 0)
{
gwarn("%s: can't send controller type\n", __func__);
return 0;
}
}
break;
case BYTE_IN_REPORT:
if(buf[1] != sizeof(adapters->axis))
case E_NETWORK_PACKET_IN_REPORT:
{
gwarn("adapter_network_read: wrong packet size\n");
return 0;
s_network_packet_in_report * report = (s_network_packet_in_report *) buf;
if((unsigned int) nread != sizeof(* report) + report->nbAxes * sizeof(* report->axes))
{
gwarn("%s: wrong packet size: %u %zu\n", __func__, nread, sizeof(* report) + report->nbAxes * sizeof(* report->axes));
return 0;
}
// store the report (no answer)
unsigned char i;
for (i = 0; i < report->nbAxes; ++i)
{
unsigned char offset = ((report->axes[i].index & 0x80) ? abs_axis_0 : 0) + (report->axes[i].index & 0x7f);
if (offset < AXIS_MAX)
{
adapters[adapter].axis[offset] = report->axes[i].value;
}
else
{
gwarn("%s: bad axis index: %s %hu\n", __func__, (report->axes[i].index & 0x80) ? "abs" : "rel", report->axes[i].index & 0x7f);
}
}
adapters[adapter].send_command = 1;
}
// store the report (no answer)
memcpy(adapters[adapter].axis, buf+2, sizeof(adapters->axis));
adapters[adapter].send_command = 1;
break;
}
// require a report to be sent immediately, except for a Sixaxis controller working over bluetooth
@@ -885,11 +904,11 @@ int adapter_detect()
{
if(adapter->remote.ip)
{
adapter->remote.fd = udp_connect(adapter->remote.ip, adapter->remote.fd, (int *)&adapter->ctype);
adapter->remote.fd = udp_connect(adapter->remote.ip, adapter->remote.port, (int *)&adapter->ctype);
if(adapter->remote.fd < 0)
{
struct in_addr addr = { .s_addr = adapter->remote.ip };
gerror(_("failed to connect to network destination: %s:%d.\n"), inet_ntoa(addr), adapter->remote.fd);
gerror(_("failed to connect to network destination: %s:%d.\n"), inet_ntoa(addr), adapter->remote.port);
ret = -1;
}
else
@@ -1132,9 +1151,18 @@ int adapter_send()
{
if(adapter->remote.fd >= 0)
{
static unsigned char report[sizeof(adapter->axis)+2] = { BYTE_IN_REPORT, sizeof(adapter->axis) };
memcpy(report+2, adapter->axis, sizeof(adapter->axis));
ret = udp_send(adapter->remote.fd, report, sizeof(report));
s_network_packet_in_report * report = &adapter->remote.report;
report->packet_type = E_NETWORK_PACKET_IN_REPORT;
report->nbAxes = 0;
unsigned char i;
for (i = 0; i < AXIS_MAX; ++i)
{
report->axes[report->nbAxes].index = (i >= abs_axis_0) ? (0x80 | (i - abs_axis_0)) : i;
report->axes[report->nbAxes].value = adapter->axis[i];
++report->nbAxes;
}
ret = udp_send(adapter->remote.fd, adapter->remote.buf, sizeof(* report) + report->nbAxes * sizeof(* report->axes));
}
}
else if(adapter->atype == E_ADAPTER_TYPE_DIY_USB)
@@ -7,6 +7,7 @@
#define CONTROLLER_H_
#include <connectors/protocol.h>
#include <gimx-network-protocol/protocol.h>
#include <config.h>
#include <gimxserial/include/gserial.h>
#include <gimxcontroller/include/controller.h>
@@ -17,6 +18,8 @@
#include <connectors/windows/sockets.h>
#endif
#include <stdio.h>
typedef enum {
E_ADAPTER_TYPE_NONE,
E_ADAPTER_TYPE_BLUETOOTH,
@@ -42,6 +45,10 @@ typedef struct {
in_addr_t ip;
unsigned short port;
int fd;
union {
unsigned char buf[sizeof(s_network_packet_in_report) + AXIS_MAX * sizeof(* ((s_network_packet_in_report * )NULL)->axes)];
s_network_packet_in_report report;
};
} remote;
};
in_addr_t src_ip;

0 comments on commit c428fe5

Please sign in to comment.