forked from psas/av3-fc
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathethmux.c
122 lines (108 loc) · 3.24 KB
/
ethmux.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <unistd.h>
#include <stdio.h>
#include <netinet/in.h>
#include <linux/net_tstamp.h>
#include <time.h>
#include <string.h>
#include "elderberry/fcfutils.h"
#include "utilities/utils_sockets.h"
#include "utilities/utils_time.h"
#include "utilities/net_addrs.h"
#include "ethmux.h"
static uint8_t buffer[ETH_MTU];
typedef void (*demux_handler)(uint8_t * buffer, unsigned int len, uint8_t * timestamp);
void sequenced_receive(unsigned short port, uint8_t * buffer, unsigned int len, uint8_t* timestamp, uint32_t * seq, demux_handler handler) {
if (len < sizeof(uint32_t)) {
sequenced_error(port, buffer, len, timestamp, 0, 0);
return;
}
uint32_t rcvseq = ntohl(*(uint32_t*)buffer);
buffer += sizeof(uint32_t);
len -= sizeof(uint32_t);
if (rcvseq < *seq) {
sequenced_error(port, buffer, len, timestamp, *seq, rcvseq);
}
if (rcvseq > *seq) {
sequenced_error(port, NULL, 0, timestamp, *seq, rcvseq);
handler(buffer, len, timestamp);
}
if (rcvseq == *seq) {
handler(buffer, len, timestamp);
}
*seq = rcvseq + 1;
}
void demux(struct pollfd *pfd){
static uint32_t seq_ADIS = 0;
static uint32_t seq_LD = 0;
static uint32_t seq_MPU = 0;
static uint32_t seq_MPL = 0;
static uint32_t seq_RNH = 0;
static uint32_t seq_RNHPORT = 0;
static uint32_t seq_RNHALARM = 0;
static uint32_t seq_RNHUMBDET = 0;
static uint32_t seq_FCFH = 0;
static uint32_t seq_GPS_COTS = 0;
struct sockaddr_in packet_info;
struct timespec ts;
socklen_t len = sizeof(packet_info);
int bytes = readsocketfromts(pfd->fd, buffer, sizeof(buffer), &packet_info, len, &ts);
unsigned short port = ntohs(packet_info.sin_port);
uint8_t timestamp[6];
to_psas_time(&ts, timestamp);
if(bytes > 0){
switch(port){
case ADIS_PORT:
sequenced_receive(port, buffer, bytes, timestamp, &seq_ADIS, demuxed_ADIS);
break;
case ARM_PORT:
demuxed_ARM(buffer, bytes, timestamp);
break;
case TEATHER_PORT:
sequenced_receive(port, buffer, bytes, timestamp, &seq_LD, demuxed_LD);
break;
case MPU_PORT:
sequenced_receive(port, buffer, bytes, timestamp, &seq_MPU, demuxed_MPU);
break;
case MPL_PORT:
sequenced_receive(port, buffer, bytes, timestamp, &seq_MPL, demuxed_MPL);
break;
case RC_SERVO_ENABLE_PORT:
demuxed_RC(buffer, bytes, timestamp);
break;
case RNH_BATTERY:
sequenced_receive(port, buffer, bytes, timestamp, &seq_RNH, demuxed_RNH);
break;
case RNH_PORT:
sequenced_receive(port, buffer, bytes, timestamp, &seq_RNHPORT, demuxed_RNH);
break;
case RNH_ALARM:
sequenced_receive(port, buffer, bytes, timestamp, &seq_RNHALARM, demuxed_RNH);
break;
case RNH_UMBDET:
sequenced_receive(port, buffer, bytes, timestamp, &seq_RNHUMBDET, demuxed_RNH);
break;
case FCF_HEALTH_PORT:
sequenced_receive(port, buffer, bytes, timestamp, &seq_FCFH, demuxed_FCFH);
break;
case GPS_COTS:
sequenced_receive(port, buffer, bytes, timestamp, &seq_GPS_COTS, demuxed_COTS);
break;
default:
break;
// TODO: add a counter or debug logging of unknown ports
}
}
}
static int fd;
void ethmux_init(void){
fd = timestamped_bound_udp_socket(FC_LISTEN_PORT);
if(fd < 0){
return;
}
fcf_add_fd(fd, POLLIN, demux);
}
void ethmux_final(void){
//We really don't need to do this but just to be pedantic
fcf_remove_fd(fd);
close(fd);
}