94 :
public goby::middleware::io::detail::SerialThread<line_in_group, line_out_group,
95 publish_layer, subscribe_layer, ThreadType,
99 goby::middleware::io::detail::SerialThread<line_in_group, line_out_group, publish_layer,
100 subscribe_layer, ThreadType, use_indexed_groups>;
104 : Base(config, index)
111 void async_read()
override
113 buffer_write_ptr_ = buffer_.data();
117 void read_first_byte()
119 boost::asio::async_read(
120 this->mutable_serial_port(),
121 boost::asio::buffer(buffer_write_ptr_,
122 buffer_.size() - (buffer_write_ptr_ - buffer_.data())),
123 boost::asio::transfer_exactly(1),
124 [
this](
const boost::system::error_code& ec, std::size_t bytes_transferred) {
125 if (!ec && bytes_transferred > 0)
127 if (buffer_[0] != SERIAL_MAGIC[0])
129 goby::glog.is_warn() &&
130 goby::glog <<
"Invalid first byte, expected: " << SERIAL_MAGIC[0]
131 <<
", received: " << buffer_[0] << std::endl;
136 buffer_write_ptr_ += bytes_transferred;
142 this->handle_read_error(ec);
149 boost::asio::async_read(
150 this->mutable_serial_port(),
151 boost::asio::buffer(buffer_write_ptr_,
152 buffer_.size() - (buffer_write_ptr_ - buffer_.data())),
154 [
this](
const boost::system::error_code& ec, std::size_t bytes_transferred) {
155 if (!ec && bytes_transferred > 0)
157 if (memcmp(buffer_.data(), SERIAL_MAGIC, SERIAL_MAGIC_BYTES) != 0)
159 goby::glog.is_warn() &&
161 <<
"Invalid magic word, expected: " << SERIAL_MAGIC
163 << std::string(buffer_.data(), buffer_.data() + SERIAL_MAGIC_BYTES)
169 buffer_write_ptr_ += bytes_transferred;
175 this->handle_read_error(ec);
182 boost::asio::async_read(
183 this->mutable_serial_port(),
184 boost::asio::buffer(buffer_write_ptr_,
185 buffer_.size() - (buffer_write_ptr_ - buffer_.data())),
186 boost::asio::transfer_exactly(SIZE_BYTES),
187 [
this](
const boost::system::error_code& ec, std::size_t bytes_transferred) {
188 if (!ec && bytes_transferred > 0)
191 message_size_ |= buffer_[SERIAL_MAGIC_BYTES];
192 message_size_ <<= BITS_IN_BYTE;
193 message_size_ |= buffer_[SERIAL_MAGIC_BYTES + 1];
194 if (message_size_ > SERIAL_MAX_SIZE)
196 goby::glog.is_warn() &&
198 <<
"Reported message size is larger than SERIAL_MAX_SIZE. Reported:"
199 << message_size_ <<
", expected max: " << SERIAL_MAX_SIZE
206 buffer_write_ptr_ += bytes_transferred;
212 this->handle_read_error(ec);
219 boost::asio::async_read(
220 this->mutable_serial_port(),
221 boost::asio::buffer(buffer_write_ptr_,
222 buffer_.size() - (buffer_write_ptr_ - buffer_.data())),
223 boost::asio::transfer_exactly(CRC_SIZE),
224 [
this](
const boost::system::error_code& ec, std::size_t bytes_transferred) {
225 if (!ec && bytes_transferred > 0)
228 char* ptr = reinterpret_cast<char*>(&crc32_);
231 for (int i = 0; i < 4; i++) { ptr[3 - i] = buffer_write_ptr_[i]; }
233 buffer_write_ptr_ += bytes_transferred;
238 this->handle_read_error(ec);
245 boost::asio::async_read(
246 this->mutable_serial_port(),
247 boost::asio::buffer(buffer_write_ptr_,
248 buffer_.size() - (buffer_write_ptr_ - buffer_.data())),
249 boost::asio::transfer_exactly(message_size_),
250 [
this](
const boost::system::error_code& ec, std::size_t bytes_transferred) {
251 if (!ec && bytes_transferred > 0)
253 auto actual_crc32 = calculate_crc32(buffer_write_ptr_, bytes_transferred);
255 if (crc32_ != actual_crc32)
257 goby::glog.is_warn() &&
258 goby::glog <<
"message_size_: " << message_size_
259 <<
", bytes_transferred: " << bytes_transferred
260 <<
", expected crc32: " << crc32_
261 <<
", actual_crc32: " << actual_crc32 << std::endl;
263 goby::glog.is_warn() && goby::glog <<
"CRC32 failure. Expected: " << crc32_
264 <<
", actual: " << actual_crc32
270 buffer_write_ptr_ += bytes_transferred;
272 auto io_msg = std::make_shared<goby::middleware::protobuf::IOData>();
273 io_msg->set_data(std::string(buffer_.data(), buffer_write_ptr_));
274 this->handle_read_success(buffer_write_ptr_ - buffer_.data(), io_msg);
279 this->handle_read_error(ec);
285 std::array<char, SERIAL_MAX_SIZE> buffer_;
286 char* buffer_write_ptr_{buffer_.data()};
287 std::uint16_t message_size_{0};
288 std::uint32_t crc32_{0};