DESERT 3.5.1
Loading...
Searching...
No Matches
uwinterpreters2c.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 <uwinterpreters2c.h>
30
31#include <algorithm>
32#include <iostream>
33#include <sstream>
34
35std::vector<std::pair<std::string, UwInterpreterS2C::Response> >
36 UwInterpreterS2C::syntax_pool{std::make_pair("RECVIM,", Response::RECVIM),
37 std::make_pair("RECV,", Response::RECV),
38 std::make_pair("OK", Response::OK),
39 std::make_pair("EMPTY", Response::EMPTY),
40 std::make_pair("BUSY", Response::BUSY),
41 std::make_pair("DELIVERING", Response::DELIVERING),
42 std::make_pair("DELIVERED", Response::DELIVERED),
43 std::make_pair("DELIVEREDIM", Response::DELIVEREDIM),
44 std::make_pair("DROPCNT", Response::DROPCNT),
45 std::make_pair("ERROR PHY OFF", Response::PHYOFF),
46 std::make_pair("ERROR NOT ACCEPTED", Response::NOT_ACCEPTED),
47 std::make_pair(
48 "ERROR WRONG DESTINATION ADDRESS", Response::WRONG_ADDR),
49 std::make_pair("ERROR CONNECTION CLOSED", Response::CONN_CLOSED),
50 std::make_pair("ERROR UNKNOWN COMMAND", Response::UNKNOWN),
51 std::make_pair("ERROR WRONG FORMAT", Response::UNKNOWN),
52 std::make_pair(
53 "ERROR BUFFER IS NOT EMPTY", Response::BUFF_NOT_EMPTY),
54 std::make_pair("ERROR BUFFER FULL", Response::BUFFER_FULL),
55 std::make_pair("ERROR OUT OF RANGE", Response::OUT_OF_RANGE),
56 std::make_pair("ERROR PROTOCOL ID", Response::PROTOCOL_ID),
57 std::make_pair("ERROR INTERNAL", Response::INTERNAL),
58 std::make_pair("FAILED", Response::FAIL),
59 std::make_pair("Source Level:", Response::CURR_SETTINGS),
60 std::make_pair("Remote Address:", Response::MODEM_STATUS),
61 std::make_pair("INITIATION NOISE", Response::INIT_NOISE),
62 std::make_pair("INITIATION DEAF", Response::INIT_DEAF),
63 std::make_pair("INITIATION LISTEN", Response::INIT_LISTEN),
64 std::make_pair("RECVSTART", Response::RECVSTART),
65 std::make_pair("RECVEND", Response::RECVEND),
66 std::make_pair("RECVFAILED", Response::RECVFAIL),
67 std::make_pair("SENDSTART", Response::SENDSTART),
68 std::make_pair("SENDEND", Response::SENDEND),
69 std::make_pair("BITRATE", Response::BITRATE),
70 std::make_pair("USBLANGLES", Response::USBLANGLES),
71 std::make_pair("USBLLONG", Response::USBLLONG)};
72
74 : sep(",")
75 , r_term("\r\n")
76 , w_term("\n")
77 , ext_proto_mode(false)
78 , usbl_info(nullptr)
79{
80 usbl_info = std::make_shared<USBLInfo>();
81}
82
86
87std::string
88UwInterpreterS2C::buildSend(std::string msg, int dest)
89{
90 std::string base_cmd = "AT*SEND";
91 std::string length = std::to_string(msg.size());
92 std::string destination = std::to_string(dest);
93
94 std::string cmd;
95 if (ext_proto_mode) {
96 cmd =
97 base_cmd + sep + "p0" + sep + length + sep + destination + sep + msg + w_term;
98 } else {
99 cmd =
100 base_cmd + sep + length + sep + destination + sep + msg + w_term;
101 }
102
103 return cmd;
104}
105
106std::string
107UwInterpreterS2C::buildSendIM(std::string msg, int dest, bool ack)
108{
109 std::string base_cmd = "AT*SENDIM";
110 std::string length = std::to_string(msg.size());
111 std::string destination = std::to_string(dest);
112
113 std::string cmd;
114 if (ext_proto_mode) {
115 if (ack) {
116 cmd = base_cmd + sep + "p0" + sep + length + sep + destination + sep + "ack" + sep +
117 msg + w_term;
118 } else {
119 cmd = base_cmd + sep + "p0" + sep + length + sep + destination + sep + "noack" +
120 sep + msg + w_term;
121 }
122 } else {
123 if (ack) {
124 cmd = base_cmd + sep + length + sep + destination + sep + "ack" + sep +
125 msg + w_term;
126 } else {
127 cmd = base_cmd + sep + length + sep + destination + sep + "noack" +
128 sep + msg + w_term;
129 }
130 }
131
132 return cmd;
133}
134
135std::string
137{
138 if (level < 0 || level > 4) {
139 std::string err_msg = "ERROR::RESET_LEVEL_OUT_OF_BOUNDS";
140 return "";
141 }
142 std::string base_cmd = "ATZ";
143 std::string lev = std::to_string(level);
144
145 std::string cmd = base_cmd + lev + w_term;
146
147 return cmd;
148}
149
150std::string
152{
153 std::string cmd = "AT?DI" + w_term;
154 return cmd;
155}
156
157std::string
159{
160 std::string cmd = "AT?S" + w_term;
161 return cmd;
162}
163
164std::string
166{
167 std::string cmd = "AT&V" + w_term;
168 return cmd;
169}
170
171std::string
173{
174 std::string base_cmd = "AT?L";
175 std::string cmd = base_cmd + w_term;
176
177 return cmd;
178}
179
180std::string
182{
183 if (level < 0 || level > 4) {
184 std::string err_msg = "ERROR::SOURCE_LEVEL_OUT_OF_BOUNDS";
185 return "";
186 }
187 std::string base_cmd = "AT!L";
188 std::string sl = std::to_string(level);
189
190 std::string cmd = base_cmd + sl + w_term;
191
192 return cmd;
193}
194
195std::string
197{
198 std::string base_cmd = "AT?AL";
199
200 std::string cmd = base_cmd + w_term;
201
202 return cmd;
203}
204
205std::string
207{
208 if (addr <= 0 || addr >= 255) {
209 std::string err_msg = "ERROR::LOCAL_ADDRESS_OUT_OF_BOUNDS";
210 return "";
211 }
212 std::string base_cmd = "AT!AL";
213 std::string address = std::to_string(addr);
214
215 std::string cmd = base_cmd + address + w_term;
216
217 return cmd;
218}
219
221UwInterpreterS2C::findResponse(std::vector<char>::iterator beg,
222 std::vector<char>::iterator end, std::vector<char>::iterator &rsp)
223{
224
226 std::vector<char>::iterator first = end;
227
228 for (uint i = 0; i < syntax_pool.size(); i++) {
229
230 auto it = std::search(beg,
231 end,
232 syntax_pool[i].first.begin(),
233 syntax_pool[i].first.end());
234
235 if (it < first) {
236 first = it;
237 cmd = syntax_pool[i].second;
238 }
239
240 rsp = first;
241 }
242
243 return cmd;
244}
245
246bool
247UwInterpreterS2C::parseResponse(Response rsp, std::vector<char>::iterator end,
248 std::vector<char>::iterator rsp_beg,
249 std::vector<char>::iterator &rsp_end, std::string &rx_payload)
250{
251 switch (rsp) {
252
253 case Response::RECVIM: {
254 auto it = std::search(rsp_beg, end, r_term.begin(), r_term.end());
255 if (it != end) {
256 rsp_end = it + r_term.size();
257 } else {
258 return false;
259 }
260
261 auto curs_b = std::find(rsp_beg, rsp_end, ',') + 1;
262 if (curs_b >= end) {
263 return false;
264 }
265 auto curs_e = std::find(curs_b, rsp_end, ',');
266 if (curs_e >= end) {
267 return false;
268 }
269 // protocol ID if Extended Protocol Mode is used
270 if (ext_proto_mode) {
271 std::string ch = std::string(curs_b, curs_e);
272 curs_b = curs_e + 1;
273 if (curs_b >= end) {
274 return false;
275 }
276 curs_e = std::find(curs_b, rsp_end, ',');
277 if (curs_e >= end) {
278 return false;
279 }
280 }
281 // length
282 int len = std::stoi(std::string(curs_b, curs_e));
283 // source address
284 curs_b = curs_e + 1;
285 if (curs_b >= end) {
286 return false;
287 }
288 curs_e = std::find(curs_b, rsp_end, ',');
289 if (curs_e >= end) {
290 return false;
291 }
292 int sour_a = std::stoi(std::string(curs_b, curs_e));
293 // destination address
294 curs_b = curs_e + 1;
295 if (curs_b >= end) {
296 return false;
297 }
298 curs_e = std::find(curs_b, rsp_end, ',');
299 if (curs_e >= end) {
300 return false;
301 }
302 int dest_a = std::stoi(std::string(curs_b, curs_e));
303 // flag (ACK ro NOT-ACK)
304 curs_b = curs_e + 1;
305 if (curs_b >= end) {
306 return false;
307 }
308 curs_e = std::find(curs_b, rsp_end, ',');
309 if (curs_e >= end) {
310 return false;
311 }
312 std::string ack = std::string(curs_b, curs_e);
313 // duration
314 curs_b = curs_e + 1;
315 if (curs_b >= end) {
316 return false;
317 }
318 curs_e = std::find(curs_b, rsp_end, ',');
319 if (curs_e >= end) {
320 return false;
321 }
322 int dur = std::stoi(std::string(curs_b, curs_e));
323 // rssi
324 curs_b = curs_e + 1;
325 if (curs_b >= end) {
326 return false;
327 }
328 curs_e = std::find(curs_b, rsp_end, ',');
329 if (curs_e >= end) {
330 return false;
331 }
332 int rssi = std::stoi(std::string(curs_b, curs_e));
333 // integrity
334 curs_b = curs_e + 1;
335 if (curs_b >= end) {
336 return false;
337 }
338 curs_e = std::find(curs_b, rsp_end, ',');
339 if (curs_e >= end) {
340 return false;
341 }
342 int integrity = std::stoi(std::string(curs_b, curs_e));
343 // velocity
344 curs_b = curs_e + 1;
345 if (curs_b >= end) {
346 return false;
347 }
348 curs_e = std::find(curs_b, rsp_end, ',');
349 if (curs_e >= end) {
350 return false;
351 }
352 std::istringstream velocity_ss(std::string(curs_b, curs_e));
353 double velocity;
354 velocity_ss >> velocity;
355 // payload
356 auto payload_beg = std::find(curs_e, rsp_end, ',') + 1;
357 if (payload_beg >= end) {
358 return false;
359 }
360 rsp_end = payload_beg + len;
361
362 auto term_beg =
363 std::search(rsp_end, end, r_term.begin(), r_term.end());
364 if (rsp_end != term_beg) {
365 return false;
366 }
367 rsp_end += r_term.size();
368 rx_payload = std::string(payload_beg, rsp_end - r_term.size());
369 return true;
370 }
371
372 case Response::RECV: {
373 auto it = search(rsp_beg, end, r_term.begin(), r_term.end());
374 if (it != end) {
375 rsp_end = it + r_term.size();
376 } else {
377 return false;
378 }
379
380 auto curs_b = std::find(rsp_beg, rsp_end, ',') + 1;
381 if (curs_b >= end) {
382 return false;
383 }
384 auto curs_e = std::find(curs_b, rsp_end, ',');
385 if (curs_e >= end) {
386 return false;
387 }
388 // Protocol ID if Extended Protocol Mode enabled
389 if (ext_proto_mode) {
390 std::string ch = std::string(curs_b, curs_e);
391 curs_b = curs_e + 1;
392 if (curs_b >= end) {
393 return false;
394 }
395 curs_e = std::find(curs_b, rsp_end, ',');
396 if (curs_e >= end) {
397 return false;
398 }
399 }
400 // length
401 int len = std::stoi(std::string(curs_b, curs_e));
402 // source address
403 curs_b = curs_e + 1;
404 if (curs_b >= end) {
405 return false;
406 }
407 curs_e = std::find(curs_b, rsp_end, ',');
408 if (curs_e >= end) {
409 return false;
410 }
411 int sour_a = std::stoi(std::string(curs_b, curs_e));
412 // destination address
413 curs_b = curs_e + 1;
414 if (curs_b >= end) {
415 return false;
416 }
417 curs_e = std::find(curs_b, rsp_end, ',');
418 if (curs_e >= end) {
419 return false;
420 }
421 int dest_a = std::stoi(std::string(curs_b, curs_e));
422 // bitrate
423 curs_b = curs_e + 1;
424 if (curs_b >= end) {
425 return false;
426 }
427 curs_e = std::find(curs_b, rsp_end, ',');
428 if (curs_e >= end) {
429 return false;
430 }
431 int bitrate = std::stoi(std::string(curs_b, curs_e));
432 // rssi
433 curs_b = curs_e + 1;
434 if (curs_b >= end) {
435 return false;
436 }
437 curs_e = std::find(curs_b, rsp_end, ',');
438 if (curs_e >= end) {
439 return false;
440 }
441 int rssi = std::stoi(std::string(curs_b, curs_e));
442 // integrity
443 curs_b = curs_e + 1;
444 if (curs_b >= end) {
445 return false;
446 }
447 curs_e = std::find(curs_b, rsp_end, ',');
448 if (curs_e >= end) {
449 return false;
450 }
451 int integrity = std::stoi(std::string(curs_b, curs_e));
452 // delay
453 curs_b = curs_e + 1;
454 if (curs_b >= end) {
455 return false;
456 }
457 curs_e = std::find(curs_b, rsp_end, ',');
458 if (curs_e >= end) {
459 return false;
460 }
461 int delay = std::stoi(std::string(curs_b, curs_e));
462 // velocity
463 curs_b = curs_e + 1;
464 if (curs_b >= end) {
465 return false;
466 }
467 curs_e = std::find(curs_b, rsp_end, ',');
468 if (curs_e >= end) {
469 return false;
470 }
471 std::istringstream velocity_ss(std::string(curs_b, curs_e));
472 double velocity;
473 velocity_ss >> velocity;
474 // payload
475 auto payload_beg = std::find(curs_e, rsp_end, ',') + 1;
476 if (payload_beg >= end) {
477 return false;
478 }
479 rsp_end = payload_beg + len;
480 auto term_beg =
481 std::search(rsp_end, end, r_term.begin(), r_term.end());
482 if (rsp_end != term_beg) {
483 return false;
484 }
485 rsp_end += r_term.size();
486 rx_payload = std::string(payload_beg, rsp_end - r_term.size());
487 return true;
488 }
489
490 case Response::OK: {
491 auto it = std::search(rsp_beg, end, r_term.begin(), r_term.end());
492 if (it != end) {
493 rsp_end = it + r_term.size();
494 return true;
495 } else {
496 return false;
497 }
498 }
499
500 case Response::EMPTY: {
501 auto it = search(rsp_beg, end, r_term.begin(), r_term.end());
502 if (it != end) {
503 rsp_end = it + r_term.size();
504 return true;
505 } else {
506 return false;
507 }
508 }
509
510 case Response::BUSY: {
511 auto it = search(rsp_beg, end, r_term.begin(), r_term.end());
512 if (it != end) {
513 rsp_end = it + r_term.size();
514 return true;
515 } else {
516 return false;
517 }
518 }
519
521 auto it = search(rsp_beg, end, r_term.begin(), r_term.end());
522 if (it != end) {
523 rsp_end = it + r_term.size();
524 } else {
525 return false;
526 }
527 // Source Level
528 auto curs_b = std::find(rsp_beg, rsp_end, ':') + 2;
529 if (curs_b >= end)
530 return false;
531 auto curs_e = std::find(curs_b, rsp_end, '\n');
532 if (curs_e >= end)
533 return false;
534 int sl_ = std::stoi(std::string(curs_b, curs_e));
535 // Source Level Control
536 curs_b = curs_e + 1;
537 curs_b = std::find(curs_b, rsp_end, ':') + 2;
538 if (curs_b >= end)
539 return false;
540 curs_e = std::find(curs_b, rsp_end, '\n');
541 if (curs_e >= end)
542 return false;
543 int sl_control = std::stoi(std::string(curs_b, curs_e));
544 // Gain
545 curs_b = curs_e + 1;
546 curs_b = std::find(curs_b, rsp_end, ':') + 2;
547 if (curs_b >= end)
548 return false;
549 curs_e = std::find(curs_b, rsp_end, '\n');
550 if (curs_e >= end)
551 return false;
552 int gain = std::stoi(std::string(curs_b, curs_e));
553 // Carrier Waveform ID
554 curs_b = curs_e + 1;
555 curs_b = std::find(curs_b, rsp_end, ':') + 2;
556 if (curs_b >= end)
557 return false;
558 curs_e = std::find(curs_b, rsp_end, '\n');
559 if (curs_e >= end)
560 return false;
561 int cwID = std::stoi(std::string(curs_b, curs_e));
562 // Local Address
563 curs_b = curs_e + 1;
564 curs_b = std::find(curs_b, rsp_end, ':') + 2;
565 if (curs_b >= end)
566 return false;
567 curs_e = std::find(curs_b, rsp_end, '\n');
568 if (curs_e >= end)
569 return false;
570 int loc_addr = std::stoi(std::string(curs_b, curs_e));
571 // Highest Address
572 curs_b = curs_e + 1;
573 curs_b = std::find(curs_b, rsp_end, ':') + 2;
574 if (curs_b >= end)
575 return false;
576 curs_e = std::find(curs_b, rsp_end, '\n');
577 if (curs_e >= end)
578 return false;
579 int loc_addr_MAX = std::stoi(std::string(curs_b, curs_e));
580 // Cluster size
581 curs_b = curs_e + 1;
582 curs_b = std::find(curs_b, rsp_end, ':') + 2;
583 if (curs_b >= end)
584 return false;
585 curs_e = std::find(curs_b, rsp_end, '\n');
586 if (curs_e >= end)
587 return false;
588 int cluster_size = std::stoi(std::string(curs_b, curs_e));
589 // Packet time
590 curs_b = curs_e + 1;
591 curs_b = std::find(curs_b, rsp_end, ':') + 2;
592 if (curs_b >= end)
593 return false;
594 curs_e = std::find(curs_b, rsp_end, '\n');
595 if (curs_e >= end)
596 return false;
597 int pck_time = std::stoi(std::string(curs_b, curs_e));
598 // Retry count
599 curs_b = curs_e + 1;
600 curs_b = std::find(curs_b, rsp_end, ':') + 2;
601 if (curs_b >= end)
602 return false;
603 curs_e = std::find(curs_b, rsp_end, '\n');
604 if (curs_e >= end)
605 return false;
606 int retry_count = std::stoi(std::string(curs_b, curs_e));
607 // Retry timeout
608 curs_b = curs_e + 1;
609 curs_b = std::find(curs_b, rsp_end, ':') + 2;
610 if (curs_b >= end)
611 return false;
612 curs_e = std::find(curs_b, rsp_end, '\n');
613 if (curs_e >= end)
614 return false;
615 int retry_to = std::stoi(std::string(curs_b, curs_e));
616 // Wake up active time
617 curs_b = curs_e + 1;
618 curs_b = std::find(curs_b, rsp_end, ':') + 2;
619 if (curs_b >= end)
620 return false;
621 curs_e = std::find(curs_b, rsp_end, '\n');
622 if (curs_e >= end)
623 return false;
624 int wa_time = std::stoi(std::string(curs_b, curs_e));
625 // Wake up period
626 curs_b = curs_e + 1;
627 curs_b = std::find(curs_b, rsp_end, ':') + 2;
628 if (curs_b >= end)
629 return false;
630 curs_e = std::find(curs_b, rsp_end, '\n');
631 if (curs_e >= end)
632 return false;
633 int wa_period = std::stoi(std::string(curs_b, curs_e));
634 // Promiscsous mode
635 curs_b = curs_e + 1;
636 curs_b = std::find(curs_b, rsp_end, ':') + 2;
637 if (curs_b >= end)
638 return false;
639 curs_e = std::find(curs_b, rsp_end, '\n');
640 if (curs_e >= end)
641 return false;
642 int promiscous = std::stoi(std::string(curs_b, curs_e));
643 // Sound speed
644 curs_b = curs_e + 1;
645 curs_b = std::find(curs_b, rsp_end, ':') + 2;
646 if (curs_b >= end)
647 return false;
648 curs_e = std::find(curs_b, rsp_end, '\n');
649 if (curs_e >= end)
650 return false;
651 int sound_speed = std::stoi(std::string(curs_b, curs_e));
652 // IM retry count
653 curs_b = curs_e + 1;
654 curs_b = std::find(curs_b, rsp_end, ':') + 2;
655 if (curs_b >= end)
656 return false;
657 curs_e = std::find(curs_b, rsp_end, '\n');
658 if (curs_e >= end)
659 return false;
660 int im_retry_count = std::stoi(std::string(curs_b, curs_e));
661 // Pool sizes
662 curs_b = curs_e + 1;
663 curs_b = std::find(curs_b, rsp_end, ':') + 2;
664 if (curs_b >= end)
665 return false;
666 curs_e = std::find(curs_b, rsp_end, '\n');
667 if (curs_e >= end)
668 return false;
669 std::string pool_size = std::string(curs_b, curs_e);
670 // Hold timeout
671 curs_b = curs_e + 1;
672 curs_b = std::find(curs_b, rsp_end, ':') + 2;
673 if (curs_b >= end)
674 return false;
675 curs_e = std::find(curs_b, rsp_end, '\n');
676 if (curs_e >= end)
677 return false;
678 int hold_to = std::stoi(std::string(curs_b, curs_e));
679 // Idle timeout
680 curs_b = curs_e + 1;
681 curs_b = std::find(curs_b, rsp_end, ':') + 2;
682 if (curs_b >= end)
683 return false;
684 curs_e = std::find(curs_b, rsp_end, '\n');
685 if (curs_e >= end)
686 return false;
687 int idle_to = std::stoi(std::string(curs_b, curs_e));
688
689 return true;
690 }
691
693 auto it = search(rsp_beg, end, r_term.begin(), r_term.end());
694 if (it != end) {
695 rsp_end = it + r_term.size();
696 return true;
697 } else {
698 return false;
699 }
700 }
701
702 case Response::DELIVERED: {
703 auto it = search(rsp_beg, end, r_term.begin(), r_term.end());
704 if (it != end) {
705 rsp_end = it + r_term.size();
706 return true;
707 } else {
708 return false;
709 }
710 }
711
713 auto it = search(rsp_beg, end, r_term.begin(), r_term.end());
714 if (it != end) {
715 rsp_end = it + r_term.size();
716 return true;
717 } else {
718 return false;
719 }
720 }
721
722 case Response::FAIL: {
723 auto it = search(rsp_beg, end, r_term.begin(), r_term.end());
724 if (it != end) {
725 rsp_end = it + r_term.size();
726 return true;
727 } else {
728 return false;
729 }
730 }
731
732 case Response::DROPCNT: {
733 auto it = search(rsp_beg, end, r_term.begin(), r_term.end());
734 if (it != end) {
735 rsp_end = it + r_term.size();
736 return true;
737 } else {
738 return false;
739 }
740 }
741
742 case Response::UNKNOWN: {
743 auto it = search(rsp_beg, end, r_term.begin(), r_term.end());
744 if (it != end) {
745 rsp_end = it + r_term.size();
746 return true;
747 } else {
748 return false;
749 }
750 }
751
753 auto it = search(rsp_beg, end, r_term.begin(), r_term.end());
754 if (it != end) {
755 rsp_end = it + r_term.size();
756 return true;
757 } else {
758 return false;
759 }
760 }
761
762 case Response::RECVSTART: {
763 auto it = search(rsp_beg, end, r_term.begin(), r_term.end());
764 if (it != end) {
765 rsp_end = it + r_term.size();
766 return true;
767 } else {
768 return false;
769 }
770 }
771
772 case Response::RECVEND: {
773 auto it = search(rsp_beg, end, r_term.begin(), r_term.end());
774 if (it != end) {
775 rsp_end = it + r_term.size();
776 return true;
777 } else {
778 return false;
779 }
780 }
781
782 case Response::RECVFAIL: {
783 auto it = search(rsp_beg, end, r_term.begin(), r_term.end());
784 if (it != end) {
785 rsp_end = it + r_term.size();
786 return true;
787 } else {
788 return false;
789 }
790 }
791
792 case Response::SENDSTART: {
793 auto it = search(rsp_beg, end, r_term.begin(), r_term.end());
794 if (it != end) {
795 rsp_end = it + r_term.size();
796 return true;
797 } else {
798 return false;
799 }
800 }
801
802 case Response::SENDEND: {
803 auto it = search(rsp_beg, end, r_term.begin(), r_term.end());
804 if (it != end) {
805 rsp_end = it + r_term.size();
806 return true;
807 } else {
808 return false;
809 }
810 }
811
812 case Response::BITRATE: {
813 auto it = search(rsp_beg, end, r_term.begin(), r_term.end());
814 if (it != end) {
815 rsp_end = it + r_term.size();
816 return true;
817 } else {
818 return false;
819 }
820 }
821
823 auto it = search(rsp_beg, end, r_term.begin(), r_term.end());
824 if (it != end) {
825 rsp_end = it + r_term.size();
826 } else {
827 return false;
828 }
829 // Local Address
830 auto curs_b = std::find(rsp_beg, rsp_end, ':') + 2;
831 if (curs_b >= end)
832 return false;
833 auto curs_e = std::find(curs_b, rsp_end, '\n');
834 if (curs_e >= end)
835 return false;
836 int loc_addr = std::stoi(std::string(curs_b, curs_e));
837 // Remote address
838 curs_b = curs_e + 1;
839 curs_b = std::find(curs_b, rsp_end, ':') + 2;
840 if (curs_b > end)
841 return false;
842 curs_e = std::find(curs_b, rsp_end, '\n');
843 if (curs_e > end)
844 return false;
845 int rem_addr = std::stoi(std::string(curs_b, curs_e));
846 // ACoustic Link Status
847 curs_b = curs_e + 1;
848 curs_b = std::find(curs_b, rsp_end, ':') + 2;
849 if (curs_b > end)
850 return false;
851 curs_e = std::find(curs_b, rsp_end, '\n');
852 if (curs_e > end)
853 return false;
854 std::string ac_status = std::string(curs_b, curs_e);
855 // Pool Status: packages and bytes free
856 curs_b = curs_e + 1;
857 curs_b = std::find(curs_b, rsp_end, ':') + 2;
858 if (curs_b > end)
859 return false;
860 curs_e = std::find(curs_b, rsp_end, ' ');
861 int n_pck = std::stoi(std::string(curs_b, curs_e));
862
863 curs_b = curs_e + 1;
864 curs_b = std::find(curs_b, rsp_end, ':') + 2;
865 if (curs_b > end)
866 return false;
867 curs_e = std::find(curs_b, rsp_end, ' ');
868 int bytes_free = std::stoi(std::string(curs_b, curs_e));
869 // Whether promiscous mode is ON or OFF
870 curs_b = curs_e + 1;
871 curs_b = std::find(curs_b, rsp_end, ':') + 2;
872 if (curs_b > end)
873 return false;
874 curs_e = std::find(curs_b, rsp_end, '\n');
875 bool is_promiscous = (std::string(curs_b, curs_e) == "ON");
876
877 return true;
878 }
879
881
882 std::stringstream ss;
883 auto it = std::search(rsp_beg, end, r_term.begin(), r_term.end());
884 if (it != end) {
885 rsp_end = it + r_term.size();
886 } else {
887 return false;
888 }
889
890 auto curs_b = std::find(rsp_beg, rsp_end, ',') + 1;
891 if (curs_b >= end) {
892 return false;
893 }
894 auto curs_e = std::find(curs_b, rsp_end, ',');
895 if (curs_e >= end) {
896 return false;
897 }
898 // Current time
899 std::string c_time = std::string(curs_b, curs_e);
900 // measurement time
901 curs_b = curs_e + 1;
902 if (curs_b >= end) {
903 return false;
904 }
905 curs_e = std::find(curs_b, rsp_end, ',');
906 if (curs_e >= end) {
907 return false;
908 }
909 std::string m_time = std::string(curs_b, curs_e);
910 // remote address
911 curs_b = curs_e + 1;
912 if (curs_b >= end) {
913 return false;
914 }
915 curs_e = std::find(curs_b, rsp_end, ',');
916 if (curs_e >= end) {
917 return false;
918 }
919 int r_addr = stoi(std::string(curs_b, curs_e));
920 // LBearing
921 curs_b = curs_e + 1;
922 if (curs_b >= end) {
923 return false;
924 }
925 curs_e = std::find(curs_b, rsp_end, ',');
926 if (curs_e >= end) {
927 return false;
928 }
929 std::string l_bearing_s = std::string(curs_b, curs_e);
930 double lbearing;
931 ss << l_bearing_s;
932 ss >> lbearing;
933 ss.clear();
934 // LBearing
935 curs_b = curs_e + 1;
936 if (curs_b >= end) {
937 return false;
938 }
939 curs_e = std::find(curs_b, rsp_end, ',');
940 if (curs_e >= end) {
941 return false;
942 }
943 std::string l_elevation_s = std::string(curs_b, curs_e);
944 double lelevation;
945 ss << l_elevation_s;
946 ss >> lelevation;
947 ss.clear();
948 // Bearing
949 curs_b = curs_e + 1;
950 if (curs_b >= end) {
951 return false;
952 }
953 curs_e = std::find(curs_b, rsp_end, ',');
954 if (curs_e >= end) {
955 return false;
956 }
957 std::string bearing_s = std::string(curs_b, curs_e);
958 double bearing;
959 ss << bearing_s;
960 ss >> bearing;
961 ss.clear();
962 // Elevation
963 curs_b = curs_e + 1;
964 if (curs_b >= end) {
965 return false;
966 }
967 curs_e = std::find(curs_b, rsp_end, ',');
968 if (curs_e >= end) {
969 return false;
970 }
971 std::string elevation_s = std::string(curs_b, curs_e);
972 double elevation;
973 ss << elevation_s;
974 ss >> elevation;
975 ss.clear();
976 // Roll
977 curs_b = curs_e + 1;
978 if (curs_b >= end) {
979 return false;
980 }
981 curs_e = std::find(curs_b, rsp_end, ',');
982 if (curs_e >= end) {
983 return false;
984 }
985 std::string roll_s = std::string(curs_b, curs_e);
986 double roll;
987 ss << roll_s;
988 ss >> roll;
989 ss.clear();
990 // Pitch
991 curs_b = curs_e + 1;
992 if (curs_b >= end) {
993 return false;
994 }
995 curs_e = std::find(curs_b, rsp_end, ',');
996 if (curs_e >= end) {
997 return false;
998 }
999 std::string pitch_s = std::string(curs_b, curs_e);
1000 double pitch;
1001 ss << pitch_s;
1002 ss >> pitch;
1003 ss.clear();
1004 // Yaw
1005 curs_b = curs_e + 1;
1006 if (curs_b >= end) {
1007 return false;
1008 }
1009 curs_e = std::find(curs_b, rsp_end, ',');
1010 if (curs_e >= end) {
1011 return false;
1012 }
1013 std::string yaw_s = std::string(curs_b, curs_e);
1014 double yaw;
1015 ss << yaw_s;
1016 ss >> yaw;
1017 ss.clear();
1018 // RSSI
1019 curs_b = curs_e + 1;
1020 if (curs_b >= end) {
1021 return false;
1022 }
1023 curs_e = std::find(curs_b, rsp_end, ',');
1024 if (curs_e >= end) {
1025 return false;
1026 }
1027 int rssi = stoi(std::string(curs_b, curs_e));
1028 // Integrity
1029 curs_b = curs_e + 1;
1030 if (curs_b >= end) {
1031 return false;
1032 }
1033 curs_e = std::find(curs_b, rsp_end, ',');
1034 if (curs_e >= end) {
1035 return false;
1036 }
1037 int integrity = stoi(std::string(curs_b, curs_e));
1038 // Accuracy
1039 curs_b = curs_e + 1;
1040 if (curs_b >= end) {
1041 return false;
1042 }
1043 curs_e = std::find(curs_b, rsp_end, '\n');
1044 if (curs_e >= end) {
1045 return false;
1046 }
1047 std::string accuracy_s = std::string(curs_b, curs_e);
1048 double accuracy;
1049 ss << accuracy_s;
1050 ss >> accuracy;
1051 ss.clear();
1052
1053 return true;
1054 }
1055 case Response::USBLLONG: {
1056
1057 std::stringstream ss;
1058 auto it = std::search(rsp_beg, end, r_term.begin(), r_term.end());
1059 if (it != end) {
1060 rsp_end = it + r_term.size();
1061 } else {
1062 return false;
1063 }
1064
1065 auto curs_b = std::find(rsp_beg, rsp_end, ',') + 1;
1066 if (curs_b >= end) {
1067 return false;
1068 }
1069 auto curs_e = std::find(curs_b, rsp_end, ',');
1070 if (curs_e >= end) {
1071 return false;
1072 }
1073 // Current time
1074 std::string c_time_s = std::string(curs_b, curs_e);
1075 double c_time;
1076 ss << c_time_s;
1077 ss >> c_time;
1078 ss.clear();
1079 // measurement time
1080 curs_b = curs_e + 1;
1081 if (curs_b >= end) {
1082 return false;
1083 }
1084 curs_e = std::find(curs_b, rsp_end, ',');
1085 if (curs_e >= end) {
1086 return false;
1087 }
1088 std::string m_time_s = std::string(curs_b, curs_e);
1089 double m_time;
1090 ss << m_time_s;
1091 ss >> m_time;
1092 ss.clear();
1093 // remote address
1094 curs_b = curs_e + 1;
1095 if (curs_b >= end) {
1096 return false;
1097 }
1098 curs_e = std::find(curs_b, rsp_end, ',');
1099 if (curs_e >= end) {
1100 return false;
1101 }
1102 int r_addr = stoi(std::string(curs_b, curs_e));
1103 // X
1104 curs_b = curs_e + 1;
1105 if (curs_b >= end) {
1106 return false;
1107 }
1108 curs_e = std::find(curs_b, rsp_end, ',');
1109 if (curs_e >= end) {
1110 return false;
1111 }
1112 std::string X_s = std::string(curs_b, curs_e);
1113 double X;
1114 ss << X_s;
1115 ss >> X;
1116 ss.clear();
1117 // Y
1118 curs_b = curs_e + 1;
1119 if (curs_b >= end) {
1120 return false;
1121 }
1122 curs_e = std::find(curs_b, rsp_end, ',');
1123 if (curs_e >= end) {
1124 return false;
1125 }
1126 std::string Y_s = std::string(curs_b, curs_e);
1127 double Y;
1128 ss << Y_s;
1129 ss >> Y;
1130 ss.clear();
1131 // Z
1132 curs_b = curs_e + 1;
1133 if (curs_b >= end) {
1134 return false;
1135 }
1136 curs_e = std::find(curs_b, rsp_end, ',');
1137 if (curs_e >= end) {
1138 return false;
1139 }
1140 std::string Z_s = std::string(curs_b, curs_e);
1141 double Z;
1142 ss << Z_s;
1143 ss >> Z;
1144 ss.clear();
1145 // E
1146 curs_b = curs_e + 1;
1147 if (curs_b >= end) {
1148 return false;
1149 }
1150 curs_e = std::find(curs_b, rsp_end, ',');
1151 if (curs_e >= end) {
1152 return false;
1153 }
1154 std::string E_s = std::string(curs_b, curs_e);
1155 double E;
1156 ss << E_s;
1157 ss >> E;
1158 ss.clear();
1159 // N
1160 curs_b = curs_e + 1;
1161 if (curs_b >= end) {
1162 return false;
1163 }
1164 curs_e = std::find(curs_b, rsp_end, ',');
1165 if (curs_e >= end) {
1166 return false;
1167 }
1168 std::string N_s = std::string(curs_b, curs_e);
1169 double N;
1170 ss << N_s;
1171 ss >> N;
1172 ss.clear();
1173 // U
1174 curs_b = curs_e + 1;
1175 if (curs_b >= end) {
1176 return false;
1177 }
1178 curs_e = std::find(curs_b, rsp_end, ',');
1179 if (curs_e >= end) {
1180 return false;
1181 }
1182 std::string U_s = std::string(curs_b, curs_e);
1183 double U;
1184 ss << U_s;
1185 ss >> U;
1186 ss.clear();
1187 // Roll
1188 curs_b = curs_e + 1;
1189 if (curs_b >= end) {
1190 return false;
1191 }
1192 curs_e = std::find(curs_b, rsp_end, ',');
1193 if (curs_e >= end) {
1194 return false;
1195 }
1196 std::string roll_s = std::string(curs_b, curs_e);
1197 double roll;
1198 ss << roll_s;
1199 ss >> roll;
1200 ss.clear();
1201 // Roll
1202 curs_b = curs_e + 1;
1203 if (curs_b >= end) {
1204 return false;
1205 }
1206 curs_e = std::find(curs_b, rsp_end, ',');
1207 if (curs_e >= end) {
1208 return false;
1209 }
1210 std::string pitch_s = std::string(curs_b, curs_e);
1211 double pitch;
1212 ss << pitch_s;
1213 ss >> pitch;
1214 ss.clear();
1215 // Yaw
1216 curs_b = curs_e + 1;
1217 if (curs_b >= end) {
1218 return false;
1219 }
1220 curs_e = std::find(curs_b, rsp_end, ',');
1221 if (curs_e >= end) {
1222 return false;
1223 }
1224 std::string yaw_s = std::string(curs_b, curs_e);
1225 double yaw;
1226 ss << yaw_s;
1227 ss >> yaw;
1228 ss.clear();
1229 // Propagation time
1230 curs_b = curs_e + 1;
1231 if (curs_b >= end) {
1232 return false;
1233 }
1234 curs_e = std::find(curs_b, rsp_end, ',');
1235 if (curs_e >= end) {
1236 return false;
1237 }
1238 std::string prop_s = std::string(curs_b, curs_e);
1239 double propagation;
1240 ss << prop_s;
1241 ss >> propagation;
1242 ss.clear();
1243 // RSSI
1244 curs_b = curs_e + 1;
1245 if (curs_b >= end) {
1246 return false;
1247 }
1248 curs_e = std::find(curs_b, rsp_end, ',');
1249 if (curs_e >= end) {
1250 return false;
1251 }
1252 int rssi = stoi(std::string(curs_b, curs_e));
1253 // Integrity
1254 curs_b = curs_e + 1;
1255 if (curs_b >= end) {
1256 return false;
1257 }
1258 curs_e = std::find(curs_b, rsp_end, ',');
1259 if (curs_e >= end) {
1260 return false;
1261 }
1262 int integrity = stoi(std::string(curs_b, curs_e));
1263 // Accuracy
1264 curs_b = curs_e + 1;
1265 if (curs_b >= end) {
1266 return false;
1267 }
1268 curs_e = std::find(curs_b, rsp_end, '\n');
1269 if (curs_e >= end) {
1270 return false;
1271 }
1272 std::string accuracy_s = std::string(curs_b, curs_e);
1273 double accuracy;
1274 ss << accuracy_s;
1275 ss >> accuracy;
1276 ss.clear();
1277
1278 usbl_info->curr_time = c_time;
1279 usbl_info->meas_time = m_time;
1280 usbl_info->r_address = r_addr;
1281 usbl_info->X = X;
1282 usbl_info->Y = Y;
1283 usbl_info->Z = Z;
1284 usbl_info->E = E;
1285 usbl_info->N = N;
1286 usbl_info->U = U;
1287 usbl_info->accuracy = accuracy;
1288
1289 return true;
1290
1291 }
1292
1293 default:
1294 return false;
1295
1296 } // end of switch on commands
1297}
1298
1299void
1301{
1302 ext_proto_mode = enabled;
1303}
1304
1305std::shared_ptr<USBLInfo>
1307{
1308 return usbl_info;
1309}
virtual ~UwInterpreterS2C()
Class destructor.
static std::vector< std::pair< std::string, UwInterpreterS2C::Response > > syntax_pool
Vector holding all possible commands for the S2C syntax and corresponding identifying token.
std::string buildATDI()
Method that builds the command to check the IM delivery status.
bool ext_proto_mode
Flag telling if Extened Protol Mode is in use.
std::shared_ptr< USBLInfo > getUSBLInfo()
Method to retrieve the USBL information saved upon reception of a USBL message.
std::string buildATV()
Method that builds the command to ask for current settings: it enlists source level,...
UwInterpreterS2C()
Class constructor.
Response
Enum listing the types of commands that could be received or sent by a S2C device; See the EvoLogics ...
std::string buildSetATAL(int addr)
Method that builds the command to set the local address of the device.
std::string buildATZ(int level)
Method that builds a reboot sequence: depending on the provided index different levels of reset can b...
std::string buildGetATL()
Method that builds the command to get the source level of the device.
std::string w_term
Terminating sequence for commands wrtten to device.
UwInterpreterS2C::Response findResponse(std::vector< char >::iterator beg, std::vector< char >::iterator end, std::vector< char >::iterator &rsp)
Method to look for S2C response inside a provided chunk of unparsed data This method only finds the b...
bool parseResponse(UwInterpreterS2C::Response rsp, std::vector< char >::iterator end, std::vector< char >::iterator rsp_beg, std::vector< char >::iterator &rsp_end, std::string &rx_payload)
Method that tries to parse a found response: if the response section of the buffer,...
std::string sep
Separator for paramters fo the commands: a comma.
void setExtProtoMode(bool enabled)
Method that sets whether Extended Protocol Mode is used or not.
std::string r_term
Terminating sequence for commands read from device.
std::string buildSendIM(std::string msg, int dest, bool ack)
Method that builds the command to send data through SENDIM command SENDIM is used to send Instant Mes...
std::shared_ptr< USBLInfo > usbl_info
Strucure holding info retrived via USBL message.
std::string buildATS()
Method that builds the command to ask for modem status: it enlists local address, acoustic link statu...
std::string buildSetATL(int level)
Method that builds the command to set the source level of the device.
std::string buildSend(std::string msg, int dest)
Method that builds the command to send data through SEND command SEND is used to send burst data: pay...
std::string buildGetATAL()
Method that builds the command to set the local address of the device.
Header of the interepreter class: this class is used ot translate form DESERT software to/from EvoLog...
const std::string sep