mirror of https://github.com/sebmillet/RF433any
105 lines
3.1 KiB
C++
105 lines
3.1 KiB
C++
// Serial.cpp
|
|
|
|
/*
|
|
Provides a way to read lines on serial
|
|
*/
|
|
|
|
/*
|
|
Copyright 2021 Sébastien Millet
|
|
|
|
`rf433any' is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU Lesser General Public License as
|
|
published by the Free Software Foundation, either version 3 of the
|
|
License, or (at your option) any later version.
|
|
|
|
`rf433any' 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 Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this program. If not, see
|
|
<https://www.gnu.org/licenses>.
|
|
*/
|
|
|
|
#include "RF433Serial.h"
|
|
#include <Arduino.h>
|
|
|
|
RF433SerialLine::RF433SerialLine():head(0),got_a_line(false) { };
|
|
|
|
void RF433SerialLine::do_events() {
|
|
if (got_a_line)
|
|
return;
|
|
if (!Serial.available())
|
|
return;
|
|
|
|
int b;
|
|
do {
|
|
b = Serial.read();
|
|
if (b == -1)
|
|
break;
|
|
buf[head++] = (char)b;
|
|
} while (head < RF433SERIAL_LINE_BUF_LEN - 1
|
|
&& b != '\n' && Serial.available());
|
|
|
|
if (head < RF433SERIAL_LINE_BUF_LEN - 1 && b != '\n')
|
|
return;
|
|
|
|
buf[head] = '\0';
|
|
|
|
// Remove trailing cr and/or nl
|
|
// FIXME?
|
|
// WON'T WORK WITH MAC-OS NEWLINES!
|
|
// (SEE ABOVE: NO STOP IF ONLY CR ENCOUNTERED)
|
|
if (head >= 1 && buf[head - 1] == '\n')
|
|
buf[--head] = '\0';
|
|
if (head >= 1 && buf[head - 1] == '\r')
|
|
buf[--head] = '\0';
|
|
got_a_line = true;
|
|
}
|
|
|
|
bool RF433SerialLine::is_line_available() {
|
|
do_events();
|
|
return got_a_line;
|
|
}
|
|
|
|
void RF433SerialLine::reset() {
|
|
head = 0;
|
|
got_a_line = false;
|
|
}
|
|
|
|
// Get USB input as a simple line, copied in caller buffer.
|
|
// A 'line' is a set of non-null characters followed by 'new line', 'new line'
|
|
// being either as per Unix or Windows convention, see below.
|
|
// Returns true if a copy was done (there was a line available), false if not
|
|
// (in which case, s is not updated).
|
|
// The terminating newline character (or 2-character CR-LF sequence) is NOT part
|
|
// of the string given to the caller.
|
|
// If the line length is above the buffer size (RF433SERIAL_LINE_BUF_LEN), then
|
|
// it'll be cut into smaller pieces.
|
|
// Because of the way the received buffer is parsed, and when using CR-LF as
|
|
// end-of-line marker (default even under Linux), it can result in a empty
|
|
// string seen after a first string with a length close to the limit.
|
|
//
|
|
// About new lines:
|
|
// - Works fine with Unix new lines (\n), tested
|
|
// - Supposed to work fine with Windows new lines (\r\n), NOT TESTED
|
|
// - WON'T WORK WITH MAC-OS NEW LINES (\r)
|
|
bool RF433SerialLine::get_line(char *s, size_t len) {
|
|
do_events();
|
|
if (!got_a_line)
|
|
return false;
|
|
snprintf(s, len, buf);
|
|
reset();
|
|
return true;
|
|
}
|
|
|
|
// Same as get_line, but with blocking I/O =
|
|
// Wait without time limit, until a line comes in.
|
|
void RF433SerialLine::get_line_blocking(char *s, size_t len) {
|
|
while (!get_line(s, len))
|
|
;
|
|
}
|
|
|
|
// vim: ts=4:sw=4:tw=80:et
|