-
Notifications
You must be signed in to change notification settings - Fork 3
/
RH_LoRaFileOps.cpp
279 lines (218 loc) · 5.69 KB
/
RH_LoRaFileOps.cpp
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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
// RH_LoRaFileOpscpp
//
// Copyright (C) 2021 Mike McCauley
#include <RH_LoRaFileOps.h>
// This can only build on Linux and compatible systems
// Caution also requires Lora-file-ops driver to be installed
// See https://github.com/starnight/LoRa/tree/file-ops
#if (RH_PLATFORM == RH_PLATFORM_UNIX)
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/select.h>
RH_LoRaFileOps::RH_LoRaFileOps(const char* port)
:
_port(port),
_fd(-1)
{
}
bool RH_LoRaFileOps::init()
{
if (!RHGenericDriver::init())
return false;
_fd = open(_port, O_RDWR);
if (_fd == -1)
{
Serial.print("RH_LoRaFileOps::init LORA device port open failed: ");
Serial.println(strerror(errno));
return false;
}
// These settings are compatible with RH_RF95::Bw125Cr45Sf2048 and the other defaults
// for RH_RF95
setFrequency(434000000);
setTxPower(13);
setSpreadingFactor(2048);
setBW(125000);
setCRC(true);
setLNA(0);
return true;
}
bool RH_LoRaFileOps::available()
{
// Test if the port can be read
fd_set read_fds;
struct timeval tv = {.tv_sec = 0, .tv_usec = 0};
FD_ZERO(&read_fds);
FD_SET(_fd, &read_fds);
if (select(_fd+1, &read_fds, NULL, NULL, &tv) == -1)
{
Serial.println("Select failed");
return false;
}
return FD_ISSET(_fd, &read_fds) ? true : false;
}
bool RH_LoRaFileOps::recv(uint8_t* buf, uint8_t* len)
{
if (_fd == -1) return false;
if (!available()) return false;
// Read the available packet from the driver
uint8_t readbuf[RH_LORAFILEOPS_MAX_PAYLOAD_LEN];
ssize_t sz;
sz = read(_fd, readbuf, RH_LORAFILEOPS_MAX_PAYLOAD_LEN);
// Remember the last signal to noise ratio, LORA mode
// Per page 111, SX1276/77/78/79 datasheet
_lastSNR = getSNR();
// Remember the RSSI of this packet, LORA mode
// This figure has already been massaged by the driver
_lastRssi = getRSSI();
// Test if its really for us
if (sz < 4)
return false; // Too short to be a real message
// Extract the 4 headers
_rxHeaderTo = readbuf[0];
_rxHeaderFrom = readbuf[1];
_rxHeaderId = readbuf[2];
_rxHeaderFlags = readbuf[3];
if (_promiscuous ||
_rxHeaderTo == _thisAddress ||
_rxHeaderTo == RH_BROADCAST_ADDRESS)
{
// Yes its for us
// Skip the 4 headers that are at the beginning of the rxBuf
if (*len > (sz - RH_LORAFILEOPS_HEADER_LEN))
*len = sz - RH_LORAFILEOPS_HEADER_LEN;
memcpy(buf, readbuf + RH_LORAFILEOPS_HEADER_LEN, *len);
Serial.println("recv OK");
return true;
}
// Not for us
return false;
}
bool RH_LoRaFileOps::send(const uint8_t* data, uint8_t len)
{
if (_fd == -1) return false;
if (len > RH_LORAFILEOPS_MAX_MESSAGE_LEN)
return false;
// Should never need to wait for a packet to be sent since the driver always
// waits before returning from write
// Assemble the entire message, including RadioHead header
// Header bytes, total size of RH_LORAFILEOPS_HEADER_LEN
uint8_t buf[RH_LORAFILEOPS_MAX_PAYLOAD_LEN];
buf[0] = _txHeaderTo;
buf[1] = _txHeaderFrom;
buf[2] = _txHeaderId;
buf[3] = _txHeaderFlags;
memcpy(buf+4, data, len);
// Send the message to the driver
ssize_t sz;
// Returns when the packet has been transmtted:
sz = write(_fd, buf, len+RH_LORAFILEOPS_HEADER_LEN);
return sz == len+RH_LORAFILEOPS_HEADER_LEN;
}
uint8_t RH_LoRaFileOps::maxMessageLength()
{
return RH_LORAFILEOPS_MAX_MESSAGE_LEN;
}
bool RH_LoRaFileOps::setFrequency(uint32_t centre)
{
if (_fd == -1) return false;
ioctl(_fd, LORA_SET_FREQUENCY, ¢re);
return true; // FIXME??
}
uint32_t RH_LoRaFileOps::getFrequency()
{
if (_fd == -1) return 0;
uint32_t freq;
ioctl(_fd, LORA_GET_FREQUENCY, &freq);
return freq;
}
void RH_LoRaFileOps::setTxPower(int32_t power)
{
if (_fd == -1) return;
ioctl(_fd, LORA_SET_POWER, &power);
}
int32_t RH_LoRaFileOps::getTxPower()
{
if (_fd == -1) return 0;
int32_t power;
ioctl(_fd, LORA_GET_POWER, &power);
return power;
}
void RH_LoRaFileOps::setState(uint32_t state)
{
if (_fd == -1) return;
ioctl(_fd, LORA_SET_STATE, &state);
}
uint32_t RH_LoRaFileOps::getState()
{
if (_fd == -1) return LORA_STATE_SLEEP;
uint32_t state;
ioctl(_fd, LORA_GET_STATE, &state);
return state;
}
void RH_LoRaFileOps::setSpreadingFactor(int32_t sf)
{
ioctl(_fd, LORA_SET_SPRFACTOR, &sf);
}
int32_t RH_LoRaFileOps::getSpreadingFactor()
{
if (_fd == -1) return 0;
uint32_t sprf;
ioctl(_fd, LORA_GET_SPRFACTOR, &sprf);
return sprf;
}
// This gets the raw RSSI figure. Its not adjusted to dBm
int32_t RH_LoRaFileOps::getRSSI()
{
if (_fd == -1) return 0;
int32_t rssi;
ioctl(_fd, LORA_GET_RSSI, &rssi);
return rssi;
}
// Last packet SNR
int32_t RH_LoRaFileOps::getSNR()
{
if (_fd == -1) return 0;
int32_t snr;
ioctl(_fd, LORA_GET_SNR, &snr);
return snr;
}
void RH_LoRaFileOps::setLNA(int32_t lna)
{
if (_fd == -1) return;
ioctl(_fd, LORA_SET_LNA, &lna);
}
int32_t RH_LoRaFileOps::getLNA()
{
if (_fd == -1) return 0;
int32_t lna;
ioctl(_fd, LORA_GET_LNA, &lna);
return lna;
}
void RH_LoRaFileOps::setLNAAGC(int32_t lnaagc)
{
if (_fd == -1) return;
ioctl(_fd, LORA_SET_LNAAGC, &lnaagc);
}
void RH_LoRaFileOps::setBW(int32_t bw)
{
if (_fd == -1) return;
ioctl(_fd, LORA_SET_BANDWIDTH, &bw);
}
int32_t RH_LoRaFileOps::getBW()
{
if (_fd == -1) return 0;
uint32_t bw;
ioctl(_fd, LORA_GET_BANDWIDTH, &bw);
return bw;
}
void RH_LoRaFileOps::setCRC(uint32_t crc)
{
if (_fd == -1) return;
ioctl(_fd, LORA_SET_CRC, &crc);
}
int RH_LoRaFileOps::lastSNR()
{
return _lastSNR;
}
#endif