forked from wiedehopf/readsb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
net_io.h
227 lines (201 loc) · 7.09 KB
/
net_io.h
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
// Part of readsb, a Mode-S/ADSB/TIS message decoder.
//
// net_io.h: network handling.
//
// Copyright (c) 2019 Michael Wolf <michael@mictronics.de>
//
// This code is based on a detached fork of dump1090-fa.
//
// Copyright (c) 2014,2015 Oliver Jowett <oliver@mutability.co.uk>
//
// This file is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// This file is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NETIO_H
#define NETIO_H
#include <sys/socket.h>
// Describes a networking service (group of connections)
struct aircraft;
struct modesMessage;
struct client;
struct net_service;
struct net_service_group;
struct messageBuffer;
typedef int (*read_fn)(struct client *, char *, int, int64_t, struct messageBuffer *);
typedef enum
{
READ_MODE_IGNORE,
READ_MODE_BEAST,
READ_MODE_BEAST_COMMAND,
READ_MODE_ASCII
} read_mode_t;
typedef struct {
const char *msg;
int32_t len;
} heartbeat_t;
// Describes one network service (a group of clients with common behaviour)
struct net_service
{
const char *descr;
struct net_service_group *group;
struct net_writer *writer; // shared writer state
int listener_count; // number of listeners
int pusher_count; // Number of push servers connected to
int connections; // number of active clients
int serial_service; // 1 if this is a service for serial devices
read_mode_t read_mode;
read_fn read_handler;
int read_sep_len;
const char *read_sep; // hander details for input data
struct client *clients; // linked list of clients connected to this service
int *listener_fds; // listening FDs
struct client *listenSockets; // dummy client structs for all open sockets for epoll commonality
char* unixSocket; // path of unix socket
int sendqOverrideSize;
int recvqOverrideSize;
heartbeat_t heartbeat_in;
heartbeat_t heartbeat_out;
};
#define NET_SERVICE_GROUP_MAX 16
struct net_service_group {
struct net_service *services;
int len;
int alloc;
int event_progress;
};
// Structure used to describe a networking client
struct client
{
struct client* next; // Pointer to next client
struct net_service *service; // Service this client is part of
char *buf; // read buffer
char *som;
char *eod;
int buflen; // Amount of data on read buffer
int bufmax; // size of the read buffer
int fd; // File descriptor
int8_t bufferToProcess;
int8_t remote;
int8_t bContinue;
int8_t discard;
int8_t processing;
int8_t acceptSocket; // not really a client but rather an accept Socket ... only fd and epollEvent will be valid
int8_t net_connector_dummyClient; // dummy client used by net_connector
int8_t pingEnabled;
int8_t modeac_requested; // 1 if this Beast output connection has asked for A/C
int8_t receiverIdLocked; // receiverId has been transmitted by other side.
int8_t unreasonable_messagerate;
char *sendq; // Write buffer - allocated later
int sendq_len; // Amount of data in SendQ
int sendq_max; // Max size of SendQ
uint32_t ping; // only 24 bit are ever sent
uint32_t pong; // only 24 bit are ever sent
int32_t recentMessages;
int64_t recentMessagesReset;
int64_t pingReceived;
int64_t pongReceived;
uint64_t bytesReceived;
uint64_t receiverId;
uint64_t receiverId2;
int64_t last_flush;
int64_t last_send;
int64_t last_read; // This is used on write-only clients to help check for dead connections
int64_t last_read_flush;
int64_t connectedSince;
uint64_t messageCounter; // counter for incoming data
uint64_t positionCounter; // counter for incoming data
uint64_t garbage; // amount of garbage we have received from this client
int64_t rtt; // last reported rtt in milliseconds
double latest_rtt; // in milliseconds, pseudo average with factor 0.9
// crude IIR pseudo rolling average, old value factor 0.995
// cumulative weigth of last 100 packets is 0.39
// cumulative weigth of last 300 packets is 0.78
// cumulative weigth of last 600 packets is 0.95
// usually around 300 packets a minute for an ro-interval of 0.2
double recent_rtt; // in milliseconds
struct epoll_event epollEvent;
struct net_connector *con;
char proxy_string[256]; // store string received from PROXY protocol v1 (v2 not supported currently)
char host[NI_MAXHOST]; // For logging
char port[NI_MAXSERV];
};
// Client connection
struct net_connector
{
char *address;
char *address0;
char *address1;
char *port;
char *port0;
char *port1;
char *protocol;
struct net_service *service;
struct client* c;
int use_addr;
int connected;
int connecting;
int silent_fail;
int fd;
int64_t next_reconnect;
int64_t connect_timeout;
int64_t lastConnect; // timestamp for last connection establish
int64_t backoff;
char resolved_addr[NI_MAXHOST+3];
struct addrinfo *addr_info;
struct addrinfo *try_addr; // pointer walking addr_info list
int gai_error;
int gai_request_in_progress;
int gai_request_done;
pthread_t thread;
pthread_mutex_t mutex;
struct client dummyClient; // client struct for epoll connection handling before we have a fully established connection
};
// Common writer state for all output sockets of one type
struct net_writer
{
void *data; // shared write buffer, sized MODES_OUT_BUF_SIZE
int dataUsed; // number of bytes of write buffer currently used
int connections; // number of active clients
struct net_service *service; // owning service
int64_t lastWrite; // time of last write to clients
uint64_t lastReceiverId;
int noTimestamps;
};
void serviceListen (struct net_service *service, char *bind_addr, char *bind_ports, int epfd);
void serviceClose(struct net_service *s);
void sendBeastSettings (int fd, const char *settings);
void sendData(struct net_writer *output, char *data, int len);
void modesInitNet (void);
void modesQueueOutput (struct modesMessage *mm);
void jsonPositionOutput(struct modesMessage *mm, struct aircraft *a);
void modesNetPeriodicWork (void);
void cleanupNetwork(void);
void writeJsonToNet(struct net_writer *writer, struct char_buffer cb);
// GNS HULC status message
typedef union __packed {
unsigned char buf[24];
struct _packed {
uint32_t serial;
uint16_t flags;
uint16_t reserved;
uint32_t epoch;
uint32_t latitude;
uint32_t longitude;
uint16_t altitude;
uint8_t satellites;
uint8_t hdop;
} status;
} hulc_status_msg_t;
void netUseMessage(struct modesMessage *mm);
void netDrainMessageBuffers();
struct modesMessage *netGetMM();
#endif