mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-20 23:33:35 +08:00
ParamServer - automatic case conversion for parameter names
This commit is contained in:
@@ -79,22 +79,48 @@ class UAVCAN_EXPORT ParamServer
|
|||||||
void (ParamServer::*)(const protocol::param::ExecuteOpcode::Request&,
|
void (ParamServer::*)(const protocol::param::ExecuteOpcode::Request&,
|
||||||
protocol::param::ExecuteOpcode::Response&)> ExecuteOpcodeCallback;
|
protocol::param::ExecuteOpcode::Response&)> ExecuteOpcodeCallback;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* This class can automatically enforce that parameter names are not case-sensitive, by means of
|
||||||
|
* automatic conversion to either upper or lower case whenever a parameter name is received.
|
||||||
|
* For instance, if the lower-case conversion is enabled, then a UAVCAN request for a parameter
|
||||||
|
* named "Foo" will be passed to the application as "foo". Similarly, when the application reports
|
||||||
|
* that it has a parameter named "FOO", the class will convert the name to "foo".
|
||||||
|
*/
|
||||||
|
enum ParamNameCaseConversion
|
||||||
|
{
|
||||||
|
ParamNameCaseConversionDisabled, ///< Do not convert parameter names. The case will remain intact.
|
||||||
|
ParamNameCaseConversionToLower, ///< Convert parameter names to lower case.
|
||||||
|
ParamNameCaseConversionToUpper ///< Convert parameter names to upper case.
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
ServiceServer<protocol::param::GetSet, GetSetCallback> get_set_srv_;
|
ServiceServer<protocol::param::GetSet, GetSetCallback> get_set_srv_;
|
||||||
ServiceServer<protocol::param::ExecuteOpcode, ExecuteOpcodeCallback> save_erase_srv_;
|
ServiceServer<protocol::param::ExecuteOpcode, ExecuteOpcodeCallback> save_erase_srv_;
|
||||||
IParamManager* manager_;
|
IParamManager* manager_;
|
||||||
|
const ParamNameCaseConversion param_name_case_conversion_mode_;
|
||||||
|
|
||||||
static bool isValueNonEmpty(const protocol::param::Value& value);
|
static bool isValueNonEmpty(const protocol::param::Value& value);
|
||||||
|
|
||||||
|
void convertParamNameCase(IParamManager::ParamName& name) const;
|
||||||
|
|
||||||
void handleGetSet(const protocol::param::GetSet::Request& request, protocol::param::GetSet::Response& response);
|
void handleGetSet(const protocol::param::GetSet::Request& request, protocol::param::GetSet::Response& response);
|
||||||
|
|
||||||
void handleExecuteOpcode(const protocol::param::ExecuteOpcode::Request& request,
|
void handleExecuteOpcode(const protocol::param::ExecuteOpcode::Request& request,
|
||||||
protocol::param::ExecuteOpcode::Response& response);
|
protocol::param::ExecuteOpcode::Response& response);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ParamServer(INode& node)
|
/**
|
||||||
|
* @param param_name_case_conversion Specifies the parameter name conversion mode. Lower case is default,
|
||||||
|
* which means that an external request for a parameter named "Foo" will
|
||||||
|
* be relayed to the application as "foo".
|
||||||
|
*/
|
||||||
|
explicit ParamServer(INode& node,
|
||||||
|
ParamNameCaseConversion param_name_case_conversion = ParamNameCaseConversionToLower)
|
||||||
: get_set_srv_(node)
|
: get_set_srv_(node)
|
||||||
, save_erase_srv_(node)
|
, save_erase_srv_(node)
|
||||||
, manager_(NULL)
|
, manager_(NULL)
|
||||||
|
, param_name_case_conversion_mode_(param_name_case_conversion)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -18,6 +18,22 @@ bool ParamServer::isValueNonEmpty(const protocol::param::Value& value)
|
|||||||
!value.value_string.empty();
|
!value.value_string.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ParamServer::convertParamNameCase(IParamManager::ParamName& name) const
|
||||||
|
{
|
||||||
|
if (param_name_case_conversion_mode_ == ParamNameCaseConversionToLower)
|
||||||
|
{
|
||||||
|
name.convertToLowerCaseASCII();
|
||||||
|
}
|
||||||
|
else if (param_name_case_conversion_mode_ == ParamNameCaseConversionToUpper)
|
||||||
|
{
|
||||||
|
name.convertToUpperCaseASCII();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
; // Conversion is not needed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ParamServer::handleGetSet(const protocol::param::GetSet::Request& in, protocol::param::GetSet::Response& out)
|
void ParamServer::handleGetSet(const protocol::param::GetSet::Request& in, protocol::param::GetSet::Response& out)
|
||||||
{
|
{
|
||||||
UAVCAN_ASSERT(manager_ != NULL);
|
UAVCAN_ASSERT(manager_ != NULL);
|
||||||
@@ -33,6 +49,8 @@ void ParamServer::handleGetSet(const protocol::param::GetSet::Request& in, proto
|
|||||||
out.name = in.name;
|
out.name = in.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
convertParamNameCase(out.name);
|
||||||
|
|
||||||
// Assign if needed, read back
|
// Assign if needed, read back
|
||||||
if (isValueNonEmpty(in.value))
|
if (isValueNonEmpty(in.value))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ TEST(ParamServer, Basic)
|
|||||||
|
|
||||||
// Get by name
|
// Get by name
|
||||||
get_set_rq = uavcan::protocol::param::GetSet::Request();
|
get_set_rq = uavcan::protocol::param::GetSet::Request();
|
||||||
get_set_rq.name = "foobar";
|
get_set_rq.name = "FOOBAR"; // Requesting in upper case
|
||||||
doCall(get_set_cln, get_set_rq, nodes);
|
doCall(get_set_cln, get_set_rq, nodes);
|
||||||
ASSERT_STREQ("foobar", get_set_cln.collector.result->response.name.c_str());
|
ASSERT_STREQ("foobar", get_set_cln.collector.result->response.name.c_str());
|
||||||
ASSERT_TRUE(get_set_cln.collector.result->response.value.value_bool.empty());
|
ASSERT_TRUE(get_set_cln.collector.result->response.value.value_bool.empty());
|
||||||
@@ -171,3 +171,68 @@ TEST(ParamServer, Basic)
|
|||||||
ASSERT_STREQ("foobar", get_set_cln.collector.result->response.name.c_str());
|
ASSERT_STREQ("foobar", get_set_cln.collector.result->response.name.c_str());
|
||||||
ASSERT_FLOAT_EQ(424242, get_set_cln.collector.result->response.value.value_float[0]);
|
ASSERT_FLOAT_EQ(424242, get_set_cln.collector.result->response.value.value_float[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ParamServer, UpperCaseConversion)
|
||||||
|
{
|
||||||
|
InterlinkedTestNodesWithSysClock nodes;
|
||||||
|
|
||||||
|
uavcan::ParamServer server(nodes.a, uavcan::ParamServer::ParamNameCaseConversionToUpper);
|
||||||
|
|
||||||
|
ParamServerTestManager mgr;
|
||||||
|
|
||||||
|
uavcan::GlobalDataTypeRegistry::instance().reset();
|
||||||
|
uavcan::DefaultDataTypeRegistrator<uavcan::protocol::param::GetSet> _reg1;
|
||||||
|
uavcan::DefaultDataTypeRegistrator<uavcan::protocol::param::ExecuteOpcode> _reg2;
|
||||||
|
|
||||||
|
ASSERT_LE(0, server.start(&mgr));
|
||||||
|
|
||||||
|
ServiceClientWithCollector<uavcan::protocol::param::GetSet> get_set_cln(nodes.b);
|
||||||
|
|
||||||
|
mgr.kv["foobar"] = 0.0; // Will be ignored because not upper case
|
||||||
|
mgr.kv["FOOBAR"] = 123.456;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get/set
|
||||||
|
*/
|
||||||
|
uavcan::protocol::param::GetSet::Request get_set_rq;
|
||||||
|
get_set_rq = uavcan::protocol::param::GetSet::Request();
|
||||||
|
get_set_rq.name = "foobar"; // Requesting in upper case
|
||||||
|
doCall(get_set_cln, get_set_rq, nodes);
|
||||||
|
ASSERT_STREQ("FOOBAR", get_set_cln.collector.result->response.name.c_str());
|
||||||
|
ASSERT_TRUE(get_set_cln.collector.result->response.value.value_bool.empty());
|
||||||
|
ASSERT_TRUE(get_set_cln.collector.result->response.value.value_int.empty());
|
||||||
|
ASSERT_FLOAT_EQ(123.456F, get_set_cln.collector.result->response.value.value_float[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ParamServer, NoCaseConversion)
|
||||||
|
{
|
||||||
|
InterlinkedTestNodesWithSysClock nodes;
|
||||||
|
|
||||||
|
uavcan::ParamServer server(nodes.a, uavcan::ParamServer::ParamNameCaseConversionDisabled);
|
||||||
|
|
||||||
|
ParamServerTestManager mgr;
|
||||||
|
|
||||||
|
uavcan::GlobalDataTypeRegistry::instance().reset();
|
||||||
|
uavcan::DefaultDataTypeRegistrator<uavcan::protocol::param::GetSet> _reg1;
|
||||||
|
uavcan::DefaultDataTypeRegistrator<uavcan::protocol::param::ExecuteOpcode> _reg2;
|
||||||
|
|
||||||
|
ASSERT_LE(0, server.start(&mgr));
|
||||||
|
|
||||||
|
ServiceClientWithCollector<uavcan::protocol::param::GetSet> get_set_cln(nodes.b);
|
||||||
|
|
||||||
|
mgr.kv["foobar"] = 0.0;
|
||||||
|
mgr.kv["FooBar"] = 123.456;
|
||||||
|
mgr.kv["FOOBAR"] = 0.0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get/set
|
||||||
|
*/
|
||||||
|
uavcan::protocol::param::GetSet::Request get_set_rq;
|
||||||
|
get_set_rq = uavcan::protocol::param::GetSet::Request();
|
||||||
|
get_set_rq.name = "FooBar";
|
||||||
|
doCall(get_set_cln, get_set_rq, nodes);
|
||||||
|
ASSERT_STREQ("FooBar", get_set_cln.collector.result->response.name.c_str());
|
||||||
|
ASSERT_TRUE(get_set_cln.collector.result->response.value.value_bool.empty());
|
||||||
|
ASSERT_TRUE(get_set_cln.collector.result->response.value.value_int.empty());
|
||||||
|
ASSERT_FLOAT_EQ(123.456F, get_set_cln.collector.result->response.value.value_float[0]);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user