DESERT 3.5.1
Loading...
Searching...
No Matches
uwinterpreterahoi.cpp
Go to the documentation of this file.
1//
2// Copyright (c) 2019 Regents of the SIGNET lab, University of Padova.
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions
7// are met:
8// 1. Redistributions of source code must retain the above copyright
9// notice, this list of conditions and the following disclaimer.
10// 2. Redistributions in binary form must reproduce the above copyright
11// notice, this list of conditions and the following disclaimer in the
12// documentation and/or other materials provided with the distribution.
13// 3. Neither the name of the University of Padova (SIGNET lab) nor the
14// names of its contributors may be used to endorse or promote products
15// derived from this software without specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29#include <algorithm>
30#include <cstring>
31#include <fstream>
32#include <iostream>
33#include <iterator>
34#include <map>
35#include <string>
36
37#include "ahoitypes.h"
38#include "uwinterpreterahoi.h"
39
40const uint8_t UwInterpreterAhoi::dle = 0x10;
41const uint8_t UwInterpreterAhoi::stx = 0x02;
42const uint8_t UwInterpreterAhoi::etx = 0x03;
43
46
47std::map<ahoi::Command, uint8_t> ahoi::commands_id{
48 std::make_pair(ahoi::Command::send, 0x00), // can be anything in [0,126]
49 std::make_pair(ahoi::Command::id, 0x84),
50 std::make_pair(ahoi::Command::batvol, 0x85),
51 std::make_pair(ahoi::Command::reset, 0x87),
52 std::make_pair(ahoi::Command::agc, 0x98),
53 std::make_pair(ahoi::Command::rxgain, 0x99),
54 std::make_pair(ahoi::Command::txgain, 0x9A),
55 std::make_pair(ahoi::Command::range_delay, 0xA8),
56 std::make_pair(ahoi::Command::distance, 0xA9),
57 std::make_pair(ahoi::Command::packetstat, 0xC0),
58 std::make_pair(ahoi::Command::packetstatreset, 0xC1),
59 std::make_pair(ahoi::Command::syncstat, 0xC2),
60 std::make_pair(ahoi::Command::syncstatreset, 0xC3),
61 std::make_pair(ahoi::Command::sfdstat, 0xC4),
62 std::make_pair(ahoi::Command::sfdstatreset, 0xC5),
63 std::make_pair(ahoi::Command::allstat, 0xC6),
64 std::make_pair(ahoi::Command::allstatreset, 0xC7),
65 std::make_pair(ahoi::Command::confirm, 0xFF)};
66
68 : id(id)
69 , sn(0)
70 , beg_del()
71 , end_del()
72{
73 beg_del[0] = dle;
74 beg_del[1] = stx;
75
76 end_del[0] = dle;
77 end_del[1] = etx;
78}
79
83
84std::string
86{
87 std::string serialized{""};
88
89 uint8_t *raw_pck = (uint8_t *) packet;
90
91 serialized += dle;
92 serialized += stx;
93
94 for (uint i = 0; i < header_size + packet->header.len; i++) {
95 if (*raw_pck == dle) {
96 serialized += dle;
97 }
98 serialized += *raw_pck++;
99 }
100
101 serialized += dle;
102 serialized += etx;
103
104 return serialized;
105}
106
107std::string
109{
110
111 return serializePacket(&pck);
112}
113
114std::string
116{
117
118 ahoi::header_t header;
119 header.src = id;
120 header.dst = 0xFF;
122 header.status = 0x00;
123 header.dsn = sn++;
124 header.len = 0;
125
126 ahoi::packet_t packet;
127 packet.header = header;
128
129 return serializePacket(&packet);
130}
131
132std::string
134{
135 ahoi::header_t header;
136 header.src = id;
137 header.dst = 0xFF;
139 header.status = 0x00;
140 header.dsn = sn++;
141 header.len = 0;
142
143 ahoi::packet_t packet;
144 packet.header = header;
145
146 return serializePacket(&packet);
147}
148
149std::string
151{
152 ahoi::header_t header;
153 header.src = id;
154 header.dst = 0xFF;
156 header.status = 0x00;
157 header.dsn = sn++;
158 header.len = 0;
159
160 ahoi::packet_t packet;
161 packet.header = header;
162
163 return serializePacket(&packet);
164}
165
166std::string
168{
169 ahoi::header_t header;
170 header.src = id;
171 header.dst = 0xFF;
173 header.status = 0x00;
174 header.dsn = sn++;
175 header.len = 0;
176
177 ahoi::packet_t packet;
178 packet.header = header;
179
180 return serializePacket(&packet);
181}
182
183std::string
185{
186 ahoi::header_t header;
187 header.src = id;
188 header.dst = 0xFF;
190 header.status = 0x00;
191 header.dsn = sn++;
192 header.len = 0;
193
194 ahoi::packet_t packet;
195 packet.header = header;
196
197 return serializePacket(&packet);
198}
199
200std::string
202{
203 ahoi::header_t header;
204 header.src = id;
205 header.dst = 0xFF;
207 header.status = 0x00;
208 header.dsn = sn++;
209 header.len = 0;
210
211 ahoi::packet_t packet;
212 packet.header = header;
213
214 return serializePacket(&packet);
215}
216
217std::string
219{
220 ahoi::header_t header;
221 header.src = id;
222 header.dst = 0xFF;
224 header.status = 0x00;
225 header.dsn = sn++;
226 header.len = 0;
227
228 ahoi::packet_t packet;
229 packet.header = header;
230
231 return serializePacket(&packet);
232}
233
234std::string
236{
237 ahoi::header_t header;
238 header.src = id;
239 header.dst = 0xFF;
241 header.status = 0x00;
242 header.dsn = sn++;
243 header.len = 0;
244
245 ahoi::packet_t packet;
246 packet.header = header;
247
248 return serializePacket(&packet);
249}
250
251std::string
253{
254 ahoi::header_t header;
255 header.src = id;
256 header.dst = 0xFF;
258 header.status = 0x00;
259 header.dsn = sn++;
260 header.len = 0;
261
262 ahoi::packet_t packet;
263 packet.header = header;
264
265 return serializePacket(&packet);
266}
267
268std::string
270{
271 ahoi::header_t header;
272 header.src = id;
273 header.dst = 0xFF;
275 header.status = 0x00;
276 header.dsn = sn++;
277 header.len = 0;
278
279 ahoi::packet_t packet;
280 packet.header = header;
281
282 return serializePacket(&packet);
283}
284
285std::string
287{
288 ahoi::header_t header;
289 header.src = id;
290 header.dst = 0xFF;
292 header.status = 0x00;
293 header.dsn = sn++;
294 header.len = 0;
295
296 ahoi::packet_t packet;
297 packet.header = header;
298
299 return serializePacket(&packet);
300}
301
302std::string
304{
305 ahoi::header_t header;
306 header.src = id;
307 header.dst = 0xFF;
309 header.status = 0x00;
310 header.dsn = sn++;
311 header.len = 0;
312
313 ahoi::packet_t packet;
314 packet.header = header;
315
316 return serializePacket(&packet);
317}
318
319std::string
321{
322 ahoi::header_t header;
323 header.src = id;
324 header.dst = 0xFF;
326 header.status = 0x00;
327 header.dsn = sn++;
328 header.len = 0;
329
330 ahoi::packet_t packet;
331 packet.header = header;
332
333 return serializePacket(&packet);
334}
335
336std::string
338{
339 ahoi::header_t header;
340 header.src = id;
341 header.dst = 0xFF;
343 header.status = 0x00;
344 header.dsn = sn++;
345 header.len = 0;
346
347 ahoi::packet_t packet;
348 packet.header = header;
349
350 return serializePacket(&packet);
351}
352
353std::string
355{
356 ahoi::header_t header;
357 header.src = id;
358 header.dst = 0xFF;
360 header.status = 0x00;
361 header.dsn = sn++;
362 header.len = 0;
363
364 ahoi::packet_t packet;
365 packet.header = header;
366
367 return serializePacket(&packet);
368}
369
370std::string
372{
373 ahoi::header_t header;
374 header.src = id;
375 header.dst = 0xFF;
377 header.status = 0x00;
378 header.dsn = sn++;
379 header.len = 0;
380
381 ahoi::packet_t packet;
382 packet.header = header;
383
384 return serializePacket(&packet);
385}
386
387std::string
388UwInterpreterAhoi::findResponse(std::vector<char>::iterator beg,
389 std::vector<char>::iterator end, std::vector<char>::iterator &rsp_beg,
390 std::vector<char>::iterator &rsp_end)
391{
392 std::string cmd = "";
393 rsp_beg = beg;
394 rsp_end = beg;
395
396 if (beg == end)
397 return "";
398
399 // New search for DLE+STX and DLE+ETX
400 auto it = std::find(beg, end, dle);
401 while (it != end) {
402
403 if (*(it + 1) == dle)
404 it = it + 2;
405 else if (*(it + 1) == stx)
406 rsp_beg = it;
407 else if (*(it + 1) == etx)
408 rsp_end = it + end_del.size();
409 ;
410
411 it = std::find(it + 1, end, dle);
412 }
413
414 if (std::distance(rsp_beg, rsp_end) < ahoi::HEADER_LEN || rsp_end < rsp_beg)
415 return std::string("");
416 else
417 return std::string(&(*rsp_beg), std::distance(rsp_beg, rsp_end));
418}
419
420void
421UwInterpreterAhoi::fixEscapes(std::vector<char> &buffer,
422 std::vector<char>::iterator &c_beg, std::vector<char>::iterator &c_end)
423{
424
425 auto it_1 = c_beg;
426 auto it_2 = c_beg;
427 auto it = c_beg;
428
429 while (it < buffer.end() - 1) {
430
431 it_1 = std::find(it, c_end, dle);
432 if ((it_2 = std::find(std::next(it_1, 1), c_end, dle)) ==
433 std::next(it_1, 1)) {
434
435 it = buffer.erase(it_2);
436 } else
437 it++;
438 }
439}
440
441std::shared_ptr<ahoi::packet_t>
443 std::vector<char>::iterator c_beg, std::vector<char>::iterator c_end)
444{
445 std::shared_ptr<ahoi::packet_t> pck = std::make_shared<ahoi::packet_t>();
446 std::shared_ptr<ahoi::header_t> head = std::make_shared<ahoi::header_t>();
447 std::shared_ptr<ahoi::footer_t> foot = std::make_shared<ahoi::footer_t>();
448
449 auto it = std::next(c_beg, beg_del.size());
450
451 // everything is single character
452 // source address
453 auto it_n = std::next(it, 1);
454 if (it_n > c_end)
455 return nullptr;
456 std::copy(it, it_n, &(head->src));
457 // destination address
458 it = it_n;
459 it_n = std::next(it, 1);
460 if (it_n > c_end)
461 return nullptr;
462 std::copy(it, it_n, &(head->dst));
463 // pck_type
464 it = it_n;
465 it_n = std::next(it, 1);
466 if (it_n > c_end)
467 return nullptr;
468 std::copy(it, it_n, &(head->type));
469 // status
470 it = it_n;
471 it_n = std::next(it, 1);
472 if (it_n > c_end)
473 return nullptr;
474 std::copy(it, it_n, &(head->status));
475 // sequence number
476 it = it_n;
477 it_n = std::next(it, 1);
478 if (it_n > c_end)
479 return nullptr;
480 std::copy(it, it_n, &(head->dsn));
481 // payload length
482 it = it_n;
483 it_n = std::next(it, 1);
484 if (it_n > c_end)
485 return nullptr;
486 std::copy(it, it_n, &(head->len));
487
488 pck->header = *head;
489
490 // payload
491 uint len = head->len;
492 it = std::next(it, 1);
493 if (len > 0) {
494 std::memcpy(&(pck->payload), &*it, (size_t) len);
495 } else {
496 return pck;
497 }
498
499 // footer
500 it = it + len;
501 if (it < c_end + end_del.size()) {
502 // power level
503 it_n = std::next(it, 1);
504 if (it_n > c_end)
505 return nullptr;
506 std::copy(it, it_n, &(foot->power));
507 // RSSI
508 it = it_n;
509 it_n = std::next(it, 1);
510 if (it_n > c_end)
511 return nullptr;
512 std::copy(it, it_n, &(foot->rssi));
513 // Number of bit errors
514 it = it_n;
515 it_n = std::next(it, 1);
516 if (it_n > c_end)
517 return nullptr;
518 std::copy(it, it_n, &(foot->biterrors));
519 // mean gain
520 it = it_n;
521 it_n = std::next(it, 1);
522 if (it_n > c_end)
523 return nullptr;
524 std::copy(it, it_n, &(foot->agcMean));
525 // Minimum gain
526 it = it_n;
527 it_n = std::next(it, 1);
528 if (it_n > c_end)
529 return nullptr;
530 std::copy(it, it_n, &(foot->agcMin));
531 // Maximum gain
532 it = it_n;
533 it_n = std::next(it, 1);
534 if (it_n > c_end)
535 return nullptr;
536 std::copy(it, it_n, &(foot->agcMax));
537
538 pck->footer = *foot;
539 } else {
540 }
541
542 return pck;
543}
std::string buildReset()
Method that builds the command.
std::string buildAgc()
Method that builds the command.
std::string buildBatVol()
Method that builds the command.
std::string buildSfdStat()
Method that builds the command.
std::string buildDistance()
Method that builds the command.
static const uint8_t etx
Ending sequence.
std::string buildID(int id)
Method that builds the command to ask the modem its own ID number.
UwInterpreterAhoi(int id)
Constructor of the interpreter class.
void fixEscapes(std::vector< char > &buffer, std::vector< char >::iterator &c_beg, std::vector< char >::iterator &c_end)
Method that erases an escape (DLE) char if part of 2-cahrs escape sequence.
std::string buildSyncStat()
Method that builds the command.
std::string buildRangeDelay()
Method that builds the command.
std::string buildAllStatReset()
Method that builds the command.
std::string buildSfdStatReset()
Method that builds the command.
~UwInterpreterAhoi()
Destructor of the interpreter class.
std::shared_ptr< ahoi::packet_t > parseResponse(std::vector< char >::iterator c_beg, std::vector< char >::iterator c_end)
Method that parses a region of memory where a response was previously found.
std::array< uint8_t, 2 > beg_del
Beginning delimiter.
static uint footer_size
Standard ahoi! packet has 6 bytes of header.
std::string buildPacketStat()
Method that builds the command.
static uint header_size
Standard ahoi! packet has 6 bytes of header.
static const uint8_t dle
std::string buildAllStat()
Method that builds the command.
std::string buildSyncStatReset()
Method that builds the command.
std::string serializePacket(ahoi::packet_t *packet)
Serialize the provided packet.
uint8_t id
Identifier of the modem: to fill the src addres field.
uint8_t sn
Sequence number for commands tranmission: at end restart.
std::array< uint8_t, 2 > end_del
Ending delimiter.
std::string findResponse(std::vector< char >::iterator beg, std::vector< char >::iterator end, std::vector< char >::iterator &rsp_beg, std::vector< char >::iterator &rsp_end)
Method that looks for ahoi! modem responses.
std::string buildTxGain()
Method that builds the command.
std::string buildRxGain()
Method that builds the command.
std::string buildPacketStatReset()
Method that builds the command.
static const uint8_t stx
Starting sequence.
std::string buildSend(ahoi::packet_t pck)
Method that builds the command to send a given message.
constexpr uint HEADER_LEN
Definition ahoitypes.h:97
std::map< ahoi::Command, uint8_t > commands_id
Interpreter for commands and responses for ahoi! modems, TUHH, Hamburg.