From 48b88cce54560a5753ca7e73fb9e65c5fb1bbaab Mon Sep 17 00:00:00 2001 From: lross03 Date: Sat, 1 Feb 2025 11:28:39 -0800 Subject: [PATCH 1/6] this is preliminary remember to clean up --- .../src/local_transceiver.cpp | 50 +++++-- .../test/test_local_transceiver.cpp | 126 ++++++++++-------- .../components/DropDown/DropDown.module.css | 103 -------------- 3 files changed, 107 insertions(+), 172 deletions(-) delete mode 100644 src/website/views/components/DropDown/DropDown.module.css diff --git a/src/network_systems/projects/local_transceiver/src/local_transceiver.cpp b/src/network_systems/projects/local_transceiver/src/local_transceiver.cpp index 2b4c976b8..1ebc857b4 100644 --- a/src/network_systems/projects/local_transceiver/src/local_transceiver.cpp +++ b/src/network_systems/projects/local_transceiver/src/local_transceiver.cpp @@ -274,7 +274,7 @@ custom_interfaces::msg::Path LocalTransceiver::receive() continue; } - if (!rcvRsps({message_to_queue_cmd, AT::Line("\n")})) { + if (!rcvRsps({message_to_queue_cmd, AT::Line("\n"), AT::Line(AT::DNLD_TO_QUEUE), AT::Line(AT::DELIMITER)})) { continue; } @@ -283,21 +283,49 @@ custom_interfaces::msg::Path LocalTransceiver::receive() continue; } - std::regex re( - R"(name=\"data\"; filename=\"[^\"]*\"\r?\n(?:.*\r?\n)*\r?\n([\s\S]*?)\r?\n--)", std::regex::ECMAScript); + std::string message_size_str; + std::string message; + std::string checksum; + uint16_t message_size_int = 0; - std::smatch match; + if (buffer_data && buffer_data->size() >= 2) { + message_size_str = buffer_data->substr(0, 2); + } else { + continue; + } + + message_size_int = (static_cast(message_size_str[0]) << 8) | //NOLINT(readability-magic-numbers) + + static_cast(message_size_str[1]); //NOLINT(readability-magic-numbers) - if (std::regex_search(*buffer_data, match, re)) { - *buffer_data = match[1]; - std::stringstream ss; - ss << *buffer_data; - std::cout << ss.str() << std::endl; + message = buffer_data->substr(2, message_size_int); + + std::cout << "Raw size bytes (hex): " + << std::hex << static_cast(static_cast(message_size_str[0])) << " " + << std::hex << static_cast(static_cast(message_size_str[1])) + << std::dec << std::endl; + + if (!message.empty()) { + std::cout << "message exists :" << message << ": size: " << message_size_int << std::endl; } else { - std::cout << "No match found." << std::endl; + std::cout << "message empty :(" << std::endl; } - receivedDataBuffer = buffer_data.value(); + // std::regex re( + // R"(name=\"data\"; filename=\"[^\"]*\"\r?\n(?:.*\r?\n)*\r?\n([\s\S]*?)\r?\n--)", std::regex::ECMAScript); + + // std::smatch match; + + // if (std::regex_search(*buffer_data, match, re)) { + // *buffer_data = match[1]; + // std::stringstream ss; + // ss << *buffer_data; + // std::cout << ss.str() << std::endl; + // } else { + // std::cout << "No match found." << std::endl; + // } + + receivedDataBuffer = message; break; } diff --git a/src/network_systems/projects/local_transceiver/test/test_local_transceiver.cpp b/src/network_systems/projects/local_transceiver/test/test_local_transceiver.cpp index 94914455c..613335199 100644 --- a/src/network_systems/projects/local_transceiver/test/test_local_transceiver.cpp +++ b/src/network_systems/projects/local_transceiver/test/test_local_transceiver.cpp @@ -227,61 +227,71 @@ TEST_F(TestLocalTransceiver, parseInMsgValid) EXPECT_EQ(parsed_test.waypoints[1].longitude, holder); } -// std::mutex port_mutex; - -// TEST_F(TestLocalTransceiver, testMailboxBlackbox) -// { -// std::lock_guard lock(port_mutex); // because same port is being used - -// std::string holder = "curl -X POST -F \"test=1234\" http://localhost:8080"; -// std::string holder2 = "printf \"at+sbdix\r\" > $LOCAL_TRANSCEIVER_TEST_PORT"; - -// system(holder.c_str()); //NOLINT -// system(holder2.c_str()); //NOLINT - -// std::optional response = lcl_trns_->readRsp(); -// std::cout << *response << std::endl; -// } - -// TEST_F(TestLocalTransceiver, parseReceiveMessageBlackbox) -// { -// std::lock_guard lock(port_mutex); - -// constexpr float holder = 14.3; -// Polaris::GlobalPath sample_data; - -// Polaris::Waypoint * waypoint_a = sample_data.add_waypoints(); -// waypoint_a->set_latitude(holder); -// waypoint_a->set_longitude(holder); -// Polaris::Waypoint * waypoint_b = sample_data.add_waypoints(); -// waypoint_b->set_latitude(holder); -// waypoint_b->set_longitude(holder); - -// std::string serialized_data; -// ASSERT_TRUE(sample_data.SerializeToString(&serialized_data)); - -// std::ofstream outfile("/tmp/serialized_data.bin", std::ios::binary); -// outfile.write(serialized_data.data(), static_cast(serialized_data.size())); -// outfile.close(); - -// std::string holder2 = "curl -X POST -F \"data=@/tmp/serialized_data.bin\" http://localhost:8080"; -// std::system(holder2.c_str()); //NOLINT - -// custom_interfaces::msg::Path received_data = lcl_trns_->receive(); - -// Polaris::GlobalPath global_path; -// for (const auto & waypoint : received_data.waypoints) { -// Polaris::Waypoint * new_waypoint = global_path.add_waypoints(); -// new_waypoint->set_latitude(waypoint.latitude); -// new_waypoint->set_longitude(waypoint.longitude); -// } - -// if (global_path.waypoints_size() > 0) { -// ASSERT_EQ(global_path.waypoints_size(), sample_data.waypoints_size()) -// << "Mismatch in number of waypoints received."; -// ASSERT_EQ(global_path.waypoints(0).latitude(), holder); -// ASSERT_EQ(global_path.waypoints(0).longitude(), holder); -// } else { -// std::cout << "No waypoints received." << std::endl; -// } -// } +std::mutex port_mutex; + +TEST_F(TestLocalTransceiver, testMailboxBlackbox) +{ + std::lock_guard lock(port_mutex); // because same port is being used + + std::string holder = "curl -X POST -F \"test=1234\" http://localhost:8080"; + std::string holder2 = "printf \"at+sbdix\r\" > $LOCAL_TRANSCEIVER_TEST_PORT"; + + system(holder.c_str()); //NOLINT + system(holder2.c_str()); //NOLINT + + std::optional response = lcl_trns_->readRsp(); + std::cout << *response << std::endl; +} + +TEST_F(TestLocalTransceiver, parseReceiveMessageBlackbox) +{ + std::lock_guard lock(port_mutex); + + constexpr float holder = 14.3; + Polaris::GlobalPath sample_data; + + Polaris::Waypoint * waypoint_a = sample_data.add_waypoints(); + waypoint_a->set_latitude(holder); + waypoint_a->set_longitude(holder); + Polaris::Waypoint * waypoint_b = sample_data.add_waypoints(); + waypoint_b->set_latitude(holder); + waypoint_b->set_longitude(holder); + + std::string serialized_data; + ASSERT_TRUE(sample_data.SerializeToString(&serialized_data)); + + uint16_t message_size = static_cast(serialized_data.size()); + uint16_t message_size_be = htons(message_size); // Convert to big-endian + + std::string size_prefix(reinterpret_cast(&message_size_be), sizeof(message_size_be)); + + std::ofstream outfile("/tmp/serialized_data.bin", std::ios::binary); + outfile.write(size_prefix.data(), size_prefix.size()); //NOLINT + outfile.write(serialized_data.data(), static_cast(serialized_data.size())); + outfile.close(); + + outfile.close(); // Close the file after writing + + std::string holder2 = "curl -X POST --data-binary @/tmp/serialized_data.bin http://localhost:8080"; + std::system(holder2.c_str()); //NOLINT + std::string test_cmd = "hexdump -C /tmp/serialized_data.bin"; + std::system(test_cmd.c_str()); //NOLINT + + custom_interfaces::msg::Path received_data = lcl_trns_->receive(); + + Polaris::GlobalPath global_path; + for (const auto & waypoint : received_data.waypoints) { + Polaris::Waypoint * new_waypoint = global_path.add_waypoints(); + new_waypoint->set_latitude(waypoint.latitude); + new_waypoint->set_longitude(waypoint.longitude); + } + + if (global_path.waypoints_size() > 0) { + ASSERT_EQ(global_path.waypoints_size(), sample_data.waypoints_size()) + << "Mismatch in number of waypoints received."; + ASSERT_EQ(global_path.waypoints(0).latitude(), holder); + ASSERT_EQ(global_path.waypoints(0).longitude(), holder); + } else { + std::cout << "No waypoints received." << std::endl; + } +} diff --git a/src/website/views/components/DropDown/DropDown.module.css b/src/website/views/components/DropDown/DropDown.module.css deleted file mode 100644 index 319627b98..000000000 --- a/src/website/views/components/DropDown/DropDown.module.css +++ /dev/null @@ -1,103 +0,0 @@ -@import 'https://fonts.googleapis.com/css2?family=Raleway:ital,wght@0,100..900;1,100..900&display=swap'; - -.iconButton { - display: flex; - justify-content: center; - align-items: center; - font-family: Verdana, sans-serif; - padding: 3px; - border: 2px solid white; - border-radius: 5px; - width: 130px; - height: 50px; - color: white; - float: right; - margin-right: 20px; - box-sizing: border-box; - transition: 0.3s ease; - transform: none; - user-select: none; -} - -.iconButton:hover { - background-color: white; - color: #3498db; - cursor: pointer; - transition: 0.3s ease; -} - -.iconButtonOpen { - font-family: Verdana, Geneva, sans-serif; - padding: 3px; - border: 2px solid white; - border-radius: 5px; - width: 130px; - height: 50px; - float: right; - margin-right: 20px; - box-sizing: border-box; - text-align: center; - background-color: white; - color: #3498db; - cursor: pointer; - transition: 0.3s ease; - transform: none; - user-select: none; -} - -.dropdownActive { - opacity: 1; - visibility: visible; - transform: translateY(0); - transition: 0.3s ease; -} - -.dropdownInactive { - opacity: 0; - visibility: hidden; - transform: translateY(-45px); - transition: 0.3s; - pointer-events: none; -} - -.dropdownMenu { - margin: 5px; - position: absolute; - right: 3px; - top: 60px; - z-index: 1000; - background-color: white; - border-bottom: 2px #3498db solid; - border-radius: 5px; -} - -.dropdownItem { - text-transform: capitalize; - display: grid; - grid-template-columns: 90px auto; - font-size: 18px; - font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif; - width: 150px; - padding: 10px; - height: 40px; - background-color: white; - border: 2px white solid; - border-radius: 5px; - color: #3498db; - align-items: center; - transform: none; - user-select: none; - cursor: pointer; -} - -.dropdownItem:hover { - background-color: whitesmoke; -} - -.dragDropIndicator { - font-size: 20px; - font-weight: bold; - position: absolute; - right: 15px; -} - From 7c075a37b92560555bc5d3b48c7a680028c16d98 Mon Sep 17 00:00:00 2001 From: lross03 Date: Wed, 5 Feb 2025 20:22:51 -0800 Subject: [PATCH 2/6] Local transceiver updated to correct receive format, but still need to fix hanging OK issue --- .../local_transceiver/src/local_transceiver.cpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/network_systems/projects/local_transceiver/src/local_transceiver.cpp b/src/network_systems/projects/local_transceiver/src/local_transceiver.cpp index 1ebc857b4..a20208ea8 100644 --- a/src/network_systems/projects/local_transceiver/src/local_transceiver.cpp +++ b/src/network_systems/projects/local_transceiver/src/local_transceiver.cpp @@ -274,7 +274,7 @@ custom_interfaces::msg::Path LocalTransceiver::receive() continue; } - if (!rcvRsps({message_to_queue_cmd, AT::Line("\n"), AT::Line(AT::DNLD_TO_QUEUE), AT::Line(AT::DELIMITER)})) { + if (!rcvRsps({message_to_queue_cmd, AT::Line("\n"), AT::Line("+SBDRB:"), AT::Line("\n")})) { continue; } @@ -300,17 +300,6 @@ custom_interfaces::msg::Path LocalTransceiver::receive() message = buffer_data->substr(2, message_size_int); - std::cout << "Raw size bytes (hex): " - << std::hex << static_cast(static_cast(message_size_str[0])) << " " - << std::hex << static_cast(static_cast(message_size_str[1])) - << std::dec << std::endl; - - if (!message.empty()) { - std::cout << "message exists :" << message << ": size: " << message_size_int << std::endl; - } else { - std::cout << "message empty :(" << std::endl; - } - // std::regex re( // R"(name=\"data\"; filename=\"[^\"]*\"\r?\n(?:.*\r?\n)*\r?\n([\s\S]*?)\r?\n--)", std::regex::ECMAScript); From 84b61958e40d598dccd6ae9972c07a8e0d21549b Mon Sep 17 00:00:00 2001 From: Jng468 Date: Tue, 25 Feb 2025 21:59:36 -0800 Subject: [PATCH 3/6] try new readrsp --- .../projects/local_transceiver/inc/at_cmds.h | 1 + .../local_transceiver/inc/local_transceiver.h | 2 ++ .../src/local_transceiver.cpp | 35 ++++++++++--------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/network_systems/projects/local_transceiver/inc/at_cmds.h b/src/network_systems/projects/local_transceiver/inc/at_cmds.h index 88af36422..35dd21bfc 100644 --- a/src/network_systems/projects/local_transceiver/inc/at_cmds.h +++ b/src/network_systems/projects/local_transceiver/inc/at_cmds.h @@ -14,6 +14,7 @@ namespace AT const std::string DELIMITER = "\r\n"; const std::string STATUS_OK = "OK"; const std::string RSP_READY = "READY"; +const std::string GARBAGE = "\n"; const std::string CHECK_CONN = "AT"; const std::string SBD_SESSION = "AT+SBDIX"; // 5.144 diff --git a/src/network_systems/projects/local_transceiver/inc/local_transceiver.h b/src/network_systems/projects/local_transceiver/inc/local_transceiver.h index adcf5c61d..fdf953186 100644 --- a/src/network_systems/projects/local_transceiver/inc/local_transceiver.h +++ b/src/network_systems/projects/local_transceiver/inc/local_transceiver.h @@ -154,6 +154,8 @@ class LocalTransceiver std::optional readRsp(); + std::optional readRspGarbage(); + /** * @brief Parse the message received from the remote server * diff --git a/src/network_systems/projects/local_transceiver/src/local_transceiver.cpp b/src/network_systems/projects/local_transceiver/src/local_transceiver.cpp index a20208ea8..70e6f75f9 100644 --- a/src/network_systems/projects/local_transceiver/src/local_transceiver.cpp +++ b/src/network_systems/projects/local_transceiver/src/local_transceiver.cpp @@ -240,6 +240,8 @@ custom_interfaces::msg::Path LocalTransceiver::receive() continue; } + auto garbage = readRspGarbage(); + std::string opt_rsp_val = opt_rsp.value(); std::vector sbd_status_vec; boost::algorithm::split(sbd_status_vec, opt_rsp_val, boost::is_any_of(AT::DELIMITER)); @@ -295,25 +297,9 @@ custom_interfaces::msg::Path LocalTransceiver::receive() } message_size_int = (static_cast(message_size_str[0]) << 8) | //NOLINT(readability-magic-numbers) - static_cast(message_size_str[1]); //NOLINT(readability-magic-numbers) - message = buffer_data->substr(2, message_size_int); - // std::regex re( - // R"(name=\"data\"; filename=\"[^\"]*\"\r?\n(?:.*\r?\n)*\r?\n([\s\S]*?)\r?\n--)", std::regex::ECMAScript); - - // std::smatch match; - - // if (std::regex_search(*buffer_data, match, re)) { - // *buffer_data = match[1]; - // std::stringstream ss; - // ss << *buffer_data; - // std::cout << ss.str() << std::endl; - // } else { - // std::cout << "No match found." << std::endl; - // } - receivedDataBuffer = message; break; } @@ -394,6 +380,23 @@ std::optional LocalTransceiver::readRsp() return rsp_str; } +std::optional LocalTransceiver::readRspGarbage() +{ + bio::streambuf buf; + error_code ec; + + // Caution: will hang if another proccess is reading from serial port + bio::read_until(serial_, buf, AT::GARBAGE, ec); + if (ec) { + return std::nullopt; + } + + std::string rsp_str = streambufToStr(buf); + rsp_str.pop_back(); // Remove the "\n" + return rsp_str; +} + + std::string LocalTransceiver::checksum(const std::string & data) { uint16_t sum = 0; From c821f2a38195a943580cb98303acabbe30282b97 Mon Sep 17 00:00:00 2001 From: lross03 Date: Tue, 25 Feb 2025 23:30:54 -0800 Subject: [PATCH 4/6] Modified readRsp to read until STATUS_OK instead of DELIMITER --- .../local_transceiver/inc/local_transceiver.h | 2 -- .../src/local_transceiver.cpp | 23 ++----------------- 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/src/network_systems/projects/local_transceiver/inc/local_transceiver.h b/src/network_systems/projects/local_transceiver/inc/local_transceiver.h index fdf953186..adcf5c61d 100644 --- a/src/network_systems/projects/local_transceiver/inc/local_transceiver.h +++ b/src/network_systems/projects/local_transceiver/inc/local_transceiver.h @@ -154,8 +154,6 @@ class LocalTransceiver std::optional readRsp(); - std::optional readRspGarbage(); - /** * @brief Parse the message received from the remote server * diff --git a/src/network_systems/projects/local_transceiver/src/local_transceiver.cpp b/src/network_systems/projects/local_transceiver/src/local_transceiver.cpp index 70e6f75f9..cbe22ec0b 100644 --- a/src/network_systems/projects/local_transceiver/src/local_transceiver.cpp +++ b/src/network_systems/projects/local_transceiver/src/local_transceiver.cpp @@ -240,8 +240,6 @@ custom_interfaces::msg::Path LocalTransceiver::receive() continue; } - auto garbage = readRspGarbage(); - std::string opt_rsp_val = opt_rsp.value(); std::vector sbd_status_vec; boost::algorithm::split(sbd_status_vec, opt_rsp_val, boost::is_any_of(AT::DELIMITER)); @@ -297,7 +295,7 @@ custom_interfaces::msg::Path LocalTransceiver::receive() } message_size_int = (static_cast(message_size_str[0]) << 8) | //NOLINT(readability-magic-numbers) - static_cast(message_size_str[1]); //NOLINT(readability-magic-numbers) + static_cast(message_size_str[1]); //NOLINT(readability-magic-numbers) message = buffer_data->substr(2, message_size_int); receivedDataBuffer = message; @@ -370,23 +368,7 @@ std::optional LocalTransceiver::readRsp() error_code ec; // Caution: will hang if another proccess is reading from serial port - bio::read_until(serial_, buf, AT::DELIMITER, ec); - if (ec) { - return std::nullopt; - } - - std::string rsp_str = streambufToStr(buf); - rsp_str.pop_back(); // Remove the "\n" - return rsp_str; -} - -std::optional LocalTransceiver::readRspGarbage() -{ - bio::streambuf buf; - error_code ec; - - // Caution: will hang if another proccess is reading from serial port - bio::read_until(serial_, buf, AT::GARBAGE, ec); + bio::read_until(serial_, buf, AT::STATUS_OK, ec); if (ec) { return std::nullopt; } @@ -396,7 +378,6 @@ std::optional LocalTransceiver::readRspGarbage() return rsp_str; } - std::string LocalTransceiver::checksum(const std::string & data) { uint16_t sum = 0; From cb3e42e0870011dfc26c1b34552cd626ac68d092 Mon Sep 17 00:00:00 2001 From: Jng468 Date: Sat, 1 Mar 2025 11:58:52 -0800 Subject: [PATCH 5/6] test with different value --- .../projects/local_transceiver/test/test_local_transceiver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network_systems/projects/local_transceiver/test/test_local_transceiver.cpp b/src/network_systems/projects/local_transceiver/test/test_local_transceiver.cpp index 613335199..d7b0dba7d 100644 --- a/src/network_systems/projects/local_transceiver/test/test_local_transceiver.cpp +++ b/src/network_systems/projects/local_transceiver/test/test_local_transceiver.cpp @@ -247,7 +247,7 @@ TEST_F(TestLocalTransceiver, parseReceiveMessageBlackbox) { std::lock_guard lock(port_mutex); - constexpr float holder = 14.3; + constexpr float holder = 10.3; Polaris::GlobalPath sample_data; Polaris::Waypoint * waypoint_a = sample_data.add_waypoints(); From 2f2c24c23316bf91b63af2e9d723c4e7d5c6400e Mon Sep 17 00:00:00 2001 From: Jng468 Date: Wed, 5 Mar 2025 20:35:54 -0800 Subject: [PATCH 6/6] restore deleted website file --- .../components/DropDown/Dropdown.module.css | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 src/website/views/components/DropDown/Dropdown.module.css diff --git a/src/website/views/components/DropDown/Dropdown.module.css b/src/website/views/components/DropDown/Dropdown.module.css new file mode 100644 index 000000000..25b4eca98 --- /dev/null +++ b/src/website/views/components/DropDown/Dropdown.module.css @@ -0,0 +1,102 @@ +@import 'https://fonts.googleapis.com/css2?family=Raleway:ital,wght@0,100..900;1,100..900&display=swap'; + +.iconButton { + display: flex; + justify-content: center; + align-items: center; + font-family: Verdana, sans-serif; + padding: 3px; + border: 2px solid white; + border-radius: 5px; + width: 130px; + height: 50px; + color: white; + float: right; + margin-right: 20px; + box-sizing: border-box; + transition: 0.3s ease; + transform: none; + user-select: none; +} + +.iconButton:hover { + background-color: white; + color: #3498db; + cursor: pointer; + transition: 0.3s ease; +} + +.iconButtonOpen { + font-family: Verdana, Geneva, sans-serif; + padding: 3px; + border: 2px solid white; + border-radius: 5px; + width: 130px; + height: 50px; + float: right; + margin-right: 20px; + box-sizing: border-box; + text-align: center; + background-color: white; + color: #3498db; + cursor: pointer; + transition: 0.3s ease; + transform: none; + user-select: none; +} + +.dropdownActive { + opacity: 1; + visibility: visible; + transform: translateY(0); + transition: 0.3s ease; +} + +.dropdownInactive { + opacity: 0; + visibility: hidden; + transform: translateY(-45px); + transition: 0.3s; + pointer-events: none; +} + +.dropdownMenu { + margin: 5px; + position: absolute; + right: 3px; + top: 60px; + z-index: 1000; + background-color: white; + border-bottom: 2px #3498db solid; + border-radius: 5px; +} + +.dropdownItem { + text-transform: capitalize; + display: grid; + grid-template-columns: 90px auto; + font-size: 18px; + font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif; + width: 150px; + padding: 10px; + height: 40px; + background-color: white; + border: 2px white solid; + border-radius: 5px; + color: #3498db; + align-items: center; + transform: none; + user-select: none; + cursor: pointer; +} + +.dropdownItem:hover { + background-color: whitesmoke; +} + +.dragDropIndicator { + font-size: 20px; + font-weight: bold; + position: absolute; + right: 15px; +}