From e7b49e404fb7383ff0c0a026ceb792f05ef049b8 Mon Sep 17 00:00:00 2001 From: Supun Randeni Date: Wed, 25 Jun 2025 21:48:04 -0400 Subject: [PATCH 1/8] Checking interface before checking active status. This fixes fault during popoto_driver startup in Ethernet mode --- src/acomms/modemdriver/driver_base.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/acomms/modemdriver/driver_base.cpp b/src/acomms/modemdriver/driver_base.cpp index cb8922fe..f93d6ad5 100644 --- a/src/acomms/modemdriver/driver_base.cpp +++ b/src/acomms/modemdriver/driver_base.cpp @@ -64,7 +64,7 @@ goby::acomms::ModemDriverBase::~ModemDriverBase() { modem_close(); } void goby::acomms::ModemDriverBase::modem_write(const std::string& out) { - if (modem_->active()) + if (modem_ && modem_->active()) modem_->write(out); else throw(ModemDriverException("Modem physical connection failed.", From 0642bf0aee5b235e8c2937c33be214bd36f65693 Mon Sep 17 00:00:00 2001 From: Supun Randeni Date: Sat, 5 Jul 2025 18:59:11 -0400 Subject: [PATCH 2/8] Cannot send serial commands before starting the modem driver. Causes a segfault. --- src/acomms/modemdriver/popoto_driver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/acomms/modemdriver/popoto_driver.cpp b/src/acomms/modemdriver/popoto_driver.cpp index 591634f0..5a318062 100644 --- a/src/acomms/modemdriver/popoto_driver.cpp +++ b/src/acomms/modemdriver/popoto_driver.cpp @@ -97,7 +97,7 @@ void goby::acomms::PopotoDriver::startup(const protobuf::DriverConfig& cfg) std::string port = popoto_driver_cfg().local().port(); // Need to issue the disconnect command to stop pshell - signal_and_write("disconnect\n"); + // signal_and_write("disconnect\n"); myConnection = ETHERNET_CONNECTION; // Initialize with the IP, port and PCM callback routine. From 985e5ec433ddbba38d541c0adf2cc881c64e04e3 Mon Sep 17 00:00:00 2001 From: Supun Randeni Date: Sat, 5 Jul 2025 19:00:57 -0400 Subject: [PATCH 3/8] Fixing the config error in TCP mode --- src/acomms/modemdriver/popoto_driver.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/acomms/modemdriver/popoto_driver.cpp b/src/acomms/modemdriver/popoto_driver.cpp index 5a318062..63e71fd0 100644 --- a/src/acomms/modemdriver/popoto_driver.cpp +++ b/src/acomms/modemdriver/popoto_driver.cpp @@ -91,17 +91,17 @@ void goby::acomms::PopotoDriver::startup(const protobuf::DriverConfig& cfg) } else if (driver_cfg_.connection_type() == goby::acomms::protobuf::DriverConfig::CONNECTION_TCP_AS_CLIENT) { - if (popoto_driver_cfg().local().has_ip() && popoto_driver_cfg().local().has_port()) + if (cfg.has_tcp_server() && cfg.has_tcp_port()) { - std::string ip = popoto_driver_cfg().local().ip(); - std::string port = popoto_driver_cfg().local().port(); - + std::string ip = cfg.tcp_server(); + // std::string port = popoto_driver_cfg().local().port(); + // Need to issue the disconnect command to stop pshell // signal_and_write("disconnect\n"); myConnection = ETHERNET_CONNECTION; // Initialize with the IP, port and PCM callback routine. - popoto0 = new popoto_client(ip, stoi(port), Popoto0PCMHandler); + popoto0 = new popoto_client(ip, cfg.tcp_port(), Popoto0PCMHandler); } } else From 9453474ddebf3e1873df7da60af07747483dbc0c Mon Sep 17 00:00:00 2001 From: Supun Randeni Date: Sat, 5 Jul 2025 19:05:44 -0400 Subject: [PATCH 4/8] Fixing truncated payload issue --- src/acomms/modemdriver/popoto_driver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/acomms/modemdriver/popoto_driver.cpp b/src/acomms/modemdriver/popoto_driver.cpp index 63e71fd0..c824a3b6 100644 --- a/src/acomms/modemdriver/popoto_driver.cpp +++ b/src/acomms/modemdriver/popoto_driver.cpp @@ -610,7 +610,7 @@ void goby::acomms::PopotoDriver::ProcessJSON(const std::string& message, std::string data = json_to_binary(j["Data"]); DecodeGobyHeader(data[0],data[1], modem_msg); if (modem_msg.type() == protobuf::ModemTransmission::DATA) - *modem_msg.add_frame() = data.substr(2); + *modem_msg.add_frame() = data.substr(1); // Header is 1 byte, correct? So this should be substr(1) not substr(2). -Supun- else if (modem_msg.type() == protobuf::ModemTransmission::ACK){ modem_msg.add_acked_frame(data[1]); } From 87b2b9dfd1bd7699b7fe92aa039a93c45767f564 Mon Sep 17 00:00:00 2001 From: Supun Randeni Date: Sat, 5 Jul 2025 19:09:46 -0400 Subject: [PATCH 5/8] Fixing the custom ack/no-ack header --- src/acomms/modemdriver/popoto_driver.cpp | 47 +++++++++++++++++++----- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/src/acomms/modemdriver/popoto_driver.cpp b/src/acomms/modemdriver/popoto_driver.cpp index c824a3b6..a442f94f 100644 --- a/src/acomms/modemdriver/popoto_driver.cpp +++ b/src/acomms/modemdriver/popoto_driver.cpp @@ -673,9 +673,18 @@ std::uint8_t goby::acomms::PopotoDriver::CreateGobyHeader(const protobuf::ModemT if (m.type() == protobuf::ModemTransmission::DATA){ header |= ( GOBY_DATA_TYPE & 0b11 ) << 6; header |= ( m.frame_start() & 0b00111111 ); + + // See if ack is requested, and encode it to the header. + // This part was missing; thus, DecodeGobyHeader() was misbehaving.. -Supun- + header &= ~(1 << GOBY_HEADER_ACK_REQUEST); // Clear bit 1 to set header to no-ack-request + if (m.ack_requested()){ + header |= (1 << GOBY_HEADER_ACK_REQUEST); // Set bit 1 is ack is requested + } + } else if (m.type() == protobuf::ModemTransmission::ACK){ header |= ( GOBY_ACK_TYPE & 0b11 ) << 6; header |= ( m.frame_start() & 0b00111111 ); + header &= ~(1 << GOBY_HEADER_ACK_REQUEST); // Clear bit 1 to set header to no-ack-request } else { throw(goby::Exception(std::string("Unsupported type provided to CreateGobyHeader: ") + protobuf::ModemTransmission::TransmissionType_Name(m.type()))); @@ -706,14 +715,34 @@ std::uint8_t goby::acomms::PopotoDriver::CreateGobyHeader(const protobuf::ModemT } void goby::acomms::PopotoDriver::DecodeGobyHeader(std::uint8_t header, std::uint8_t ack_num,protobuf::ModemTransmission& m){ - m.set_type(( header & (1 << GOBY_HEADER_TYPE)) ? protobuf::ModemTransmission::ACK - : protobuf::ModemTransmission::DATA); - if (m.type() == protobuf::ModemTransmission::DATA){ - m.set_ack_requested( header & (1 << GOBY_HEADER_ACK_REQUEST)); - m.set_frame_start( ack_num ); - } - else if (m.type() == protobuf::ModemTransmission::ACK){ - m.set_frame_start(ack_num); - m.add_acked_frame( ack_num ); + // m.set_type(( header & (1 << GOBY_HEADER_TYPE)) ? protobuf::ModemTransmission::ACK + // : protobuf::ModemTransmission::DATA); + // if (m.type() == protobuf::ModemTransmission::DATA){ + // m.set_ack_requested( header & (1 << GOBY_HEADER_ACK_REQUEST)); + // m.set_frame_start( ack_num ); + // } + // else if (m.type() == protobuf::ModemTransmission::ACK){ + // m.set_frame_start(ack_num); + // m.add_acked_frame( ack_num ); + // } + + // ----- + // The above block of code doesn't seem to work. I simplified it below, + // and hopefully it serves the same purpose. -Supun- + + uint8_t goby_header_type = (header >> 6) & 0b11; + switch (goby_header_type) + { + case GOBY_DATA_TYPE: + m.set_type(protobuf::ModemTransmission::DATA); + m.set_ack_requested( header & (1 << GOBY_HEADER_ACK_REQUEST)); + m.set_frame_start( ack_num ); + break; + case GOBY_ACK_TYPE: + m.set_type(protobuf::ModemTransmission::ACK); + m.set_frame_start(ack_num); + m.add_acked_frame( ack_num ); + break; } + // ----- } From 97606762aa778ce1861dbb83f2854bf446ef1bff Mon Sep 17 00:00:00 2001 From: Supun Randeni Date: Sat, 5 Jul 2025 19:12:02 -0400 Subject: [PATCH 6/8] This doesn't handle goby ack properly. I think it is because this doesn't point to the correct acked frame. --- src/acomms/modemdriver/popoto_driver.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/acomms/modemdriver/popoto_driver.cpp b/src/acomms/modemdriver/popoto_driver.cpp index a442f94f..7718b751 100644 --- a/src/acomms/modemdriver/popoto_driver.cpp +++ b/src/acomms/modemdriver/popoto_driver.cpp @@ -343,6 +343,10 @@ void goby::acomms::PopotoDriver::send(protobuf::ModemTransmission& msg) { // use empty data packet to indicate ACK // TODO - get Popoto to provide ACK packet type in header + + // I think goby needs to know which frame is this ack associated with (acked_frame). + // Right now, you set 'frame_start' of the ack packet to 'acked_frame'. I don't think + // this works. -Supun- } else { @@ -422,7 +426,11 @@ void goby::acomms::PopotoDriver::do_work() ack.set_type(goby::acomms::protobuf::ModemTransmission::ACK); for (int i = modem_msg_.frame_start(), n = modem_msg_.frame_size() + modem_msg_.frame_start(); i < n; ++i){ ack.set_frame_start(i); - } + } + // I'm not sure what's happening in the above for loop.. + // Isn't this as same as: + // ack.set_frame_start(modem_msg_.frame_size() + modem_msg_.frame_start()-1) + // Or am I missing something here? -Supun- send(ack); // reply with the ack msg } From 1c77bb855e77e36d6aa45ca385258c7590a99c25 Mon Sep 17 00:00:00 2001 From: Supun Randeni Date: Sat, 5 Jul 2025 19:18:15 -0400 Subject: [PATCH 7/8] signal_and_write function doesn't work with TransmitJSON commands with multiple arguments due to a problem in popoto API. Making a separate signal_and_write_raw() function for TransmitJSON commands with multiple arguments --- src/acomms/modemdriver/popoto_driver.cpp | 55 ++++++++++++++++++------ src/acomms/modemdriver/popoto_driver.h | 1 + 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/acomms/modemdriver/popoto_driver.cpp b/src/acomms/modemdriver/popoto_driver.cpp index 7718b751..fed9af12 100644 --- a/src/acomms/modemdriver/popoto_driver.cpp +++ b/src/acomms/modemdriver/popoto_driver.cpp @@ -353,19 +353,36 @@ void goby::acomms::PopotoDriver::send(protobuf::ModemTransmission& msg) throw(goby::Exception(std::string("Unsupported type provided to send: ") + protobuf::ModemTransmission::TransmissionType_Name(msg.type()))); } - - // To send a bin msg it needs to be in 8 bit CSV values - std::stringstream raw; - raw << "transmitJSON { \"ClassUserID\": 16, \"ApplicationType\": " << application_type << ", \"AckRequest\": " << (msg.ack_requested() ? 1 : 0) << ", \"StationID\": "<< driver_cfg_.modem_id() << ", \"DestinationID\": " << dest << ", \"Payload\":{\"Data\":[" << jsonStr << "]}}"; - + if (myConnection == SERIAL_CONNECTION) - raw << "\n"; // Need to append new line char for Serial Only - - // Send the raw string to terminal for debugging - glog.is(DEBUG1) && glog << raw.str() << std::endl; - - // Send over the wire - signal_and_write(raw.str()); + { + // To send a bin msg it needs to be in 8 bit CSV values + std::stringstream raw; + raw << "transmitJSON { \"ClassUserID\": 16, \"ApplicationType\": " << application_type << ", \"AckRequest\": " << (msg.ack_requested() ? 1 : 0) << ", \"StationID\": "<< driver_cfg_.modem_id() << ", \"DestinationID\": " << dest << ", \"Payload\":{\"Data\":[" << jsonStr << "]}}"; + + if (myConnection == SERIAL_CONNECTION) + raw << "\n"; // Need to append new line char for Serial Only + + // Send the raw string to terminal for debugging + glog.is(DEBUG1) && glog << raw.str() << std::endl; + + // Send over the wire + signal_and_write(raw.str()); + } + else if (myConnection == ETHERNET_CONNECTION) + { + std::string app_type_str_ = std::to_string(application_type); + std::string ack_str_ = std::to_string((msg.ack_requested() ? 1 : 0)); + std::string station_id_str_ = std::to_string(driver_cfg_.modem_id()); + std::string dest_str_ = std::to_string(dest); + std::string command = "{ \"Command\": \"TransmitJSON\", \"Arguments\": { \"ClassUserID\": 16, \"ApplicationType\": " + app_type_str_ + + ", \"AckRequest\": " + ack_str_ + + ", \"StationID\": " + station_id_str_ + + ", \"DestinationID\": " + dest_str_ + + ", \"Payload\": { \"Data\": [" + jsonStr + "] } } }\n"; + + signal_and_write_raw(command); + } } // ---------------------------- Ranging ---------------------------------------------------- @@ -489,6 +506,20 @@ void goby::acomms::PopotoDriver::signal_and_write(const std::string& raw) } } +// --------------------------- Write over the wire in raw json format ------------------------------ +// Popoto API has a problem here: https://github.com/Delresearch/PopotoAPI/blob/2b511ff2109b6cde85b2261aec414882a332e8eb/CPP/popoto_client/include/TCPCmdClient.hpp#L54 +// Due to the way they string handle, you cannot send TransmitJSON type commands that has multiple +// arguments; e.g. "Arguments": { "ClassUserID": 16, "ApplicationType": 0, ... +// So I'm using their raw send_data() function rather than SendCommand() function to by pass this. +// I'm sure the issue persists in both serial and Ethernet modes, But I have only tested in Ethernet +// mode, so I'm leaving the serial mode as is. -Supun- +void goby::acomms::PopotoDriver::signal_and_write_raw(std::string raw) +{ + if (popoto0->cmd->isConnected()) { + popoto0->cmd->send_data((char*)raw.c_str(), (int)raw.length()); + } +} + // Change from setRateXXXX to PayloadMode XXXX // e.g. // setRate1280 to setvaluei PayloadMode 2 diff --git a/src/acomms/modemdriver/popoto_driver.h b/src/acomms/modemdriver/popoto_driver.h index 2ebd8091..762d01e9 100644 --- a/src/acomms/modemdriver/popoto_driver.h +++ b/src/acomms/modemdriver/popoto_driver.h @@ -72,6 +72,7 @@ class PopotoDriver : public ModemDriverBase private: void parse_in(const std::string& in, std::map* out); void signal_and_write(const std::string& raw); + void signal_and_write_raw(std::string raw); // 2 byte header code // std::uint16_t CreateGobyHeader(const protobuf::ModemTransmission& m); From f920d5f90bb81304bca56c3f148e801b1fdca1b9 Mon Sep 17 00:00:00 2001 From: Supun Randeni Date: Sat, 5 Jul 2025 19:21:37 -0400 Subject: [PATCH 8/8] Adding two-way ranging functionality --- src/acomms/modemdriver/popoto_driver.cpp | 120 +++++++++++++++++++---- src/acomms/modemdriver/popoto_driver.h | 10 ++ src/acomms/protobuf/popoto_driver.proto | 13 ++- 3 files changed, 118 insertions(+), 25 deletions(-) diff --git a/src/acomms/modemdriver/popoto_driver.cpp b/src/acomms/modemdriver/popoto_driver.cpp index fed9af12..4f094565 100644 --- a/src/acomms/modemdriver/popoto_driver.cpp +++ b/src/acomms/modemdriver/popoto_driver.cpp @@ -96,6 +96,7 @@ void goby::acomms::PopotoDriver::startup(const protobuf::DriverConfig& cfg) std::string ip = cfg.tcp_server(); // std::string port = popoto_driver_cfg().local().port(); + // Need to issue the disconnect command to stop pshell // signal_and_write("disconnect\n"); @@ -208,13 +209,25 @@ void goby::acomms::PopotoDriver::handle_initiate_transmission( { switch (msg.GetExtension(popoto::protobuf::transmission).type()) { - case popoto::protobuf::POPOTO_TWO_WAY_RANGE: + case popoto::protobuf::POPOTO_TWO_WAY_RANGE_REQUEST: + glog.is(DEBUG1) && glog << group(glog_out_group()) + << "We were asked to transmit a range request from " + << msg.src() << " to " << msg.dest() << " at TX power " + << popoto_driver_cfg().modem_power() + << std::endl; // Adding this glog for debugging -Supun- send_range_request(msg.dest()); // send a ranging message break; case popoto::protobuf::POPOTO_PLAY_FILE: play_file(msg); break; - case popoto::protobuf::POPOTO_TWO_WAY_PING: send_ping(msg); break; + case popoto::protobuf::POPOTO_TWO_WAY_PING: + glog.is(DEBUG1) && glog << group(glog_out_group()) + << "We were asked to send a two-way ping from " + << msg.src() << " to " << msg.dest() << " at TX power " + << popoto_driver_cfg().modem_power() + << std::endl; // Adding this glog for debugging -Supun- + send_ping(msg); + break; case popoto::protobuf::POPOTO_DEEP_SLEEP: popoto_sleep(); break; @@ -223,6 +236,12 @@ void goby::acomms::PopotoDriver::handle_initiate_transmission( case popoto::protobuf::POPOTO_WAKE: send_wake(); // the wake will just be a ping for the moment break; + case popoto::protobuf::POPOTO_TWO_WAY_RANGE_RESPONSE: + glog.is(WARN) && glog << group(glog_out_group()) << "You cannot send a " + " POPOTO_TWO_WAY_RANGE_RESPONSE. This is something that " + " you ONLY receive in return to a POPOTO_TWO_WAY_RANGE_REQUEST" + << std::endl; + break; default: glog.is(DEBUG1) && @@ -232,6 +251,7 @@ void goby::acomms::PopotoDriver::handle_initiate_transmission( << msg << std::endl; break; } + break; // Added the missing break -Supun- } default: @@ -391,13 +411,26 @@ void goby::acomms::PopotoDriver::send_range_request(int dest) std::stringstream raw; raw << "setvaluei RemoteID " << dest << "\n"; signal_and_write(raw.str()); + + if (myConnection == SERIAL_CONNECTION) + { + // A range messages needs to be formated with 'range txPower' we will use the default power from .moos launch file + std::stringstream range; + range << "setvaluef range " << popoto_driver_cfg().modem_power() << "\n"; - // A range messages needs to be formated with 'range txPower' we will use the default power from .moos launch file - std::stringstream range; - range << "range " << popoto_driver_cfg().modem_power() << "\n"; - - // Send over the wire - signal_and_write(range.str()); + // Send over the wire + signal_and_write(range.str()); + } + else if (myConnection == ETHERNET_CONNECTION) + { + std::string tx_power_str_ = std::to_string(popoto_driver_cfg().modem_power()); + std::string dest_str_ = std::to_string(dest); + + std::string command = "{ \"Command\": \"Event_sendRanging\", \"Arguments\": { \"TxPowerWatts\": " + tx_power_str_ + + " , \"RemoteID\": " + dest_str_ + + " } }\n"; + signal_and_write_raw(command); + } } // --------------------------- Incoming msgs ------------------------------------------------ @@ -417,6 +450,7 @@ void goby::acomms::PopotoDriver::do_work() in = StripString(in, "MSMStatus "); // Below is over ethernet only in = StripString(in, "DataPacket "); in = StripString(in, "HeaderPacket "); + in = StripString(in, "RangeReport "); protobuf::ModemRaw raw; raw.set_raw(in); @@ -424,7 +458,8 @@ void goby::acomms::PopotoDriver::do_work() if (json::accept(in)) { ProcessJSON(in, modem_msg_); - if (modem_msg_.has_type()) + if (modem_msg_.has_type()) + // This assumes that the type (which contains in the header) is set after the message is fully populated?! -Supun- { glog.is(DEBUG1) && glog << group(glog_in_group()) << "received: " << modem_msg_ << std::endl; @@ -453,6 +488,7 @@ void goby::acomms::PopotoDriver::do_work() } ModemDriverBase::signal_receive(modem_msg_); modem_msg_.Clear(); + transmissions_type_internal = UNKNOWN; // clearing this } } } @@ -576,10 +612,12 @@ void goby::acomms::PopotoDriver::DecodeHeader(std::vector data, enum PopotoMessageType { DATA_MESSAGE = 0, - RANGE_RESPONSE = 128, + RANGE_RESPONSE = 138, RANGE_REQUEST = 129, STATUS = 130 }; + // Popoto documentation (https://www.popotomodem.com/static/17704245ba22b453f7e532e2d40273ee/PMM5544UsersGuide.pdf page 279) says range response MessageID is 128. + // But looking at the actual range response messages, it is 138! -Supun- // Process binary payload data switch (data[0]) @@ -600,8 +638,9 @@ void goby::acomms::PopotoDriver::DecodeHeader(std::vector data, // use empty data packet to indicate ACK // TODO - get Popoto to provide ACK packet type in header - if (length == 0) - modem_msg.set_type(protobuf::ModemTransmission::ACK); + if (length == 0){ + modem_msg.set_type(protobuf::ModemTransmission::ACK); + } std::vector modulation_to_rate{0, 4, 3, 2, 1, 5}; if (modulation < modulation_to_rate.size()) @@ -610,9 +649,15 @@ void goby::acomms::PopotoDriver::DecodeHeader(std::vector data, break; } - case RANGE_RESPONSE: type = "Range response"; break; + case RANGE_RESPONSE: + type = "Range response"; + transmissions_type_internal = POPOTO_TWO_WAY_RANGE_RESPONSE; + break; - case RANGE_REQUEST: type = "Range_request"; break; + case RANGE_REQUEST: + type = "Range_request"; + transmissions_type_internal = POPOTO_TWO_WAY_RANGE_REQUEST; + break; case STATUS: type = "Status message"; break; @@ -636,7 +681,7 @@ void goby::acomms::PopotoDriver::ProcessJSON(const std::string& message, json j = json::parse(message); json::iterator it = j.begin(); const std::string& label = it.key(); - std::string str; + // std::string str; protobuf::ModemRaw raw; raw.set_raw(message); @@ -646,12 +691,27 @@ void goby::acomms::PopotoDriver::ProcessJSON(const std::string& message, } else if (label == "Data") { - std::string data = json_to_binary(j["Data"]); - DecodeGobyHeader(data[0],data[1], modem_msg); - if (modem_msg.type() == protobuf::ModemTransmission::DATA) - *modem_msg.add_frame() = data.substr(1); // Header is 1 byte, correct? So this should be substr(1) not substr(2). -Supun- - else if (modem_msg.type() == protobuf::ModemTransmission::ACK){ - modem_msg.add_acked_frame(data[1]); + if (transmissions_type_internal == POPOTO_TWO_WAY_RANGE_RESPONSE) { + // Once you set the type, the message will be published to the DB + // So we wait until the data frame (usually the last) and then set type + modem_msg.set_type(protobuf::ModemTransmission::DRIVER_SPECIFIC); + modem_msg.MutableExtension(popoto::protobuf::transmission) + ->set_type(popoto::protobuf::POPOTO_TWO_WAY_RANGE_RESPONSE); + } + else if (transmissions_type_internal == POPOTO_TWO_WAY_RANGE_REQUEST) { + // Once you set the type, the message will be published to the DB + modem_msg.set_type(protobuf::ModemTransmission::DRIVER_SPECIFIC); + modem_msg.MutableExtension(popoto::protobuf::transmission) + ->set_type(popoto::protobuf::POPOTO_TWO_WAY_RANGE_REQUEST); + } + else { + std::string data = json_to_binary(j["Data"]); + DecodeGobyHeader(data[0],data[1], modem_msg); + if (modem_msg.type() == protobuf::ModemTransmission::DATA) + *modem_msg.add_frame() = data.substr(1); // Header is 1 byte, correct? So this should be substr(1) not substr(2). -Supun- + else if (modem_msg.type() == protobuf::ModemTransmission::ACK){ + modem_msg.add_acked_frame(data[1]); + } } } else if (label == "Alert") @@ -674,6 +734,24 @@ void goby::acomms::PopotoDriver::ProcessJSON(const std::string& message, { glog.is(DEBUG1) && glog << label << ": " << j[label] << std::endl; } + + // Parsing the range report + if (transmissions_type_internal == POPOTO_TWO_WAY_RANGE_RESPONSE) + { + if (j.contains("Range") && j.contains("Roundtrip Delay") && j.contains("SpeedOfSound")) { + double range = j["Range"]; + double twtt = j["Roundtrip Delay"]; + double sound_speed = j["SpeedOfSound"]; + modem_msg.MutableExtension(popoto::protobuf::transmission) + ->mutable_ranging_reply()->set_one_way_travel_time(twtt/2); + modem_msg.MutableExtension(popoto::protobuf::transmission) + ->mutable_ranging_reply()->set_two_way_travel_time(twtt); + modem_msg.MutableExtension(popoto::protobuf::transmission) + ->mutable_ranging_reply()->set_modem_range(range); + modem_msg.MutableExtension(popoto::protobuf::transmission) + ->mutable_ranging_reply()->set_modem_sound_speed(sound_speed); + } + } } diff --git a/src/acomms/modemdriver/popoto_driver.h b/src/acomms/modemdriver/popoto_driver.h index 762d01e9..20e05a08 100644 --- a/src/acomms/modemdriver/popoto_driver.h +++ b/src/acomms/modemdriver/popoto_driver.h @@ -151,6 +151,16 @@ class PopotoDriver : public ModemDriverBase const std::string setvalf = "setvaluef"; const std::string getvali = "getvaluei"; const std::string getvalf = "getvaluef"; + + enum TransmissionTypeInternal + { + UNKNOWN = 0, // used + DATA = 1, // just placeholder + ACK = 2, // just placeholder + POPOTO_TWO_WAY_RANGE_REQUEST = 3, // used + POPOTO_TWO_WAY_RANGE_RESPONSE = 4 // used + }; + TransmissionTypeInternal transmissions_type_internal; }; } // namespace acomms } // namespace goby diff --git a/src/acomms/protobuf/popoto_driver.proto b/src/acomms/protobuf/popoto_driver.proto index f98f1cf3..bccde5b5 100644 --- a/src/acomms/protobuf/popoto_driver.proto +++ b/src/acomms/protobuf/popoto_driver.proto @@ -61,15 +61,20 @@ enum TransmissionType POPOTO_TWO_WAY_PING = 1; // modem 1 interrogates modem 2; modem 2 replies // and modem 1 computes one way travel time POPOTO_PLAY_FILE = 2; - POPOTO_TWO_WAY_RANGE = 3; - POPOTO_DEEP_SLEEP = 4; - POPOTO_WAKE = 5; - POPOTO_SET_TX = 6; + POPOTO_TWO_WAY_RANGE_REQUEST = 3; // Ranging request + POPOTO_TWO_WAY_RANGE_RESPONSE = 4; // Response that you receive to a ranging request + POPOTO_DEEP_SLEEP = 5; + POPOTO_WAKE = 6; + POPOTO_SET_TX = 7; } message RangingReply { required double one_way_travel_time = 1 + [(dccl.field).units.unit = "si::second"]; // Popoto doesn't give this. This will be calculated by the driver using TWTT + optional double two_way_travel_time = 2 [(dccl.field).units.unit = "si::second"]; + optional double modem_range = 3; // meters + optional double modem_sound_speed = 4; // m/s } message Transmission {