From 5d82cc48f162de2eb4eaf3fa47e07f579f9699ad Mon Sep 17 00:00:00 2001 From: Gabi Melman Date: Wed, 2 Oct 2024 11:34:12 +0300 Subject: [PATCH] Version 0.38.2 --- CMakeLists.txt | 1 + ...for Face Authentication (BAO 3.8.21) 1.pdf | Bin include/RealSenseID/AuthenticateStatus.h | 3 +- include/RealSenseID/DeviceController.h | 12 +- include/RealSenseID/EnrollStatus.h | 3 +- include/RealSenseID/FaceprintsDefines.h | 3 +- include/RealSenseID/Version.h | 2 +- release_info.json | 14 +- release_notes.txt | 10 + samples/python/device_log.py | 15 ++ src/DeviceController.cc | 7 + src/DeviceControllerImpl.cc | 98 ++++++++- src/DeviceControllerImpl.h | 1 + src/FwUpdate/FwUpdateEngine.cc | 9 +- src/PacketManager/SerialPacket.h | 1 + src/StatusHelper.cc | 4 + tools/rsid-cli/main.cc | 130 ++++++++++-- tools/rsid-viewer/Dictionary1.xaml | 3 +- tools/rsid-viewer/MainWindow.xaml | 14 +- tools/rsid-viewer/MainWindow.xaml.cs | 195 ++++++++++++++++-- tools/rsid-viewer/OKCancelDialog.xaml.cs | 9 +- wrappers/c/include/rsid_c/rsid_client.h | 6 + wrappers/c/include/rsid_c/rsid_status.h | 6 +- wrappers/c/src/rsid_c_client.cc | 2 + wrappers/c/src/rsid_c_device_controller.cc | 29 +++ wrappers/csharp/Authenticator.cs | 6 +- wrappers/csharp/DeviceController.cs | 13 ++ wrappers/python/device_controller_py.cc | 17 +- wrappers/python/face_auth_py.cc | 6 +- 29 files changed, 547 insertions(+), 72 deletions(-) rename "LicenseNotices/fw/OBL license for Intel RealSense\342\204\242 ID Vision Library for Face Authentication (BAO 3.8.21) 1.pdf" => LicenseNotices/fw/OBL license for Intel RealSense ID Vision Library for Face Authentication (BAO 3.8.21) 1.pdf (100%) create mode 100644 samples/python/device_log.py diff --git a/CMakeLists.txt b/CMakeLists.txt index de54451..ccf938f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,6 +73,7 @@ option(RSID_SECURE "Enable secure communication with device" OFF) option(RSID_TOOLS "Build additional tools" ON) option(RSID_PY "Build python wrapper" OFF) + # install option option(RSID_INSTALL "Generate the install target and rsidConfig.cmake" OFF) diff --git "a/LicenseNotices/fw/OBL license for Intel RealSense\342\204\242 ID Vision Library for Face Authentication (BAO 3.8.21) 1.pdf" b/LicenseNotices/fw/OBL license for Intel RealSense ID Vision Library for Face Authentication (BAO 3.8.21) 1.pdf similarity index 100% rename from "LicenseNotices/fw/OBL license for Intel RealSense\342\204\242 ID Vision Library for Face Authentication (BAO 3.8.21) 1.pdf" rename to LicenseNotices/fw/OBL license for Intel RealSense ID Vision Library for Face Authentication (BAO 3.8.21) 1.pdf diff --git a/include/RealSenseID/AuthenticateStatus.h b/include/RealSenseID/AuthenticateStatus.h index e0b5845..626f63f 100644 --- a/include/RealSenseID/AuthenticateStatus.h +++ b/include/RealSenseID/AuthenticateStatus.h @@ -47,7 +47,8 @@ enum class RSID_API AuthenticateStatus Spoof_3D, Spoof_LR, Spoof_Disparity, - Spoof_Surface + Spoof_Surface, + Spoof_Plane_Disparity }; /** diff --git a/include/RealSenseID/DeviceController.h b/include/RealSenseID/DeviceController.h index 98b2da8..b827704 100644 --- a/include/RealSenseID/DeviceController.h +++ b/include/RealSenseID/DeviceController.h @@ -69,11 +69,21 @@ class RSID_API DeviceController Status QueryOtpVersion(uint8_t& version); /** - * Send ping packet to device + * Send ping packet to device. * @return SerialStatus::Success if device responded with a valid ping response. */ Status Ping(); + /** + * Retrieve logs from the device. + * + * @param log String that will be filled with the device's log. + * @return SerialStatus::Success on success. + * @Note: Maximum log size is 128kB; therefore, this function allocates up to 128KB and can take approximately 12-14 + * seconds to complete. + */ + Status FetchLog(std::string& log); + private: RealSenseID::DeviceControllerImpl* _impl = nullptr; }; diff --git a/include/RealSenseID/EnrollStatus.h b/include/RealSenseID/EnrollStatus.h index fe1e4b4..3be03f6 100644 --- a/include/RealSenseID/EnrollStatus.h +++ b/include/RealSenseID/EnrollStatus.h @@ -47,7 +47,8 @@ enum class RSID_API EnrollStatus Spoof_3D, Spoof_LR, Spoof_Disparity, - Spoof_Surface + Spoof_Surface, + Spoof_Plane_Disparity }; /** diff --git a/include/RealSenseID/FaceprintsDefines.h b/include/RealSenseID/FaceprintsDefines.h index a4b360e..3ff581a 100644 --- a/include/RealSenseID/FaceprintsDefines.h +++ b/include/RealSenseID/FaceprintsDefines.h @@ -69,9 +69,10 @@ struct ExtractedFaceprintsElement #ifdef __cplusplus ExtractedFaceprintsElement() { - version = (int)RSID_FACEPRINTS_VERSION; + version = RSID_FACEPRINTS_VERSION; featuresType = 0; flags = 0; + ::memset(featuresVector, 0, sizeof(featuresVector)); } ExtractedFaceprintsElement(const ExtractedFaceprintsElement& other) diff --git a/include/RealSenseID/Version.h b/include/RealSenseID/Version.h index ecd2b8b..fffda8b 100644 --- a/include/RealSenseID/Version.h +++ b/include/RealSenseID/Version.h @@ -9,7 +9,7 @@ #define RSID_VER_MAJOR 0 #define RSID_VER_MINOR 38 -#define RSID_VER_PATCH 0 +#define RSID_VER_PATCH 2 #define RSID_VERSION (RSID_VER_MAJOR * 10000 + RSID_VER_MINOR * 100 + RSID_VER_PATCH) diff --git a/release_info.json b/release_info.json index 9f1ad42..cdac2b1 100644 --- a/release_info.json +++ b/release_info.json @@ -1,8 +1,8 @@ { - "sw_version": 3800, - "sw_version_str": "0.38.0", - "fw_version": 607000306, - "fw_version_str": "6.7.0.306", - "release_url": "https://github.com/IntelRealSense/RealSenseID/releases/tag/v0.38.0", - "release_notes_url": "https://github.com/IntelRealSense/RealSenseID/blob/v0.38.0/release_notes.txt" -} + "sw_version": 3802, + "sw_version_str": "0.38.2", + "fw_version": 609000301, + "fw_version_str": "6.9.0.301", + "release_url": "https://github.com/IntelRealSense/RealSenseID/releases/tag/v0.38.2", + "release_notes_url": "https://github.com/IntelRealSense/RealSenseID/blob/v0.32.0/release_notes.txt" +} \ No newline at end of file diff --git a/release_notes.txt b/release_notes.txt index 891c2a0..de49d8b 100644 --- a/release_notes.txt +++ b/release_notes.txt @@ -1,3 +1,13 @@ +Realsense ID version 0.38.2 +----------------------------------- +* New firmware release - version 6.9.0.301 + * Improved TNR and TPR for Anti-Spoofing + * Improved debuggability + * Bug fixes +* New host SW: + * Get FW log feature + * Added unpair option to viewer + Realsense ID version 0.38.0 ----------------------------------- * New firmware release - version 6.7.0.306 diff --git a/samples/python/device_log.py b/samples/python/device_log.py new file mode 100644 index 0000000..953e448 --- /dev/null +++ b/samples/python/device_log.py @@ -0,0 +1,15 @@ +""" +License: Apache 2.0. See LICENSE file in root directory. +Copyright(c) 2020-2024 Intel Corporation. All Rights Reserved. +""" + +import rsid_py + +PORT = 'COM4' + +if __name__ == '__main__': + with rsid_py.DeviceController(PORT) as d: + log = d.fetch_log() + with open("device.log", 'w') as f: + f.write(log) + print(f'Saved {len(log)} bytes to device.log') diff --git a/src/DeviceController.cc b/src/DeviceController.cc index e815b4b..eb1b5b3 100644 --- a/src/DeviceController.cc +++ b/src/DeviceController.cc @@ -55,4 +55,11 @@ Status DeviceController::Ping() { return _impl->Ping(); } + +Status DeviceController::FetchLog(std::string& log) +{ + return _impl->FetchLog(log); +} + + } // namespace RealSenseID \ No newline at end of file diff --git a/src/DeviceControllerImpl.cc b/src/DeviceControllerImpl.cc index 05bc092..38f6e01 100644 --- a/src/DeviceControllerImpl.cc +++ b/src/DeviceControllerImpl.cc @@ -9,6 +9,8 @@ #include "Logger.h" #include #include +#include + #ifdef _WIN32 #include "PacketManager/WindowsSerial.h" @@ -111,7 +113,8 @@ Status DeviceControllerImpl::QueryFirmwareVersion(std::string& version) std::string line; while (std::getline(ss, line, '\n')) { - static const std::regex module_regex {R"((OPFW|NNLED|DNET|RECOG|YOLO|AS2DLR|NNLAS|NNLEDR|SPOOFS) : ([\d\.]+))"}; + static const std::regex module_regex { + R"((OPFW|NNLED|DNET|RECOG|YOLO|AS2DLR|NNLAS|NNLEDR|SPOOFS|ASDISP) : ([\d\.]+))"}; std::smatch match; auto match_ok = std::regex_search(line, match, module_regex); @@ -156,8 +159,8 @@ Status DeviceControllerImpl::QuerySerialNumber(std::string& serial) try { - auto send_status = _serial->SendBytes(PacketManager::Commands::device_info, - ::strlen(PacketManager::Commands::device_info)); + auto send_status = + _serial->SendBytes(PacketManager::Commands::device_info, ::strlen(PacketManager::Commands::device_info)); if (send_status != PacketManager::SerialStatus::Ok) { LOG_ERROR(LOG_TAG, "Failed sending serial number command"); @@ -223,7 +226,8 @@ Status DeviceControllerImpl::QueryOtpVersion(uint8_t& otpVer) { try { - auto send_status = _serial->SendBytes(PacketManager::Commands::otp_ver, ::strlen(PacketManager::Commands::otp_ver)); + auto send_status = + _serial->SendBytes(PacketManager::Commands::otp_ver, ::strlen(PacketManager::Commands::otp_ver)); if (send_status != PacketManager::SerialStatus::Ok) { LOG_ERROR(LOG_TAG, "Failed sending otp version command"); @@ -332,4 +336,90 @@ Status DeviceControllerImpl::Ping() } return Status::Ok; } + +Status DeviceControllerImpl::FetchLog(std::string& result) +{ + try + { + result.clear(); + auto send_status = + _serial->SendBytes(PacketManager::Commands::getlogs, ::strlen(PacketManager::Commands::getlogs)); + if (send_status != PacketManager::SerialStatus::Ok) + { + LOG_ERROR(LOG_TAG, "Failed sending getLogs command"); + return ToStatus(send_status); + } + + constexpr size_t max_result_size = 128 * 1024; + constexpr size_t reserve_size = 1024; + char buffer[1] = {0}; + const std::string start_token = "\nSTART_OF_LOG\n"; + const std::string end_token = "\nEND_OF_LOG\n"; + + result.reserve(reserve_size); + bool done = false; + // receive the data one byte at a time until "END_OF_LOG" or no more data is available (timeout is reached) + while (!done) + { + auto status = _serial->RecvBytes(buffer, 1); + switch (status) + { + case PacketManager::SerialStatus::Ok: { + auto chr = buffer[0]; + bool chr_ok = + std::isprint(static_cast(chr)) || std::isspace(static_cast(chr)); + result.push_back(chr_ok ? chr : '?'); + done = result.size() >= max_result_size; + break; + } + case PacketManager::SerialStatus::RecvTimeout: { + done = true; + break; + } + default: + LOG_ERROR(LOG_TAG, "Failed reading serial"); + return ToStatus(status); + } + } + + // remove the end token suffix if exists + auto pos = result.rfind(end_token); + if (pos != std::string::npos) + { + result.erase(pos); + } + + // expect the START_OF_LOG token + pos = result.find(start_token); + if (pos != std::string::npos) + { + result.erase(0, pos + start_token.size()); + } + else + { + result.clear(); + LOG_ERROR(LOG_TAG, "Didn't receive the START_OF_LOG token"); + return Status::Error; + } + + // make sure it ends with '\n' + if (!result.empty() && result.back() != '\n') + { + result.push_back('\n'); + } + + LOG_DEBUG(LOG_TAG, "Got %zu log bytes", result.size()); + return Status::Ok; + } + catch (std::exception& ex) + { + LOG_EXCEPTION(LOG_TAG, ex); + return Status::Error; + } + catch (...) + { + LOG_ERROR(LOG_TAG, "Unknown exception"); + return Status::Error; + } +} } // namespace RealSenseID diff --git a/src/DeviceControllerImpl.h b/src/DeviceControllerImpl.h index 48d8011..a900a62 100644 --- a/src/DeviceControllerImpl.h +++ b/src/DeviceControllerImpl.h @@ -28,6 +28,7 @@ class DeviceControllerImpl Status QuerySerialNumber(std::string& serial); Status QueryOtpVersion(uint8_t& otpVer); Status Ping(); + Status FetchLog(std::string& log); private: std::unique_ptr _serial; diff --git a/src/FwUpdate/FwUpdateEngine.cc b/src/FwUpdate/FwUpdateEngine.cc index 2519c30..5f24ec1 100644 --- a/src/FwUpdate/FwUpdateEngine.cc +++ b/src/FwUpdate/FwUpdateEngine.cc @@ -23,7 +23,8 @@ static const char* LOG_TAG = "FwUpdater"; static const char* DumpFilename = "fw-update.log"; static const std::set AllowedModules {"OPFW", "NNLED", "DNET", "RECOG", - "YOLO", "AS2DLR", "NNLAS", "NNLEDR", "SPOOFS"}; + "YOLO", "AS2DLR", "NNLAS", "NNLEDR", + "SPOOFS", "ASDISP"}; static const char* OPFW = "OPFW"; @@ -63,7 +64,7 @@ bool FwUpdateEngine::ParseDlVer(const char* input, const std::string& module_nam // regex to find line of the form: OPFW : [OPFW] [0.0.0.1] (active) // regex groups to match: module_name, module_name, version, state static const std::regex rgx { - R"((\w+) : \[(OPFW|NNLED|DNET|RECOG|YOLO|AS2DLR|SCRAP|NNLAS|NNLEDR|SPOOFS)\] \[([\d\.]+)\] \(([\w-]+)\))"}; + R"((\w+) : \[(OPFW|NNLED|DNET|RECOG|YOLO|AS2DLR|SCRAP|NNLAS|NNLEDR|SPOOFS|ASDISP)\] \[([\d\.]+)\] \(([\w-]+)\))"}; std::smatch match; @@ -410,7 +411,7 @@ void FwUpdateEngine::BurnModule(ProgressTick tick, const ModuleInfo& module, con // clean obsolete modules from FW by shrinking the size 1 block (minimum allowed) void FwUpdateEngine::CleanObsoleteModules() { - const std::vector obsolete_modules = {"NNLAS", "NNLEDR"}; + const std::vector obsolete_modules = {"NNLAS", "NNLEDR", "SPOOFS"}; // Note: NEVER add "OPFW" to the "obsolete_modules" list above ! for (const std::string &obsolete_name : obsolete_modules) @@ -437,7 +438,7 @@ void FwUpdateEngine::BurnSelectModules(const ModuleVector& modules, ProgressTick auto is_last_module = module_count == modules.size(); bool is_first_module = module_count == 1; - if (module.name == "SPOOFS") // NNLEDR/SPOOFS are new modules and need to be declated + if (module.name == "SPOOFS" || module.name == "ASDISP") // NNLEDR/SPOOFS are new modules and need to be declared { _comm->WriteCmd(Cmds::dlnew(module.name, module.size)); _comm->WaitForIdle(); diff --git a/src/PacketManager/SerialPacket.h b/src/PacketManager/SerialPacket.h index c8db1d4..072e03c 100644 --- a/src/PacketManager/SerialPacket.h +++ b/src/PacketManager/SerialPacket.h @@ -149,6 +149,7 @@ enum class MsgId : char static const char* device_info = "\r\nbspver -device\r\n"; static const char* reset = "\r\nreset\r\n"; static const char* otp_ver = "\r\ngetOtpVer\r\n"; + static const char* getlogs= "\r\ngetLogs\r\n"; } // namespace Commands } // namespace PacketManager } // namespace RealSenseID diff --git a/src/StatusHelper.cc b/src/StatusHelper.cc index 36e2196..f8c6e01 100644 --- a/src/StatusHelper.cc +++ b/src/StatusHelper.cc @@ -100,6 +100,8 @@ const char* Description(EnrollStatus status) return "Spoof_Disparity"; case RealSenseID::EnrollStatus::InvalidFeatures: return "Invalid_Features"; + case RealSenseID::EnrollStatus::Spoof_Plane_Disparity: + return "Spoof_Plane_Disparity"; default: return "Unknown Status"; } @@ -196,6 +198,8 @@ const char* Description(AuthenticateStatus status) return "TooManySpoofs"; case RealSenseID::AuthenticateStatus::InvalidFeatures: return "Invalid_Features"; + case RealSenseID::AuthenticateStatus::Spoof_Plane_Disparity: + return "Spoof_Plane_Disparity"; default: return "Unknown Status"; } diff --git a/tools/rsid-cli/main.cc b/tools/rsid-cli/main.cc index 185a0b9..2ed21ee 100644 --- a/tools/rsid-cli/main.cc +++ b/tools/rsid-cli/main.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,13 @@ #include #include #include +#include +#ifdef _WIN32 +#include // for _mkdir +#else +#include // for mkdir +#endif + #ifdef RSID_SECURE #include "secure_mode_helper.h" @@ -41,6 +49,13 @@ static RealSenseID::AuthenticateStatus s_last_auth_faceprint_status; // last faceprint enroll extract status static RealSenseID::EnrollStatus s_last_enroll_faceprint_status; +struct Args +{ + RealSenseID::SerialConfig serial_config; +#ifdef RSID_SECURE + bool unpair = false; // perform pair + unpair + exit +#endif +}; // Define the callback functions void on_start_license_check() @@ -249,7 +264,7 @@ void get_device_config(const RealSenseID::SerialConfig& serial_config) auto status = authenticator->QueryDeviceConfig(device_config); if (status == RealSenseID::Status::Ok) { - std::cout << std::endl << "Authentication settings::" << std::endl; + std::cout << std::endl << "Authentication settings:" << std::endl; std::cout << " * Rotation: " << device_config.camera_rotation << std::endl; std::cout << " * Security: " << device_config.security_level << std::endl; std::cout << " * Algo flow Mode: " << device_config.algo_flow << std::endl; @@ -500,6 +515,58 @@ void provide_license(const RealSenseID::SerialConfig& serial_config) std::cout << "Status: " << status << std::endl << std::endl; } +// get logs from the device and display last 2 KB +void query_log(const RealSenseID::SerialConfig& serial_config) +{ + RealSenseID::DeviceController deviceController; + auto connect_status = deviceController.Connect(serial_config); + if (connect_status != RealSenseID::Status::Ok) + { + std::cout << "Failed connecting to port " << serial_config.port << " status:" << connect_status << std::endl; + return; + } + + std::string log; + constexpr size_t max_logsize = 2048; + std::cout << "Fetching device log..." << std::endl; + auto status = deviceController.FetchLog(log); + + if (status != RealSenseID::Status::Ok) + { + std::cout << "Failed getting logs!\n"; + return; + } + + deviceController.Disconnect(); + + // create dumps dir if not exist and save the log in it + std::string dumps_dir = "dumps"; + std::string logfile = dumps_dir + "/f450.log"; +#ifdef _WIN32 + int rv = _mkdir(dumps_dir.c_str()); +#else + int rv = mkdir(dumps_dir.c_str(), 0777); +#endif // _WIN32 + if (rv == -1 && errno != EEXIST) + { + std::string msg = "Error creating directory " + dumps_dir; + std::perror(msg.c_str()); + return; + } + + std::ofstream ofs(logfile); + ofs << log; + if (ofs) + { + std::cout << "\n*** Saved to " << logfile << " (" << log.size() << " bytes) ***" << std::endl << std::endl; + } + else + { + std::string msg = "*** Failed saving to " + logfile; + std::perror(logfile.c_str()); + } +} + // extract faceprints for new enrolled user class MyEnrollServerClbk : public RealSenseID::EnrollFaceprintsExtractionCallback { @@ -686,13 +753,16 @@ void authenticate_faceprints(const RealSenseID::SerialConfig& serial_config) void print_usage() { +#ifdef RSID_SECURE + std::cout << "Usage: rsid-cli [-unpair]" << std::endl; +#else std::cout << "Usage: rsid-cli " << std::endl; +#endif } -RealSenseID::SerialConfig config_from_argv(int argc, char* argv[]) +Args config_from_argv(int argc, char* argv[]) { - RealSenseID::SerialConfig config; - if (argc < 2) + if (argc != 2 && argc != 3) { print_usage(); @@ -700,18 +770,38 @@ RealSenseID::SerialConfig config_from_argv(int argc, char* argv[]) auto devices = RealSenseID::DiscoverDevices(); if (!devices.empty()) { - std::for_each(devices.begin(), devices.end(), [](const auto &device) { + std::for_each(devices.begin(), devices.end(), [](const auto& device) { std::cout << " [*] Found rsid device on port: " << device.serialPort << std::endl; }); - } else { + } + else + { std::cout << " [ ] No rsid devices were found." << std::endl; } std::exit(1); } - config.port = argv[1]; - return config; + // mandatory serial port in first arg + Args args; + args.serial_config.port = argv[1]; + +#ifdef RSID_SECURE + // optional unpair command in second arg + if (argc > 2) + { + if (std::string(argv[2]) == "-unpair") + { + args.unpair = true; + } + else + { + print_usage(); + std::exit(1); + } + } +#endif + return args; } void print_menu_opt(const char* line) @@ -743,6 +833,7 @@ void print_menu() print_menu_opt("'x' to ping the device."); print_menu_opt("'l' to provide license."); print_menu_opt("'L' to unlock."); + print_menu_opt("'o' to fetch device log."); print_menu_opt("'q' to quit."); // server mode opts @@ -788,7 +879,7 @@ void sample_loop(const RealSenseID::SerialConfig& serial_config) do_authenticate(serial_config); break; case 't': { - std::stringstream ss; // Used to convert string to int + std::stringstream ss; // Used to convert string to int int iter = 5; while (true) { @@ -803,7 +894,7 @@ void sample_loop(const RealSenseID::SerialConfig& serial_config) } int delay_ms = 50; - + while (true) { input.clear(); @@ -1023,6 +1114,9 @@ void sample_loop(const RealSenseID::SerialConfig& serial_config) case 'l': provide_license(serial_config); break; + case 'o': + query_log(serial_config); + break; } } } @@ -1031,8 +1125,20 @@ int main(int argc, char* argv[]) { try { - auto config = config_from_argv(argc, argv); - sample_loop(config); + auto args = config_from_argv(argc, argv); +#ifdef RSID_SECURE + if (args.unpair) + { + std::cout << "**** Pairing device ****\n"; + pair_device(args.serial_config); + std::this_thread::sleep_for(std::chrono::milliseconds(100)); + std::cout << "\n***** Un-Pairing device****\n"; + unpair_device(args.serial_config); + return 0; + } +#endif // RSID_SECURE + + sample_loop(args.serial_config); return 0; } catch (const std::exception& ex) diff --git a/tools/rsid-viewer/Dictionary1.xaml b/tools/rsid-viewer/Dictionary1.xaml index 6d2a260..e3c9f0a 100644 --- a/tools/rsid-viewer/Dictionary1.xaml +++ b/tools/rsid-viewer/Dictionary1.xaml @@ -35,6 +35,7 @@ +