Skip to content

Commit

Permalink
Merge pull request #6743 from remibettan/fw-logs-wrapper-android
Browse files Browse the repository at this point in the history
Fw logs and terminal parser api fix, wrappers android and C#
  • Loading branch information
ev-mp authored Jul 7, 2020
2 parents fdf89fd + 6a47ef6 commit 4c6bdf7
Show file tree
Hide file tree
Showing 25 changed files with 1,002 additions and 199 deletions.
10 changes: 2 additions & 8 deletions include/librealsense2/h/rs_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ rs2_firmware_log_message* rs2_create_fw_log_message(rs2_device* dev, rs2_error**
* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored.
* \return true for success, false for failure - failure happens if no firmware log was sent by the hardware monitor
*/
int rs2_get_fw_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error);
int rs2_get_fw_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg, rs2_error** error);

/**
* \brief Gets RealSense flash log - this is a fw log that has been written in the device during the previous shutdown of the device
Expand All @@ -372,7 +372,7 @@ int rs2_get_fw_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_e
* \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored.
* \return true for success, false for failure - failure happens if no firmware log was sent by the hardware monitor
*/
int rs2_get_flash_log(rs2_device* dev, rs2_firmware_log_message** fw_log_msg, rs2_error** error);
int rs2_get_flash_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg, rs2_error** error);

/**
* Delete RealSense firmware log message
Expand Down Expand Up @@ -448,12 +448,6 @@ void rs2_delete_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_pa
*/
int rs2_parse_firmware_log(rs2_device* dev, rs2_firmware_log_message* fw_log_msg, rs2_firmware_log_parsed_message* parsed_msg, rs2_error** error);

/**
* Delete RealSense firmware log parsed message
* \param[in] device Realsense firmware log parsed message to delete
*/
void rs2_delete_fw_log_parsed_message(rs2_firmware_log_parsed_message* fw_log_parsed_msg);

/**
* \brief Gets RealSense firmware log parsed message.
* \param[in] fw_log_parsed_msg firmware log parsed message object
Expand Down
4 changes: 2 additions & 2 deletions include/librealsense2/hpp/rs_internal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ namespace rs2
rs2_error* e = nullptr;
rs2_firmware_log_message* m = msg.get_message().get();
bool fw_log_pulling_status =
rs2_get_fw_log(_dev.get(), &(m), &e);
rs2_get_fw_log(_dev.get(), m, &e);

error::handle(e);

Expand All @@ -524,7 +524,7 @@ namespace rs2
rs2_error* e = nullptr;
rs2_firmware_log_message* m = msg.get_message().get();
bool flash_log_pulling_status =
rs2_get_flash_log(_dev.get(), &(m), &e);
rs2_get_flash_log(_dev.get(), m, &e);

error::handle(e);

Expand Down
212 changes: 68 additions & 144 deletions src/android/jni/debug_protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,138 +2,11 @@
// Copyright(c) 2019 Intel Corporation. All Rights Reserved.

#include <jni.h>
#include <memory>
#include <vector>
#include "error.h"
#include <iostream>
#include <fstream>
#include <string>
#include "../../../include/librealsense2/h/rs_internal.h"
#include "../../../common/parser.hpp" //needed for auto completion in nGetCommands

#include "../../../include/librealsense2/rs.h"
#include "../../../include/librealsense2/hpp/rs_device.hpp"
#include "../../api.h"
#include "../../../common/parser.hpp"

using std::string;
using std::hex;

std::vector<uint8_t> send_and_receive_raw_data(JNIEnv *env, rs2_device * dev, const std::vector<uint8_t>& input)
{
std::vector<uint8_t> results;

rs2_error *e = NULL;
std::shared_ptr<const rs2_raw_data_buffer> list(
rs2_send_and_receive_raw_data(dev, (void*)input.data(), (uint32_t)input.size(), &e),
rs2_delete_raw_data);
handle_error(env, e);

auto size = rs2_get_raw_data_size(list.get(), &e);
handle_error(env, e);

auto start = rs2_get_raw_data(list.get(), &e);

results.insert(results.begin(), start, start + size);

return results;
}

std::string hex_mode(JNIEnv *env, rs2_device * dev, const std::string& line)
{
std::vector<uint8_t> raw_data;
std::stringstream ss(line);
std::string word;
while (ss >> word)
{
std::stringstream converter;
int temp;
converter << std::hex << word;
converter >> temp;
raw_data.push_back(temp);
}
if (raw_data.empty())
throw std::runtime_error("Wrong input!");

auto result = send_and_receive_raw_data(env, dev, raw_data);

std::stringstream rv;
for (auto& elem : result)
rv << std::setfill('0') << std::setw(2) << std::hex << static_cast<int>(elem) << " ";

return rv.str();
}

std::vector<uint8_t> build_raw_command_data(const command& command, const std::vector<std::string>& params)
{
if (params.size() > command.parameters.size() && !command.is_cmd_write_data)
throw std::runtime_error("Input string was not in a correct format!");

std::vector<parameter> vec_parameters;
for (auto param_index = 0; param_index < params.size(); ++param_index)
{
auto is_there_write_data = param_index >= int(command.parameters.size());
auto name = (is_there_write_data) ? "" : command.parameters[param_index].name;
auto is_reverse_bytes = (is_there_write_data) ? false : command.parameters[param_index].is_reverse_bytes;
auto is_decimal = (is_there_write_data) ? false : command.parameters[param_index].is_decimal;
auto format_length = (is_there_write_data) ? -1 : command.parameters[param_index].format_length;
vec_parameters.push_back(parameter(name, params[param_index], is_decimal, is_reverse_bytes, format_length));
}

std::vector<uint8_t> raw_data;
encode_raw_data_command(command, vec_parameters, raw_data);
return raw_data;
}

std::string xml_mode(const std::string& line, const commands_xml& cmd_xml, std::map<std::string,
xml_parser_function>& format_type_to_lambda, JNIEnv *env, jlong handle)
{
try {
std::vector<string> tokens;
std::stringstream ss(line);
std::string word;
while (ss >> word) {
std::stringstream converter;
converter << hex << word;
tokens.push_back(word);
}

if (tokens.empty())
throw std::runtime_error("Wrong input!");

auto command_str = tokens.front();
auto it = cmd_xml.commands.find(command_str);
if (it == cmd_xml.commands.end())
throw std::runtime_error("Command not found!");

auto command = it->second;
std::vector<std::string> params;
for (auto i = 1; i < tokens.size(); ++i)
params.push_back(tokens[i]);

auto raw_data = build_raw_command_data(command, params);

auto result = send_and_receive_raw_data(env, reinterpret_cast<rs2_device *>(handle),
raw_data);

unsigned returned_opcode = *result.data();
// check returned opcode
if (command.op_code != returned_opcode) {
std::stringstream msg;
msg << "OpCodes do not match! Sent 0x" << hex << command.op_code << " but received 0x"
<< hex << (returned_opcode) << "!";
throw std::runtime_error(msg.str());
}

if(!command.is_read_command)
return "Executed Successfully";

std::string rv;
decode_string_from_raw_data(command, cmd_xml.custom_formatters, result.data(),
result.size(), rv, format_type_to_lambda);
return rv;
}catch(std::exception& e){
return e.what();
}
}

extern "C"
JNIEXPORT jbyteArray JNICALL
Expand All @@ -142,11 +15,22 @@ Java_com_intel_realsense_librealsense_DebugProtocol_nSendAndReceiveRawData(JNIEn
jbyteArray buffer_) {
jbyte *buffer = env->GetByteArrayElements(buffer_, NULL);
jsize length = env->GetArrayLength(buffer_);
std::vector<uint8_t> buff(reinterpret_cast<uint8_t*>(buffer), reinterpret_cast<uint8_t*>(buffer) + length);
auto ret = send_and_receive_raw_data(env, reinterpret_cast<rs2_device *>(handle), buff);

rs2_error* e = NULL;
std::shared_ptr<const rs2_raw_data_buffer> response_bytes(
rs2_send_and_receive_raw_data(reinterpret_cast<rs2_device*>(handle), (void*)buffer, (int)length, &e),
rs2_delete_raw_data);

int response_size = rs2_get_raw_data_size(response_bytes.get(), &e);
handle_error(env, e);

const unsigned char* response_start = rs2_get_raw_data(response_bytes.get(), &e);
handle_error(env, e);

env->ReleaseByteArrayElements(buffer_, buffer, 0);
jbyteArray rv = env->NewByteArray(ret.size());
env->SetByteArrayRegion (rv, 0, ret.size(), reinterpret_cast<const jbyte *>(ret.data()));
jbyteArray rv = env->NewByteArray(response_size);
env->SetByteArrayRegion (rv, 0, response_size, reinterpret_cast<const jbyte *>(response_start));

return rv;
}

Expand All @@ -159,23 +43,63 @@ Java_com_intel_realsense_librealsense_DebugProtocol_nSendAndReceiveData(JNIEnv *
const char *file_path = env->GetStringUTFChars(filePath, 0);
const char *line = env->GetStringUTFChars(command, 0);

std::map<string, xml_parser_function> format_type_to_lambda;
commands_xml cmd_xml;
std::ifstream f(file_path);
std::string xml_content((std::istreambuf_iterator<char>(f)), std::istreambuf_iterator<char>());

std::string result = "failed to open commands file";
bool sts = parse_xml_from_file(file_path, cmd_xml);
if(sts){
update_format_type_to_lambda(format_type_to_lambda);
rs2_error* e = NULL;

result = xml_mode(line, cmd_xml, format_type_to_lambda, env, handle);
}
//creating terminal parser
std::shared_ptr<rs2_terminal_parser> terminal_parser = std::shared_ptr<rs2_terminal_parser>(
rs2_create_terminal_parser(xml_content.c_str(), &e),
rs2_delete_terminal_parser);
handle_error(env, e);

//using parser to get bytes command from the string command
int line_length = strlen(line);
std::shared_ptr<const rs2_raw_data_buffer> command_buffer(
rs2_terminal_parse_command(terminal_parser.get(), line, line_length, &e),
rs2_delete_raw_data);
handle_error(env, e);

int command_size = rs2_get_raw_data_size(command_buffer.get(), &e);
handle_error(env, e);

const unsigned char* command_start = rs2_get_raw_data(command_buffer.get(), &e);
handle_error(env, e);

//calling send_receive to get the bytes response
std::shared_ptr<const rs2_raw_data_buffer> response_bytes(
rs2_send_and_receive_raw_data(reinterpret_cast<rs2_device*>(handle), (void*)command_start, command_size, &e),
rs2_delete_raw_data);

int response_size = rs2_get_raw_data_size(response_bytes.get(), &e);
handle_error(env, e);

const unsigned char* response_start = rs2_get_raw_data(response_bytes.get(), &e);
handle_error(env, e);

//using parser to get response string from response bytes and string command
std::shared_ptr<const rs2_raw_data_buffer> response_buffer(
rs2_terminal_parse_response(terminal_parser.get(), line, line_length,
(void*)response_start, response_size, &e),
rs2_delete_raw_data);
handle_error(env, e);

int response_buffer_size = rs2_get_raw_data_size(response_buffer.get(), &e);
handle_error(env, e);

const unsigned char* response_buffer_start = rs2_get_raw_data(response_buffer.get(), &e);
handle_error(env, e);

//releasing jni resources
env->ReleaseStringUTFChars(command, line);
env->ReleaseStringUTFChars(filePath, file_path);

jbyteArray rv = env->NewByteArray(result.size());
env->SetByteArrayRegion(rv, 0, result.size(),
reinterpret_cast<const jbyte *>(result.c_str()));
//assigning return value
jbyteArray rv = env->NewByteArray(response_buffer_size);
env->SetByteArrayRegion(rv, 0, response_buffer_size,
reinterpret_cast<const jbyte *>(response_buffer_start));

return rv;
}

Expand Down
Loading

0 comments on commit 4c6bdf7

Please sign in to comment.