From a10b751195b8114c7b5600240bb816df8438a0cf Mon Sep 17 00:00:00 2001 From: "kibak.yoon" Date: Mon, 19 Dec 2016 22:52:37 +0900 Subject: [PATCH] sensord: refactoring sensorctl for testing modules - To refactoring, there was the following changes. * add test_bench to create testcases easily * clean tester/injector/info/loopback files - testing command examples $ sensorctl test accelerometer /* test accelerometer sensor manually */ $ sensorctl test auto all /* test all testcases automatically with full-log */ $ sensorctl test auto socket 0 /* test socket module automatically without full-log */ $ sensorctl info all $ sensorctl inject Change-Id: Ie888c81f85d282eab77a8e1227d26710a85e9c61 Signed-off-by: kibak.yoon --- include/sensor_hal_types.h | 1 + src/sensorctl/CMakeLists.txt | 9 +- src/sensorctl/dbus_util.cpp | 12 +- src/sensorctl/dbus_util.h | 6 +- src/sensorctl/{info_manager.cpp => info.cpp} | 53 +++-- src/sensorctl/{info_manager.h => info.h} | 8 +- src/sensorctl/injector.cpp | 108 ++++++++++ src/sensorctl/injector.h | 51 ++++- src/sensorctl/injector_context_orientation.cpp | 37 ++-- src/sensorctl/injector_manager.cpp | 130 ------------ src/sensorctl/injector_manager.h | 58 ------ src/sensorctl/injector_wrist_up_conf.cpp | 59 ------ ...wrist_up_algo.cpp => injector_wristup_algo.cpp} | 45 ++-- src/sensorctl/injector_wristup_conf.cpp | 65 ++++++ src/sensorctl/log.h | 85 ++++++++ .../{loopback_manager.cpp => loopback.cpp} | 19 +- src/sensorctl/{loopback_manager.h => loopback.h} | 4 +- .../{injector_wrist_up_conf.h => macro.h} | 17 +- src/sensorctl/mainloop.cpp | 69 +++++++ .../{injector_context_orientation.h => mainloop.h} | 20 +- src/sensorctl/sensor_adapter.cpp | 160 +++++++++++++++ src/sensorctl/sensor_adapter.h | 62 ++++++ src/sensorctl/sensor_manager.cpp | 133 ++++++------ src/sensorctl/sensor_manager.h | 15 +- src/sensorctl/sensorctl.cpp | 78 +++---- src/sensorctl/sensorctl_log.h | 49 ----- src/sensorctl/test_bench.cpp | 226 +++++++++++++++++++++ src/sensorctl/test_bench.h | 201 ++++++++++++++++++ src/sensorctl/testcase/accelerometer.cpp | 170 ++++++++++++++++ src/sensorctl/testcase/sensor_basic.cpp | 168 +++++++++++++++ .../sensor_interval.cpp} | 21 +- src/sensorctl/tester.cpp | 188 +++++++++++++++++ src/sensorctl/tester.h | 25 ++- src/sensorctl/tester_manager.cpp | 79 ------- src/sensorctl/tester_sensor.cpp | 151 -------------- src/sensorctl/tester_sensor.h | 34 ---- src/sensorctl/util.cpp | 59 ++++++ src/sensorctl/{tester_manager.h => util.h} | 16 +- 38 files changed, 1885 insertions(+), 806 deletions(-) rename src/sensorctl/{info_manager.cpp => info.cpp} (63%) rename src/sensorctl/{info_manager.h => info.h} (81%) create mode 100644 src/sensorctl/injector.cpp delete mode 100644 src/sensorctl/injector_manager.cpp delete mode 100644 src/sensorctl/injector_manager.h delete mode 100644 src/sensorctl/injector_wrist_up_conf.cpp rename src/sensorctl/{injector_wrist_up_algo.cpp => injector_wristup_algo.cpp} (59%) create mode 100644 src/sensorctl/injector_wristup_conf.cpp create mode 100644 src/sensorctl/log.h rename src/sensorctl/{loopback_manager.cpp => loopback.cpp} (83%) rename src/sensorctl/{loopback_manager.h => loopback.h} (91%) rename src/sensorctl/{injector_wrist_up_conf.h => macro.h} (64%) create mode 100644 src/sensorctl/mainloop.cpp rename src/sensorctl/{injector_context_orientation.h => mainloop.h} (70%) create mode 100644 src/sensorctl/sensor_adapter.cpp create mode 100644 src/sensorctl/sensor_adapter.h delete mode 100644 src/sensorctl/sensorctl_log.h create mode 100644 src/sensorctl/test_bench.cpp create mode 100644 src/sensorctl/test_bench.h create mode 100644 src/sensorctl/testcase/accelerometer.cpp create mode 100644 src/sensorctl/testcase/sensor_basic.cpp rename src/sensorctl/{injector_wrist_up_algo.h => testcase/sensor_interval.cpp} (62%) create mode 100644 src/sensorctl/tester.cpp delete mode 100644 src/sensorctl/tester_manager.cpp delete mode 100644 src/sensorctl/tester_sensor.cpp delete mode 100644 src/sensorctl/tester_sensor.h create mode 100644 src/sensorctl/util.cpp rename src/sensorctl/{tester_manager.h => util.h} (67%) diff --git a/include/sensor_hal_types.h b/include/sensor_hal_types.h index 6beb935..6ad991d 100644 --- a/include/sensor_hal_types.h +++ b/include/sensor_hal_types.h @@ -223,6 +223,7 @@ typedef struct { #define CONVERT_TYPE_ATTR(type, index) ((type) << 8 | 0x80 | (index)) enum sensor_attribute { + SENSOR_ATTR_ACCELEROMETER_INJECTION = CONVERT_TYPE_ATTR(SENSOR_DEVICE_ACCELEROMETER, 0xFF), SENSOR_ATTR_ACTIVITY = CONVERT_TYPE_ATTR(SENSOR_DEVICE_ACTIVITY_TRACKER, 0x1), SENSOR_ATTR_PEDOMETER_HEIGHT = CONVERT_TYPE_ATTR(SENSOR_DEVICE_HUMAN_PEDOMETER, 0x1), diff --git a/src/sensorctl/CMakeLists.txt b/src/sensorctl/CMakeLists.txt index 2b9c675..7b44303 100644 --- a/src/sensorctl/CMakeLists.txt +++ b/src/sensorctl/CMakeLists.txt @@ -2,19 +2,20 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) PROJECT(sensorctl CXX) INCLUDE(GNUInstallDirs) -SET(DEPS glib-2.0 gio-2.0) +SET(DEPENDENTS glib-2.0 gio-2.0) INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED ${DEPS}) +PKG_CHECK_MODULES(PKGS REQUIRED ${DEPENDENTS}) INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_SOURCE_DIR}/src/ ${CMAKE_SOURCE_DIR}/src/hal/ ${CMAKE_SOURCE_DIR}/src/client/ ${CMAKE_SOURCE_DIR}/src/shared/ ) -FOREACH(flag ${pkgs_CFLAGS}) +FOREACH(flag ${PKGS_CFLAGS}) SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}") ENDFOREACH(flag) @@ -24,5 +25,5 @@ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}") FILE(GLOB_RECURSE SRCS *.cpp) ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE CXX) -TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} sensor) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${PKGS_LDFLAGS} sensor sensord-shared) INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/src/sensorctl/dbus_util.cpp b/src/sensorctl/dbus_util.cpp index 886872e..a18d8c0 100644 --- a/src/sensorctl/dbus_util.cpp +++ b/src/sensorctl/dbus_util.cpp @@ -17,10 +17,13 @@ * */ +#include "dbus_util.h" + #include #include #include -#include + +#include "log.h" static GDBusConnection *connection; @@ -39,7 +42,7 @@ bool dbus_init(void) gaddr = g_dbus_address_get_for_bus_sync(G_BUS_TYPE_SYSTEM, NULL, &error); if (!gaddr) { - PRINT("ERROR: Failed to get dbus address : %s", error->message); + _E("Failed to get dbus address : %s\n", error->message); g_error_free(error); error = NULL; return false; @@ -52,13 +55,13 @@ bool dbus_init(void) g_free(gaddr); if (!connection) { - PRINT("ERROR: Failed to get dbus connection : %s", error->message); + _E("Failed to get dbus connection : %s\n", error->message); g_error_free(error); error = NULL; return false; } - PRINT("G-DBUS connected[%s]\n", + _I("G-DBUS connected[%s]\n", g_dbus_connection_get_unique_name(connection)); return true; } @@ -104,4 +107,3 @@ GVariant *make_variant_int(int count, char *options[]) return NULL; } - diff --git a/src/sensorctl/dbus_util.h b/src/sensorctl/dbus_util.h index a51d903..e03166a 100644 --- a/src/sensorctl/dbus_util.h +++ b/src/sensorctl/dbus_util.h @@ -17,11 +17,15 @@ * */ -#pragma once // _DBUS_UTIL_H_ +#pragma once /* __DBUS_UTIL_H__ */ #include #include +#define SENSORD_BUS_NAME "org.tizen.system.sensord" +#define SENSORD_OBJ_PATH "/Org/Tizen/System/SensorD" +#define SENSORD_INTERFACE_NAME "org.tizen.system.sensord" + bool dbus_init(void); bool dbus_fini(void); bool dbus_emit_signal(gchar *dest_bus_name, gchar *object_path, diff --git a/src/sensorctl/info_manager.cpp b/src/sensorctl/info.cpp similarity index 63% rename from src/sensorctl/info_manager.cpp rename to src/sensorctl/info.cpp index 676bc40..6597230 100644 --- a/src/sensorctl/info_manager.cpp +++ b/src/sensorctl/info.cpp @@ -1,7 +1,7 @@ /* * sensorctl * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,37 +17,38 @@ * */ +#include "info.h" + #include -#include #include #include -#include -#include "info_manager.h" -bool info_manager::process(int argc, char *argv[]) +#include "log.h" + +#define INFO_ARGC 3 /* e.g. {sensorctl, info, accelerometer} */ + +bool info_manager::run(int argc, char *argv[]) { sensor_type_t type; + sensor_t *sensors; + int count; - if (argc == 2) { + if (argc < INFO_ARGC) { usage(); return false; } type = get_sensor_type(argv[2]); - if (type == UNKNOWN_SENSOR) - return false; - - sensor_t *sensors; - int count; + RETVM_IF(type == UNKNOWN_SENSOR, false, "Wrong argument : %s\n", argv[2]); sensord_get_sensor_list(type, &sensors, &count); - sensor_info(sensors, count); + show_info(sensors, count); - free(sensors); + delete sensors; return true; } -void info_manager::sensor_info(sensor_t *sensors, int count) +void info_manager::show_info(sensor_t *sensors, int count) { sensor_t sensor; char *vendor; @@ -71,24 +72,22 @@ void info_manager::sensor_info(sensor_t *sensors, int count) sensord_get_fifo_count(sensor, &fifo_count); sensord_get_max_batch_count(sensor, &max_batch_count); - PRINT("-------sensor[%d] information-------\n", i); - PRINT("vendor : %s\n", vendor); - PRINT("name : %s\n", name); - PRINT("min_range : %f\n", min_range); - PRINT("max_range : %f\n", max_range); - PRINT("resolution : %f\n", resolution); - PRINT("min_interval : %d\n", min_interval); - PRINT("fifo_count : %d\n", fifo_count); - PRINT("max_batch_count : %d\n", max_batch_count); - PRINT("--------------------------------\n"); + _N("-------sensor[%d] information-------\n", i); + _N("vendor : %s\n", vendor); + _N("name : %s\n", name); + _N("min_range : %f\n", min_range); + _N("max_range : %f\n", max_range); + _N("resolution : %f\n", resolution); + _N("min_interval : %d\n", min_interval); + _N("fifo_count : %d\n", fifo_count); + _N("max_batch_count : %d\n", max_batch_count); + _N("--------------------------------\n"); } } void info_manager::usage(void) { - PRINT("usage: sensorctl info \n"); - PRINT("\n"); + _N("usage: sensorctl info \n\n"); usage_sensors(); } - diff --git a/src/sensorctl/info_manager.h b/src/sensorctl/info.h similarity index 81% rename from src/sensorctl/info_manager.h rename to src/sensorctl/info.h index b71dfc0..b85b6ca 100644 --- a/src/sensorctl/info_manager.h +++ b/src/sensorctl/info.h @@ -1,7 +1,7 @@ /* * sensorctl * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,7 +17,7 @@ * */ -#pragma once // _INFO_MANAGER_H_ +#pragma once /* __INFO_MANAGER_H__ */ #include #include "sensor_manager.h" @@ -27,8 +27,8 @@ public: info_manager() {} virtual ~info_manager() {} - bool process(int argc, char *argv[]); + bool run(int argc, char *argv[]); private: - void sensor_info(sensor_t *sensors, int count); + void show_info(sensor_t *sensors, int count); void usage(void); }; diff --git a/src/sensorctl/injector.cpp b/src/sensorctl/injector.cpp new file mode 100644 index 0000000..a4e7b75 --- /dev/null +++ b/src/sensorctl/injector.cpp @@ -0,0 +1,108 @@ +/* + * sensorctl + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "injector.h" + +#include +#include +#include + +#include "log.h" +#include "dbus_util.h" + +std::vector injector_manager::injectors; + +injector::injector(sensor_type_t sensor_type, const char *event_name) +: m_type(sensor_type) +, m_name(event_name) +{ + injector_manager::register_injector(this); +} + +injector_manager::injector_manager() +{ + if (!dbus_init()) { + _E("Failed to init dbus"); + throw; + } +} + +injector_manager::~injector_manager() +{ + dbus_fini(); +} + +void injector_manager::register_injector(injector *inject) +{ + injectors.push_back(inject); +} + +bool injector_manager::run(int argc, char *argv[]) +{ + sensor_type_t type; + bool result; + + if (argc < INJECTOR_ARGC) { + usage(); + return false; + } + + /* 1. get sensor type */ + type = get_sensor_type(argv[2]); + RETVM_IF(type == UNKNOWN_SENSOR, false, "Invalid argument : %s\n", argv[2]); + + /* 2. set up injector */ + injector *_injector = get_injector(type, argv[3]); + RETVM_IF(!_injector, false, "Cannot find matched injector\n"); + + /* 3. set up injector */ + result = _injector->setup(); + RETVM_IF(!result, false, "Failed to init injector\n"); + + /* 4. inject event */ + result = _injector->inject(argc, argv); + RETVM_IF(!result, false, "Failed to run injector\n"); + + /* 5. tear down injector */ + result = _injector->teardown(); + RETVM_IF(!result, false, "Failed to tear down injector\n"); + + return true; +} + +injector *injector_manager::get_injector(sensor_type_t type, const char *name) +{ + int count; + + count = injectors.size(); + + for (int i = 0; i < count; ++i) { + if (type == injectors[i]->type() && + (injectors[i]->name() == name)) + return injectors[i]; + } + return NULL; +} + +void injector_manager::usage(void) +{ + _N("usage: sensorctl inject [] []\n\n"); + + usage_sensors(); +} diff --git a/src/sensorctl/injector.h b/src/sensorctl/injector.h index f9e8b40..ca942fc 100644 --- a/src/sensorctl/injector.h +++ b/src/sensorctl/injector.h @@ -1,7 +1,7 @@ /* * sensorctl * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,16 +17,51 @@ * */ -#pragma once // _INJECTOR_H_ +#pragma once /* __INJECTOR_H__ */ #include +#include +#include -#define SENSORD_BUS_NAME "org.tizen.system.sensord" -#define SENSORD_OBJ_PATH "/Org/Tizen/System/SensorD" -#define SENSORD_INTERFACE_NAME "org.tizen.system.sensord" +#include "sensor_manager.h" + +#define NAME_MAX_TEST 32 +#define INJECTOR_ARGC 4 /* e.g. {sensorctl, inject, wristup, conf} */ + +#define REGISTER_INJECTOR(sensor_type, event_name, injector_type) \ +static injector_type injector(sensor_type, event_name); + +class injector { +public: + injector(sensor_type_t sensor_type, const char *event_name); + virtual ~injector() {} + + virtual bool setup(void) { return true; } + virtual bool teardown(void) { return true; } + + const std::string& name() const { return m_name; } + const sensor_type_t type() const { return m_type; } + + virtual bool inject(int argc, char *argv[]) = 0; + +private: + sensor_type_t m_type; + std::string m_name; +}; + +class injector_manager : public sensor_manager { +public: + static void register_injector(injector *injector); -class injector_interface { public: - virtual bool init(void) { return true; } - virtual bool inject(int option_count, char *options[]) = 0; + injector_manager(); + virtual ~injector_manager(); + + bool run(int argc, char *argv[]); + +private: + static std::vector injectors; + + injector *get_injector(sensor_type_t type, const char *name); + void usage(void); }; diff --git a/src/sensorctl/injector_context_orientation.cpp b/src/sensorctl/injector_context_orientation.cpp index 863b901..7219ea9 100644 --- a/src/sensorctl/injector_context_orientation.cpp +++ b/src/sensorctl/injector_context_orientation.cpp @@ -20,26 +20,33 @@ #include #include #include -#include +#include "log.h" #include "dbus_util.h" -#include "injector_manager.h" -#include "injector_context_orientation.h" +#include "injector.h" #define CONTEXT_ORIENTATION_SIGNAL "orientation" -bool injector_context_orientation::inject(int option_count, char *options[]) +class injector_context_orientation : public injector { +public: + injector_context_orientation(sensor_type_t sensor_type, const char *event_name); + virtual ~injector_context_orientation() {} + + bool inject(int argc, char *argv[]); +}; + +injector_context_orientation::injector_context_orientation(sensor_type_t sensor_type, const char *event_name) +: injector(sensor_type, event_name) { - GVariant *variant; +} - if (option_count == 0) { - _E("ERROR: invalid argument\n"); - return false; - } +bool injector_context_orientation::inject(int argc, char *argv[]) +{ + GVariant *variant; - variant = make_variant_int(option_count, options); + RETVM_IF(argc <= INJECTOR_ARGC, false, "Invalid argument\n"); - if (variant == NULL) - return false; + variant = make_variant_int(argc - INJECTOR_ARGC, &argv[INJECTOR_ARGC]); + RETVM_IF(!variant, false, "Cannot make variant\n"); dbus_emit_signal(NULL, (gchar *)SENSORD_OBJ_PATH, @@ -48,9 +55,9 @@ bool injector_context_orientation::inject(int option_count, char *options[]) variant, NULL); - PRINT("set options to context: \n"); - for (int i = 0; i < option_count; ++i) - PRINT("option %d: %s\n", i, options[i]); + _I("Set up options to wristup:"); + for (int i = 0; i < argc - INJECTOR_ARGC; ++i) + _I("option %d: %s\n", i, argv[i]); return true; } diff --git a/src/sensorctl/injector_manager.cpp b/src/sensorctl/injector_manager.cpp deleted file mode 100644 index 8aeebb0..0000000 --- a/src/sensorctl/injector_manager.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/* - * sensorctl - * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include -#include -#include -#include -#include "dbus_util.h" -#include "injector.h" -#include "injector_manager.h" - -#define NAME_MAX_TEST 32 -#define ARGC_BASE 4 /* e.g. {sensorctl, inject, wristup, conf} */ - -static std::vector injector_infos; - -injector_manager::injector_manager() -{ - if (!dbus_init()) { - _E("Failed to init dbus"); - throw; - } -} - -injector_manager::~injector_manager() -{ - dbus_fini(); -} - -bool injector_manager::register_injector(injector_info info) -{ - injector_infos.push_back(info); - return true; -} - -injector_interface *injector_manager::get_injector(sensor_type_t type, const char *name) -{ - int injector_count; - injector_count = injector_infos.size(); - - for (int i = 0; i < injector_count; ++i) { - if (type == injector_infos[i].type && - !strcmp(injector_infos[i].name, name)) - return injector_infos[i].injector; - } - return NULL; -} - -bool injector_manager::process(int argc, char *argv[]) -{ - int option_count; - char *options[8]; - bool result; - sensor_type_t type; - char *event_name; - int i; - - if (argc < 4) { - usage(); - return false; - } - - /* 1. get sensor type */ - type = get_sensor_type(argv[2]); - if (type == UNKNOWN_SENSOR) { - _E("ERROR : failed to process injector\n"); - return false; - } - - /* 2. set up injector */ - event_name = argv[3]; - - injector_interface *injector = get_injector(type, event_name); - if (injector == NULL) { - _E("ERROR: cannot find matched injector\n"); - return false; - } - - /* 3. init injector */ - result = injector->init(); - if (!result) { - _E("ERROR: failed to init injector\n"); - return false; - } - - /* 4. inject event with options */ - option_count = argc - ARGC_BASE; - for (i = 0; i < option_count; ++i) { - options[i] = new char[NAME_MAX_TEST]; - strncpy(options[i], argv[ARGC_BASE + i], strlen(argv[ARGC_BASE + i])); - } - - result = injector->inject(option_count, options); - if (!result) { - _E("ERROR : failed to process injector\n"); - for (i = 0; i < option_count; ++i) - delete [] options[i]; - - return false; - } - - for (i = 0; i < option_count; ++i) - delete [] options[i]; - - return true; -} - -void injector_manager::usage(void) -{ - PRINT("usage: sensorctl inject [] []\n\n"); - - usage_sensors(); -} - diff --git a/src/sensorctl/injector_manager.h b/src/sensorctl/injector_manager.h deleted file mode 100644 index 380c486..0000000 --- a/src/sensorctl/injector_manager.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * sensorctl - * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#pragma once // _INJECT_MANAGER_H_ - -#include -#include -#include "injector.h" -#include "sensor_manager.h" - -#define REGISTER_INJECTOR(sensor_type, sensor_name, injector_type) \ -static void __attribute__((constructor)) reg_injector(void) \ -{ \ - struct injector_info info; \ - info.type = (sensor_type); \ - info.name = (sensor_name); \ - info.injector = new(std::nothrow) (injector_type)(); \ - if (!info.injector) { \ - _E("ERROR: Failed to allocate memory(%s)", #injector_type); \ - return; \ - } \ - injector_manager::register_injector(info); \ -} - -struct injector_info { - sensor_type_t type; - const char *name; - injector_interface *injector; -}; - -class injector_manager : public sensor_manager { -public: - injector_manager(); - virtual ~injector_manager(); - - bool process(int argc, char *argv[]); - - static bool register_injector(injector_info info); -private: - injector_interface *get_injector(sensor_type_t type, const char *name); - void usage(void); -}; diff --git a/src/sensorctl/injector_wrist_up_conf.cpp b/src/sensorctl/injector_wrist_up_conf.cpp deleted file mode 100644 index 11e7a2f..0000000 --- a/src/sensorctl/injector_wrist_up_conf.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * sensorctl - * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include -#include -#include -#include -#include "dbus_util.h" -#include "injector_manager.h" -#include "injector_wrist_up_conf.h" - -#define WRIST_UP_CONF_SIGNAL "conf" - -bool injector_wrist_up_conf::inject(int option_count, char *options[]) -{ - GVariant *variant; - - if (option_count == 0) { - _E("ERROR: invalid argument\n"); - return false; - } - - variant = make_variant_int(option_count, options); - - if (variant == NULL) - return false; - - dbus_emit_signal(NULL, - (gchar *)SENSORD_OBJ_PATH, - (gchar *)SENSORD_INTERFACE_NAME, - (gchar *)WRIST_UP_CONF_SIGNAL, - variant, - NULL); - - PRINT("set options to wristup: \n"); - for (int i = 0; i < option_count; ++i) - PRINT("option %d: %s\n", i, options[i]); - - return true; -} - -REGISTER_INJECTOR(MOTION_SENSOR, "conf", injector_wrist_up_conf) - diff --git a/src/sensorctl/injector_wrist_up_algo.cpp b/src/sensorctl/injector_wristup_algo.cpp similarity index 59% rename from src/sensorctl/injector_wrist_up_algo.cpp rename to src/sensorctl/injector_wristup_algo.cpp index 766e6ec..2585bd8 100644 --- a/src/sensorctl/injector_wrist_up_algo.cpp +++ b/src/sensorctl/injector_wristup_algo.cpp @@ -23,18 +23,32 @@ #include #include #include -#include + +#include "log.h" #include "dbus_util.h" -#include "injector_manager.h" -#include "injector_wrist_up_algo.h" +#include "injector.h" -#define WRIST_UP_ALGO_SIGNAL "algo" +#define WRISTUP_ALGO_SIGNAL "algo" #define OPTION_INDEX 0 typedef std::map option_map_t; static option_map_t option_map; -bool injector_wrist_up_algo::init(void) +class injector_wristup_algo : public injector { +public: + injector_wristup_algo(sensor_type_t sensor_type, const char *event_name); + virtual ~injector_wristup_algo() {} + + bool setup(void); + bool inject(int argc, char *argv[]); +}; + +injector_wristup_algo::injector_wristup_algo(sensor_type_t sensor_type, const char *event_name) +: injector(sensor_type, event_name) +{ +} + +bool injector_wristup_algo::setup(void) { option_map.insert(option_map_t::value_type("auto", 0)); option_map.insert(option_map_t::value_type("green", 1)); @@ -44,34 +58,27 @@ bool injector_wrist_up_algo::init(void) return true; } -bool injector_wrist_up_algo::inject(int option_count, char *options[]) +bool injector_wristup_algo::inject(int argc, char *argv[]) { int option; - if (option_count == 0) { - _E("ERROR: invalid argument\n"); - return false; - } + RETVM_IF(argc == 0, false, "Invalid argument\n"); option_map_t::iterator it; - it = option_map.find(options[OPTION_INDEX]); - - if (it == option_map.end()) { - _E("ERROR: no matched-option: %s\n", options[OPTION_INDEX]); - return false; - } + it = option_map.find(argv[INJECTOR_ARGC]); + RETVM_IF(it == option_map.end(), false, "No matched option: %s\n", argv[INJECTOR_ARGC]); option = it->second; dbus_emit_signal(NULL, (gchar *)SENSORD_OBJ_PATH, (gchar *)SENSORD_INTERFACE_NAME, - (gchar *)WRIST_UP_ALGO_SIGNAL, + (gchar *)WRISTUP_ALGO_SIGNAL, g_variant_new("(i)", option), NULL); - _I("set [%s] mode to wristup (%d)", options[OPTION_INDEX], option); + _I("Set up [%s] mode to wristup (%d)\n", argv[INJECTOR_ARGC], option); return true; } -REGISTER_INJECTOR(MOTION_SENSOR, "algo", injector_wrist_up_algo) +REGISTER_INJECTOR(GESTURE_WRIST_UP_SENSOR, WRISTUP_ALGO_SIGNAL, injector_wristup_algo) diff --git a/src/sensorctl/injector_wristup_conf.cpp b/src/sensorctl/injector_wristup_conf.cpp new file mode 100644 index 0000000..5d356c5 --- /dev/null +++ b/src/sensorctl/injector_wristup_conf.cpp @@ -0,0 +1,65 @@ +/* + * sensorctl + * + * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include +#include +#include "log.h" +#include "dbus_util.h" +#include "injector.h" + +#define WRISTUP_CONF_SIGNAL "conf" + +class injector_wristup_conf : public injector { +public: + injector_wristup_conf(sensor_type_t sensor_type, const char *event_name); + virtual ~injector_wristup_conf() {} + + bool inject(int argc, char *argv[]); +}; + +injector_wristup_conf::injector_wristup_conf(sensor_type_t sensor_type, const char *event_name) +: injector(sensor_type, event_name) +{ +} + +bool injector_wristup_conf::inject(int argc, char *argv[]) +{ + GVariant *variant; + + RETVM_IF(argc <= INJECTOR_ARGC, false, "Invalid argument\n"); + + variant = make_variant_int(argc - INJECTOR_ARGC, &argv[INJECTOR_ARGC]); + RETVM_IF(!variant, false, "Cannot make variant\n"); + + dbus_emit_signal(NULL, + (gchar *)SENSORD_OBJ_PATH, + (gchar *)SENSORD_INTERFACE_NAME, + (gchar *)WRISTUP_CONF_SIGNAL, + variant, + NULL); + + _I("Set up options to wristup:"); + for (int i = 0; i < argc - INJECTOR_ARGC; ++i) + _I("option %d: %s\n", i, argv[i]); + + return true; +} + +REGISTER_INJECTOR(GESTURE_WRIST_UP_SENSOR, WRISTUP_CONF_SIGNAL, injector_wristup_conf) diff --git a/src/sensorctl/log.h b/src/sensorctl/log.h new file mode 100644 index 0000000..00cefbd --- /dev/null +++ b/src/sensorctl/log.h @@ -0,0 +1,85 @@ +/* + * sensorctl + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#pragma once /* __LOG_H__ */ + +#include +#include + +#define _NRM "\x1B[0m" +#define _RED "\x1B[31m" +#define _GRN "\x1B[32m" +#define _YEL "\x1B[33m" +#define _BLU "\x1B[34m" +#define _MAG "\x1B[35m" +#define _CYN "\x1B[36m" +#define _WHT "\x1B[37m" +#define _RST "\033[0m" + +#define _N(fmt, args...) \ +do { \ + g_print(fmt, ##args); \ +} while (0) + +#define _E(fmt, args...) \ +do { \ + g_print("\x1B[31m" fmt "\033[0m", ##args); \ +} while (0) + +#define _I(fmt, args...) \ +do { \ + g_print("\x1B[32m" fmt "\033[0m", ##args); \ +} while (0) + +#define WARN_IF(expr, fmt, arg...) \ +do { \ + if(expr) { \ + _E(fmt, ##arg); \ + } \ +} while (0) + +#define RET_IF(expr) \ +do { \ + if(expr) { \ + return; \ + } \ +} while (0) + +#define RETV_IF(expr, val) \ +do { \ + if(expr) { \ + return (val); \ + } \ +} while (0) + +#define RETM_IF(expr, fmt, arg...) \ +do { \ + if(expr) { \ + _E(fmt, ##arg); \ + return; \ + } \ +} while (0) + +#define RETVM_IF(expr, val, fmt, arg...) \ +do { \ + if(expr) { \ + _E(fmt, ##arg); \ + return (val); \ + } \ +} while (0) diff --git a/src/sensorctl/loopback_manager.cpp b/src/sensorctl/loopback.cpp similarity index 83% rename from src/sensorctl/loopback_manager.cpp rename to src/sensorctl/loopback.cpp index b7908b6..ee177b8 100644 --- a/src/sensorctl/loopback_manager.cpp +++ b/src/sensorctl/loopback.cpp @@ -1,7 +1,7 @@ /* * sensorctl * - * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -21,8 +21,9 @@ #include #include #include -#include -#include "loopback_manager.h" + +#include "log.h" +#include "loopback.h" #define SHUB_INST_LIB_ADD ((char)-79) #define SHUB_INST_LIB_REMOVE ((char)-78) @@ -40,7 +41,7 @@ static void int_to_bytes(int32_t value, int length, char cmd[]) } } -bool loopback_manager::process(int argc, char *argv[]) +bool loopback_manager::run(int argc, char *argv[]) { if (argc < DEFAULT_COMMAND_SIZE || argc > MAX_COMMAND_SIZE) { usage(); @@ -88,10 +89,10 @@ bool loopback_manager::process(int argc, char *argv[]) void loopback_manager::usage(void) { - PRINT("usage: sensorctl loopback [start/stop] [14byte sensor char data]\n"); - PRINT("ex: sensorctl loopback start 15000 1 1 19 1 (after 15000ms, wrist up event)\n"); - PRINT("ex: sensorctl loopback stop\n"); - PRINT(" * if not enought 14byte, remain bytes are filled with 0\n"); - PRINT("\n"); + _N("usage: sensorctl loopback [start/stop] [14byte sensor char data]\n"); + _N("ex: sensorctl loopback start 15000 1 1 19 1 (after 15000ms, wrist up event)\n"); + _N("ex: sensorctl loopback stop\n"); + _N(" * if not enought 14byte, remain bytes are filled with 0\n"); + _N("\n"); } diff --git a/src/sensorctl/loopback_manager.h b/src/sensorctl/loopback.h similarity index 91% rename from src/sensorctl/loopback_manager.h rename to src/sensorctl/loopback.h index 2aa3297..3117e27 100644 --- a/src/sensorctl/loopback_manager.h +++ b/src/sensorctl/loopback.h @@ -17,7 +17,7 @@ * */ -#pragma once // _LOOPBACK_MANAGER_H_ +#pragma once /* __LOOPBACK_MANAGER_H__ */ #include #include "sensor_manager.h" @@ -27,7 +27,7 @@ public: loopback_manager() {} virtual ~loopback_manager() {} - bool process(int argc, char *argv[]); + bool run(int argc, char *argv[]); private: void usage(void); }; diff --git a/src/sensorctl/injector_wrist_up_conf.h b/src/sensorctl/macro.h similarity index 64% rename from src/sensorctl/injector_wrist_up_conf.h rename to src/sensorctl/macro.h index 93b75f4..4e624a5 100644 --- a/src/sensorctl/injector_wrist_up_conf.h +++ b/src/sensorctl/macro.h @@ -1,7 +1,7 @@ /* * sensorctl * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,18 +17,7 @@ * */ -#pragma once // _WRISTUP_INJECTOR_H_ - -#include -#include -#include "injector.h" +#pragma once /* __MACRO_H__ */ #define NAME_MAX_TEST 32 - -class injector_wrist_up_conf: public injector_interface { -public: - injector_wrist_up_conf() {} - virtual ~injector_wrist_up_conf() {} - - bool inject(int option_count, char *options[]); -}; +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) diff --git a/src/sensorctl/mainloop.cpp b/src/sensorctl/mainloop.cpp new file mode 100644 index 0000000..8ea1d4a --- /dev/null +++ b/src/sensorctl/mainloop.cpp @@ -0,0 +1,69 @@ +/* + * sensorctl + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "mainloop.h" + +void mainloop::run(void) +{ + instance().start_loop(); +} + +void mainloop::stop(void) +{ + instance().stop_loop(); +} + +bool mainloop::is_running(void) +{ + return instance().is_loop_running(); +} + +mainloop& mainloop::instance(void) +{ + static mainloop loop; + return loop; +} + +void mainloop::start_loop(void) +{ + if (is_loop_running()) + return; + + m_mainloop = g_main_loop_new(NULL, false); + m_running = true; + + g_main_loop_run(m_mainloop); +} + +void mainloop::stop_loop(void) +{ + if (!is_loop_running()) + return; + + g_main_loop_quit(m_mainloop); + g_main_loop_unref(m_mainloop); + m_mainloop = NULL; + m_running = false; +} + +bool mainloop::is_loop_running(void) +{ + return m_running; +} + diff --git a/src/sensorctl/injector_context_orientation.h b/src/sensorctl/mainloop.h similarity index 70% rename from src/sensorctl/injector_context_orientation.h rename to src/sensorctl/mainloop.h index 01d2d18..70e3e53 100644 --- a/src/sensorctl/injector_context_orientation.h +++ b/src/sensorctl/mainloop.h @@ -17,16 +17,24 @@ * */ -#pragma once // _CONTEXT_INJECTOR_H_ +#pragma once /* __MAINLOOP_H__ */ #include #include -#include "injector.h" -class injector_context_orientation: public injector_interface { +class mainloop { public: - injector_context_orientation() {} - virtual ~injector_context_orientation() {} + static void run(void); + static void stop(void); + static bool is_running(void); - bool inject(int option_count, char *options[]); +private: + static mainloop& instance(); + + void start_loop(void); + void stop_loop(void); + bool is_loop_running(void); + + GMainLoop *m_mainloop; + bool m_running; }; diff --git a/src/sensorctl/sensor_adapter.cpp b/src/sensorctl/sensor_adapter.cpp new file mode 100644 index 0000000..056b5a6 --- /dev/null +++ b/src/sensorctl/sensor_adapter.cpp @@ -0,0 +1,160 @@ +/* + * sensorctl + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "sensor_adapter.h" + +#include + +#include "log.h" +#include "mainloop.h" +#include "test_bench.h" + +#define SENSOR_EVENT(type) ((type) << 16 | 0x1) + +bool sensor_adapter::is_supported(sensor_type_t type) +{ + sensor_t sensor; + int ret; + + ret = sensord_get_default_sensor(type, &sensor); + ASSERT_TRUE(ret); + + return true; +} + +int sensor_adapter::get_count(sensor_type_t type) +{ + sensor_t *sensors; + int count = 0; + + if (sensord_get_sensors(type, &sensors, &count) == 0) + free(sensors); + + return count; +} + +bool sensor_adapter::get_handle(sensor_info info, int &handle) +{ + int err; + int count; + sensor_t *sensors; + + err = sensord_get_sensors(info.type, &sensors, &count); + ASSERT_EQ(err, 0); + + handle = sensord_connect(sensors[info.index]); + ASSERT_GE(handle, 0); + + return true; +} + +bool sensor_adapter::start(sensor_info info, int &handle) +{ + sensor_t *sensors; + int count; + int err; + bool ret; + + err = sensord_get_sensors(info.type, &sensors, &count); + ASSERT_EQ(err, 0); + + handle = sensord_connect(sensors[info.index]); + ASSERT_GE(handle, 0); + + ret = sensord_register_event(handle, SENSOR_EVENT(info.type), info.interval, info.batch_latency, info.cb, NULL); + ASSERT_TRUE(ret); + + ret = sensord_start(handle, info.powersave); + ASSERT_TRUE(ret); + + free(sensors); + + return true; +} + +bool sensor_adapter::stop(sensor_info info, int handle) +{ + bool ret; + + ret = sensord_unregister_event(handle, SENSOR_EVENT(info.type)); + EXPECT_TRUE(ret); + + ret = sensord_stop(handle); + EXPECT_TRUE(ret); + + ret = sensord_disconnect(handle); + EXPECT_TRUE(ret); + + return true; +} + +bool sensor_adapter::change_interval(int handle, int interval) +{ + return true; +} + +bool sensor_adapter::change_batch_latency(int handle, int batch_latency) +{ + return true; +} + +bool sensor_adapter::change_powersave(int handle, int powersave) +{ + return true; +} + +bool sensor_adapter::set_attribute(int handle, int attribute, int value) +{ + bool ret; + + ret = sensord_set_attribute_int(handle, attribute, value); + ASSERT_TRUE(ret); + + return true; +} + +bool sensor_adapter::set_attribute(int handle, int attribute, char *value, int size) +{ + int ret; + + ret = sensord_set_attribute_str(handle, attribute, value, size); + + return ((ret == 0) ? true : false); +} + +bool sensor_adapter::get_data(int handle, sensor_type_t type, sensor_data_t &data) +{ + bool ret; + + ret = sensord_get_data(handle, SENSOR_EVENT(type), &data); + ASSERT_TRUE(ret); + + return true; +} + +bool sensor_adapter::flush(int handle) +{ + bool ret; + + ret = sensord_flush(handle); + ASSERT_TRUE(ret); + + return true; +} + diff --git a/src/sensorctl/sensor_adapter.h b/src/sensorctl/sensor_adapter.h new file mode 100644 index 0000000..631c4e5 --- /dev/null +++ b/src/sensorctl/sensor_adapter.h @@ -0,0 +1,62 @@ +/* + * sensorctl + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#pragma once /* __SENSOR_ADAPTER_H__ */ + +#include + +class sensor_info { +public: + sensor_info(sensor_type_t _type, int _index, int _interval, int _batch_latency, int _powersave, sensor_cb_t _cb, void *_user_data) + : type(_type) + , index(_index) + , interval(_interval) + , batch_latency(_batch_latency) + , powersave(_powersave) + , cb(_cb) + , user_data(_user_data) + { } + + sensor_type_t type; + int index; + int interval; + int batch_latency; + int powersave; + sensor_cb_t cb; + void *user_data; +}; + +class sensor_adapter { +public: + static bool is_supported(sensor_type_t type); + static int get_count(sensor_type_t type); + static bool get_handle(sensor_info info, int &handle); + + static bool start(sensor_info info, int &handle); + static bool stop(sensor_info info, int handle); + + static bool change_interval(int handle, int interval); + static bool change_batch_latency(int handle, int batch_latency); + static bool change_powersave(int handle, int powersave); + static bool set_attribute(int handle, int attribute, int value); + static bool set_attribute(int handle, int attribute, char *value, int size); + + static bool get_data(int handle, sensor_type_t type, sensor_data_t &data); + static bool flush(int handle); +}; diff --git a/src/sensorctl/sensor_manager.cpp b/src/sensorctl/sensor_manager.cpp index ce2e4ef..25ff923 100644 --- a/src/sensorctl/sensor_manager.cpp +++ b/src/sensorctl/sensor_manager.cpp @@ -1,7 +1,7 @@ /* * sensorctl * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +17,14 @@ * */ -#include -#include -#include #include "sensor_manager.h" -#define NAME_MAX_TEST 32 +#include +#include + +#include "log.h" +#include "util.h" +#include "macro.h" struct sensor_info { sensor_type_t type; @@ -30,86 +32,97 @@ struct sensor_info { }; static struct sensor_info sensor_infos[] = { - {ALL_SENSOR, "all"}, + {ALL_SENSOR, "all"}, // General Sensors - {ACCELEROMETER_SENSOR, "accelerometer"}, - {GEOMAGNETIC_SENSOR, "magnetic"}, - {LIGHT_SENSOR, "light"}, - {PROXIMITY_SENSOR, "proximity"}, - {GYROSCOPE_SENSOR, "gyroscope"}, - {PRESSURE_SENSOR, "pressure"}, - {BIO_SENSOR, "bio"}, - {BIO_HRM_SENSOR, "hrm"}, - {AUTO_ROTATION_SENSOR, "auto_rotation"}, - {GRAVITY_SENSOR, "gravity"}, - {LINEAR_ACCEL_SENSOR, "linear_accel"}, - {ROTATION_VECTOR_SENSOR, "rotation_vector"}, - {ORIENTATION_SENSOR, "orientation"}, - {TEMPERATURE_SENSOR, "temperature"}, - {HUMIDITY_SENSOR, "humidity"}, - {ULTRAVIOLET_SENSOR, "ultraviolet"}, - {BIO_LED_GREEN_SENSOR, "hrm_led_green"}, - {BIO_LED_IR_SENSOR, "hrm_led_ir"}, - {BIO_LED_RED_SENSOR, "hrm_led_red"}, - {GYROSCOPE_UNCAL_SENSOR, "gyro_uncal"}, - {GEOMAGNETIC_UNCAL_SENSOR, "mag_uncal"}, - {GYROSCOPE_RV_SENSOR, "gyro_rv"}, - {GEOMAGNETIC_RV_SENSOR, "mag_rv"}, - /* If WRIST_UP_SENSOR is created, it has to be changed to WRIST_UP_SENSOR */ - {MOTION_SENSOR, "motion"}, - {CONTEXT_SENSOR, "context"}, - {EXERCISE_SENSOR, "exercise"}, - {GESTURE_WRIST_UP_SENSOR, "wristup"}, + {ACCELEROMETER_SENSOR, "accelerometer"}, + {GRAVITY_SENSOR, "gravity"}, + {LINEAR_ACCEL_SENSOR, "linear_accel"}, + {GEOMAGNETIC_SENSOR, "magnetic"}, + {ROTATION_VECTOR_SENSOR, "rotation_vector"}, + {ORIENTATION_SENSOR, "orientation"}, + {GYROSCOPE_SENSOR, "gyroscope"}, + {LIGHT_SENSOR, "light"}, + {PROXIMITY_SENSOR, "proximity"}, + {PRESSURE_SENSOR, "pressure"}, + {ULTRAVIOLET_SENSOR, "uv"}, + {TEMPERATURE_SENSOR, "temperature"}, + {HUMIDITY_SENSOR, "humidity"}, + {HRM_SENSOR, "hrm"}, + {HRM_RAW_SENSOR, "hrm_raw"}, + {HRM_LED_GREEN_SENSOR, "hrm_led_green"}, + {HRM_LED_IR_SENSOR, "hrm_led_ir"}, + {HRM_LED_RED_SENSOR, "hrm_led_red"}, + {GYROSCOPE_UNCAL_SENSOR, "gyro_uncal"}, + {GEOMAGNETIC_UNCAL_SENSOR, "mag_uncal"}, + {GYROSCOPE_RV_SENSOR, "gyro_rv"}, + {GEOMAGNETIC_RV_SENSOR, "mag_rv"}, + + {HUMAN_PEDOMETER_SENSOR, "pedo"}, + {HUMAN_SLEEP_MONITOR_SENSOR, "sleep_monitor"}, + + {AUTO_ROTATION_SENSOR, "auto_rotation"}, + //{AUTO_BRIGHTENESS_SENSOR, "auto_brighteness"}, + {MOTION_SENSOR, "motion"}, + {CONTEXT_SENSOR, "context"}, + + {GESTURE_MOVEMENT_SENSOR, "movement"}, + {GESTURE_WRIST_UP_SENSOR, "wristup"}, + {GESTURE_WRIST_DOWN_SENSOR, "wristdown"}, + {GESTURE_MOVEMENT_STATE_SENSOR, "movement_state"}, + + {WEAR_STATUS_SENSOR, "wear_status"}, + {WEAR_ON_MONITOR_SENSOR, "wear_on"}, + {GPS_BATCH_SENSOR, "gps"}, + {ACTIVITY_TRACKER_SENSOR, "activity"}, + {SLEEP_DETECTOR_SENSOR, "sleep_detector"}, }; -bool sensor_manager::process(int argc, char *argv[]) +sensor_manager::~sensor_manager() { - return false; } -void sensor_manager::usage_sensors(void) +bool sensor_manager::run(int argc, char *argv[]) { - PRINT("The sensor types are:\n"); - int sensor_count = ARRAY_SIZE(sensor_infos); + return true; +} - for (int i = 0; i < sensor_count; ++i) - PRINT(" %d: %s(%d)\n", i, sensor_infos[i].name, sensor_infos[i].type); - PRINT("\n"); +void sensor_manager::stop(void) +{ } -sensor_type_t sensor_manager::get_sensor_type(char *name) +sensor_type_t sensor_manager::get_sensor_type(const char *name) { int index; - int sensor_count = ARRAY_SIZE(sensor_infos); + int count; + + if (util::is_hex(name)) + return (sensor_type_t) (strtol(name, NULL, 16)); + + if (util::is_number(name)) + return (sensor_type_t) (atoi(name)); - for (index = 0; index < sensor_count; ++index) { + count = ARRAY_SIZE(sensor_infos); + + for (index = 0; index < count; ++index) { if (!strcmp(sensor_infos[index].name, name)) break; } - if (index == sensor_count) { - _E("ERROR: sensor name is wrong\n"); + if (index == count) { + _E("Invaild sensor name\n"); usage_sensors(); return UNKNOWN_SENSOR; } return sensor_infos[index].type; } -const char *sensor_manager::get_sensor_name(sensor_type_t type) +void sensor_manager::usage_sensors(void) { - int index; + _N("The sensor types are:\n"); int sensor_count = ARRAY_SIZE(sensor_infos); - for (index = 0; index < sensor_count; ++index) { - if (sensor_infos[index].type == type) - break; - } - - if (index == sensor_count) { - _E("ERROR: sensor name is wrong\n"); - usage_sensors(); - return "UNKNOWN SENSOR"; - } - return sensor_infos[index].name; + for (int i = 0; i < sensor_count; ++i) + _N("%3d: %s(%#x)\n", i, sensor_infos[i].name, sensor_infos[i].type); + _N("\n"); } diff --git a/src/sensorctl/sensor_manager.h b/src/sensorctl/sensor_manager.h index 9fd3476..152abcd 100644 --- a/src/sensorctl/sensor_manager.h +++ b/src/sensorctl/sensor_manager.h @@ -1,7 +1,7 @@ /* * sensorctl * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,16 +17,19 @@ * */ -#pragma once // _SENSOR_MANAGER_H_ +#pragma once /* __SENSOR_MANAGER_H__ */ #include class sensor_manager { public: - virtual bool process(int argc, char *argv[]); + virtual ~sensor_manager(); + + virtual bool run(int argc, char *argv[]); + virtual void stop(void); + protected: - void usage_sensors(void); + sensor_type_t get_sensor_type(const char *name); - sensor_type_t get_sensor_type(char *name); - const char * get_sensor_name(sensor_type_t type); + void usage_sensors(void); }; diff --git a/src/sensorctl/sensorctl.cpp b/src/sensorctl/sensorctl.cpp index aa4543e..a35e286 100644 --- a/src/sensorctl/sensorctl.cpp +++ b/src/sensorctl/sensorctl.cpp @@ -22,79 +22,85 @@ #include #include -#include +#include "log.h" #include "sensor_manager.h" -#include "tester_manager.h" -#include "injector_manager.h" -#include "info_manager.h" -#include "loopback_manager.h" +#include "tester.h" +#include "injector.h" +#include "info.h" +#include "loopback.h" -static void good_bye(void) -{ -} - -static void signal_handler(int signo) -{ - _E("\nReceived SIGNAL(%d)\n", signo); - exit(EXIT_SUCCESS); - - return; -} +static sensor_manager *manager; -void usage(void) +static void usage(void) { - PRINT("usage: sensorctl []\n"); + _N("usage: sensorctl []\n"); - PRINT("The sensorctl commands are:\n"); - PRINT(" test: test sensor(s)\n"); - PRINT(" inject: inject the event to sensor\n"); - PRINT(" info: show sensor infos\n"); - PRINT(" loopback: sensor loopback test\n"); + _N("The sensorctl commands are:\n"); + _N(" test: test sensor(s)\n"); + _N(" inject: inject the event to sensor\n"); + _N(" info: show sensor infos\n"); } -sensor_manager *create_manager(int argc, char *argv[2]) +static sensor_manager *create_manager(char *command) { sensor_manager *manager = NULL; - if (!strcmp(argv[1], "test")) + if (!strcmp(command, "test")) manager = new(std::nothrow) tester_manager; - if (!strcmp(argv[1], "inject")) + if (!strcmp(command, "inject")) manager = new(std::nothrow) injector_manager; - if (!strcmp(argv[1], "info")) + if (!strcmp(command, "info")) manager = new(std::nothrow) info_manager; - if (!strcmp(argv[1], "loopback")) + if (!strcmp(command, "loopback")) manager = new(std::nothrow) loopback_manager; if (!manager) { - _E("failed to allocate memory for manager"); + _E("failed to allocate memory for manager\n"); return NULL; } return manager; } -int main(int argc, char *argv[]) +static void destroy_manager(sensor_manager *manager) +{ + if (!manager) + return; + + delete manager; + manager = NULL; +} + +static void signal_handler(int signo) { - atexit(good_bye); + _E("\nReceived SIGNAL(%d)\n", signo); + manager->stop(); +} + +int main(int argc, char *argv[]) +{ signal(SIGINT, signal_handler); signal(SIGHUP, signal_handler); signal(SIGTERM, signal_handler); signal(SIGQUIT, signal_handler); signal(SIGABRT, signal_handler); + signal(SIGTSTP, signal_handler); if (argc < 2) { usage(); - return 0; + return EXIT_SUCCESS; } - sensor_manager *manager = create_manager(argc, argv); + manager = create_manager(argv[1]); if (!manager) { usage(); - return 0; + return EXIT_SUCCESS; } - manager->process(argc, argv); + manager->run(argc, argv); + + destroy_manager(manager); - return 0; + return EXIT_SUCCESS; } diff --git a/src/sensorctl/sensorctl_log.h b/src/sensorctl/sensorctl_log.h deleted file mode 100644 index f5f8f25..0000000 --- a/src/sensorctl/sensorctl_log.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * sensorctl - * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#pragma once // _SENSORCTL_LOG_H_ - -#include -#include - -#define KNRM "\x1B[0m" -#define KRED "\x1B[31m" -#define KGRN "\x1B[32m" -#define KYEL "\x1B[33m" -#define KBLU "\x1B[34m" -#define KMAG "\x1B[35m" -#define KCYN "\x1B[36m" -#define KWHT "\x1B[37m" -#define RESET "\033[0m" - -#define PRINT(fmt, args...) \ - do { \ - g_print(fmt, ##args); \ - } while (0) - -#define _E(fmt, args...) \ - do { \ - g_print("\x1B[31m" fmt "\033[0m", ##args); \ - } while (0) - -#define _I(fmt, args...) \ - do { \ - g_print("\x1B[32m" fmt "\033[0m", ##args); \ - } while (0) - diff --git a/src/sensorctl/test_bench.cpp b/src/sensorctl/test_bench.cpp new file mode 100644 index 0000000..f675133 --- /dev/null +++ b/src/sensorctl/test_bench.cpp @@ -0,0 +1,226 @@ +/* + * sensorctl + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "log.h" +#include "test_bench.h" + +/* + * Implementation of test_option + */ +bool test_option::full_log = false; +std::string test_option::group = ""; + +void test_option::show_full_log(bool show) +{ + full_log = show; +} + +void test_option::set_group(const char *gname) +{ + group = gname; +} + +void test_option::set_options(int argc, char *argv[]) +{ + /* TODO: use getopt() */ + if (argc > 3) + set_group(argv[3]); + if (argc > 4) + show_full_log(atoi(argv[4])); +} + +/* + * Implementation of test_case + */ +test_case::test_case(const std::string &group, const std::string &name) +: m_group(group) +, m_name(name) +{ + test_bench::register_testcase(group, this); +} + +void test_case::started(void) +{ + _I("[----------]\n"); + _I("[ RUN ] "); + _N("%s.%s\n", m_group.c_str(), m_name.c_str()); +} + +void test_case::stopped(void) +{ + _I("[ OK ] "); + _N("%s.%s\n", m_group.c_str(), m_name.c_str()); + _I("[----------]\n"); +} + +void test_case::show(bool result) +{ + if (result) + _I("[ PASSED ] "); + else + _E("[ FAILED ] "); + _N("%s.%s\n", m_group.c_str(), m_name.c_str()); +} + +void test_case::run_testcase(void) +{ + bool result; + + started(); + result = (this->*m_func)(); + stopped(); + show(result); +} + +void test_case::register_func(test_func func) +{ + m_func = func; +} + +/* + * Implementation of test_bench + */ +test_bench& test_bench::instance() +{ + static test_bench bench; + return bench; +} + +void test_bench::register_testcase(const std::string &group, test_case *testcase) +{ + instance().add_testcase(group, testcase); +} + +void test_bench::push_failure(const std::string &function, long line, const std::string &msg) +{ + instance().add_failure(function, line, msg); +} + +void test_bench::run_all_testcase(void) +{ + instance().run(); +} + +void test_bench::stop_all_testcase(void) +{ + instance().stop(); +} + +void test_bench::add_testcase(const std::string &group, test_case *testcase) +{ + if (!testcase) + return; + + testcases.insert(std::pair(group, testcase)); +} + +void test_bench::add_failure(const std::string &function, long line, const std::string &msg) +{ + test_result fail(function, line, msg); + + results.push_back(fail); + m_failure_count++; +} + +void test_bench::started(void) +{ + _I("[==========] "); + _N("Running %d testcases\n", count(test_option::group)); +} + +void test_bench::stopped(void) +{ + _I("[==========] "); + _N("%d testcases ran\n", count(test_option::group)); +} + +void test_bench::show_failures(void) +{ + _N("================================\n"); + + if (m_failure_count == 0) { + _N("there was no fail case\n"); + return; + } + + _N("%d case(s) are failed, listed below:\n", m_failure_count); + + for (unsigned int i = 0; i < results.size(); ++i) { + _E("[ FAILED ] "); + _N("%s(%ld) -> %s\n", + results[i].function.c_str(), + results[i].line, + results[i].msg.c_str()); + } +} + +void test_bench::run(void) +{ + std::size_t found; + m_failure_count = 0; + + started(); + + for (auto it = testcases.begin(); it != testcases.end(); ++it) { + if (m_stop) + break; + + found = it->first.find("skip"); + + if (test_option::group.empty() && found != std::string::npos) + continue; + + found = it->first.find(test_option::group); + + if (!test_option::group.empty() && found == std::string::npos) + continue; + + it->second->run_testcase(); + } + + stopped(); + show_failures(); +} + +void test_bench::stop(void) +{ + m_stop = true; +} + +unsigned int test_bench::count(std::string &group) +{ + if (group.empty()) + return testcases.size() - count_by_key("skip"); + + return count_by_key(group.c_str()); +} + +unsigned int test_bench::count_by_key(const char *key) +{ + int count = 0; + + for (auto it = testcases.begin(); it != testcases.end(); ++it) { + std::size_t found = it->first.find(key); + + if (found != std::string::npos) + count++; + } + + return count; +} diff --git a/src/sensorctl/test_bench.h b/src/sensorctl/test_bench.h new file mode 100644 index 0000000..8525e39 --- /dev/null +++ b/src/sensorctl/test_bench.h @@ -0,0 +1,201 @@ +/* + * sensorctl + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#pragma once /* __TEST_BENCH_H__ */ + +#include +#include +#include +#include +#include + +#define FAIL(left, comp, right) \ +do { \ + _E("[ FAIL ] "); \ + std::ostringstream os; \ + os << __FUNCTION__ << "(" << __LINE__ << ") : " \ + << #left << "(" << left << ") " \ + << #comp << " " << #right << "(" << right << ")"; \ + std::cout << os.str() << std::endl; \ + test_bench::push_failure(__FUNCTION__, __LINE__, os.str()); \ +} while (0) + +#define PASS(left, comp, right) \ +do { \ + if (test_option::full_log) { \ + _I("[ PASS ] "); \ + std::ostringstream os; \ + os << __FUNCTION__ << "(" << __LINE__ << ") : " \ + << #left << "(" << left << ") " \ + << #comp << " " << #right << "(" << right << ")"; \ + std::cout << os.str() << std::endl; \ + } \ +} while (0) + +#define ASSERT(left, comp, right) \ +do { \ + if (!((left) comp (right))) { \ + FAIL(left, comp, right); \ + return false; \ + } \ + PASS(left, comp, right); \ +} while (0) + + +#define EXPECT(left, comp, right) \ +do { \ + if (!((left) comp (right))) { \ + FAIL(left, comp, right); \ + } else { \ + PASS(left, comp, right); \ + } \ +} while (0) + +#define ASSERT_TRUE(condition) ASSERT(condition, ==, true) +#define ASSERT_FALSE(condition) ASSERT(condition, ==, false) +#define ASSERT_EQ(left, right) ASSERT(left, ==, right) +#define ASSERT_NE(left, right) ASSERT(left, !=, right) +#define ASSERT_LT(left, right) ASSERT(left, <, right) +#define ASSERT_LE(left, right) ASSERT(left, <=, right) +#define ASSERT_GT(left, right) ASSERT(left, >, right) +#define ASSERT_GE(left, right) ASSERT(left, >=, right) +#define ASSERT_NEAR(left, right, err) \ +do { \ + ASSERT(left, >=, (right - (err))); \ + ASSERT(left, <=, (right + (err))); \ +} while (0) + +#define EXPECT_TRUE(condition) EXPECT(condition, ==, true) +#define EXPECT_FALSE(condition) EXPECT(condition, ==, false) +#define EXPECT_EQ(left, right) EXPECT(left, ==, right) +#define EXPECT_NE(left, right) EXPECT(left, !=, right) +#define EXPECT_LT(left, right) EXPECT(left, <, right) +#define EXPECT_LE(left, right) EXPECT(left, <=, right) +#define EXPECT_GT(left, right) EXPECT(left, >, right) +#define EXPECT_GE(left, right) EXPECT(left, >=, right) +#define EXPECT_NEAR(left, right, err) \ +do { \ + EXPECT(left, >=, (right - (err))); \ + EXPECT(left, <=, (right + (err))); \ +} while (0) + +#define TESTCASE(group, name) \ +class test_case_##group_##name : public test_case { \ +public: \ + test_case_##group_##name() \ + : test_case(#group, #name) \ + { \ + register_func(static_cast(&test_case_##group_##name::test)); \ + } \ + bool test(void); \ +} test_case_##group_##name##_instance; \ +bool test_case_##group_##name::test(void) + +/* + * Declaration of test_option + */ +class test_option { +public: + static bool full_log; + static std::string group; + + static void show_full_log(bool show); + static void set_group(const char *gname); + static void set_options(int argc, char *argv[]); +}; + +/* + * Decloaration of test_result + */ +class test_result { +public: + test_result(const std::string &_function, long _line, const std::string &_msg) + : function(_function) + , line(_line) + , msg(_msg) { } + + std::string function; + long line; + std::string msg; +}; + +/* + * Declaration of test_case + */ +class test_case { +public: + test_case(const std::string &group, const std::string &name); + + void run_testcase(void); + + const std::string& group() const { return m_group; } + const std::string& name() const { return m_name; } + +protected: + typedef bool (test_case::*test_func)(); + + void started(void); + void stopped(void); + void show(bool result); + void register_func(test_func func); + +private: + const std::string m_group; + const std::string m_name; + test_func m_func; +}; + +/* + * Declaration of test_bench + */ +class test_bench { +public: + test_bench() + : m_failure_count(0) + , m_stop(false) + {} + + static void register_testcase(const std::string &group, test_case *testcase); + + static void run_all_testcase(void); + static void stop_all_testcase(void); + + static void push_failure(const std::string &function, long line, const std::string &msg); + +private: + static test_bench& instance(); + + void add_failure(const std::string &function, long line, const std::string &msg); + + void started(void); + void stopped(void); + void show_failures(void); + + void add_testcase(const std::string &group, test_case *testcase); + void run(void); + void stop(void); + + unsigned int count(std::string &group); + unsigned int count_by_key(const char *key); + + std::multimap testcases; + std::vector results; + int m_failure_count; + bool m_stop; +}; diff --git a/src/sensorctl/testcase/accelerometer.cpp b/src/sensorctl/testcase/accelerometer.cpp new file mode 100644 index 0000000..ed526c3 --- /dev/null +++ b/src/sensorctl/testcase/accelerometer.cpp @@ -0,0 +1,170 @@ +/* + * sensorctl + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include + +#include "log.h" +#include "mainloop.h" +#include "test_bench.h" +#include "sensor_adapter.h" + +static void basic_cb(sensor_t sensor, unsigned int event_type, sensor_data_t *data, void *user_data) +{ + EXPECT_GT(data->timestamp, 0); + EXPECT_NEAR(data->values[0], 0, 19.6); + EXPECT_NEAR(data->values[1], 0, 19.6); + EXPECT_NEAR(data->values[2], 0, 19.6); + + mainloop::stop(); +} + +TESTCASE(accelerometer_basic, start_stop_p) +{ + bool ret; + int handle; + + sensor_info info(ACCELEROMETER_SENSOR, 0, + 100, 1000, SENSOR_OPTION_ALWAYS_ON, basic_cb, NULL); + + ret = sensor_adapter::start(info, handle); + ASSERT_TRUE(ret); + + mainloop::run(); + + ret = sensor_adapter::stop(info, handle); + ASSERT_TRUE(ret); + + return true; +} + +static void get_data_cb(sensor_t sensor, unsigned int event_type, sensor_data_t *data, void *user_data) +{ + mainloop::stop(); +} + +TESTCASE(accelerometer_basic, get_data_p) +{ + bool ret; + int handle; + sensor_data_t data; + + sensor_info info(ACCELEROMETER_SENSOR, 0, + 100, 1000, SENSOR_OPTION_ALWAYS_ON, get_data_cb, NULL); + + ret = sensor_adapter::start(info, handle); + ASSERT_TRUE(ret); + + mainloop::run(); + + ret = sensor_adapter::get_data(handle, info.type, data); + ASSERT_TRUE(ret); + + ret = sensor_adapter::stop(info, handle); + ASSERT_TRUE(ret); + + return true; +} + +static unsigned long long prev_prev_ts; +static unsigned long long prev_ts; +static int event_count; + +static void accel_regular_interval_cb(sensor_t sensor, unsigned int event_type, sensor_data_t *data, void *user_data) +{ + int prev_gap; + int current_gap; + if (prev_prev_ts == 0) { + prev_prev_ts = data->timestamp; + return; + } + + if (prev_ts == 0) { + prev_ts = data->timestamp; + return; + } + + prev_gap = prev_ts - prev_prev_ts; + current_gap = data->timestamp - prev_ts; + + EXPECT_NEAR(current_gap, prev_gap, 10000); + prev_prev_ts = prev_ts; + prev_ts = data->timestamp; + + if (event_count++ > 3) + mainloop::stop(); +} + +TESTCASE(accelerometer_interval, regular_interval_p) +{ + bool ret; + int handle; + prev_prev_ts = 0; + prev_ts = 0; + event_count = 0; + + sensor_info info(ACCELEROMETER_SENSOR, 0, + 100, 1000, SENSOR_OPTION_ALWAYS_ON, accel_regular_interval_cb, NULL); + + ret = sensor_adapter::start(info, handle); + ASSERT_TRUE(ret); + + mainloop::run(); + + ret = sensor_adapter::stop(info, handle); + ASSERT_TRUE(ret); + + return true; +} + +static void accel_interval_100ms_cb(sensor_t sensor, unsigned int event_type, sensor_data_t *data, void *user_data) +{ + if (prev_ts == 0) { + prev_ts = data->timestamp; + return; + } + + /* 100ms + 20ms(error) */ + EXPECT_LE(data->timestamp - prev_ts, 120000); + prev_ts = data->timestamp; + + if (event_count++ > 3) + mainloop::stop(); +} + +TESTCASE(accelerometer_interval, 100ms_interval_p) +{ + bool ret; + int handle; + + prev_ts = 0; + event_count = 0; + + sensor_info info(ACCELEROMETER_SENSOR, 0, + 100, 1000, SENSOR_OPTION_ALWAYS_ON, accel_interval_100ms_cb, NULL); + + ret = sensor_adapter::start(info, handle); + ASSERT_TRUE(ret); + + mainloop::run(); + + ret = sensor_adapter::stop(info, handle); + ASSERT_TRUE(ret); + + return true; +} diff --git a/src/sensorctl/testcase/sensor_basic.cpp b/src/sensorctl/testcase/sensor_basic.cpp new file mode 100644 index 0000000..466b80a --- /dev/null +++ b/src/sensorctl/testcase/sensor_basic.cpp @@ -0,0 +1,168 @@ +/* + * sensorctl + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include + +#include "log.h" +#include "mainloop.h" +#include "test_bench.h" +#include "sensor_adapter.h" + +static void basic_cb(sensor_t sensor, unsigned int event_type, sensor_data_t *data, void *user_data) +{ + EXPECT_GT(data->timestamp, 0); + //_N("[ DATA ] %f\n", data->values[0]); + mainloop::stop(); +} + +TESTCASE(all_sensor_test, scenario_basic_p) +{ + int err; + bool ret; + int count; + int handle; + sensor_t *sensors; + sensor_type_t type; + + err = sensord_get_sensors(ALL_SENSOR, &sensors, &count); + ASSERT_EQ(err, 0); + + for (int i = 0; i < count; ++i) { + sensord_get_type(sensors[i], &type); + /* TODO */ + _N("[ TYPE ] %s\n", "UNKNOWN_SENSOR"); + + sensor_info info(type, 0, 100, 1000, SENSOR_OPTION_ALWAYS_ON, basic_cb, NULL); + + ret = sensor_adapter::start(info, handle); + EXPECT_TRUE(ret); + + mainloop::run(); + + ret = sensor_adapter::stop(info, handle); + EXPECT_TRUE(ret); + } + + free(sensors); + + return true; +} + +typedef bool (*process_func_t)(const char *msg, int size, int count); + +static pid_t run_process(process_func_t func, const char *msg, int size, int count) +{ + pid_t pid = fork(); + if (pid < 0) + return -1; + + if (pid == 0) { + if (!func(msg, size, count)) + _E("Failed to run process\n"); + exit(0); + } + + return pid; +} + +static bool run_echo_command_test(const char *str, int size, int cout) +{ + bool ret = true; + int handle; + char buf[4096] = {'1', '1', '1', }; + + sensor_info info(ACCELEROMETER_SENSOR, 0, + 100, 1000, SENSOR_OPTION_ALWAYS_ON, basic_cb, NULL); + sensor_adapter::get_handle(info, handle); + + usleep(10000); + for (int i = 0; i < 1024; ++i) + ret &= sensor_adapter::set_attribute(handle, SENSOR_ATTR_ACCELEROMETER_INJECTION, buf, 4096); + ASSERT_TRUE(ret); + + return true; +} + +TESTCASE(echo_command_test, echo_command_p) +{ + pid_t pid; + + usleep(100000); + + for (int i = 0; i < 100; ++i) { + pid = run_process(run_echo_command_test, NULL, 0, 0); + EXPECT_GE(pid, 0); + } + + pid = run_process(run_echo_command_test, NULL, 0, 0); + EXPECT_GE(pid, 0); + + ASSERT_TRUE(true); + usleep(100000); + + return true; +} + +#if 0 +TESTCASE(gyroscope_value_p) +{ + scenario_basic_p(GYROSCOPE_SENSOR); +} + +TESTCASE(gravitye_value_p) +{ + scenario_basic_p(GRAVITY_SENSOR); +} + +TESTCASE(linear_accel_value_p) +{ + scenario_basic_p(LINEAR_ACCEL_SENSOR); +} + +TESTCASE(proximity_value_p) +{ + scenario_basic_p(PROXIMITY_SENSOR); +} + +TESTCASE(pressure_value_p) +{ + scenario_basic_p(PRESSURE_SENSOR); +} + +TESTCASE(hrm_value_p) +{ + scenario_basic_p(HRM_SENSOR); +} + +TESTCASE(hrm_raw_value_p) +{ + scenario_basic_p(HRM_RAW_SENSOR); +} + +TESTCASE(hrm_led_green_value_p) +{ + scenario_basic_p(HRM_LED_GREEN_SENSOR); +} + +TESTCASE(wrist_up_value_p) +{ + scenario_basic_p(GESTURE_WRIST_UP_SENSOR); +} +#endif diff --git a/src/sensorctl/injector_wrist_up_algo.h b/src/sensorctl/testcase/sensor_interval.cpp similarity index 62% rename from src/sensorctl/injector_wrist_up_algo.h rename to src/sensorctl/testcase/sensor_interval.cpp index a5bd6fe..8318fd5 100644 --- a/src/sensorctl/injector_wrist_up_algo.h +++ b/src/sensorctl/testcase/sensor_interval.cpp @@ -1,7 +1,7 @@ /* * sensorctl * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,17 +17,10 @@ * */ -#pragma once // _WRISTUP_INJECTOR_H_ +#include "test_bench.h" -#include -#include -#include "injector.h" - -class injector_wrist_up_algo: public injector_interface { -public: - injector_wrist_up_algo() {} - virtual ~injector_wrist_up_algo() {} - - bool init(void); - bool inject(int option_count, char *options[]); -}; +TESTCASE(sensor_interval, all_sensor_interval_10ms_p) +{ + /* TODO: test 10ms interval */ + return true; +} diff --git a/src/sensorctl/tester.cpp b/src/sensorctl/tester.cpp new file mode 100644 index 0000000..c164a57 --- /dev/null +++ b/src/sensorctl/tester.cpp @@ -0,0 +1,188 @@ +/* + * sensorctl + * + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "tester.h" + +#include +#include +#include +#include + +#include "log.h" +#include "macro.h" +#include "mainloop.h" +#include "test_bench.h" +#include "sensor_adapter.h" + +#define TESTER_ARGC 3 /* e.g. {sensorctl, test, accelerometer} */ + +#define MAX_COUNT 999999 +#define DEFAULT_INTERVAL 100 +#define DEFAULT_LATENCY 0 +#define DEFAULT_POWERSAVE_OPTION SENSOR_OPTION_ALWAYS_ON + +static sensor_type_t type; +static int interval; +static int latency; +static int powersave; +static int repeat; + +static int event_count = 0; + +tester_manager::tester_manager() +{ +} + +tester_manager::~tester_manager() +{ +} + +bool tester_manager::run(int argc, char *argv[]) +{ + if (argc < TESTER_ARGC) { + usage(); + return false; + } + + if (!setup(argc, argv)) { + usage(); + return false; + } + + test_bench::run_all_testcase(); + + return true; +} + +bool tester_manager::setup(int argc, char *argv[]) +{ + if (strncmp(argv[2], "auto", 4) == 0) + return setup_auto(argc, argv); + + return setup_manual(argc, argv); +} + +bool tester_manager::setup_auto(int argc, char *argv[]) +{ + if (argc > 5) + repeat = atoi(argv[5]); + + test_option::show_full_log(true); + test_option::set_options(argc, argv); + + return true; +} + +bool tester_manager::setup_manual(int argc, char *argv[]) +{ + type = get_sensor_type(argv[2]); + RETVM_IF(type == UNKNOWN_SENSOR, false, "Invalid argument\n"); + + interval = DEFAULT_INTERVAL; + latency = DEFAULT_LATENCY; + powersave = DEFAULT_POWERSAVE_OPTION; + event_count = 0; + + if (argc >= TESTER_ARGC + 1) + interval = atoi(argv[TESTER_ARGC]); + if (argc >= TESTER_ARGC + 2) + latency = atoi(argv[TESTER_ARGC + 1]); + if (argc >= TESTER_ARGC + 3) + powersave = atoi(argv[TESTER_ARGC + 2]); + + test_option::show_full_log(true); + test_option::set_group("skip_manual"); + /* test_option::set_options(argc, argv); */ + + return true; +} + +void tester_manager::stop(void) +{ + if (mainloop::is_running()) + mainloop::stop(); +} + +void tester_manager::usage(void) +{ + _N("usage: sensorctl test auto [group] [log]\n"); + _N("usage: sensorctl test [interval] [batch_latency] [event_count] [test_count]\n"); + + usage_sensors(); + + _N("auto:\n"); + _N(" test sensors automatically.\n"); + _N("group:\n"); + _N(" a group name(or a specific word contained in the group name).\n"); + _N("log:\n"); + _N(" enable(1) or disable(0). default value is 1.\n"); + _N("sensor_type: specific sensor\n"); + _N(" test specific sensor manually.\n"); + _N("interval_ms:\n"); + _N(" interval. default value is 100ms.\n"); + _N("batch_latency_ms:\n"); + _N(" batch_latency. default value is 1000ms.\n"); + _N("event count(n):\n"); + _N(" test sensor until it gets n event. default is 999999(infinitly).\n"); + _N("test count(n):\n"); + _N(" test sensor in n times repetitively, default is 1.\n\n"); +} + +/* manual test case */ +static void test_cb(sensor_t sensor, unsigned int event_type, sensor_data_t *data, void *user_data) +{ + if (event_count >= MAX_COUNT) { + mainloop::stop(); + return; + } + + _N("%llu ", data->timestamp); + for (int i = 0; i < data->value_count; ++i) + _N(" %10f", data->values[i]); + _N("\n"); +} + +TESTCASE(skip_manual, sensor_test) +{ + int handle; + bool ret; + int index = 0; + sensor_data_t data; + + if (sensor_adapter::get_count(type) > 1) { + _N("There are more than 2 sensors. please enter the index : "); + scanf("%d", &index); + } + + sensor_info info(type, index, interval, latency, powersave, test_cb, NULL); + + ret = sensor_adapter::start(info, handle); + ASSERT_TRUE(ret); + + ret = sensor_adapter::get_data(handle, type, data); + EXPECT_TRUE(ret); + + mainloop::run(); + + ret = sensor_adapter::stop(info, handle); + ASSERT_TRUE(ret); + + return true; +} + diff --git a/src/sensorctl/tester.h b/src/sensorctl/tester.h index 2d912c9..148a402 100644 --- a/src/sensorctl/tester.h +++ b/src/sensorctl/tester.h @@ -1,7 +1,7 @@ /* * sensorctl * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +17,27 @@ * */ -#pragma once // _TESTER_H_ +#pragma once /* __TESTER_H__ */ #include +#include +#include -class tester_interface { +#include "sensor_manager.h" + +class tester_manager : public sensor_manager { public: - virtual bool init(void) = 0; - virtual bool test(sensor_type_t type, int option_count, char *options[]) = 0; + tester_manager(); + virtual ~tester_manager(); + + bool run(int argc, char *argv[]); + void stop(void); + +private: + bool setup(int argc, char *argv[]); + bool setup_auto(int argc, char *argv[]); + bool setup_manual(int argc, char *argv[]); + + void usage(void); }; + diff --git a/src/sensorctl/tester_manager.cpp b/src/sensorctl/tester_manager.cpp deleted file mode 100644 index c16140f..0000000 --- a/src/sensorctl/tester_manager.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * sensorctl - * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include -#include -#include -#include -#include "tester.h" -#include "tester_manager.h" -#include "tester_sensor.h" - -#define NAME_MAX_TEST 32 -#define ARGC_BASE 3 /* e.g. {sensorctl, test, accelerometer} */ - -bool tester_manager::process(int argc, char *argv[]) -{ - int option_count; - char *options[8]; - sensor_type_t type; - int i; - - if (argc == 2) { - usage(); - return false; - } - - /* 1. get sensor type */ - type = get_sensor_type(argv[2]); - if (type == UNKNOWN_SENSOR) { - _E("ERROR : failed to process injector\n"); - return false; - } - - /* 2. set up injector */ - tester_interface *tester = new tester_sensor(); - tester->init(); - - /* 3. test sensor with options */ - option_count = argc - ARGC_BASE; - for (i = 0; i < option_count; ++i) { - options[i] = new char[NAME_MAX_TEST]; - strncpy(options[i], argv[ARGC_BASE + i], strlen(argv[ARGC_BASE + i])); - } - - tester->test(type, option_count, options); - - return true; -} - -void tester_manager::usage(void) -{ - PRINT("usage: sensorctl test [interval] [event_count] [test_count]\n\n"); - - usage_sensors(); - - PRINT("interval_ms:\n"); - PRINT(" interval. default value is 100ms.\n"); - PRINT("event count(n):\n"); - PRINT(" test sensor until it gets n event. default is 999999(infinitly).\n"); - PRINT("test count(n):\n"); - PRINT(" test sensor in n times repetitively, default is 1.\n\n"); -} - diff --git a/src/sensorctl/tester_sensor.cpp b/src/sensorctl/tester_sensor.cpp deleted file mode 100644 index 7f324f6..0000000 --- a/src/sensorctl/tester_sensor.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* - * sensorctl - * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include -#include -#include -#include -#include -#include -#include "tester_sensor.h" - -#define DEFAULT_INTERVAL 100 -#define DEFAULT_LATENCY 0 -#define DEFAULT_TEST_COUNT 1 -#define DEFAULT_EVENT_COUNT 9999 - -#define SENSOR_SHIFT_TYPE 16 - -static GMainLoop *mainloop; -static int check_loop; - -static const char *result_str(bool result) { - if (result) return KGRN "[PASS]" RESET; - else return KRED "[FAIL]" RESET; -} - -bool tester_sensor::init(void) -{ - return true; -} - -void tester_sensor::test_cb(sensor_t sensor, unsigned int event_type, sensor_data_t *data, void *user_data) -{ - sensor_type_t type; - int *cnt_event; - - sensord_get_type(sensor, &type); - - cnt_event = (int *)user_data; - - if (check_loop++ >= *cnt_event) { - if (!mainloop) - return; - - g_main_loop_quit(mainloop); - g_main_loop_unref(mainloop); - mainloop = NULL; - return; - } - - PRINT("[%llu] %s:", data->timestamp, sensord_get_name(sensor)); - - if (type == GESTURE_WRIST_UP_SENSOR) { - PRINT("[%d]\n", ((sensorhub_data_t *)data)->hub_data[0]); - return; - } - - for (int i = 0; i < data->value_count; ++i) - PRINT(" [%f]", data->values[i]); - PRINT("\n"); -} - -void tester_sensor::test_sensor(sensor_type_t type, int interval, int latency, int cnt_test, int cnt_event) -{ - bool result; - sensor_t sensor; - unsigned int event_id; - sensor_data_t data; - int handle; - int count = 0; - - event_id = type << SENSOR_SHIFT_TYPE | 0x1; - - while (count++ < cnt_test) { - mainloop = g_main_loop_new(NULL, FALSE); - check_loop = 0; - - PRINT("=======================================\n"); - PRINT("TEST(%d/%d)\n", count, cnt_test); - PRINT("=======================================\n"); - - sensor = sensord_get_sensor(type); - PRINT("%s sensord_get_sensor: sensor(%p)\n", result_str((sensor == NULL)? 0 : 1), sensor); - - handle = sensord_connect(sensor); - PRINT("%s sensord_connect: handle(%d)\n", result_str((handle >= 0)), handle); - - result = sensord_register_event(handle, event_id, interval, latency, test_cb, (void *)&cnt_event); - PRINT("%s sensord_register_event\n", result_str(result)); - - result = sensord_start(handle, 3); - PRINT("%s sensord_start\n", result_str(result)); - - result = sensord_get_data(handle, event_id, &data); - PRINT("%s sensord_get_data\n", result_str(result)); - - result = sensord_flush(handle); - PRINT("%s sensord_flush\n", result_str(result)); - - if (result) { - for (int i = 0; i < data.value_count; ++i) - PRINT("[%f] ", data.values[i]); - PRINT("\n"); - } - - g_main_loop_run(mainloop); - - result = sensord_unregister_event(handle, event_id); - PRINT("%s sensord_unregister_event: handle(%d)\n", result_str(result), handle); - result = sensord_stop(handle); - PRINT("%s sensord_stop: handle(%d)\n", result_str(result), handle); - result = sensord_disconnect(handle); - PRINT("%s sensord_disconnect: handle(%d)\n", result_str(result), handle); - } -} - -bool tester_sensor::test(sensor_type_t type, int option_count, char *options[]) -{ - int interval = DEFAULT_INTERVAL; - int latency = DEFAULT_LATENCY; - int cnt_test = DEFAULT_TEST_COUNT; - int cnt_event = DEFAULT_EVENT_COUNT; - - sensor_type_t sensor_type = type; - - if (option_count >= 1) - interval = atoi(options[0]); - if (option_count >= 2) - cnt_event = atoi(options[1]); - if (option_count >= 3) - cnt_test = atoi(options[2]); - - test_sensor(sensor_type, interval, latency, cnt_test, cnt_event); - return true; -} diff --git a/src/sensorctl/tester_sensor.h b/src/sensorctl/tester_sensor.h deleted file mode 100644 index 68b76b4..0000000 --- a/src/sensorctl/tester_sensor.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * sensorctl - * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#pragma once // _SENSOR_TESTER_H_ - -#include "tester.h" - -class tester_sensor : public tester_interface { -public: - tester_sensor() {} - virtual ~tester_sensor() {} - - virtual bool init(void); - virtual bool test(sensor_type_t type, int option_count, char *options[]); -private: - void test_sensor(sensor_type_t type, int interval, int latency, int cnt_test, int cnt_event); - static void test_cb(sensor_t sensor, unsigned int event_type, sensor_data_t *data, void *user_data); -}; diff --git a/src/sensorctl/util.cpp b/src/sensorctl/util.cpp new file mode 100644 index 0000000..9b2016f --- /dev/null +++ b/src/sensorctl/util.cpp @@ -0,0 +1,59 @@ +/* + * sensorctl + * + * Copyright (c) 2016 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include +#include "util.h" + +bool util::is_number(const char *value) +{ + if (value == NULL || *value == 0) + return false; + + while (*value) { + if (*value < '0' || *value > '9') + return false; + value++; + } + + return true; +} + +bool util::is_hex(const char *value) +{ + if (value == NULL || *value == 0) + return false; + + if (value[0] != '0') + return false; + + if (value[1] != 'x' && value[1] != 'X') + return false; + + value += 2; + + while (*value) { + if ((*value < '0' || *value > '9') && + (*value < 'a' || *value > 'f') && + (*value < 'A' || *value > 'F')) + return false; + value++; + } + + return true; +} diff --git a/src/sensorctl/tester_manager.h b/src/sensorctl/util.h similarity index 67% rename from src/sensorctl/tester_manager.h rename to src/sensorctl/util.h index 16f4b16..b2dcbc8 100644 --- a/src/sensorctl/tester_manager.h +++ b/src/sensorctl/util.h @@ -1,7 +1,7 @@ /* * sensorctl * - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2017 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,16 +17,10 @@ * */ -#pragma once // _TEST_MANAGER_H_ +#pragma once /* __UTIL_H__ */ -#include "sensor_manager.h" - -class tester_manager : public sensor_manager { +class util { public: - tester_manager() {} - virtual ~tester_manager() {} - - bool process(int argc, char *argv[]); -private: - void usage(void); + static bool is_number(const char *value); + static bool is_hex(const char *value); }; -- 2.7.4