there are the quite many changes between private and public.
but almost patches are for code-clean and mobile specific features.
through updating sensord at once, private, tizen 2.3, tizen 3.0 code are
in sync.
Change-Id: Ieaef0357c810682c6b9c82f7429f9a680eccd25c
Signed-off-by: Kibak Yoon <kibak.yoon@samsung.com>
<MODEL id="lsm330dlc-accel">
<NAME value="LSM330DLC"/>
<VENDOR value="ST Microelectronics"/>
- <RAW_DATA_UNIT value="1"/>
- <RESOLUTION value="12"/>
+ <RAW_DATA_UNIT value="1" />
+ <RESOLUTION value="12" />
+ </MODEL>
+
+ <MODEL id="LSM330">
+ <NAME value="LSM330"/>
+ <VENDOR value="ST Microelectronics"/>
+ <RAW_DATA_UNIT value="1" />
+ <RESOLUTION value="12" />
+ </MODEL>
+
+ <MODEL id="K2HH">
+ <NAME value="K2HH" />
+ <VENDOR value="ST Microelectronics"/>
+ <RAW_DATA_UNIT value="0.061"/>
+ <RESOLUTION value="16"/>
</MODEL>
<MODEL id="MPU6500">
<NAME value="MPU6500"/>
<VENDOR value="Invensense"/>
- <RAW_DATA_UNIT SM-Z910F="0.061" value="0.244"/>
- <RESOLUTION value="16"/>
+ <RAW_DATA_UNIT SM-Z910F="0.061" SM-Z9005="0.061" value="0.244"/>
+ <RESOLUTION value="16" />
</MODEL>
<MODEL id="MPU6515">
<RESOLUTION value="16"/>
</MODEL>
+ <MODEL id="ICM20628">
+ <NAME value="ICM20628"/>
+ <VENDOR value="Invensense"/>
+ <RAW_DATA_UNIT value="0.244" />
+ <RESOLUTION value="16" />
+ </MODEL>
+
<MODEL id="bma222e">
<NAME value="BMA222E"/>
<VENDOR value="BOSCH"/>
<RAW_DATA_UNIT value="15.63"/>
<RESOLUTION value="8"/>
</MODEL>
+
+ <MODEL id="BMI160">
+ <NAME value="BMI160"/>
+ <VENDOR value="Bosch"/>
+ <RAW_DATA_UNIT value="0.244"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+
+ <MODEL id="maru_sensor_accel_1">
+ <NAME value="maru_sensor_accel_1"/>
+ <VENDOR value="Tizen_SDK"/>
+ <RAW_DATA_UNIT value="0.061"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
</ACCEL>
<GYRO>
<NAME value="LSM330DLC"/>
<VENDOR value="ST Microelectronics"/>
<RAW_DATA_UNIT value="17.50"/>
- <RESOLUTION value="12"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+
+ <MODEL id="LSM330">
+ <NAME value="LSM330"/>
+ <VENDOR value="ST Microelectronics"/>
+ <RAW_DATA_UNIT value="17.50" />
+ <RESOLUTION value="16" />
</MODEL>
<MODEL id="MPU6500">
<RAW_DATA_UNIT value="15.26"/>
<RESOLUTION value="16"/>
</MODEL>
+
+ <MODEL id="ICM20628">
+ <NAME value="ICM20628"/>
+ <VENDOR value="Invensense"/>
+ <RAW_DATA_UNIT value="61.04"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+
+ <MODEL id="BMI160">
+ <NAME value="BMI160"/>
+ <VENDOR value="Bosch"/>
+ <RAW_DATA_UNIT value="61.04"/>
+ <RESOLUTION value="16"/>
+ </MODEL>
+
+ <MODEL id="maru_sensor_gyro_1">
+ <NAME value="maru_sensor_gyro_1"/>
+ <VENDOR value="Tizen_SDK"/>
+ <RAW_DATA_UNIT value="1000"/>
+ <RESOLUTION value="16"/>
+ <MIN_RANGE value="-573"/>
+ <MAX_RANGE value="573"/>
+ </MODEL>
</GYRO>
<PROXI>
<VENDOR value="Sharp"/>
</MODEL>
- <MODEL id="cm36651">
+ <MODEL id="CM36651">
<NAME value="CM36651"/>
<VENDOR value="Capella"/>
</MODEL>
+
+ <MODEL id="MAX88922">
+ <NAME value="MAX88922"/>
+ <VENDOR value="MAXIM"/>
+ </MODEL>
+
+ <MODEL id="maru_sensor_proxi_1">
+ <NAME value="maru_sensor_proxi_1"/>
+ <VENDOR value="Tizen_SDK"/>
+ </MODEL>
</PROXI>
<LIGHT>
<VENDOR value="Sharp"/>
</MODEL>
- <MODEL id="cm36651">
+ <MODEL id="CM36651">
<NAME value="CM36651"/>
<VENDOR value="Capella"/>
</MODEL>
+
+ <MODEL id="MAX88922">
+ <NAME value="MAX88922"/>
+ <VENDOR value="MAXIM"/>
+ </MODEL>
+
+ <MODEL id="AL3320">
+ <NAME value="AL3320"/>
+ <VENDOR value="LITEON"/>
+ </MODEL>
+
+ <MODEL id="BH1733">
+ <NAME value="BH1733"/>
+ <VENDOR value="ROHM"/>
+ </MODEL>
+
+ <MODEL id="maru_sensor_light_1">
+ <NAME value="maru_sensor_light_1"/>
+ <VENDOR value="Tizen_SDK"/>
+ </MODEL>
</LIGHT>
<MAGNETIC>
+ <MODEL id="AK8975C">
+ <NAME value="AK8975C" />
+ <VENDOR value="AKM"/>
+ <RAW_DATA_UNIT value="0.06"/>
+ <MIN_RANGE value="-1200"/>
+ <MAX_RANGE value="1200"/>
+ </MODEL>
+
<MODEL id="AK09911C">
<NAME value="AK09911C"/>
<VENDOR value="AKM"/>
<MODEL id="MPU9250">
<NAME value="MPU9250"/>
<VENDOR value="Invensense"/>
+ <RAW_DATA_UNIT value="1.0"/>
+ <MIN_RANGE value="-4800"/>
+ <MAX_RANGE value="4800"/>
+ </MODEL>
+
+ <MODEL id="YAS537">
+ <NAME value="YAS537"/>
+ <VENDOR value="Yamaha"/>
+ <RAW_DATA_UNIT value="0.1"/>
+ <MIN_RANGE value="-4800"/>
+ <MAX_RANGE value="4800"/>
+ </MODEL>
+
+ <MODEL id="maru_sensor_geo_1">
+ <NAME value="maru_sensor_geo_1"/>
+ <VENDOR value="Tizen_SDK"/>
+ <RAW_DATA_UNIT value="0.6"/>
+ <RESOLUTION value="14"/>
+ <MIN_RANGE value="-2000"/>
+ <MAX_RANGE value="2000"/>
</MODEL>
</MAGNETIC>
<TEMPERATURE_RESOLUTION value="0.002083"/>
<TEMPERATURE_OFFSET value="42.5"/>
</MODEL>
+ <MODEL id="maru_sensor_pressure_1">
+ <NAME value="maru_sensor_pressure_1" />
+ <VENDOR value="Tizen_SDK"/>
+ <RAW_DATA_UNIT value="0.0193"/>
+ <MIN_RANGE value="260"/>
+ <MAX_RANGE value="1260"/>
+ <RESOLUTION value="1"/>
+ <TEMPERATURE_RESOLUTION value="0.05"/>
+ <TEMPERATURE_OFFSET value="0"/>
+ </MODEL>
</PRESSURE>
<TEMPERATURE>
<RAW_DATA_UNIT value="0.01"/>
<RESOLUTION value="1"/>
</MODEL>
+
+ <MODEL id="SHTC1">
+ <NAME value="SHTC1" />
+ <VENDOR value="SENSIRION"/>
+ <RAW_DATA_UNIT value="0.01"/>
+ <RESOLUTION value="1"/>
+ </MODEL>
</TEMPERATURE>
+
+ <HUMIDITY>
+ <MODEL id="SHTC1">
+ <NAME value="SHTC1" />
+ <VENDOR value="SENSIRION"/>
+ <RAW_DATA_UNIT value="0.01"/>
+ <MIN_RANGE value="-10"/>
+ <MAX_RANGE value="110"/>
+ <RESOLUTION value="1"/>
+ </MODEL>
+ </HUMIDITY>
+
+ <ULTRAVIOLET>
+ <MODEL id="UVIS25">
+ <NAME value="UVIS25" />
+ <VENDOR value="STM"/>
+ <RAW_DATA_UNIT value="0.0625"/>
+ <MIN_RANGE value="0"/>
+ <MAX_RANGE value="15"/>
+ </MODEL>
+ <MODEL id="maru_sensor_uv_1">
+ <NAME value="maru_sensor_uv_1" />
+ <VENDOR value="Tizen_SDK"/>
+ <RAW_DATA_UNIT value="0.1"/>
+ <MIN_RANGE value="0"/>
+ <MAX_RANGE value="15"/>
+ </MODEL>
+ </ULTRAVIOLET>
</SENSOR>
IF("${GEO}" STREQUAL "ON")
add_subdirectory(geo)
ENDIF()
+IF("${AUTO_ROTATION}" STREQUAL "ON")
+add_subdirectory(auto_rotation)
+ENDIF()
IF("${PRESSURE}" STREQUAL "ON")
add_subdirectory(pressure)
ENDIF()
IF("${TEMPERATURE}" STREQUAL "ON")
add_subdirectory(temperature)
ENDIF()
+IF("${HUMIDITY}" STREQUAL "ON")
+add_subdirectory(humidity)
+ENDIF()
+IF("${ULTRAVIOLET}" STREQUAL "ON")
+add_subdirectory(ultraviolet)
+ENDIF()
IF("${ORIENTATION}" STREQUAL "ON")
set(SENSOR_FUSION_ENABLE "1")
set(ORIENTATION_ENABLE "1")
IF("${LINEAR_ACCELERATION_ENABLE}" STREQUAL "1")
add_subdirectory(linear_accel)
ENDIF()
+add_subdirectory(rotation_vector)
add_subdirectory(server)
add_subdirectory(libsensord)
vector<unsigned int> supported_events = {
ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME,
+ ACCELEROMETER_EVENT_UNPROCESSED_DATA_REPORT_ON_TIME,
};
for_each(supported_events.begin(), supported_events.end(),
AUTOLOCK(m_mutex);
AUTOLOCK(m_client_info_mutex);
+ if (get_client_cnt(ACCELEROMETER_EVENT_UNPROCESSED_DATA_REPORT_ON_TIME)) {
+ base_event.sensor_id = get_id();
+ base_event.event_type = ACCELEROMETER_EVENT_UNPROCESSED_DATA_REPORT_ON_TIME;
+ push(base_event);
+ }
+
if (get_client_cnt(ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME)) {
base_event.sensor_id = get_id();
base_event.event_type = ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME;
data.values[2] = RAW_DATA_TO_METRE_PER_SECOND_SQUARED_UNIT(data.values[2] * m_raw_data_unit);
}
-extern "C" void *create(void)
+extern "C" sensor_module* create(void)
{
- accel_sensor *inst;
+ accel_sensor *sensor;
try {
- inst = new accel_sensor();
+ sensor = new(std::nothrow) accel_sensor;
} catch (int err) {
- ERR("accel_sensor class create fail , errno : %d , errstr : %s\n", err, strerror(err));
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
return NULL;
}
- return (void*)inst;
-}
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
-extern "C" void destroy(void *inst)
-{
- delete (accel_sensor*)inst;;
+ module->sensors.push_back(sensor);
+ return module;
}
#define INPUT_NAME "accelerometer_sensor"
#define ACCEL_SENSORHUB_POLL_NODE_NAME "accel_poll_delay"
-#define SCAN_EL_DIR "scan_elements/"
-#define SCALE_AVAILABLE_NODE "in_accel_scale_available"
-#define ACCEL_RINGBUF_LEN 32
-#define SEC_MSEC 1000
-#define MSEC_TO_FREQ(VAL) ((SEC_MSEC) / (VAL))
-#define NSEC_TO_MUSEC(VAL) ((VAL) / 1000)
-
accel_sensor_hal::accel_sensor_hal()
: m_x(-1)
, m_y(-1)
const string sensorhub_interval_node_name = "accel_poll_delay";
csensor_config &config = csensor_config::get_instance();
- node_path_info_query query;
- node_path_info info;
- int input_method = IIO_METHOD;
+ node_info_query query;
+ node_info info;
- if (!get_model_properties(SENSOR_TYPE_ACCEL, m_model_id, input_method)) {
- ERR("Failed to find model_properties");
+ if (!find_model_id(SENSOR_TYPE_ACCEL, m_model_id)) {
+ ERR("Failed to find model id");
throw ENXIO;
}
- query.input_method = input_method;
query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name);
query.sensor_type = SENSOR_TYPE_ACCEL;
- query.input_event_key = "accelerometer_sensor";
+ query.key = "accelerometer_sensor";
query.iio_enable_node_name = "accel_enable";
query.sensorhub_interval_node_name = sensorhub_interval_node_name;
- if (!get_node_path_info(query, info)) {
+ if (!get_node_info(query, info)) {
ERR("Failed to get node info");
throw ENXIO;
}
- show_node_path_info(info);
+ show_node_info(info);
+ m_method = info.method;
m_data_node = info.data_node_path;
+ m_enable_node = info.enable_node_path;
m_interval_node = info.interval_node_path;
- m_accel_dir = info.base_dir;
- m_trigger_path = info.trigger_node_path;
- m_buffer_enable_node_path = info.buffer_enable_node_path;
- m_buffer_length_node_path = info.buffer_length_node_path;
- m_available_freq_node_path = info.available_freq_node_path;
- m_available_scale_node_path = m_accel_dir + string(SCALE_AVAILABLE_NODE);
if (!config.get(SENSOR_TYPE_ACCEL, m_model_id, ELEMENT_VENDOR, m_vendor)) {
ERR("[VENDOR] is empty\n");
INFO("m_chip_name = %s\n",m_chip_name.c_str());
- if (input_method == IIO_METHOD) {
- m_trigger_name = m_model_id + "-trigger";
- if (!verify_iio_trigger(m_trigger_name)) {
- ERR("Failed verify trigger");
- throw ENXIO;
- }
- string scan_dir = m_accel_dir + "scan_elements/";
- if (!get_generic_channel_names(scan_dir, string("_type"), m_generic_channel_names))
- ERR ("Failed to find any input channels");
- else
- {
- INFO ("generic channel names:");
- for (vector <string>::iterator it = m_generic_channel_names.begin();
- it != m_generic_channel_names.end(); ++it) {
- INFO ("%s", it->c_str());
- }
- }
- }
-
long resolution;
if (!config.get(SENSOR_TYPE_ACCEL, m_model_id, ELEMENT_RESOLUTION, resolution)) {
}
m_raw_data_unit = (float)(raw_data_unit);
+ INFO("m_raw_data_unit = %f\n", m_raw_data_unit);
- m_node_handle = open(m_data_node.c_str(), O_RDONLY | O_NONBLOCK);
- if (m_node_handle < 0) {
+ if ((m_node_handle = open(m_data_node.c_str(), O_RDWR)) < 0) {
ERR("accel handle open fail for accel processor, error:%s\n", strerror(errno));
throw ENXIO;
}
- if (setup_channels() == true)
- INFO("IIO channel setup successful");
- else {
- ERR("IIO channel setup failed");
- throw ENXIO;
- }
+ if (m_method == INPUT_EVENT_METHOD) {
+ int clockId = CLOCK_MONOTONIC;
+ if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0)
+ ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str());
-// int clockId = CLOCK_MONOTONIC;
-// if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0) {
-// ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str());
-// throw ENXIO;
-// }
+ update_value = [=](bool wait) {
+ return this->update_value_input_event(wait);
+ };
+ } else {
+ if (!info.buffer_length_node_path.empty())
+ set_node_value(info.buffer_length_node_path, 480);
+
+ if (!info.buffer_enable_node_path.empty())
+ set_node_value(info.buffer_enable_node_path, 1);
+
+ update_value = [=](bool wait) {
+ return this->update_value_iio(wait);
+ };
+ }
- INFO("m_raw_data_unit = %f\n", m_raw_data_unit);
INFO("accel_sensor is created!\n");
}
accel_sensor_hal::~accel_sensor_hal()
{
- enable_resource(false);
- if (m_data != NULL)
- delete []m_data;
-
close(m_node_handle);
m_node_handle = -1;
return ACCELEROMETER_SENSOR;
}
-bool accel_sensor_hal::add_accel_channels_to_array(void)
+bool accel_sensor_hal::enable(void)
{
- int i = 0;
- m_channels = (struct channel_parameters*) malloc(sizeof(struct channel_parameters) * m_generic_channel_names.size());
- for (vector <string>::iterator it = m_generic_channel_names.begin();
- it != m_generic_channel_names.end(); ++it) {
- if (add_channel_to_array(m_accel_dir.c_str(), it->c_str() , &m_channels[i++]) < 0) {
- ERR("Failed to add channel %s to channel array", it->c_str());
- return false;
- }
- }
+ AUTOLOCK(m_mutex);
+
+ set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_ACCELEROMETER_ENABLE_BIT);
+ set_interval(m_polling_interval);
+
+ m_fired_time = 0;
+ INFO("Accel sensor real starting");
return true;
}
-bool accel_sensor_hal::setup_channels(void)
+bool accel_sensor_hal::disable(void)
{
- int freq, i;
- double sf;
+ AUTOLOCK(m_mutex);
- enable_resource(true);
+ set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_ACCELEROMETER_ENABLE_BIT);
- if (!add_accel_channels_to_array()) {
- ERR("Failed to add channels to array!");
- return false;
- }
+ INFO("Accel sensor real stopping");
+ return true;
+}
- INFO("Sorting channels by index");
- sort_channels_by_index(m_channels, m_generic_channel_names.size());
- INFO("Sorting channels by index completed");
+bool accel_sensor_hal::set_interval(unsigned long val)
+{
+ unsigned long long polling_interval_ns;
- m_scan_size = get_channel_array_size(m_channels, m_generic_channel_names.size());
- if (m_scan_size == 0) {
- ERR("Channel array size is zero");
- return false;
- }
+ AUTOLOCK(m_mutex);
- m_data = new (std::nothrow) char[m_scan_size * ACCEL_RINGBUF_LEN];
- if (m_data == NULL) {
- ERR("Couldn't create data buffer\n");
- return false;
- }
+ polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu);
- FILE *fp = NULL;
- fp = fopen(m_available_freq_node_path.c_str(), "r");
- if (!fp) {
- ERR("Fail to open available frequencies file:%s\n", m_available_freq_node_path.c_str());
+ if (!set_node_value(m_interval_node, polling_interval_ns)) {
+ ERR("Failed to set polling resource: %s\n", m_interval_node.c_str());
return false;
}
- for (i = 0; i < MAX_FREQ_COUNT; i++)
- m_sample_freq[i] = 0;
+ INFO("Interval is changed from %dms to %dms]", m_polling_interval, val);
+ m_polling_interval = val;
+ return true;
+}
- i = 0;
- while (fscanf(fp, "%d", &freq) > 0)
- m_sample_freq[i++] = freq;
+bool accel_sensor_hal::update_value_input_event(bool wait)
+{
+ int accel_raw[3] = {0,};
+ bool x,y,z;
+ int read_input_cnt = 0;
+ const int INPUT_MAX_BEFORE_SYN = 10;
+ unsigned long long fired_time = 0;
+ bool syn = false;
+
+ x = y = z = false;
+
+ struct input_event accel_input;
+ DBG("accel event detection!");
+
+ while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) {
+ int len = read(m_node_handle, &accel_input, sizeof(accel_input));
+ if (len != sizeof(accel_input)) {
+ ERR("accel_file read fail, read_len = %d\n",len);
+ return false;
+ }
- m_sample_freq_count = i;
+ ++read_input_cnt;
+
+ if (accel_input.type == EV_REL) {
+ switch (accel_input.code) {
+ case REL_X:
+ accel_raw[0] = (int)accel_input.value;
+ x = true;
+ break;
+ case REL_Y:
+ accel_raw[1] = (int)accel_input.value;
+ y = true;
+ break;
+ case REL_Z:
+ accel_raw[2] = (int)accel_input.value;
+ z = true;
+ break;
+ default:
+ ERR("accel_input event[type = %d, code = %d] is unknown.", accel_input.type, accel_input.code);
+ return false;
+ break;
+ }
+ } else if (accel_input.type == EV_SYN) {
+ syn = true;
+ fired_time = sensor_hal::get_timestamp(&accel_input.time);
+ } else {
+ ERR("accel_input event[type = %d, code = %d] is unknown.", accel_input.type, accel_input.code);
+ return false;
+ }
+ }
- fp = fopen(m_available_scale_node_path.c_str(), "r");
- if (!fp) {
- ERR("Fail to open available scale factors file:%s\n", m_available_scale_node_path.c_str());
+ if (syn == false) {
+ ERR("EV_SYN didn't come until %d inputs had come", read_input_cnt);
return false;
}
- for (i = 0; i < MAX_SCALING_COUNT; i++)
- m_scale_factor[i] = 0;
+ AUTOLOCK(m_value_mutex);
- i = 0;
+ if (x)
+ m_x = accel_raw[0];
+ if (y)
+ m_y = accel_raw[1];
+ if (z)
+ m_z = accel_raw[2];
- while (fscanf(fp, "%lf", &sf) > 0)
- m_scale_factor[i++] = sf;
+ m_fired_time = fired_time;
- m_scale_factor_count = i;
+ DBG("m_x = %d, m_y = %d, m_z = %d, time = %lluus", m_x, m_y, m_z, m_fired_time);
return true;
}
-void accel_sensor_hal::decode_data(void)
+
+bool accel_sensor_hal::update_value_iio(bool wait)
{
- AUTOLOCK(m_value_mutex);
+ const int READ_LEN = 14;
+ char data[READ_LEN] = {0,};
- m_x = convert_bytes_to_int(*(unsigned short int *)(m_data + m_channels[0].buf_index), &m_channels[0]);
- m_y = convert_bytes_to_int(*(unsigned short int *)(m_data + m_channels[1].buf_index), &m_channels[1]);
- m_z = convert_bytes_to_int(*(unsigned short int *)(m_data + m_channels[2].buf_index), &m_channels[2]);
+ struct pollfd pfd;
- long long int val = *(long long int *)(m_data + m_channels[3].buf_index);
- if ((val >> m_channels[3].valid_bits) & 1)
- val = (val & m_channels[3].mask) | ~m_channels[3].mask;
+ pfd.fd = m_node_handle;
+ pfd.events = POLLIN | POLLERR;
+ pfd.revents = 0;
- m_fired_time = (unsigned long long int)(NSEC_TO_MUSEC(val));
- DBG("m_x = %d, m_y = %d, m_z = %d, time = %lluus", m_x, m_y, m_z, m_fired_time);
-}
-bool accel_sensor_hal::setup_trigger(const char* trig_name, bool verify)
-{
- int ret = 0;
+ int ret = poll(&pfd, 1, -1);
- ret = update_sysfs_string(m_trigger_path.c_str(), trig_name);
- if (ret < 0) {
- ERR("failed to write to current_trigger,%s,%s\n", m_trigger_path.c_str(), trig_name);
+ if (ret == -1) {
+ ERR("poll error:%s m_node_handle:d", strerror(errno), m_node_handle);
+ return false;
+ } else if (!ret) {
+ ERR("poll timeout m_node_handle:%d", m_node_handle);
return false;
}
- INFO("current_trigger setup successfully\n");
- return true;
-}
-bool accel_sensor_hal::setup_buffer(int enable)
-{
- int ret;
- ret = update_sysfs_num(m_buffer_length_node_path.c_str(), ACCEL_RINGBUF_LEN, true);
- if (ret < 0) {
- ERR("failed to write to buffer/length\n");
+ if (pfd.revents & POLLERR) {
+ ERR("poll exception occurred! m_node_handle:%d", m_node_handle);
return false;
}
- INFO("buffer/length setup successfully\n");
- ret = update_sysfs_num(m_buffer_enable_node_path.c_str(), enable, true);
- if (ret < 0) {
- ERR("failed to write to buffer/enable\n");
+ if (!(pfd.revents & POLLIN)) {
+ ERR("poll nothing to read! m_node_handle:%d, pfd.revents = %d", m_node_handle, pfd.revents);
return false;
}
- if (enable)
- INFO("buffer enabled\n");
- else
- INFO("buffer disabled\n");
- return true;
-}
+ int len = read(m_node_handle, data, sizeof(data));
-bool accel_sensor_hal::enable_resource(bool enable)
-{
- string temp;
- if(enable)
- setup_trigger(m_trigger_name.c_str(), enable);
- else
- setup_trigger("NULL", enable);
-
- for (vector <string>::iterator it = m_generic_channel_names.begin();
- it != m_generic_channel_names.end(); ++it) {
- temp = m_accel_dir + string(SCAN_EL_DIR) + *it + string("_en");
- if (update_sysfs_num(temp.c_str(), enable) < 0)
- return false;
+ if (len != sizeof(data)) {
+ ERR("Failed to read data, m_node_handle:%d read_len:%d", m_node_handle, len);
+ return false;
}
- setup_buffer(enable);
- return true;
-}
-bool accel_sensor_hal::enable(void)
-{
- AUTOLOCK(m_mutex);
+ AUTOLOCK(m_value_mutex);
- if (!enable_resource(true))
- return false;
+ m_x = *((short *)(data));
+ m_y = *((short *)(data + 2));
+ m_z = *((short *)(data + 4));
- set_interval(m_polling_interval);
+ m_fired_time = *((long long*)(data + 6));
- m_fired_time = 0;
- INFO("Accel sensor real starting");
- return true;
-}
+ INFO("m_x = %d, m_y = %d, m_z = %d, time = %lluus", m_x, m_y, m_z, m_fired_time);
-bool accel_sensor_hal::disable(void)
-{
- AUTOLOCK(m_mutex);
-
- if (!enable_resource(false))
- return false;
-
- INFO("Accel sensor real stopping");
return true;
-}
-
-bool accel_sensor_hal::set_interval(unsigned long ms_interval)
-{
- int freq, i;
-
- freq = (int)(MSEC_TO_FREQ(ms_interval));
-
- for (i=0; i < m_sample_freq_count; i++) {
- if (freq == m_sample_freq[i]) {
- if (update_sysfs_num(m_interval_node.c_str(), freq, true) == 0) {
- INFO("Interval is changed from %lums to %lums]", m_polling_interval, ms_interval);
- m_polling_interval = ms_interval;
- return true;
- }
- else {
- ERR("Failed to set data %lu\n", ms_interval);
- return false;
- }
- }
- }
- DBG("The interval not supported: %lu\n", ms_interval);
- ERR("Failed to set data %lu\n", ms_interval);
- return false;
-}
-
-bool accel_sensor_hal::update_value(bool wait)
-{
- int i;
- struct pollfd pfd;
- ssize_t read_size;
- const int TIMEOUT = 1000;
-
- pfd.fd = m_node_handle;
- pfd.events = POLLIN;
- if (wait)
- poll(&pfd, 1, TIMEOUT);
- else
- poll(&pfd, 1, 0);
-
- read_size = read(m_node_handle, m_data, ACCEL_RINGBUF_LEN * m_scan_size);
- if (read_size <= 0) {
- ERR("Accel:No data available\n");
- return false;
- }
- else {
- for (i = 0; i < (read_size / m_scan_size); i++)
- decode_data();
- }
- return true;
}
bool accel_sensor_hal::is_data_ready(bool wait)
return true;
}
-extern "C" void *create(void)
+extern "C" sensor_module* create(void)
{
- accel_sensor_hal *inst;
+ accel_sensor_hal *sensor;
try {
- inst = new accel_sensor_hal();
+ sensor = new(std::nothrow) accel_sensor_hal;
} catch (int err) {
- ERR("accel_sensor class create fail , errno : %d , errstr : %s\n", err, strerror(err));
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
return NULL;
}
- return (void*)inst;
-}
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
-extern "C" void destroy(void *inst)
-{
- delete (accel_sensor_hal*)inst;
+ module->sensors.push_back(sensor);
+ return module;
}
#ifndef _ACCEL_SENSOR_HAL_H_
#define _ACCEL_SENSOR_HAL_H_
-#define MAX_FREQ_COUNT 16
-#define MAX_SCALING_COUNT 16
-
#include <sensor_hal.h>
#include <string>
-#include <iio_common.h>
+#include <functional>
using std::string;
bool is_data_ready(bool wait);
virtual int get_sensor_data(sensor_data_t &data);
bool get_properties(sensor_properties_s &properties);
-// bool check_hw_node(void);
private:
int m_x;
unsigned long m_polling_interval;
unsigned long long m_fired_time;
- int m_scale_factor_count;
- int m_sample_freq_count;
- int m_sample_freq[MAX_FREQ_COUNT];
- double m_scale_factor[MAX_SCALING_COUNT];
- char *m_data;
- int m_scan_size;
- struct channel_parameters *m_channels;
-
- string m_trigger_name;
- string m_trigger_path;
- string m_buffer_enable_node_path;
- string m_buffer_length_node_path;
- string m_available_freq_node_path;
- string m_available_scale_node_path;
- string m_accel_dir;
- vector<string> m_generic_channel_names;
-
string m_model_id;
string m_vendor;
string m_chip_name;
int m_resolution;
float m_raw_data_unit;
+ int m_method;
string m_data_node;
+ string m_enable_node;
string m_interval_node;
+ std::function<bool (bool)> update_value;
+
bool m_sensorhub_controlled;
cmutex m_value_mutex;
- bool update_value(bool wait);
- bool calibration(int cmd);
-
- bool setup_trigger(const char* trig_name, bool verify);
- bool setup_buffer(int enable);
- bool enable_resource(bool enable);
- bool add_accel_channels_to_array(void);
- bool setup_channels(void);
- bool setup_trigger(char* trig_name, bool verify);
- void decode_data(void);
+ bool update_value_input_event(bool wait);
+ bool update_value_iio(bool wait);
};
#endif /*_ACCEL_SENSOR_HAL_CLASS_H_*/
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(auto_rotation CXX)
+
+SET(SENSOR_NAME auto_rotation_sensor)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_SOURCE_DIR}/src/libsensord)
+
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(auto_rot_pkgs REQUIRED vconf)
+
+FOREACH(flag ${auto_rot_pkgs_LDFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${auto_rot_pkgs_CFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+add_library(${SENSOR_NAME} SHARED
+ auto_rotation_sensor.cpp
+ auto_rotation_alg.cpp
+ auto_rotation_alg_emul.cpp
+ )
+
+target_link_libraries(${SENSOR_NAME} ${auto_rot_pkgs_LDFLAGS} "-lm")
+
+install(TARGETS ${SENSOR_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}/sensord)
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 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 <common.h>
+#include <auto_rotation_alg.h>
+
+auto_rotation_alg::auto_rotation_alg()
+{
+}
+
+auto_rotation_alg::~auto_rotation_alg()
+{
+}
+
+bool auto_rotation_alg::open(void)
+{
+ return true;
+}
+
+bool auto_rotation_alg::close(void)
+{
+ return true;
+}
+
+bool auto_rotation_alg::start(void)
+{
+ return true;
+}
+
+bool auto_rotation_alg::stop(void)
+{
+ return true;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 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.
+ *
+ */
+
+#ifndef _AUTO_ROTATION_ALG_H_
+#define _AUTO_ROTATION_ALG_H_
+
+class auto_rotation_alg
+{
+public:
+ auto_rotation_alg();
+ virtual ~auto_rotation_alg();
+
+ virtual bool open(void);
+ virtual bool close(void);
+ virtual bool start(void);
+ virtual bool stop(void);
+ virtual bool get_rotation(float acc[3], unsigned long long timestamp, int prev_rotation, int &rotation) = 0;
+};
+#endif /* _AUTO_ROTATION_ALG_H_ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 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_common.h>
+#include <common.h>
+#include <sensor_auto_rotation.h>
+#include <auto_rotation_alg_emul.h>
+#include <stdlib.h>
+#include <math.h>
+
+#define ROTATION_RULE_CNT 4
+
+struct rotation_rule {
+ int tilt;
+ int angle;
+};
+
+struct rotation_rule rot_rule[ROTATION_RULE_CNT] = {
+ {40, 80},
+ {50, 70},
+ {60, 65},
+ {90, 60},
+};
+
+auto_rotation_alg_emul::auto_rotation_alg_emul()
+{
+}
+
+auto_rotation_alg_emul::~auto_rotation_alg_emul()
+{
+ close();
+}
+
+int auto_rotation_alg_emul::convert_rotation(int prev_rotation,
+ float acc_pitch, float acc_theta)
+{
+ const int ROTATION_0 = 0;
+ const int ROTATION_90 = 90;
+ const int ROTATION_180 = 180;
+ const int ROTATION_360 = 360;
+ const int TILT_MIN = 30;
+ int tilt;
+ int angle;
+
+ int new_rotation = AUTO_ROTATION_DEGREE_UNKNOWN;
+
+ for (int i = 0; i < ROTATION_RULE_CNT; ++i) {
+ tilt = rot_rule[i].tilt;
+
+ if ((acc_pitch < TILT_MIN) || (acc_pitch > tilt))
+ continue;
+
+ if ((prev_rotation == AUTO_ROTATION_DEGREE_0) || (prev_rotation == AUTO_ROTATION_DEGREE_180))
+ angle = rot_rule[i].angle;
+ else
+ angle = ROTATION_90 - rot_rule[i].angle;
+
+ if ((acc_theta >= ROTATION_360 - angle && acc_theta <= ROTATION_360 - 1) ||
+ (acc_theta >= ROTATION_0 && acc_theta <= ROTATION_0 + angle))
+ new_rotation = AUTO_ROTATION_DEGREE_0;
+ else if (acc_theta >= ROTATION_0 + angle && acc_theta <= ROTATION_180 - angle)
+ new_rotation = AUTO_ROTATION_DEGREE_90;
+ else if (acc_theta >= ROTATION_180 - angle && acc_theta <= ROTATION_180 + angle)
+ new_rotation = AUTO_ROTATION_DEGREE_180;
+ else if (acc_theta >= ROTATION_180 + angle && acc_theta <= ROTATION_360 - angle)
+ new_rotation = AUTO_ROTATION_DEGREE_270;
+
+ break;
+ }
+
+ return new_rotation;
+}
+
+bool auto_rotation_alg_emul::get_rotation(float acc[3],
+ unsigned long long timestamp, int prev_rotation, int &cur_rotation)
+{
+ const int ROTATION_90 = 90;
+ const int RADIAN = 57.29747;
+
+ double atan_value;
+ int acc_theta;
+ int acc_pitch;
+ double realg;
+ float x, y, z;
+
+ x = acc[0];
+ y = acc[1];
+ z = acc[2];
+
+ atan_value = atan2(x, y);
+ acc_theta = (int)(atan_value * (RADIAN) + 360) % 360;
+ realg = (double)sqrt((x * x) + (y * y) + (z * z));
+ acc_pitch = ROTATION_90 - abs((int) (asin(z / realg) * RADIAN));
+
+ cur_rotation = convert_rotation(prev_rotation, acc_pitch, acc_theta);
+
+ if (cur_rotation == AUTO_ROTATION_DEGREE_UNKNOWN)
+ return false;
+
+ if (cur_rotation != prev_rotation)
+ return true;
+
+ return false;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 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.
+ *
+ */
+
+#ifndef _AUTO_ROTATION_ALG_EMUL_H_
+#define _AUTO_ROTATION_ALG_EMUL_H_
+
+#include <auto_rotation_alg.h>
+
+class auto_rotation_alg_emul : public auto_rotation_alg
+{
+public:
+ auto_rotation_alg_emul();
+ virtual ~auto_rotation_alg_emul();
+
+ virtual bool get_rotation(float acc[3], unsigned long long timestamp, int prev_rotation, int &cur_rotation);
+
+private:
+ int convert_rotation(int prev_rotation, float acc_pitch, float acc_theta);
+};
+#endif /* _AUTO_ROTATION_ALG_EMUL_H_ */
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <math.h>
+#include <time.h>
+#include <sys/types.h>
+#include <dlfcn.h>
+
+#include <common.h>
+#include <sf_common.h>
+
+#include <virtual_sensor.h>
+#include <auto_rotation_sensor.h>
+#include <sensor_plugin_loader.h>
+#include <auto_rotation_alg.h>
+#include <auto_rotation_alg_emul.h>
+
+using std::bind1st;
+using std::mem_fun;
+
+#define SENSOR_NAME "AUTO_ROTATION_SENSOR"
+#define AUTO_ROTATION_LIB "/usr/lib/sensord/libauto-rotation.so"
+
+auto_rotation_sensor::auto_rotation_sensor()
+: m_accel_sensor(NULL)
+, m_rotation(0)
+, m_rotation_time(1) // rotation state is valid from initial state, so set rotation time to non-zero value
+, m_alg(NULL)
+{
+ m_name = string(SENSOR_NAME);
+
+ register_supported_event(AUTO_ROTATION_EVENT_CHANGE_STATE);
+}
+
+auto_rotation_sensor::~auto_rotation_sensor()
+{
+ delete m_alg;
+
+ INFO("auto_rotation_sensor is destroyed!\n");
+}
+
+bool auto_rotation_sensor::check_lib(void)
+{
+ if (access(AUTO_ROTATION_LIB, F_OK) < 0)
+ return false;
+
+ return true;
+}
+
+auto_rotation_alg *auto_rotation_sensor::get_alg()
+{
+ return new auto_rotation_alg_emul();
+}
+
+bool auto_rotation_sensor::init()
+{
+ m_accel_sensor = sensor_plugin_loader::get_instance().get_sensor(ACCELEROMETER_SENSOR);
+
+ if (!m_accel_sensor) {
+ ERR("cannot load accel sensor_hal[%s]", sensor_base::get_name());
+ return false;
+ }
+
+ m_alg = get_alg();
+
+ if (!m_alg) {
+ ERR("Not supported AUTO ROTATION sensor");
+ return false;
+ }
+
+ if (!m_alg->open())
+ return false;
+
+ set_privilege(SENSOR_PRIVILEGE_INTERNAL);
+
+ INFO("%s is created!\n", sensor_base::get_name());
+
+ return true;
+}
+
+sensor_type_t auto_rotation_sensor::get_type(void)
+{
+ return AUTO_ROTATION_SENSOR;
+}
+
+bool auto_rotation_sensor::on_start(void)
+{
+ const int SAMPLING_TIME = 60;
+ m_rotation = AUTO_ROTATION_DEGREE_UNKNOWN;
+
+ m_alg->start();
+
+ m_accel_sensor->add_client(ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME);
+ m_accel_sensor->add_interval((int)this , SAMPLING_TIME, true);
+ m_accel_sensor->start();
+
+ return activate();
+}
+
+bool auto_rotation_sensor::on_stop(void)
+{
+ m_accel_sensor->delete_client(ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME);
+ m_accel_sensor->delete_interval((int)this , true);
+ m_accel_sensor->stop();
+
+ return deactivate();
+}
+
+void auto_rotation_sensor::synthesize(const sensor_event_t& event, vector<sensor_event_t> &outs)
+{
+ AUTOLOCK(m_mutex);
+
+ if (event.event_type == ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME) {
+ int rotation;
+ float acc[3];
+ acc[0] = event.data.values[0];
+ acc[1] = event.data.values[1];
+ acc[2] = event.data.values[2];
+
+ if (!m_alg->get_rotation(acc, event.data.timestamp, m_rotation, rotation))
+ return;
+
+ AUTOLOCK(m_value_mutex);
+ sensor_event_t rotation_event;
+
+ INFO("Rotation: %d, ACC[0]: %f, ACC[1]: %f, ACC[2]: %f", rotation, event.data.values[0], event.data.values[1], event.data.values[2]);
+ rotation_event.sensor_id = get_id();
+ rotation_event.data.accuracy = SENSOR_ACCURACY_GOOD;
+ rotation_event.event_type = AUTO_ROTATION_EVENT_CHANGE_STATE;
+ rotation_event.data.timestamp = event.data.timestamp;
+ rotation_event.data.values[0] = rotation;
+ rotation_event.data.value_count = 1;
+ outs.push_back(rotation_event);
+ m_rotation = rotation;
+ m_rotation_time = event.data.timestamp;
+
+ return;
+ }
+ return;
+}
+
+int auto_rotation_sensor::get_sensor_data(unsigned int data_id, sensor_data_t &data)
+{
+ if (data_id != AUTO_ROTATION_BASE_DATA_SET)
+ return -1;
+
+ AUTOLOCK(m_value_mutex);
+
+ data.accuracy = SENSOR_ACCURACY_GOOD;
+ data.timestamp = m_rotation_time;
+ data.values[0] = m_rotation;
+ data.value_count = 1;
+
+ return 0;
+}
+
+bool auto_rotation_sensor::get_properties(sensor_properties_t &properties)
+{
+ properties.name = "Auto Rotation Sensor";
+ properties.vendor = "Samsung Electronics";
+ properties.min_range = AUTO_ROTATION_DEGREE_UNKNOWN;
+ properties.max_range = AUTO_ROTATION_DEGREE_270;
+ properties.min_interval = 1;
+ properties.resolution = 1;
+ properties.fifo_count = 0;
+ properties.max_batch_count = 0;
+
+ return true;
+}
+
+extern "C" sensor_module* create(void)
+{
+ auto_rotation_sensor *sensor;
+
+ try {
+ sensor = new(std::nothrow) auto_rotation_sensor;
+ } catch (int err) {
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
+ return NULL;
+ }
+
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
+
+ module->sensors.push_back(sensor);
+ return module;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 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.
+ *
+ */
+
+#ifndef _AUTO_ROTATION_SENSOR_H_
+#define _AUTO_ROTATION_SENSOR_H_
+
+#include <sensor_internal.h>
+#include <vconf.h>
+#include <string>
+#include <auto_rotation_alg.h>
+
+using std::string;
+
+class auto_rotation_sensor : public virtual_sensor {
+public:
+ auto_rotation_sensor();
+ virtual ~auto_rotation_sensor();
+
+ bool init();
+ sensor_type_t get_type(void);
+
+ static bool working(void *inst);
+
+ void synthesize(const sensor_event_t& event, vector<sensor_event_t> &outs);
+
+ int get_sensor_data(unsigned int data_id, sensor_data_t &data);
+ virtual bool get_properties(sensor_properties_t &properties);
+private:
+ sensor_base *m_accel_sensor;
+ cmutex m_value_mutex;
+
+ int m_rotation;
+ unsigned long long m_rotation_time;
+ auto_rotation_alg *m_alg;
+
+ auto_rotation_alg *get_alg();
+ virtual bool on_start(void);
+ virtual bool on_stop(void);
+ bool check_lib(void);
+};
+
+#endif
register_supported_event(GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME);
register_supported_event(GEOMAGNETIC_EVENT_CALIBRATION_NEEDED);
+ register_supported_event(GEOMAGNETIC_EVENT_UNPROCESSED_DATA_REPORT_ON_TIME);
physical_sensor::set_poller(geo_sensor::working, this);
}
AUTOLOCK(m_client_info_mutex);
AUTOLOCK(m_mutex);
+ if (get_client_cnt(GEOMAGNETIC_EVENT_UNPROCESSED_DATA_REPORT_ON_TIME)) {
+ event.sensor_id = get_id();
+ event.event_type = GEOMAGNETIC_EVENT_UNPROCESSED_DATA_REPORT_ON_TIME;
+ push(event);
+ }
+
if (get_client_cnt(GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME)) {
event.sensor_id = get_id();
event.event_type = GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME;
return -1;
state = m_sensor_hal->get_sensor_data(data);
+ raw_to_base(data);
if (state < 0) {
ERR("m_sensor_hal get struct_data fail\n");
data.values[2] = data.values[2] * m_resolution;
}
-extern "C" void *create(void)
+extern "C" sensor_module* create(void)
{
- geo_sensor *inst;
+ geo_sensor *sensor;
try {
- inst = new geo_sensor();
+ sensor = new(std::nothrow) geo_sensor;
} catch (int err) {
- ERR("geo_sensor class create fail , errno : %d , errstr : %s\n", err, strerror(err));
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
return NULL;
}
- return (void*)inst;
-}
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
-extern "C" void destroy(void *inst)
-{
- delete (geo_sensor*)inst;;
+ module->sensors.push_back(sensor);
+ return module;
}
#include <geo_sensor_hal.h>
#include <sys/ioctl.h>
#include <fstream>
-#include <iio_common.h>
using std::ifstream;
#define SENSOR_TYPE_MAGNETIC "MAGNETIC"
-#define ELEMENT_NAME "NAME"
+#define ELEMENT_NAME "NAME"
#define ELEMENT_VENDOR "VENDOR"
#define ELEMENT_RAW_DATA_UNIT "RAW_DATA_UNIT"
#define ELEMENT_MIN_RANGE "MIN_RANGE"
#define ELEMENT_MAX_RANGE "MAX_RANGE"
#define ATTR_VALUE "value"
-#define INITIAL_TIME -1
-#define GAUSS_TO_UTESLA(val) ((val) * 100.0f)
-
geo_sensor_hal::geo_sensor_hal()
-: m_polling_interval(POLL_1HZ_MS)
-, m_x(0)
+: m_x(0)
, m_y(0)
, m_z(0)
, m_hdst(0)
-, m_fired_time(INITIAL_TIME)
+, m_fired_time(0)
, m_node_handle(-1)
+, m_polling_interval(POLL_1HZ_MS)
{
const string sensorhub_interval_node_name = "mag_poll_delay";
csensor_config &config = csensor_config::get_instance();
- node_path_info_query query;
- node_path_info info;
- int input_method = IIO_METHOD;
+ node_info_query query;
+ node_info info;
- if (!get_model_properties(SENSOR_TYPE_MAGNETIC, m_model_id, input_method)) {
- ERR("Failed to find model_properties");
+ if (!find_model_id(SENSOR_TYPE_MAGNETIC, m_model_id)) {
+ ERR("Failed to find model id");
throw ENXIO;
-
}
- query.input_method = input_method;
query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name);
query.sensor_type = SENSOR_TYPE_MAGNETIC;
- query.input_event_key = "geomagnetic_sensor";
+ query.key = "geomagnetic_sensor";
query.iio_enable_node_name = "geomagnetic_enable";
query.sensorhub_interval_node_name = sensorhub_interval_node_name;
- if (!get_node_path_info(query, info)) {
+ bool error = get_node_info(query, info);
+
+ query.key = "magnetic_sensor";
+ error |= get_node_info(query, info);
+
+ if (!error) {
ERR("Failed to get node info");
throw ENXIO;
}
- show_node_path_info(info);
+ show_node_info(info);
m_data_node = info.data_node_path;
m_enable_node = info.enable_node_path;
m_interval_node = info.interval_node_path;
- if (input_method == IIO_METHOD) {
- m_geo_dir = info.base_dir;
- m_x_node = m_geo_dir + string(X_RAW_VAL_NODE);
- m_y_node = m_geo_dir + string(Y_RAW_VAL_NODE);
- m_z_node = m_geo_dir + string(Z_RAW_VAL_NODE);
- m_x_scale_node = m_geo_dir + string(X_SCALE_NODE);
- m_y_scale_node = m_geo_dir + string(Y_SCALE_NODE);
- m_z_scale_node = m_geo_dir + string(Z_SCALE_NODE);
- INFO("Raw data node X: %s", m_x_node.c_str());
- INFO("Raw data node Y: %s", m_y_node.c_str());
- INFO("Raw data node Z: %s", m_z_node.c_str());
- INFO("scale node X: %s", m_x_scale_node.c_str());
- INFO("scale node Y: %s", m_y_scale_node.c_str());
- INFO("scale node Z: %s", m_z_scale_node.c_str());
- }
-
if (!config.get(SENSOR_TYPE_MAGNETIC, m_model_id, ELEMENT_VENDOR, m_vendor)) {
ERR("[VENDOR] is empty\n");
throw ENXIO;
throw ENXIO;
}
- init_resources();
-
INFO("m_chip_name = %s\n",m_chip_name.c_str());
+
+ double min_range;
+
+ if (!config.get(SENSOR_TYPE_MAGNETIC, m_model_id, ELEMENT_MIN_RANGE, min_range)) {
+ ERR("[MIN_RANGE] is empty\n");
+ throw ENXIO;
+ }
+
+ m_min_range = (float)min_range;
+ INFO("m_min_range = %f\n",m_min_range);
+
+ double max_range;
+
+ if (!config.get(SENSOR_TYPE_MAGNETIC, m_model_id, ELEMENT_MAX_RANGE, max_range)) {
+ ERR("[MAX_RANGE] is empty\n");
+ throw ENXIO;
+ }
+
+ m_max_range = (float)max_range;
+ INFO("m_max_range = %f\n",m_max_range);
+
+ double raw_data_unit;
+
+ if (!config.get(SENSOR_TYPE_MAGNETIC, m_model_id, ELEMENT_RAW_DATA_UNIT, raw_data_unit)) {
+ ERR("[RAW_DATA_UNIT] is empty\n");
+ throw ENXIO;
+ }
+
+ m_raw_data_unit = (float)(raw_data_unit);
+
+ if ((m_node_handle = open(m_data_node.c_str(),O_RDWR)) < 0) {
+ ERR("Failed to open handle(%d)", m_node_handle);
+ throw ENXIO;
+ }
+
+ int clockId = CLOCK_MONOTONIC;
+ if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0)
+ ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str());
+
INFO("m_raw_data_unit = %f\n", m_raw_data_unit);
INFO("geo_sensor_hal is created!\n");
geo_sensor_hal::~geo_sensor_hal()
{
- if (m_node_handle > 0)
- close(m_node_handle);
+ close(m_node_handle);
m_node_handle = -1;
INFO("geo_sensor is destroyed!\n");
bool geo_sensor_hal::enable(void)
{
- m_fired_time = INITIAL_TIME;
+ AUTOLOCK(m_mutex);
+
+ set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_GEOMAGNETIC_ENABLE_BIT);
+ set_interval(m_polling_interval);
+
+ m_fired_time = 0;
INFO("Geo sensor real starting");
return true;
}
bool geo_sensor_hal::disable(void)
{
+ AUTOLOCK(m_mutex);
+
+ set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_GEOMAGNETIC_ENABLE_BIT);
+
INFO("Geo sensor real stopping");
return true;
}
bool geo_sensor_hal::set_interval(unsigned long val)
{
- INFO("Polling interval cannot be changed.");
+ unsigned long long polling_interval_ns;
+
+ AUTOLOCK(m_mutex);
+
+ polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu);
+
+ if (!set_node_value(m_interval_node, polling_interval_ns)) {
+ ERR("Failed to set polling resource: %s\n", m_interval_node.c_str());
+ return false;
+ }
+
+ INFO("Interval is changed from %dms to %dms]", m_polling_interval, val);
+ m_polling_interval = val;
return true;
}
-bool geo_sensor_hal::update_value(void)
+bool geo_sensor_hal::update_value(bool wait)
{
- int raw_values[3] = {0,};
- ifstream temp_handle;
+ int geo_raw[4] = {0,};
+ bool x,y,z,hdst;
+ int read_input_cnt = 0;
+ const int INPUT_MAX_BEFORE_SYN = 10;
+ unsigned long long fired_time = 0;
+ bool syn = false;
+
+ x = y = z = hdst = false;
+
+ struct input_event geo_input;
+ DBG("geo event detection!");
+
+ while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) {
+ int len = read(m_node_handle, &geo_input, sizeof(geo_input));
+ if (len != sizeof(geo_input)) {
+ ERR("geo_file read fail, read_len = %d\n",len);
+ return false;
+ }
+
+ ++read_input_cnt;
+
+ if (geo_input.type == EV_REL) {
+ switch (geo_input.code) {
+ case REL_RX:
+ geo_raw[0] = (int)geo_input.value;
+ x = true;
+ break;
+ case REL_RY:
+ geo_raw[1] = (int)geo_input.value;
+ y = true;
+ break;
+ case REL_RZ:
+ geo_raw[2] = (int)geo_input.value;
+ z = true;
+ break;
+ case REL_HWHEEL:
+ geo_raw[3] = (int)geo_input.value;
+ hdst = true;
+ break;
+ default:
+ ERR("geo_input event[type = %d, code = %d] is unknown.", geo_input.type, geo_input.code);
+ return false;
+ break;
+ }
+ } else if (geo_input.type == EV_SYN) {
+ syn = true;
+ fired_time = get_timestamp(&geo_input.time);
+ } else {
+ ERR("geo_input event[type = %d, code = %d] is unknown.", geo_input.type, geo_input.code);
+ return false;
+ }
+ }
- if (!read_node_value<int>(m_x_node, raw_values[0]))
- return false;
- if (!read_node_value<int>(m_y_node, raw_values[1]))
- return false;
- if (!read_node_value<int>(m_z_node, raw_values[2]))
- return false;
+ AUTOLOCK(m_value_mutex);
+
+ if (x)
+ m_x = geo_raw[0];
+ if (y)
+ m_y = geo_raw[1];
+ if (z)
+ m_z = geo_raw[2];
+ if (hdst)
+ m_hdst = geo_raw[3] - 1; /* accuracy bias: -1 */
- m_x = GAUSS_TO_UTESLA(raw_values[0] * m_x_scale);
- m_y = GAUSS_TO_UTESLA(raw_values[1] * m_y_scale);
- m_z = GAUSS_TO_UTESLA(raw_values[2] * m_z_scale);
+ m_fired_time = fired_time;
- m_fired_time = INITIAL_TIME;
- INFO("x = %d, y = %d, z = %d, time = %lluus", raw_values[0], raw_values[1], raw_values[2], m_fired_time);
- INFO("x = %f, y = %f, z = %f, time = %lluus", m_x, m_y, m_z, m_fired_time);
+ DBG("m_x = %d, m_y = %d, m_z = %d, m_hdst = %d, time = %lluus", m_x, m_y, m_z, m_hdst, m_fired_time);
return true;
}
bool geo_sensor_hal::is_data_ready(bool wait)
{
bool ret;
- ret = update_value();
+ ret = update_value(wait);
return ret;
}
int geo_sensor_hal::get_sensor_data(sensor_data_t &data)
{
- data.accuracy = SENSOR_ACCURACY_GOOD;
+ data.accuracy = (m_hdst == 1) ? 0 : m_hdst; /* hdst 0 and 1 are needed to calibrate */
data.timestamp = m_fired_time;
data.value_count = 3;
data.values[0] = (float)m_x;
return true;
}
-bool geo_sensor_hal::init_resources(void)
+extern "C" sensor_module* create(void)
{
- ifstream temp_handle;
-
- if (!read_node_value<double>(m_x_scale_node, m_x_scale)) {
- ERR("Failed to read x scale node");
- return false;
- }
- if (!read_node_value<double>(m_y_scale_node, m_y_scale)) {
- ERR("Failed to read y scale node");
- return false;
- }
- if (!read_node_value<double>(m_z_scale_node, m_z_scale)) {
- ERR("Failed to read y scale node");
- return false;
- }
- INFO("Scale Values: %f, %f, %f", m_x_scale, m_y_scale, m_z_scale);
- return true;
-}
-
-extern "C" void *create(void)
-{
- geo_sensor_hal *inst;
+ geo_sensor_hal *sensor;
try {
- inst = new geo_sensor_hal();
+ sensor = new(std::nothrow) geo_sensor_hal;
} catch (int err) {
- ERR("geo_sensor_hal class create fail , errno : %d , errstr : %s\n", err, strerror(err));
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
return NULL;
}
- return (void*)inst;
-}
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
-extern "C" void destroy(void *inst)
-{
- delete (geo_sensor_hal*)inst;
+ module->sensors.push_back(sensor);
+ return module;
}
#include <sensor_hal.h>
#include <string>
-#define X_RAW_VAL_NODE "in_magn_x_raw"
-#define Y_RAW_VAL_NODE "in_magn_y_raw"
-#define Z_RAW_VAL_NODE "in_magn_z_raw"
-#define X_SCALE_NODE "in_magn_x_scale"
-#define Y_SCALE_NODE "in_magn_y_scale"
-#define Z_SCALE_NODE "in_magn_z_scale"
-
using std::string;
class geo_sensor_hal : public sensor_hal
float m_max_range;
float m_raw_data_unit;
- unsigned long m_polling_interval;
-
double m_x;
double m_y;
double m_z;
- double m_x_scale;
- double m_y_scale;
- double m_z_scale;
int m_hdst;
unsigned long long m_fired_time;
int m_node_handle;
+ unsigned long m_polling_interval;
string m_enable_node;
-
- /*For Input Method*/
string m_data_node;
string m_interval_node;
- /*For IIO method*/
- string m_geo_dir;
- string m_x_node;
- string m_y_node;
- string m_z_node;
- string m_x_scale_node;
- string m_y_scale_node;
- string m_z_scale_node;
-
bool m_sensorhub_controlled;
cmutex m_value_mutex;
- bool update_value(void);
- bool init_resources(void);
+ bool update_value(bool wait);
};
#endif /*_GEO_SENSOR_HAL_H_*/
, m_x(INITIAL_VALUE)
, m_y(INITIAL_VALUE)
, m_z(INITIAL_VALUE)
+, m_time(0)
{
cvirtual_sensor_config &config = cvirtual_sensor_config::get_instance();
- m_name = string(SENSOR_NAME);
- m_timestamp = get_timestamp();
+ m_name = std::string(SENSOR_NAME);
register_supported_event(GRAVITY_EVENT_RAW_DATA_REPORT_ON_TIME);
if (!config.get(SENSOR_TYPE_GRAVITY, ELEMENT_VENDOR, m_vendor)) {
AUTOLOCK(m_mutex);
m_orientation_sensor->add_client(ORIENTATION_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_orientation_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), true);
+ m_orientation_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false);
m_orientation_sensor->start();
activate();
AUTOLOCK(m_mutex);
m_orientation_sensor->delete_client(ORIENTATION_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_orientation_sensor->delete_interval((intptr_t)this, true);
+ m_orientation_sensor->delete_interval((intptr_t)this, false);
m_orientation_sensor->stop();
deactivate();
bool gravity_sensor::add_interval(int client_id, unsigned int interval)
{
AUTOLOCK(m_mutex);
- m_orientation_sensor->add_interval(client_id , interval, true);
+ m_orientation_sensor->add_interval(client_id , interval, false);
- return sensor_base::add_interval(client_id, interval, true);
+ return sensor_base::add_interval(client_id, interval, false);
}
bool gravity_sensor::delete_interval(int client_id)
{
AUTOLOCK(m_mutex);
- m_orientation_sensor->delete_interval(client_id , true);
+ m_orientation_sensor->delete_interval(client_id , false);
- return sensor_base::delete_interval(client_id, true);
+ return sensor_base::delete_interval(client_id, false);
}
void gravity_sensor::synthesize(const sensor_event_t &event, vector<sensor_event_t> &outs)
}
if (event.event_type == ORIENTATION_EVENT_RAW_DATA_REPORT_ON_TIME) {
- diff_time = event.data.timestamp - m_timestamp;
+ diff_time = event.data.timestamp - m_time;
- if (m_timestamp && (diff_time < m_interval * MIN_DELIVERY_DIFF_FACTOR))
+ if (m_time && (diff_time < m_interval * MIN_DELIVERY_DIFF_FACTOR))
return;
gravity_event.sensor_id = get_id();
gravity_event.event_type = GRAVITY_EVENT_RAW_DATA_REPORT_ON_TIME;
- m_timestamp = get_timestamp();
if ((roll >= (M_PI/2)-DEVIATION && roll <= (M_PI/2)+DEVIATION) ||
(roll >= -(M_PI/2)-DEVIATION && roll <= -(M_PI/2)+DEVIATION)) {
gravity_event.data.values[0] = m_gravity_sign_compensation[0] * GRAVITY * sin(roll) * cos(azimuth);
gravity_event.data.values[2] = m_gravity_sign_compensation[2] * GRAVITY * cos(roll) * cos(pitch);
}
gravity_event.data.value_count = 3;
- gravity_event.data.timestamp = m_timestamp;
+ gravity_event.data.timestamp = get_timestamp();
gravity_event.data.accuracy = SENSOR_ACCURACY_GOOD;
push(gravity_event);
+
+ {
+ AUTOLOCK(m_value_mutex);
+
+ m_time = gravity_event.data.timestamp;
+ m_x = gravity_event.data.values[0];
+ m_y = gravity_event.data.values[1];
+ m_z = gravity_event.data.values[2];
+ }
}
}
properties.resolution = 0.000001;
properties.vendor = m_vendor;
properties.name = SENSOR_NAME;
+ properties.fifo_count = 0;
+ properties.max_batch_count = 0;
+ properties.min_interval = 1;
return true;
}
-extern "C" void *create(void)
+extern "C" sensor_module* create(void)
{
- gravity_sensor *inst;
+ gravity_sensor *sensor;
try {
- inst = new gravity_sensor();
+ sensor = new(std::nothrow) gravity_sensor;
} catch (int err) {
- ERR("Failed to create gravity_sensor class, errno : %d, errstr : %s", err, strerror(err));
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
return NULL;
}
- return (void *)inst;
-}
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
-extern "C" void destroy(void *inst)
-{
- delete (gravity_sensor *)inst;
+ module->sensors.push_back(sensor);
+ return module;
}
#include <sensor_internal.h>
#include <virtual_sensor.h>
-#include <string>
-
-using std::string;
class gravity_sensor : public virtual_sensor {
public:
float m_x;
float m_y;
float m_z;
- unsigned long long m_timestamp;
+ int m_accuracy;
+ unsigned long long m_time;
unsigned int m_interval;
string m_vendor;
bool on_stop(void);
};
-#endif
+#endif /* _GRAVITY_SENSOR_H_ */
m_name = string(SENSOR_NAME);
register_supported_event(GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME);
+ register_supported_event(GYROSCOPE_EVENT_UNPROCESSED_DATA_REPORT_ON_TIME);
physical_sensor::set_poller(gyro_sensor::working, this);
}
AUTOLOCK(m_client_info_mutex);
+ if (get_client_cnt(GYROSCOPE_EVENT_UNPROCESSED_DATA_REPORT_ON_TIME)) {
+ event.sensor_id = get_id();
+ event.event_type = GYROSCOPE_EVENT_UNPROCESSED_DATA_REPORT_ON_TIME;
+ push(event);
+ }
+
if (get_client_cnt(GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME)) {
event.sensor_id = get_id();
event.event_type = GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME;
data.values[2] = data.values[2] * m_resolution;
}
-extern "C" void *create(void)
+extern "C" sensor_module* create(void)
{
- gyro_sensor *inst;
+ gyro_sensor *sensor;
try {
- inst = new gyro_sensor();
+ sensor = new(std::nothrow) gyro_sensor;
} catch (int err) {
- ERR("gyro_sensor class create fail , errno : %d , errstr : %s\n", err, strerror(err));
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
return NULL;
}
- return (void*)inst;
-}
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
-extern "C" void destroy(void *inst)
-{
- delete (gyro_sensor*)inst;;
+ module->sensors.push_back(sensor);
+ return module;
}
#include <gyro_sensor_hal.h>
#include <sys/ioctl.h>
#include <fstream>
-#include <sys/poll.h>
using std::ifstream;
#define ATTR_VALUE "value"
-#define SCALE_AVAILABLE_NODE "in_anglvel_scale_available"
-#define SCAN_EL_DIR "scan_elements/"
-#define TRIG_SUFFIX "-trigger"
-#define GYRO_RINGBUF_LEN 32
-#define SEC_MSEC 1000
-#define MSEC_TO_FREQ(VAL) ((SEC_MSEC) / (VAL))
-#define NSEC_TO_MUSEC(VAL) ((VAL) / 1000)
-
gyro_sensor_hal::gyro_sensor_hal()
: m_x(-1)
, m_y(-1)
const string sensorhub_interval_node_name = "gyro_poll_delay";
csensor_config &config = csensor_config::get_instance();
- node_path_info_query query;
- node_path_info info;
- int input_method = IIO_METHOD;
+ node_info_query query;
+ node_info info;
- if (!get_model_properties(SENSOR_TYPE_GYRO, m_model_id, input_method)) {
- ERR("Failed to find model_properties");
+ if (!find_model_id(SENSOR_TYPE_GYRO, m_model_id)) {
+ ERR("Failed to find model id");
throw ENXIO;
}
- query.input_method = input_method;
query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name);
query.sensor_type = SENSOR_TYPE_GYRO;
- query.input_event_key = "gyro_sensor";
+ query.key = "gyro_sensor";
query.iio_enable_node_name = "gyro_enable";
query.sensorhub_interval_node_name = sensorhub_interval_node_name;
- if (!get_node_path_info(query, info)) {
+ if (!get_node_info(query, info)) {
ERR("Failed to get node info");
throw ENXIO;
}
- show_node_path_info(info);
+ show_node_info(info);
m_data_node = info.data_node_path;
+ m_enable_node = info.enable_node_path;
m_interval_node = info.interval_node_path;
- m_gyro_dir = info.base_dir;
- m_trigger_path = info.trigger_node_path;
- m_buffer_enable_node_path = info.buffer_enable_node_path;
- m_buffer_length_node_path = info.buffer_length_node_path;
- m_available_freq_node_path = info.available_freq_node_path;
- m_available_scale_node_path = m_gyro_dir + string(SCALE_AVAILABLE_NODE);
if (!config.get(SENSOR_TYPE_GYRO, m_model_id, ELEMENT_VENDOR, m_vendor)) {
ERR("[VENDOR] is empty\n");
INFO("m_chip_name = %s\n",m_chip_name.c_str());
- if (input_method == IIO_METHOD) {
- m_trigger_name = m_model_id + TRIG_SUFFIX;
- if (!verify_iio_trigger(m_trigger_name)) {
- ERR("Failed verify trigger");
- throw ENXIO;
- }
- string scan_dir = m_gyro_dir + SCAN_EL_DIR;
- if (!get_generic_channel_names(scan_dir, string("_type"), m_generic_channel_names))
- ERR ("Failed to find any input channels");
- else {
- INFO ("generic channel names:");
- for (vector <string>::iterator it = m_generic_channel_names.begin();
- it != m_generic_channel_names.end(); ++it) {
- INFO ("%s", it->c_str());
- }
- }
- }
-
long resolution;
if (!config.get(SENSOR_TYPE_GYRO, m_model_id, ELEMENT_RESOLUTION, resolution)) {
throw ENXIO;
}
- if (setup_channels() == true)
- INFO("IIO channel setup successful");
- else {
- ERR("IIO channel setup failed");
- throw ENXIO;
- }
+ int clockId = CLOCK_MONOTONIC;
+ if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0)
+ ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str());
INFO("m_raw_data_unit = %f\n",m_raw_data_unit);
INFO("RAW_DATA_TO_DPS_UNIT(m_raw_data_unit) = [%f]",RAW_DATA_TO_DPS_UNIT(m_raw_data_unit));
gyro_sensor_hal::~gyro_sensor_hal()
{
- enable_resource(false);
- if (m_data != NULL)
- delete []m_data;
-
close(m_node_handle);
m_node_handle = -1;
{
AUTOLOCK(m_mutex);
- if (!enable_resource(true))
- return false;
-
+ set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_GYROSCOPE_ENABLE_BIT);
set_interval(m_polling_interval);
m_fired_time = 0;
{
AUTOLOCK(m_mutex);
- if (!enable_resource(false))
- return false;
+ set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_GYROSCOPE_ENABLE_BIT);
INFO("Gyro sensor real stopping");
return true;
}
-bool gyro_sensor_hal::set_interval(unsigned long ms_interval)
+bool gyro_sensor_hal::set_interval(unsigned long val)
{
- int freq, i;
+ unsigned long long polling_interval_ns;
+
+ AUTOLOCK(m_mutex);
- freq = (int)(MSEC_TO_FREQ(ms_interval));
+ polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu);
- for (i=0; i < m_sample_freq_count; i++) {
- if (freq == m_sample_freq[i]) {
- if (update_sysfs_num(m_interval_node.c_str(), freq, true) == 0) {
- INFO("Interval is changed from %lums to %lums]", m_polling_interval, ms_interval);
- m_polling_interval = ms_interval;
- return true;
- }
- else {
- ERR("Failed to set data %lu\n", ms_interval);
- return false;
- }
- }
+ if (!set_node_value(m_interval_node, polling_interval_ns)) {
+ ERR("Failed to set polling resource: %s\n", m_interval_node.c_str());
+ return false;
}
- DBG("The interval not supported: %lu\n", ms_interval);
- ERR("Failed to set data %lu\n", ms_interval);
- return false;
+ INFO("Interval is changed from %dms to %dms]", m_polling_interval, val);
+ m_polling_interval = val;
+ return true;
}
+
bool gyro_sensor_hal::update_value(bool wait)
{
- int i;
- struct pollfd pfd;
- ssize_t read_size;
- const int TIMEOUT = 1000;
-
- pfd.fd = m_node_handle;
- pfd.events = POLLIN;
- if (wait)
- poll(&pfd, 1, TIMEOUT);
- else
- poll(&pfd, 1, 0);
-
- read_size = read(m_node_handle, m_data, GYRO_RINGBUF_LEN * m_scan_size);
- if (read_size <= 0) {
- ERR("Gyro:No data available\n");
- return false;
- }
- else {
- for (i = 0; i < (read_size / m_scan_size); i++)
- decode_data();
+ int gyro_raw[3] = {0,};
+ bool x,y,z;
+ int read_input_cnt = 0;
+ const int INPUT_MAX_BEFORE_SYN = 10;
+ unsigned long long fired_time = 0;
+ bool syn = false;
+
+ x = y = z = false;
+
+ struct input_event gyro_input;
+ DBG("gyro event detection!");
+
+ while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) {
+ int len = read(m_node_handle, &gyro_input, sizeof(gyro_input));
+ if (len != sizeof(gyro_input)) {
+ ERR("gyro_file read fail, read_len = %d\n, %s",len, strerror(errno));
+ return false;
+ }
+
+ ++read_input_cnt;
+
+ if (gyro_input.type == EV_REL) {
+ switch (gyro_input.code) {
+ case REL_RX:
+ gyro_raw[0] = (int)gyro_input.value;
+ x = true;
+ break;
+ case REL_RY:
+ gyro_raw[1] = (int)gyro_input.value;
+ y = true;
+ break;
+ case REL_RZ:
+ gyro_raw[2] = (int)gyro_input.value;
+ z = true;
+ break;
+ default:
+ ERR("gyro_input event[type = %d, code = %d] is unknown.", gyro_input.type, gyro_input.code);
+ return false;
+ break;
+ }
+ } else if (gyro_input.type == EV_SYN) {
+ syn = true;
+ fired_time = sensor_hal::get_timestamp(&gyro_input.time);
+ } else {
+ ERR("gyro_input event[type = %d, code = %d] is unknown.", gyro_input.type, gyro_input.code);
+ return false;
+ }
}
+
+ AUTOLOCK(m_value_mutex);
+
+ if (x)
+ m_x = gyro_raw[0];
+ if (y)
+ m_y = gyro_raw[1];
+ if (z)
+ m_z = gyro_raw[2];
+
+ m_fired_time = fired_time;
+
+ DBG("m_x = %d, m_y = %d, m_z = %d, time = %lluus", m_x, m_y, m_z, m_fired_time);
+
return true;
}
}
-bool gyro_sensor_hal::add_gyro_channels_to_array(void)
-{
- int i = 0;
- m_channels = (struct channel_parameters*) malloc(sizeof(struct channel_parameters) * m_generic_channel_names.size());
- for (vector <string>::iterator it = m_generic_channel_names.begin();
- it != m_generic_channel_names.end(); ++it) {
- if (add_channel_to_array(m_gyro_dir.c_str(), it->c_str() , &m_channels[i++]) < 0) {
- ERR("Failed to add channel %s to channel array", it->c_str());
- return false;
- }
- }
- return true;
-}
-
-bool gyro_sensor_hal::setup_channels(void)
+extern "C" sensor_module* create(void)
{
- int freq, i;
- double sf;
-
- enable_resource(true);
-
- if (!add_gyro_channels_to_array()) {
- ERR("Failed to add channels to array!");
- return false;
- }
-
- INFO("Sorting channels by index");
- sort_channels_by_index(m_channels, m_generic_channel_names.size());
- INFO("Sorting channels by index completed");
-
- m_scan_size = get_channel_array_size(m_channels, m_generic_channel_names.size());
- if (m_scan_size == 0) {
- ERR("Channel array size is zero");
- return false;
- }
-
- m_data = new (std::nothrow) char[m_scan_size * GYRO_RINGBUF_LEN];
- if (m_data == NULL) {
- ERR("Couldn't create data buffer\n");
- return false;
- }
-
- FILE *fp = NULL;
- fp = fopen(m_available_freq_node_path.c_str(), "r");
- if (!fp) {
- ERR("Fail to open available frequencies file:%s\n", m_available_freq_node_path.c_str());
- return false;
- }
-
- for (i = 0; i < MAX_FREQ_COUNT; i++)
- m_sample_freq[i] = 0;
-
- i = 0;
-
- while (fscanf(fp, "%d", &freq) > 0)
- m_sample_freq[i++] = freq;
-
- m_sample_freq_count = i;
-
- fp = fopen(m_available_scale_node_path.c_str(), "r");
- if (!fp) {
- ERR("Fail to open available scale factors file:%s\n", m_available_scale_node_path.c_str());
- return false;
- }
-
- for (i = 0; i < MAX_SCALING_COUNT; i++)
- m_scale_factor[i] = 0;
-
- i = 0;
-
- while (fscanf(fp, "%lf", &sf) > 0)
- m_scale_factor[i++] = sf;
-
- m_scale_factor_count = i;
-
- return true;
-}
-
-void gyro_sensor_hal::decode_data(void)
-{
- AUTOLOCK(m_value_mutex);
-
- m_x = convert_bytes_to_int(*(unsigned short int *)(m_data + m_channels[0].buf_index), &m_channels[0]);
- m_y = convert_bytes_to_int(*(unsigned short int *)(m_data + m_channels[1].buf_index), &m_channels[1]);
- m_z = convert_bytes_to_int(*(unsigned short int *)(m_data + m_channels[2].buf_index), &m_channels[2]);
-
- long long int val = *(long long int *)(m_data + m_channels[3].buf_index);
- if ((val >> m_channels[3].valid_bits) & 1)
- val = (val & m_channels[3].mask) | ~m_channels[3].mask;
-
- m_fired_time = (unsigned long long int)(NSEC_TO_MUSEC(val));
- INFO("m_x = %d, m_y = %d, m_z = %d, time = %lluus", m_x, m_y, m_z, m_fired_time);
-}
-
-bool gyro_sensor_hal::setup_trigger(const char* trig_name, bool verify)
-{
- int ret = 0;
-
- ret = update_sysfs_string(m_trigger_path.c_str(), trig_name);
- if (ret < 0) {
- ERR("failed to write to current_trigger,%s,%s\n", m_trigger_path.c_str(), trig_name);
- return false;
- }
- INFO("current_trigger setup successfully\n");
- return true;
-}
-
-bool gyro_sensor_hal::setup_buffer(int enable)
-{
- int ret;
- ret = update_sysfs_num(m_buffer_length_node_path.c_str(), GYRO_RINGBUF_LEN, true);
- if (ret < 0) {
- ERR("failed to write to buffer/length\n");
- return false;
- }
- INFO("buffer/length setup successfully\n");
-
- ret = update_sysfs_num(m_buffer_enable_node_path.c_str(), enable, true);
- if (ret < 0) {
- ERR("failed to write to buffer/enable\n");
- return false;
- }
-
- if (enable)
- INFO("buffer enabled\n");
- else
- INFO("buffer disabled\n");
- return true;
-}
-
-bool gyro_sensor_hal::enable_resource(bool enable)
-{
- string temp;
- if(enable)
- setup_trigger(m_trigger_name.c_str(), enable);
- else
- setup_trigger("NULL", enable);
-
- for (vector <string>::iterator it = m_generic_channel_names.begin();
- it != m_generic_channel_names.end(); ++it) {
- temp = m_gyro_dir + string(SCAN_EL_DIR) + *it + string("_en");
- if (update_sysfs_num(temp.c_str(), enable) < 0)
- return false;
- }
- setup_buffer(enable);
- return true;
-}
-
-extern "C" void *create(void)
-{
- gyro_sensor_hal *inst;
+ gyro_sensor_hal *sensor;
try {
- inst = new gyro_sensor_hal();
+ sensor = new(std::nothrow) gyro_sensor_hal;
} catch (int err) {
- ERR("gyro_sensor class create fail , errno : %d , errstr : %s\n", err, strerror(err));
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
return NULL;
}
- return (void*)inst;
-}
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
-extern "C" void destroy(void *inst)
-{
- delete (gyro_sensor_hal*)inst;
+ module->sensors.push_back(sensor);
+ return module;
}
#include <sensor_hal.h>
#include <string>
-#include <iio_common.h>
-
-#define MAX_FREQ_COUNT 16
-#define MAX_SCALING_COUNT 16
using std::string;
unsigned long m_polling_interval;
unsigned long long m_fired_time;
- int m_scale_factor_count;
- int m_sample_freq_count;
- int m_sample_freq[MAX_FREQ_COUNT];
- double m_scale_factor[MAX_SCALING_COUNT];
- char *m_data;
- int m_scan_size;
- struct channel_parameters *m_channels;
-
- string m_trigger_name;
- string m_trigger_path;
- string m_buffer_enable_node_path;
- string m_buffer_length_node_path;
- string m_available_freq_node_path;
- string m_available_scale_node_path;
- string m_gyro_dir;
- vector<string> m_generic_channel_names;
-
string m_model_id;
string m_vendor;
string m_chip_name;
+ float m_min_range;
+ float m_max_range;
int m_resolution;
float m_raw_data_unit;
string m_data_node;
+ string m_enable_node;
string m_interval_node;
bool m_sensorhub_controlled;
cmutex m_value_mutex;
bool update_value(bool wait);
- bool setup_trigger(const char* trig_name, bool verify);
- bool setup_buffer(int enable);
- bool enable_resource(bool enable);
- bool add_gyro_channels_to_array(void);
- bool setup_channels(void);
- bool setup_trigger(char* trig_name, bool verify);
- void decode_data(void);
-
};
#endif /*_GYRO_SENSOR_HAL_CLASS_H_*/
install(FILES sensor_gyro.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sensor/)
install(FILES sensor_pressure.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sensor/)
install(FILES sensor_context.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sensor/)
+install(FILES sensor_auto_rotation.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sensor/)
install(FILES sensor_gravity.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sensor/)
install(FILES sensor_linear_accel.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sensor/)
install(FILES sensor_orientation.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/sensor/)
retvm_if (!get_sensor_list(), false, "Fail to get sensor list from server");
vector<sensor_info *> sensor_infos = sensor_info_manager::get_instance().get_infos(type);
- *list = (sensor_t *) malloc(sizeof(sensor_info *) * sensor_infos.size());
- retvm_if(!*list, false, "Failed to allocate memory");
- for (unsigned int i = 0; i < sensor_infos.size(); ++i)
+ if (!sensor_infos.empty()) {
+ *list = (sensor_t *) malloc(sizeof(sensor_info *) * sensor_infos.size());
+ retvm_if(!*list, false, "Failed to allocate memory");
+ }
+
+ for (int i = 0; i < sensor_infos.size(); ++i)
*(*list + i) = sensor_info_to_sensor(sensor_infos[i]);
*sensor_count = sensor_infos.size();
}
-bool sensord_send_sensorhub_data(int handle, const char *data, int data_len)
+API bool sensord_send_sensorhub_data(int handle, const char *data, int data_len)
{
sensor_id_t sensor_id;
command_channel *cmd_channel;
}
if(!cmd_channel->cmd_get_data(data_id, sensor_data)) {
- ERR("Cmd_get_struct(%d, %d, 0x%x) failed for %s", client_id, data_id, sensor_data, get_client_name());
+ ERR("cmd_get_data(%d, %d, 0x%x) failed for %s", client_id, data_id, sensor_data, get_client_name());
return false;
}
FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, GYROSCOPE_SENSOR, 0, 1),
FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, PRESSURE_SENSOR, 0, 1),
FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, CONTEXT_SENSOR, 0, 1),
+ FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, AUTO_ROTATION_SENSOR, 0, 1),
FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, GRAVITY_SENSOR, 0, 1),
FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, LINEAR_ACCEL_SENSOR, 0, 1),
FILL_LOG_ELEMENT(LOG_ID_SENSOR_TYPE, ORIENTATION_SENSOR, 0, 1),
FILL_LOG_ELEMENT(LOG_ID_EVENT, GEOMAGNETIC_EVENT_CALIBRATION_NEEDED, 0, 1),
FILL_LOG_ELEMENT(LOG_ID_EVENT, PROXIMITY_EVENT_CHANGE_STATE, 0,1),
FILL_LOG_ELEMENT(LOG_ID_EVENT, LIGHT_EVENT_CHANGE_LEVEL, 0, 1),
-
FILL_LOG_ELEMENT(LOG_ID_EVENT, PROXIMITY_EVENT_STATE_REPORT_ON_TIME, 0, 10),
FILL_LOG_ELEMENT(LOG_ID_EVENT, PROXIMITY_EVENT_DISTANCE_DATA_REPORT_ON_TIME, 0, 10),
FILL_LOG_ELEMENT(LOG_ID_EVENT, CONTEXT_EVENT_REPORT, 0, 1),
-
+ FILL_LOG_ELEMENT(LOG_ID_EVENT, AUTO_ROTATION_EVENT_CHANGE_STATE, 0, 1),
FILL_LOG_ELEMENT(LOG_ID_EVENT, ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME, 0, 10),
FILL_LOG_ELEMENT(LOG_ID_EVENT, GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME, 0, 10),
FILL_LOG_ELEMENT(LOG_ID_EVENT, GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME, 0, 10),
FILL_LOG_ELEMENT(LOG_ID_DATA, LIGHT_BASE_DATA_SET, 0, 25),
FILL_LOG_ELEMENT(LOG_ID_DATA, LIGHT_LUX_DATA_SET, 0, 25),
FILL_LOG_ELEMENT(LOG_ID_DATA, CONTEXT_BASE_DATA_SET, 0, 25),
+ FILL_LOG_ELEMENT(LOG_ID_DATA, AUTO_ROTATION_BASE_DATA_SET, 0, 25),
FILL_LOG_ELEMENT(LOG_ID_DATA, GRAVITY_BASE_DATA_SET, 0, 25),
FILL_LOG_ELEMENT(LOG_ID_DATA, LINEAR_ACCEL_BASE_DATA_SET, 0, 25),
FILL_LOG_ELEMENT(LOG_ID_DATA, ORIENTATION_BASE_DATA_SET, 0, 25),
case GEOMAGNETIC_EVENT_CALIBRATION_NEEDED:
case LIGHT_EVENT_CHANGE_LEVEL:
case PROXIMITY_EVENT_CHANGE_STATE:
+ case AUTO_ROTATION_EVENT_CHANGE_STATE:
return true;
break;
}
switch (sensor) {
case GEOMAGNETIC_SENSOR:
return GEOMAGNETIC_EVENT_CALIBRATION_NEEDED;
+ case ROTATION_VECTOR_SENSOR:
+ return ROTATION_VECTOR_EVENT_CALIBRATION_NEEDED;
case ORIENTATION_SENSOR:
return ORIENTATION_EVENT_CALIBRATION_NEEDED;
default:
enum accelerometer_event_type {
ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME = (ACCELEROMETER_SENSOR << 16) | 0x0001,
+ ACCELEROMETER_EVENT_UNPROCESSED_DATA_REPORT_ON_TIME = (ACCELEROMETER_SENSOR << 16) | 0x0002,
};
/**
--- /dev/null
+/*
+ * libsensord
+ *
+ * Copyright (c) 2014 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.
+ *
+ */
+
+#ifndef _SENSOR_AUTO_ROTATION_H_
+#define _SENSOR_AUTO_ROTATION_H_
+
+//! Pre-defined events for the auto_rotation sensor
+//! Sensor Plugin developer can add more event to their own headers
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @defgroup SENSOR_AUTO_ROTATION Auto Rotation Sensor
+ * @ingroup SENSOR_FRAMEWORK
+ *
+ * These APIs are used to control the Auto Rotation sensor.
+ * @{
+ */
+
+enum auto_rotation_data_id {
+ AUTO_ROTATION_BASE_DATA_SET = (AUTO_ROTATION_SENSOR << 16) | 0x0001,
+};
+
+enum auto_rotation_event_type {
+ AUTO_ROTATION_EVENT_CHANGE_STATE = (AUTO_ROTATION_SENSOR << 16) | 0x0001,
+};
+
+enum auto_rotation_state {
+ AUTO_ROTATION_DEGREE_UNKNOWN = 0,
+ AUTO_ROTATION_DEGREE_0,
+ AUTO_ROTATION_DEGREE_90,
+ AUTO_ROTATION_DEGREE_180,
+ AUTO_ROTATION_DEGREE_270,
+};
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+//! End of a file
enum geomag_evet_type {
GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME = (GEOMAGNETIC_SENSOR << 16) | 0x0001,
GEOMAGNETIC_EVENT_CALIBRATION_NEEDED = (GEOMAGNETIC_SENSOR << 16) | 0x0002,
+ GEOMAGNETIC_EVENT_UNPROCESSED_DATA_REPORT_ON_TIME = (GEOMAGNETIC_SENSOR << 16) | 0x0003,
};
/**
enum gyro_event_type {
GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME = (GYROSCOPE_SENSOR << 16) | 0x0001,
+ GYROSCOPE_EVENT_UNPROCESSED_DATA_REPORT_ON_TIME = (GYROSCOPE_SENSOR << 16) | 0x0002,
};
/**
#include <sensor_gyro.h>
#include <sensor_pressure.h>
#include <sensor_context.h>
+#include <sensor_auto_rotation.h>
#include <sensor_gravity.h>
#include <sensor_linear_accel.h>
#include <sensor_orientation.h>
AUTOLOCK(m_client_info_mutex);
+ event.sensor_id = get_id();
if (get_client_cnt(LIGHT_EVENT_LUX_DATA_REPORT_ON_TIME)) {
event.event_type = LIGHT_EVENT_LUX_DATA_REPORT_ON_TIME;
push(event);
bool light_sensor::on_start(void)
{
- AUTOLOCK(m_mutex);
-
if (!m_sensor_hal->enable()) {
ERR("m_sensor_hal start fail");
return false;
bool light_sensor::on_stop(void)
{
- AUTOLOCK(m_mutex);
-
if (!m_sensor_hal->disable()) {
ERR("m_sensor_hal stop fail");
return false;
return stop_poll();
}
-bool light_sensor::get_properties(const unsigned int type, sensor_properties_s &properties)
+bool light_sensor::get_properties(sensor_properties_s &properties)
{
m_sensor_hal->get_properties(properties);
-
- if (type == LIGHT_LUX_DATA_SET)
- return 0;
-
- if (type == LIGHT_BASE_DATA_SET) {
- properties.min_range = 0;
- properties.max_range = sizeof(m_light_level) / sizeof(m_light_level[0]) - 1;
- properties.resolution = 1;
- return 0;
- }
-
- return -1;
+ return true;
}
-int light_sensor::get_sensor_data(const unsigned int type, sensor_data_t &data)
+int light_sensor::get_sensor_data(unsigned int type, sensor_data_t &data)
{
int ret;
ret = m_sensor_hal->get_sensor_data(data);
AUTOLOCK(m_mutex);
INFO("Polling interval is set to %dms", interval);
+
return m_sensor_hal->set_interval(interval);
}
void light_sensor::raw_to_level(sensor_data_t &data)
{
data.values[0] = (int) adc_to_light_level((int)data.values[0]);
- data.values_num = 1;
+ data.value_count = 1;
}
-extern "C" void *create(void)
+extern "C" sensor_module* create(void)
{
- light_sensor *inst;
+ light_sensor *sensor;
try {
- inst = new light_sensor();
+ sensor = new(std::nothrow) light_sensor;
} catch (int err) {
- ERR("Failed to create light_sensor class, errno : %d, errstr : %s", err, strerror(err));
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
return NULL;
}
- return (void *)inst;
-}
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
-extern "C" void destroy(void *inst)
-{
- delete (light_sensor *)inst;
+ module->sensors.push_back(sensor);
+ return module;
}
#include <physical_sensor.h>
#include <sensor_hal.h>
-class light_sensor : public physical_sensor
-{
+class light_sensor : public physical_sensor {
public:
light_sensor();
virtual ~light_sensor();
static bool working(void *inst);
- virtual bool on_start(void);
- virtual bool on_stop(void);
-
virtual bool set_interval(unsigned long interval);
- virtual bool get_properties(const unsigned int type, sensor_properties_s &properties);
+ virtual bool get_properties(sensor_properties_s &properties);
int get_sensor_data(const unsigned int type, sensor_data_t &data);
private:
static const int m_light_level[];
+
sensor_hal *m_sensor_hal;
int m_level;
+ virtual bool on_start(void);
+ virtual bool on_stop(void);
+
+ bool process_event(void);
int adc_to_light_level(int adc);
+
void raw_to_level(sensor_data_t &data);
void raw_to_state(sensor_data_t &data);
- bool process_event(void);
};
#endif /*_LIGHT_SENSOR_H_*/
#include <csensor_config.h>
#include <light_sensor_hal.h>
#include <sys/ioctl.h>
-#include <iio_common.h>
using std::ifstream;
: m_polling_interval(POLL_1HZ_MS)
, m_adc(INVALID_VALUE)
, m_fired_time(INITIAL_TIME)
-, m_node_handle(-1)
+, m_node_handle(INITIAL_VALUE)
{
const string sensorhub_interval_node_name = "light_poll_delay";
csensor_config &config = csensor_config::get_instance();
- node_path_info_query query;
- node_path_info info;
- int input_method = IIO_METHOD;
+ node_info_query query;
+ node_info info;
- if (!get_model_properties(SENSOR_TYPE_LIGHT, m_model_id, input_method)) {
- ERR("Failed to find model_properties");
+ if (!find_model_id(SENSOR_TYPE_LIGHT, m_model_id)) {
+ ERR("Failed to find model id");
throw ENXIO;
}
- query.input_method = IIO_METHOD;
query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name);
query.sensor_type = SENSOR_TYPE_LIGHT;
- query.input_event_key = "light_sensor";
+ query.key = "light_sensor";
query.iio_enable_node_name = "light_enable";
query.sensorhub_interval_node_name = sensorhub_interval_node_name;
- if (!get_node_path_info(query, info)) {
+ if (!get_node_info(query, info)) {
ERR("Failed to get node info");
throw ENXIO;
}
- show_node_path_info(info);
+ show_node_info(info);
m_data_node = info.data_node_path;
m_enable_node = info.enable_node_path;
m_interval_node = info.interval_node_path;
- if(input_method == IIO_METHOD) {
- m_light_dir=info.base_dir;
- m_light_node = m_light_dir + string(ILL_CLEAR_NODE);
-
- INFO("m_light_node = %s", m_light_node.c_str());
- INFO("m_light_dir = %s", m_light_dir.c_str());
- }
-
if (!config.get(SENSOR_TYPE_LIGHT, m_model_id, ELEMENT_VENDOR, m_vendor)) {
ERR("[VENDOR] is empty\n");
throw ENXIO;
INFO("m_chip_name = %s\n",m_chip_name.c_str());
- if ((m_node_handle = open(m_light_node.c_str(),O_RDWR)) < 0) {
+ if ((m_node_handle = open(m_data_node.c_str(),O_RDWR)) < 0) {
ERR("Failed to open handle(%d)", m_node_handle);
throw ENXIO;
}
+ int clockId = CLOCK_MONOTONIC;
+ if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0)
+ ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str());
+
INFO("light_sensor_hal is created!\n");
}
bool light_sensor_hal::enable(void)
{
- m_fired_time = INITIAL_TIME;
+ AUTOLOCK(m_mutex);
+
+ set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_LIGHT_ENABLE_BIT);
+ set_interval(m_polling_interval);
+
+ m_fired_time = 0;
INFO("Light sensor real starting");
return true;
}
bool light_sensor_hal::disable(void)
{
+ AUTOLOCK(m_mutex);
+
+ set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_LIGHT_ENABLE_BIT);
+
INFO("Light sensor real stopping");
return true;
}
bool light_sensor_hal::set_interval(unsigned long val)
{
+ unsigned long long polling_interval_ns;
+
+ AUTOLOCK(m_mutex);
+
+ polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu);
+
+ if (!set_node_value(m_interval_node, polling_interval_ns)) {
+ ERR("Failed to set polling resource: %s\n", m_interval_node.c_str());
+ return false;
+ }
+
+ INFO("Interval is changed from %dms to %dms]", m_polling_interval, val);
+ m_polling_interval = val;
return true;
}
bool light_sensor_hal::update_value(bool wait)
{
-
unsigned short int adc = INITIAL_VALUE;
- if (!read_node_value<unsigned short int>(m_light_node, adc))
- {
- INFO("Read Value Failed. clear val: %d", adc);
+
+ struct input_event light_event;
+ DBG("light event detection!");
+
+ int len = read(m_node_handle, &light_event, sizeof(light_event));
+ if (len == -1) {
+ DBG("read(m_node_handle) is error:%s.\n", strerror(errno));
+ return false;
+ }
+
+ if (light_event.type == EV_ABS && light_event.code == ABS_MISC) {
+ adc = light_event.value;
+ } else if (light_event.type == EV_REL && light_event.code == REL_MISC) {
+ adc = light_event.value - BIAS;
+ } else if (light_event.type == EV_REL && light_event.code == REL_RX) {
+ adc = light_event.value - BIAS;
+ } else {
+ DBG("light input event[type = %d, code = %d] is unknown.", light_event.type, light_event.code);
return false;
}
- INFO("Read Value success. Light Sensor clear val: %d", adc);
+
+ DBG("read event, len : %d, type : %x, code : %x, value : %x",
+ len, light_event.type, light_event.code, light_event.value);
+
+ DBG("update_value, adc : %d", adc);
+
AUTOLOCK(m_value_mutex);
- m_adc = (int)adc;
+ m_adc = adc;
+ m_fired_time = get_timestamp(&light_event.time);
return true;
-
}
bool light_sensor_hal::is_data_ready(bool wait)
{
AUTOLOCK(m_value_mutex);
data.accuracy = SENSOR_ACCURACY_GOOD;
- data.timestamp = m_fired_time ;
+ data.timestamp = m_fired_time;
data.value_count = 1;
data.values[0] = (float) m_adc;
properties.name = m_chip_name;
properties.vendor = m_vendor;
properties.min_range = 0;
- properties.max_range = 65536;
+ properties.max_range = 65535;
properties.min_interval = 1;
properties.resolution = 1;
properties.fifo_count = 0;
return true;
}
-extern "C" void *create(void)
+extern "C" sensor_module* create(void)
{
- light_sensor_hal *inst;
+ light_sensor_hal *sensor;
try {
- inst = new light_sensor_hal();
+ sensor = new(std::nothrow) light_sensor_hal;
} catch (int err) {
- ERR("light_sensor_hal class create fail , errno : %d , errstr : %s\n", err, strerror(err));
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
return NULL;
}
- return (void*)inst;
-}
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
-extern "C" void destroy(void *inst)
-{
- delete (light_sensor_hal*)inst;
+ module->sensors.push_back(sensor);
+ return module;
}
#ifndef _LIGHT_SENSOR_HAL_H_
#define _LIGHT_SENSOR_HAL_H_
-#define ILL_CLEAR_NODE "in_illuminance_clear_raw"
+
#include <sensor_hal.h>
#include <string>
string m_enable_node;
string m_data_node;
string m_interval_node;
- string m_clear_raw_node;
- string m_light_dir;
- string m_light_node;
bool m_sensorhub_controlled;
, m_x(INITIAL_VALUE)
, m_y(INITIAL_VALUE)
, m_z(INITIAL_VALUE)
+, m_time(0)
{
cvirtual_sensor_config &config = cvirtual_sensor_config::get_instance();
m_name = string(SENSOR_NAME);
- m_timestamp = get_timestamp();
m_enable_linear_accel = 0;
register_supported_event(LINEAR_ACCEL_EVENT_RAW_DATA_REPORT_ON_TIME);
{
AUTOLOCK(m_mutex);
m_gravity_sensor->add_client(GRAVITY_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_gravity_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), true);
+ m_gravity_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false);
m_gravity_sensor->start();
m_accel_sensor->add_client(ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_accel_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), true);
+ m_accel_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false);
m_accel_sensor->start();
activate();
{
AUTOLOCK(m_mutex);
m_gravity_sensor->delete_client(GRAVITY_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_gravity_sensor->delete_interval((intptr_t)this, true);
+ m_gravity_sensor->delete_interval((intptr_t)this, false);
m_gravity_sensor->stop();
m_accel_sensor->delete_client(ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_accel_sensor->delete_interval((intptr_t)this, true);
+ m_accel_sensor->delete_interval((intptr_t)this, false);
m_accel_sensor->stop();
deactivate();
bool linear_accel_sensor::add_interval(int client_id, unsigned int interval)
{
AUTOLOCK(m_mutex);
- m_gravity_sensor->add_interval(client_id, interval, true);
- m_accel_sensor->add_interval((intptr_t)this , interval, true);
+ m_gravity_sensor->add_interval(client_id, interval, false);
+ m_accel_sensor->add_interval(client_id, interval, false);
- return sensor_base::add_interval(client_id, interval, true);
+ return sensor_base::add_interval(client_id, interval, false);
}
bool linear_accel_sensor::delete_interval(int client_id)
{
AUTOLOCK(m_mutex);
- m_gravity_sensor->delete_interval(client_id, true);
- m_accel_sensor->delete_interval(client_id, true);
+ m_gravity_sensor->delete_interval(client_id, false);
+ m_accel_sensor->delete_interval(client_id, false);
- return sensor_base::delete_interval(client_id, true);
+ return sensor_base::delete_interval(client_id, false);
}
void linear_accel_sensor::synthesize(const sensor_event_t &event, vector<sensor_event_t> &outs)
unsigned long long diff_time;
if (event.event_type == ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME) {
- diff_time = event.data.timestamp - m_timestamp;
+ diff_time = event.data.timestamp - m_time;
- if (m_timestamp && (diff_time < m_interval * MIN_DELIVERY_DIFF_FACTOR))
+ if (m_time && (diff_time < m_interval * MIN_DELIVERY_DIFF_FACTOR))
return;
m_accel.m_data.m_vec[0] = m_accel_rotation_direction_compensation[0] * (event.data.values[0] - m_accel_static_bias[0]) / m_accel_scale;
m_enable_linear_accel |= ACCELEROMETER_ENABLED;
}
else if (event.event_type == GRAVITY_EVENT_RAW_DATA_REPORT_ON_TIME) {
- diff_time = event.data.timestamp - m_timestamp;
+ diff_time = event.data.timestamp - m_time;
- if (m_timestamp && (diff_time < m_interval * MIN_DELIVERY_DIFF_FACTOR))
+ if (m_time && (diff_time < m_interval * MIN_DELIVERY_DIFF_FACTOR))
return;
m_gravity.m_data.m_vec[0] = event.data.values[0];
if (m_enable_linear_accel == LINEAR_ACCEL_ENABLED) {
m_enable_linear_accel = 0;
- m_timestamp = get_timestamp();
-
- AUTOLOCK(m_value_mutex);
lin_accel_event.sensor_id = get_id();
lin_accel_event.event_type = LINEAR_ACCEL_EVENT_RAW_DATA_REPORT_ON_TIME;
lin_accel_event.data.value_count = 3;
- lin_accel_event.data.timestamp = m_timestamp;
+ lin_accel_event.data.timestamp = get_timestamp();
lin_accel_event.data.accuracy = SENSOR_ACCURACY_GOOD;
lin_accel_event.data.values[0] = m_linear_accel_sign_compensation[0] * (m_accel.m_data.m_vec[0] - m_gravity.m_data.m_vec[0]);
lin_accel_event.data.values[1] = m_linear_accel_sign_compensation[1] * (m_accel.m_data.m_vec[1] - m_gravity.m_data.m_vec[1]);
lin_accel_event.data.values[2] = m_linear_accel_sign_compensation[2] * (m_accel.m_data.m_vec[2] - m_gravity.m_data.m_vec[2]);
push(lin_accel_event);
+
+ {
+ AUTOLOCK(m_value_mutex);
+ m_time = lin_accel_event.data.timestamp;
+ m_x = lin_accel_event.data.values[0];
+ m_y = lin_accel_event.data.values[1];
+ m_z = lin_accel_event.data.values[2];
+ }
}
return;
return true;
}
-extern "C" void *create(void)
+extern "C" sensor_module* create(void)
{
- linear_accel_sensor *inst;
+ linear_accel_sensor *sensor;
try {
- inst = new linear_accel_sensor();
+ sensor = new(std::nothrow) linear_accel_sensor;
} catch (int err) {
- ERR("Failed to create linear_accel_sensor class, errno : %d, errstr : %s", err, strerror(err));
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
return NULL;
}
- return (void *)inst;
-}
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
-extern "C" void destroy(void *inst)
-{
- delete (linear_accel_sensor *)inst;
+ module->sensors.push_back(sensor);
+ return module;
}
float m_x;
float m_y;
float m_z;
- unsigned long long m_timestamp;
+ unsigned long long m_time;
unsigned int m_interval;
unsigned int m_enable_linear_accel;
, m_roll(INITIAL_VALUE)
, m_pitch(INITIAL_VALUE)
, m_azimuth(INITIAL_VALUE)
+, m_time(0)
{
cvirtual_sensor_config &config = cvirtual_sensor_config::get_instance();
m_name = string(SENSOR_NAME);
register_supported_event(ORIENTATION_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_timestamp = get_timestamp();
m_enable_orientation = 0;
if (!config.get(SENSOR_TYPE_ORIENTATION, ELEMENT_VENDOR, m_vendor)) {
AUTOLOCK(m_mutex);
m_accel_sensor->add_client(ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_accel_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), true);
+ m_accel_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false);
m_accel_sensor->start();
m_gyro_sensor->add_client(GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_gyro_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), true);
+ m_gyro_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false);
m_gyro_sensor->start();
m_magnetic_sensor->add_client(GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_magnetic_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), true);
+ m_magnetic_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false);
m_magnetic_sensor->start();
activate();
AUTOLOCK(m_mutex);
m_accel_sensor->delete_client(ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_accel_sensor->delete_interval((intptr_t)this, true);
+ m_accel_sensor->delete_interval((intptr_t)this, false);
m_accel_sensor->stop();
m_gyro_sensor->delete_client(GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_gyro_sensor->delete_interval((intptr_t)this, true);
+ m_gyro_sensor->delete_interval((intptr_t)this, false);
m_gyro_sensor->stop();
m_magnetic_sensor->delete_client(GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_magnetic_sensor->delete_interval((intptr_t)this, true);
+ m_magnetic_sensor->delete_interval((intptr_t)this, false);
m_magnetic_sensor->stop();
deactivate();
{
AUTOLOCK(m_mutex);
- m_accel_sensor->add_interval(client_id, interval, true);
- m_gyro_sensor->add_interval(client_id, interval, true);
- m_magnetic_sensor->add_interval(client_id, interval, true);
+ m_accel_sensor->add_interval(client_id, interval, false);
+ m_gyro_sensor->add_interval(client_id, interval, false);
+ m_magnetic_sensor->add_interval(client_id, interval, false);
- return sensor_base::add_interval(client_id, interval, true);
+ return sensor_base::add_interval(client_id, interval, false);
}
bool orientation_sensor::delete_interval(int client_id)
{
AUTOLOCK(m_mutex);
- m_accel_sensor->delete_interval(client_id, true);
- m_gyro_sensor->delete_interval(client_id, true);
- m_magnetic_sensor->delete_interval(client_id, true);
+ m_accel_sensor->delete_interval(client_id, false);
+ m_gyro_sensor->delete_interval(client_id, false);
+ m_magnetic_sensor->delete_interval(client_id, false);
- return sensor_base::delete_interval(client_id, true);
+ return sensor_base::delete_interval(client_id, false);
}
void orientation_sensor::synthesize(const sensor_event_t &event, vector<sensor_event_t> &outs)
float azimuth_offset;
if (event.event_type == ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME) {
- diff_time = event.data.timestamp - m_timestamp;
+ diff_time = event.data.timestamp - m_time;
- if (m_timestamp && (diff_time < m_interval * MIN_DELIVERY_DIFF_FACTOR))
+ if (m_time && (diff_time < m_interval * MIN_DELIVERY_DIFF_FACTOR))
return;
pre_process_data(m_accel, event.data.values, m_accel_static_bias, m_accel_rotation_direction_compensation, m_accel_scale);
m_enable_orientation |= ACCELEROMETER_ENABLED;
}
else if (event.event_type == GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME) {
- diff_time = event.data.timestamp - m_timestamp;
+ diff_time = event.data.timestamp - m_time;
- if (m_timestamp && (diff_time < m_interval * MIN_DELIVERY_DIFF_FACTOR))
+ if (m_time && (diff_time < m_interval * MIN_DELIVERY_DIFF_FACTOR))
return;
pre_process_data(m_gyro, event.data.values, m_gyro_static_bias, m_gyro_rotation_direction_compensation, m_gyro_scale);
m_enable_orientation |= GYROSCOPE_ENABLED;
}
else if (event.event_type == GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME) {
- diff_time = event.data.timestamp - m_timestamp;
+ diff_time = event.data.timestamp - m_time;
- if (m_timestamp && (diff_time < m_interval * MIN_DELIVERY_DIFF_FACTOR))
+ if (m_time && (diff_time < m_interval * MIN_DELIVERY_DIFF_FACTOR))
return;
pre_process_data(m_magnetic, event.data.values, m_geomagnetic_static_bias, m_geomagnetic_rotation_direction_compensation, m_geomagnetic_scale);
if (m_enable_orientation == ORIENTATION_ENABLED) {
m_enable_orientation = 0;
- m_timestamp = get_timestamp();
m_orientation.m_pitch_phase_compensation = m_pitch_rotation_compensation;
m_orientation.m_roll_phase_compensation = m_roll_rotation_compensation;
orientation_event.sensor_id = get_id();
orientation_event.event_type = ORIENTATION_EVENT_RAW_DATA_REPORT_ON_TIME;
orientation_event.data.accuracy = SENSOR_ACCURACY_GOOD;
- orientation_event.data.timestamp = m_timestamp;
+ orientation_event.data.timestamp = get_timestamp();
orientation_event.data.value_count = 3;
orientation_event.data.values[1] = euler_orientation.m_ang.m_vec[0];
orientation_event.data.values[2] = euler_orientation.m_ang.m_vec[1];
else
orientation_event.data.values[0] = euler_orientation.m_ang.m_vec[2] + azimuth_offset;
+ {
+ AUTOLOCK(m_value_mutex);
+ m_time = orientation_event.data.timestamp;
+ m_azimuth = orientation_event.data.values[0];
+ m_pitch = orientation_event.data.values[1];
+ m_roll = orientation_event.data.values[2];
+ }
+
push(orientation_event);
}
properties.max_range = 2 * PI;
}
properties.resolution = 0.000001;
-
properties.vendor = m_vendor;
properties.name = SENSOR_NAME;
+ properties.min_interval = 1;
+ properties.fifo_count = 0;
+ properties.max_batch_count = 0;
return true;
}
-extern "C" void *create(void)
+extern "C" sensor_module* create(void)
{
- orientation_sensor *inst;
+ orientation_sensor *sensor;
try {
- inst = new orientation_sensor();
+ sensor = new(std::nothrow) orientation_sensor;
} catch (int err) {
- ERR("orientation_sensor class create fail , errno : %d , errstr : %s", err, strerror(err));
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
return NULL;
}
- return (void *)inst;
-}
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
-extern "C" void destroy(void *inst)
-{
- delete (orientation_sensor *)inst;
+ module->sensors.push_back(sensor);
+ return module;
}
float m_roll;
float m_pitch;
float m_azimuth;
- unsigned long long m_timestamp;
+ unsigned long long m_time;
unsigned int m_interval;
string m_vendor;
void pressure_sensor::raw_to_base(sensor_data_t &data)
{
+ data.values[0] = data.values[0] * m_resolution;
m_sea_level_pressure = data.values[1] * SEA_LEVEL_RESOLUTION;
data.values[1] = pressure_to_altitude(data.values[0]);
+ data.values[2] = data.values[2] * m_temperature_resolution + m_temperature_offset;
data.value_count = 3;
}
-extern "C" void *create(void)
+extern "C" sensor_module* create(void)
{
- pressure_sensor *inst;
+ pressure_sensor *sensor;
try {
- inst = new pressure_sensor();
+ sensor = new(std::nothrow) pressure_sensor;
} catch (int err) {
- ERR("pressure_sensor class create fail , errno : %d , errstr : %s\n", err, strerror(err));
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
return NULL;
}
- return (void*)inst;
-}
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
-extern "C" void destroy(void *inst)
-{
- delete (pressure_sensor*)inst;;
+ module->sensors.push_back(sensor);
+ return module;
}
#include <physical_sensor.h>
#include <sensor_hal.h>
-class pressure_sensor : public physical_sensor
-{
+class pressure_sensor : public physical_sensor {
public:
pressure_sensor();
virtual ~pressure_sensor();
#include <dirent.h>
#include <linux/input.h>
#include <csensor_config.h>
-#include <sys/ioctl.h>
#include <pressure_sensor_hal.h>
+#include <sys/ioctl.h>
#include <fstream>
-#include <string>
-#include <iio_common.h>
using std::ifstream;
-using std::string;
-#define SENSOR_TYPE_PRESSURE "PRESSURE"
+#define SENSOR_TYPE_PRESSURE "PRESSURE"
#define ELEMENT_NAME "NAME"
#define ELEMENT_VENDOR "VENDOR"
#define ELEMENT_RAW_DATA_UNIT "RAW_DATA_UNIT"
#define SEA_LEVEL_PRESSURE 101325.0
-#define EVENT_EN_NODE "events/in_pressure_mag_either_en"
-#define PRESSURE_SCALE "/in_pressure_scale"
-#define PRESSURE_RAW "/in_pressure_raw"
-#define TEMP_OFFSET "/in_temp_offset"
-#define TEMP_SCALE "/in_temp_scale"
-#define TEMP_RAW "/in_temp_raw"
-#define NO_FLAG 0
-#define TIMEOUT 1
-
pressure_sensor_hal::pressure_sensor_hal()
: m_pressure(0)
+, m_sea_level_pressure(SEA_LEVEL_PRESSURE)
, m_temperature(0)
, m_polling_interval(POLL_1HZ_MS)
, m_fired_time(0)
const string sensorhub_interval_node_name = "pressure_poll_delay";
csensor_config &config = csensor_config::get_instance();
- node_path_info_query query;
- node_path_info info;
- int input_method = IIO_METHOD;
+ node_info_query query;
+ node_info info;
- if (!get_model_properties(SENSOR_TYPE_PRESSURE, m_model_id, input_method)) {
- ERR("Failed to find model_properties");
+ if (!find_model_id(SENSOR_TYPE_PRESSURE, m_model_id)) {
+ ERR("Failed to find model id");
throw ENXIO;
}
- query.input_method = input_method;
query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name);
query.sensor_type = SENSOR_TYPE_PRESSURE;
- query.input_event_key = "pressure_sensor";
- query.iio_enable_node_name = EVENT_EN_NODE;
+ query.key = "pressure_sensor";
+ query.iio_enable_node_name = "pressure_enable";
query.sensorhub_interval_node_name = sensorhub_interval_node_name;
- if (!get_node_path_info(query, info)) {
+ bool error = get_node_info(query, info);
+
+ query.key = "barometer_sensor";
+ error |= get_node_info(query, info);
+
+ if (!error) {
ERR("Failed to get node info");
throw ENXIO;
}
+
+ show_node_info(info);
+
m_data_node = info.data_node_path;
- m_pressure_dir = info.base_dir;
m_enable_node = info.enable_node_path;
- m_pressure_node = m_pressure_dir + string(PRESSURE_RAW);
- m_temp_node = m_pressure_dir + string(TEMP_RAW);
-
- INFO("m_data_node:%s",m_data_node.c_str());
- INFO("m_pressure_dir:%s",m_pressure_dir.c_str());
- INFO("m_enable_node:%s",m_enable_node.c_str());
+ m_interval_node = info.interval_node_path;
if (!config.get(SENSOR_TYPE_PRESSURE, m_model_id, ELEMENT_VENDOR, m_vendor)) {
ERR("[VENDOR] is empty\n");
m_raw_data_unit = (float)(raw_data_unit);
INFO("m_raw_data_unit = %f\n", m_raw_data_unit);
- string file_name;
-
- file_name = m_pressure_dir + string(TEMP_SCALE);
- if (!read_node_value<int>(file_name, m_temp_scale))
- throw ENXIO;
-
- file_name = m_pressure_dir + string(TEMP_OFFSET);
- if (!read_node_value<float>(file_name, m_temp_offset))
- throw ENXIO;
-
- file_name = m_pressure_dir + string(PRESSURE_SCALE);
- if (!read_node_value<int>(file_name, m_pressure_scale))
- throw ENXIO;
-
- INFO("Temperature scale:%d", m_temp_scale);
- INFO("Temperature offset:%f", m_temp_offset);
- INFO("Pressure scale:%d", m_pressure_scale);
-
- int fd, ret;
- fd = open(m_data_node.c_str(), NO_FLAG);
- if (fd == -1) {
- ERR("Could not open event resource");
+ if ((m_node_handle = open(m_data_node.c_str(),O_RDWR)) < 0) {
+ ERR("Failed to open handle(%d)", m_node_handle);
throw ENXIO;
}
- ret = ioctl(fd, IOCTL_IIO_EVENT_FD, &m_node_handle);
-
- close(fd);
-
- if ((ret == -1) || (m_node_handle == -1)) {
- ERR("Failed to retrieve node handle from event node: %s", m_data_node.c_str());
- throw ENXIO;
- }
+ int clockId = CLOCK_MONOTONIC;
+ if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0)
+ ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str());
INFO("pressure_sensor_hal is created!\n");
}
bool pressure_sensor_hal::enable(void)
{
AUTOLOCK(m_mutex);
- update_sysfs_num(m_enable_node.c_str(), true);
+
+ set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_PRESSURE_ENABLE_BIT);
+
set_interval(m_polling_interval);
m_fired_time = 0;
{
AUTOLOCK(m_mutex);
- update_sysfs_num(m_enable_node.c_str(), false);
+ set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_PRESSURE_ENABLE_BIT);
INFO("Pressure sensor real stopping");
return true;
bool pressure_sensor_hal::set_interval(unsigned long val)
{
- INFO("set_interval not supported");
- return true;
-}
+ unsigned long long polling_interval_ns;
-bool pressure_sensor_hal::update_value(bool wait)
-{
- iio_event_t pressure_event;
- fd_set readfds, exceptfds;
- struct timeval tv;
- int raw_pressure_count;
- int raw_temp_count;
- int ret;
-
- FD_ZERO(&readfds);
- FD_ZERO(&exceptfds);
- FD_SET(m_node_handle, &readfds);
- FD_SET(m_node_handle, &exceptfds);
-
- if (wait) {
- tv.tv_sec = TIMEOUT;
- tv.tv_usec = 0;
- }
- else {
- tv.tv_sec = 0;
- tv.tv_usec = 0;
- }
+ AUTOLOCK(m_mutex);
- ret = select(m_node_handle + 1, &readfds, NULL, &exceptfds, &tv);
+ polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu);
- if (ret == -1) {
- ERR("select error:%s m_node_handle:d", strerror(errno), m_node_handle);
- return false;
- }
- else if (!ret) {
- DBG("select timeout");
+ if (!set_node_value(m_interval_node, polling_interval_ns)) {
+ ERR("Failed to set polling resource: %s\n", m_interval_node.c_str());
return false;
}
- if (FD_ISSET(m_node_handle, &exceptfds)) {
- ERR("select exception occurred!");
- return false;
- }
+ INFO("Interval is changed from %dms to %dms]", m_polling_interval, val);
+ m_polling_interval = val;
+ return true;
+}
- if (FD_ISSET(m_node_handle, &readfds)) {
- INFO("pressure event detection!");
+bool pressure_sensor_hal::update_value(bool wait)
+{
+ int pressure_raw[3] = {0,};
+ bool pressure = false;
+ bool sea_level = false;
+ bool temperature = false;
+ int read_input_cnt = 0;
+ const int INPUT_MAX_BEFORE_SYN = 10;
+ unsigned long long fired_time = 0;
+ bool syn = false;
+
+ struct input_event pressure_event;
+ DBG("pressure event detection!");
+
+ while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) {
int len = read(m_node_handle, &pressure_event, sizeof(pressure_event));
-
- if (len == -1) {
- ERR("Error in read(m_event_fd):%s.", strerror(errno));
+ if (len != sizeof(pressure_event)) {
+ ERR("pressure_file read fail, read_len = %d\n",len);
return false;
}
- m_fired_time = pressure_event.timestamp;
- if (!read_node_value<int>(m_pressure_node, raw_pressure_count))
- return false;
- if (!read_node_value<int>(m_temp_node, raw_temp_count))
+
+ ++read_input_cnt;
+
+ if (pressure_event.type == EV_REL) {
+ switch (pressure_event.code) {
+ case REL_X:
+ case REL_HWHEEL:
+ pressure_raw[0] = (int)pressure_event.value;
+ pressure = true;
+ break;
+ case REL_Y:
+ case REL_DIAL:
+ pressure_raw[1] = (int)pressure_event.value;
+ sea_level = true;
+ break;
+ case REL_Z:
+ case REL_WHEEL:
+ pressure_raw[2] = (int)pressure_event.value;
+ temperature = true;
+ break;
+ default:
+ ERR("pressure_event event[type = %d, code = %d] is unknown.", pressure_event.type, pressure_event.code);
+ return false;
+ break;
+ }
+ } else if (pressure_event.type == EV_SYN) {
+ syn = true;
+ fired_time = sensor_hal::get_timestamp(&pressure_event.time);
+ } else {
+ ERR("pressure_event event[type = %d, code = %d] is unknown.", pressure_event.type, pressure_event.code);
return false;
- m_pressure = ((float)raw_pressure_count)/((float)m_pressure_scale);
- m_temperature = m_temp_offset + ((float)raw_temp_count)/((float)m_temp_scale);
- }
- else {
- ERR("No pressure event data available to read");
- return false;
+ }
}
- return true;
+ AUTOLOCK(m_value_mutex);
+
+ if (pressure)
+ m_pressure = pressure_raw[0];
+ if (sea_level)
+ m_sea_level_pressure = pressure_raw[1];
+ if (temperature)
+ m_temperature = pressure_raw[2];
+
+ m_fired_time = fired_time;
+
+ DBG("m_pressure = %d, sea_level = %d, temperature = %d, time = %lluus", m_pressure, m_sea_level_pressure, m_temperature, m_fired_time);
+
+ return true;
}
bool pressure_sensor_hal::is_data_ready(bool wait)
data.timestamp = m_fired_time ;
data.value_count = 3;
data.values[0] = m_pressure;
- data.values[1] = SEA_LEVEL_PRESSURE;
+ data.values[1] = m_sea_level_pressure;
data.values[2] = m_temperature;
return 0;
return true;
}
-extern "C" void *create(void)
+extern "C" sensor_module* create(void)
{
- pressure_sensor_hal *inst;
+ pressure_sensor_hal *sensor;
try {
- inst = new pressure_sensor_hal();
+ sensor = new(std::nothrow) pressure_sensor_hal;
} catch (int err) {
- ERR("pressure_sensor_hal class create fail , errno : %d , errstr : %s\n", err, strerror(err));
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
return NULL;
}
- return (void*)inst;
-}
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
-extern "C" void destroy(void *inst)
-{
- delete (pressure_sensor_hal*)inst;
+ module->sensors.push_back(sensor);
+ return module;
}
virtual ~pressure_sensor_hal();
string get_model_id(void);
sensor_type_t get_type(void);
+
bool enable(void);
bool disable(void);
bool set_interval(unsigned long val);
bool is_data_ready(bool wait);
virtual int get_sensor_data(sensor_data_t &data);
virtual bool get_properties(sensor_properties_s &properties);
-
private:
string m_model_id;
string m_vendor;
string m_chip_name;
- int m_pressure_scale;
float m_pressure;
-
- int m_temp_scale;
- float m_temp_offset;
+ float m_sea_level_pressure;
float m_temperature;
int m_resolution;
float m_min_range;
float m_max_range;
float m_raw_data_unit;
-
+ float m_temp_resolution;
+ float m_temp_offset;
unsigned long m_polling_interval;
unsigned long long m_fired_time;
string m_data_node;
string m_interval_node;
- string m_pressure_dir;
- string m_pressure_node;
- string m_temp_node;
-
bool m_sensorhub_controlled;
cmutex m_value_mutex;
if (get_client_cnt(PROXIMITY_EVENT_CHANGE_STATE)) {
event.event_type = PROXIMITY_EVENT_CHANGE_STATE;
- raw_to_state(event.data);
+ raw_to_base(event.data);
push(event);
}
}
return -1;
}
- if (type == PROXIMITY_DISTANCE_DATA_SET) {
- raw_to_base(data);
- return 0;
- }
+ raw_to_base(data);
return 0;
}
void proxi_sensor::raw_to_base(sensor_data_t &data)
{
- data.values[0] = (float)((PROXIMITY_STATE_NEAR - data.values[0]) * 5);
-}
-
-void proxi_sensor::raw_to_state(sensor_data_t &data)
-{
+ data.values[0] = (float)(data.values[0] * 5);
data.value_count = 1;
}
-extern "C" void *create(void)
+extern "C" sensor_module* create(void)
{
- proxi_sensor *inst;
+ proxi_sensor *sensor;
try {
- inst = new proxi_sensor();
+ sensor = new(std::nothrow) proxi_sensor;
} catch (int err) {
- ERR("proxi_sensor class create fail , errno : %d , errstr : %s\n", err, strerror(err));
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
return NULL;
}
- return (void*)inst;
-}
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
-extern "C" void destroy(void *inst)
-{
- delete (proxi_sensor*)inst;
+ module->sensors.push_back(sensor);
+ return module;
}
bool process_event(void);
};
-#endif
+#endif // _PROXI_SENSOR_H_
#include <proxi_sensor_hal.h>
#include <sys/ioctl.h>
#include <fstream>
-#include <iio_common.h>
using std::ifstream;
-#define NO_FLAG 0
-#define PROXIMITY_TYPE 8
-
-#define EVENT_DIR "events/"
-#define EVENT_EN_NODE "in_proximity_thresh_either_en"
-
#define SENSOR_TYPE_PROXI "PROXI"
#define ELEMENT_NAME "NAME"
#define ELEMENT_VENDOR "VENDOR"
const string sensorhub_interval_node_name = "prox_poll_delay";
csensor_config &config = csensor_config::get_instance();
- node_path_info_query query;
- node_path_info info;
- int input_method = IIO_METHOD;
+ node_info_query query;
+ node_info info;
- if (!get_model_properties(SENSOR_TYPE_PROXI, m_model_id, input_method)) {
- ERR("Failed to find model_properties");
+ if (!find_model_id(SENSOR_TYPE_PROXI, m_model_id)) {
+ ERR("Failed to find model id");
throw ENXIO;
}
- query.input_method = input_method;
- query.sensorhub_controlled = m_sensorhub_controlled = false;
+ query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name);
query.sensor_type = SENSOR_TYPE_PROXI;
- query.input_event_key = "proximity_sensor";
+ query.key = "proximity_sensor";
query.iio_enable_node_name = "proximity_enable";
query.sensorhub_interval_node_name = sensorhub_interval_node_name;
- if (!get_node_path_info(query, info)) {
+ if (!get_node_info(query, info)) {
ERR("Failed to get node info");
throw ENXIO;
}
- m_data_node = info.data_node_path;
- m_enable_node = info.base_dir + string(EVENT_DIR) + string(EVENT_EN_NODE);
+ show_node_info(info);
- INFO("data node: %s",m_data_node.c_str());
- INFO("enable node: %s",m_enable_node.c_str());
+ m_data_node = info.data_node_path;
+ m_enable_node = info.enable_node_path;
if (!config.get(SENSOR_TYPE_PROXI, m_model_id, ELEMENT_VENDOR, m_vendor)) {
ERR("[VENDOR] is empty\n");
INFO("m_chip_name = %s\n",m_chip_name.c_str());
- int fd, ret;
- fd = open(m_data_node.c_str(), NO_FLAG);
- if (fd == -1) {
- ERR("Could not open event resource");
+ if ((m_node_handle = open(m_data_node.c_str(), O_RDWR)) < 0) {
+ ERR("Proxi handle(%d) open fail", m_node_handle);
throw ENXIO;
}
- ret = ioctl(fd, IOCTL_IIO_EVENT_FD, &m_node_handle);
-
- close(fd);
-
- if ((ret == -1) || (m_node_handle == -1)) {
- ERR("Failed to retrieve event fd");
- throw ENXIO;
- }
+ int clockId = CLOCK_MONOTONIC;
+ if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0)
+ ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str());
INFO("Proxi_sensor_hal is created!\n");
return PROXIMITY_SENSOR;
}
-bool proxi_sensor_hal::enable_resource(bool enable)
-{
- update_sysfs_num(m_enable_node.c_str(), enable);
- return true;
-}
-
bool proxi_sensor_hal::enable(void)
{
AUTOLOCK(m_mutex);
- enable_resource(true);
+ set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_PROXIMITY_ENABLE_BIT);
m_fired_time = 0;
INFO("Proxi sensor real starting");
{
AUTOLOCK(m_mutex);
- enable_resource(true);
+ set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_PROXIMITY_ENABLE_BIT);
INFO("Proxi sensor real stopping");
return true;
bool proxi_sensor_hal::update_value(bool wait)
{
- iio_event_t proxi_event;
- fd_set readfds, exceptfds;
+ struct input_event proxi_event;
+ INFO("proxi event detection!");
- FD_ZERO(&readfds);
- FD_ZERO(&exceptfds);
- FD_SET(m_node_handle, &readfds);
- FD_SET(m_node_handle, &exceptfds);
+ int len = read(m_node_handle, &proxi_event, sizeof(proxi_event));
- int ret;
- ret = select(m_node_handle + 1, &readfds, NULL, &exceptfds, NULL);
-
- if (ret == -1) {
- ERR("select error:%s m_node_handle:%d", strerror(errno), m_node_handle);
- return false;
- }
- else if (!ret) {
- DBG("select timeout");
- return false;
- }
-
- if (FD_ISSET(m_node_handle, &exceptfds)) {
- ERR("select exception occurred!");
+ if (len == -1) {
+ DBG("read(m_node_handle) is error:%s.\n", strerror(errno));
return false;
}
- if (FD_ISSET(m_node_handle, &readfds)) {
- INFO("proximity event detection!");
- int len = read(m_node_handle, &proxi_event, sizeof(proxi_event));
-
- if (len == -1) {
- DBG("Error in read(m_node_handle):%s.", strerror(errno));
+ DBG("read event, len : %d , type : %x , code : %x , value : %x", len, proxi_event.type, proxi_event.code, proxi_event.value);
+ if ((proxi_event.type == EV_ABS) && (proxi_event.code == PROXI_CODE)) {
+ AUTOLOCK(m_value_mutex);
+ if (proxi_event.value == PROXIMITY_NODE_STATE_FAR) {
+ INFO("PROXIMITY_STATE_FAR state occured\n");
+ m_state = PROXIMITY_STATE_FAR;
+ } else if (proxi_event.value == PROXIMITY_NODE_STATE_NEAR) {
+ INFO("PROXIMITY_STATE_NEAR state occured\n");
+ m_state = PROXIMITY_STATE_NEAR;
+ } else {
+ ERR("PROXIMITY_STATE Unknown: %d\n",proxi_event.value);
return false;
}
-
- ull_bytes_t ev_data;
- ev_data.num = proxi_event.event_id;
- if (ev_data.bytes[CH_TYPE] == PROXIMITY_TYPE) {
- AUTOLOCK(m_value_mutex);
- int temp;
- temp = GET_DIR_VAL(ev_data.bytes[DIRECTION]);
- if (temp == PROXIMITY_NODE_STATE_FAR) {
- INFO("PROXIMITY_STATE_FAR state occurred");
- m_state = PROXIMITY_STATE_FAR;
- }
- else if (temp == PROXIMITY_NODE_STATE_NEAR) {
- INFO("PROXIMITY_STATE_NEAR state occurred");
- m_state = PROXIMITY_STATE_NEAR;
- }
- else {
- ERR("PROXIMITY_STATE Unknown: %d", proxi_event.event_id);
- return false;
- }
- }
- m_fired_time = proxi_event.timestamp;
- }
- else {
- ERR("No proximity event data available to read");
+ m_fired_time = sensor_hal::get_timestamp(&proxi_event.time);
+ } else {
return false;
}
return true;
return true;
}
-extern "C" void *create(void)
+extern "C" sensor_module* create(void)
{
- proxi_sensor_hal *inst;
+ proxi_sensor_hal *sensor;
try {
- inst = new proxi_sensor_hal();
+ sensor = new(std::nothrow) proxi_sensor_hal;
} catch (int err) {
- ERR("proxi_sensor class create fail , errno : %d , errstr : %s\n", err, strerror(err));
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
return NULL;
}
- return (void*)inst;
-}
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
-extern "C" void destroy(void *inst)
-{
- delete (proxi_sensor_hal*)inst;
+ module->sensors.push_back(sensor);
+ return module;
}
cmutex m_value_mutex;
bool update_value(bool wait);
- bool enable_resource(bool enable);
};
#endif /*_PROXI_SENSOR_HAL_H_*/
IF("${RV}" STREQUAL "ON")
add_subdirectory(rv)
ENDIF()
-
AUTOLOCK(m_mutex);
m_accel_sensor->add_client(ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_accel_sensor->add_interval((int)this, (m_interval/MS_TO_US), false);
+ m_accel_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false);
m_accel_sensor->start();
m_gyro_sensor->add_client(GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_gyro_sensor->add_interval((int)this, (m_interval/MS_TO_US), false);
+ m_gyro_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false);
m_gyro_sensor->start();
m_magnetic_sensor->add_client(GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_magnetic_sensor->add_interval((int)this, (m_interval/MS_TO_US), false);
+ m_magnetic_sensor->add_interval((intptr_t)this, (m_interval/MS_TO_US), false);
m_magnetic_sensor->start();
activate();
AUTOLOCK(m_mutex);
m_accel_sensor->delete_client(ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_accel_sensor->delete_interval((int)this, false);
+ m_accel_sensor->delete_interval((intptr_t)this, false);
m_accel_sensor->stop();
m_gyro_sensor->delete_client(GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_gyro_sensor->delete_interval((int)this, false);
+ m_gyro_sensor->delete_interval((intptr_t)this, false);
m_gyro_sensor->stop();
m_magnetic_sensor->delete_client(GEOMAGNETIC_EVENT_RAW_DATA_REPORT_ON_TIME);
- m_magnetic_sensor->delete_interval((int)this, false);
+ m_magnetic_sensor->delete_interval((intptr_t)this, false);
m_magnetic_sensor->stop();
deactivate();
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(rv_raw CXX)
+
+SET(SENSOR_NAME rv_raw_sensor)
+SET(SENSOR_HAL_NAME rv_raw_sensor_hal)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_SOURCE_DIR}/src/libsensord)
+
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(rv_raw_pkgs REQUIRED vconf)
+
+FOREACH(flag ${rv_raw_pkgs_LDFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${rv_raw_pkgs_CFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+add_library(${SENSOR_NAME} SHARED
+ rv_raw_sensor.cpp
+)
+
+add_library(${SENSOR_HAL_NAME} SHARED
+ rv_raw_sensor_hal.cpp
+)
+
+target_link_libraries(${SENSOR_NAME} ${rv_raw_pkgs_LDFLAGS} "-lm")
+target_link_libraries(${SENSOR_HAL_NAME} ${rv_raw_pkgs_LDFLAGS})
+
+install(TARGETS ${SENSOR_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}/sensord)
+install(TARGETS ${SENSOR_HAL_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}/sensord)
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 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 <common.h>
+#include <sf_common.h>
+
+#include <rv_raw_sensor.h>
+#include <sensor_plugin_loader.h>
+
+#define SENSOR_NAME "RV_RAW_SENSOR"
+
+rv_raw_sensor::rv_raw_sensor()
+: m_sensor_hal(NULL)
+{
+ m_name = string(SENSOR_NAME);
+
+ register_supported_event(RV_RAW_EVENT_RAW_DATA_REPORT_ON_TIME);
+ register_supported_event(RV_RAW_EVENT_CALIBRATION_NEEDED);
+
+ physical_sensor::set_poller(rv_raw_sensor::working, this);
+}
+
+rv_raw_sensor::~rv_raw_sensor()
+{
+ INFO("rv_raw_sensor is destroyed!\n");
+}
+
+bool rv_raw_sensor::init()
+{
+ m_sensor_hal = sensor_plugin_loader::get_instance().get_sensor_hal(RV_RAW_SENSOR);
+
+ if (!m_sensor_hal) {
+ ERR("cannot load sensor_hal[%s]", sensor_base::get_name());
+ return false;
+ }
+
+ sensor_properties_t properties;
+
+ if (!m_sensor_hal->get_properties(properties)) {
+ ERR("sensor->get_properties() is failed!\n");
+ return false;
+ }
+
+ set_privilege(SENSOR_PRIVILEGE_INTERNAL);
+
+ INFO("%s is created!\n", sensor_base::get_name());
+
+ return true;
+}
+
+sensor_type_t rv_raw_sensor::get_type(void)
+{
+ return RV_RAW_SENSOR;
+}
+
+bool rv_raw_sensor::working(void *inst)
+{
+ rv_raw_sensor *sensor = (rv_raw_sensor*)inst;
+ return sensor->process_event();;
+}
+
+bool rv_raw_sensor::process_event(void)
+{
+ sensor_event_t event;
+
+ if (!m_sensor_hal->is_data_ready(true))
+ return true;
+
+ m_sensor_hal->get_sensor_data(event.data);
+
+ AUTOLOCK(m_client_info_mutex);
+ AUTOLOCK(m_mutex);
+
+ if (get_client_cnt(RV_RAW_EVENT_RAW_DATA_REPORT_ON_TIME)) {
+ event.sensor_id = get_id();
+ event.event_type = RV_RAW_EVENT_RAW_DATA_REPORT_ON_TIME;
+ push(event);
+ }
+
+ return true;
+}
+
+bool rv_raw_sensor::on_start(void)
+{
+ if (!m_sensor_hal->enable()) {
+ ERR("m_sensor_hal start fail\n");
+ return false;
+ }
+
+ return start_poll();
+}
+
+bool rv_raw_sensor::on_stop(void)
+{
+ if (!m_sensor_hal->disable()) {
+ ERR("m_sensor_hal stop fail\n");
+ return false;
+ }
+
+ return stop_poll();
+}
+
+bool rv_raw_sensor::get_properties(sensor_properties_t &properties)
+{
+ return m_sensor_hal->get_properties(properties);
+}
+
+int rv_raw_sensor::get_sensor_data(unsigned int type, sensor_data_t &data)
+{
+ int state;
+
+ if (type != RV_RAW_BASE_DATA_SET)
+ return -1;
+
+ state = m_sensor_hal->get_sensor_data(data);
+
+ if (state < 0) {
+ ERR("m_sensor_hal get struct_data fail\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+bool rv_raw_sensor::set_interval(unsigned long interval)
+{
+ AUTOLOCK(m_mutex);
+
+ INFO("Polling interval is set to %dms", interval);
+
+ return m_sensor_hal->set_interval(interval);
+}
+
+extern "C" sensor_module* create(void)
+{
+ rv_raw_sensor *sensor;
+
+ try {
+ sensor = new(std::nothrow) rv_raw_sensor;
+ } catch (int err) {
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
+ return NULL;
+ }
+
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
+
+ module->sensors.push_back(sensor);
+ return module;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 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.
+ *
+ */
+
+#ifndef _RV_RAW_SENSOR_H_
+#define _RV_RAW_SENSOR_H_
+
+#include <sensor_common.h>
+
+#include <physical_sensor.h>
+#include <sensor_hal.h>
+
+class rv_raw_sensor : public physical_sensor {
+public:
+ rv_raw_sensor();
+ virtual ~rv_raw_sensor();
+
+ virtual bool init();
+ virtual sensor_type_t get_type(void);
+
+ static bool working(void *inst);
+
+ virtual bool set_interval(unsigned long interval);
+ virtual bool get_properties(sensor_properties_t &properties);
+ int get_sensor_data(unsigned int type, sensor_data_t &data);
+private:
+ sensor_hal *m_sensor_hal;
+
+ virtual bool on_start(void);
+ virtual bool on_stop(void);
+
+ bool process_event(void);
+};
+
+#endif /*_RV_RAW_SENSOR_H_*/
--- /dev/null
+/*
+ * rv_raw_sensor_hal
+ *
+ * Copyright (c) 2014 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 <fcntl.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <linux/input.h>
+#include <csensor_config.h>
+#include <rv_raw_sensor_hal.h>
+#include <sys/ioctl.h>
+#include <fstream>
+
+using std::ifstream;
+
+#define SENSOR_TYPE_RV_RAW "ROTATION_VECTOR"
+#define ELEMENT_NAME "NAME"
+#define ELEMENT_VENDOR "VENDOR"
+#define ATTR_VALUE "value"
+
+rv_raw_sensor_hal::rv_raw_sensor_hal()
+: m_quat_a(0)
+, m_quat_b(0)
+, m_quat_c(0)
+, m_quat_d(0)
+, m_polling_interval(POLL_1HZ_MS)
+{
+ const string sensorhub_interval_node_name = "rot_poll_delay";
+ csensor_config &config = csensor_config::get_instance();
+
+ node_info_query query;
+ node_info info;
+
+ if (!find_model_id(SENSOR_TYPE_RV_RAW, m_model_id)) {
+ ERR("Failed to find model id");
+ throw ENXIO;
+
+ }
+
+ query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name);
+ query.sensor_type = SENSOR_TYPE_RV_RAW;
+ query.key = "rot_sensor";
+ query.iio_enable_node_name = "rot_enable";
+ query.sensorhub_interval_node_name = sensorhub_interval_node_name;
+
+ if (!get_node_info(query, info)) {
+ ERR("Failed to get node info");
+ throw ENXIO;
+ }
+
+ show_node_info(info);
+
+ m_data_node = info.data_node_path;
+ m_enable_node = info.enable_node_path;
+ m_interval_node = info.interval_node_path;
+
+ if (!config.get(SENSOR_TYPE_RV_RAW, m_model_id, ELEMENT_VENDOR, m_vendor)) {
+ ERR("[VENDOR] is empty\n");
+ throw ENXIO;
+ }
+
+ INFO("m_vendor = %s", m_vendor.c_str());
+
+ if (!config.get(SENSOR_TYPE_RV_RAW, m_model_id, ELEMENT_NAME, m_chip_name)) {
+ ERR("[NAME] is empty\n");
+ throw ENXIO;
+ }
+
+ INFO("m_chip_name = %s", m_chip_name.c_str());
+
+ if ((m_node_handle = open(m_data_node.c_str(),O_RDWR)) < 0) {
+ ERR("Failed to open handle(%d)", m_node_handle);
+ throw ENXIO;
+ }
+
+ int clockId = CLOCK_MONOTONIC;
+ if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0)
+ ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str());
+
+ INFO("rv_raw_sensor_hal is created!\n");
+
+}
+
+rv_raw_sensor_hal::~rv_raw_sensor_hal()
+{
+ close(m_node_handle);
+ m_node_handle = -1;
+
+ INFO("rv_raw_sensor_hal is destroyed!\n");
+}
+
+string rv_raw_sensor_hal::get_model_id(void)
+{
+ return m_model_id;
+}
+
+sensor_type_t rv_raw_sensor_hal::get_type(void)
+{
+ return RV_RAW_SENSOR;
+}
+
+bool rv_raw_sensor_hal::enable(void)
+{
+ AUTOLOCK(m_mutex);
+
+ set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_ROTATION_VECTOR_ENABLE_BIT);
+ set_interval(m_polling_interval);
+
+ m_fired_time = 0;
+ INFO("Rotation vector raw sensor real starting");
+ return true;
+}
+
+bool rv_raw_sensor_hal::disable(void)
+{
+ AUTOLOCK(m_mutex);
+
+ set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_ROTATION_VECTOR_ENABLE_BIT);
+
+ INFO("Rotation vector raw sensor real stopping");
+ return true;
+}
+
+bool rv_raw_sensor_hal::set_interval(unsigned long val)
+{
+ unsigned long long polling_interval_ns;
+
+ AUTOLOCK(m_mutex);
+
+ polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu);
+
+ if (!set_node_value(m_interval_node, polling_interval_ns)) {
+ ERR("Failed to set polling resource: %s\n", m_interval_node.c_str());
+ return false;
+ }
+
+ INFO("Interval is changed from %dms to %dms]", m_polling_interval, val);
+ m_polling_interval = val;
+ return true;
+
+}
+
+bool rv_raw_sensor_hal::update_value(bool wait)
+{
+ int rot_raw[5] = {0,};
+ bool quat_a,quat_b,quat_c,quat_d,acc_rot;
+ int read_input_cnt = 0;
+ const int INPUT_MAX_BEFORE_SYN = 10;
+ unsigned long long fired_time = 0;
+ bool syn = false;
+
+ quat_a = quat_b = quat_c = quat_d = acc_rot = false;
+
+ struct input_event rot_input;
+ DBG("geo event detection!");
+
+ while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) {
+ int len = read(m_node_handle, &rot_input, sizeof(rot_input));
+ if (len != sizeof(rot_input)) {
+ ERR("rot_file read fail, read_len = %d\n",len);
+ return false;
+ }
+
+ ++read_input_cnt;
+
+ if (rot_input.type == EV_REL) {
+ switch (rot_input.code) {
+ case REL_X:
+ rot_raw[0] = (int)rot_input.value;
+ quat_a = true;
+ break;
+ case REL_Y:
+ rot_raw[1] = (int)rot_input.value;
+ quat_b = true;
+ break;
+ case REL_Z:
+ rot_raw[2] = (int)rot_input.value;
+ quat_c = true;
+ break;
+ case REL_RX:
+ rot_raw[3] = (int)rot_input.value;
+ quat_d = true;
+ break;
+ case REL_RY:
+ rot_raw[4] = (int)rot_input.value;
+ acc_rot = true;
+ break;
+ default:
+ ERR("rot_input event[type = %d, code = %d] is unknown.", rot_input.type, rot_input.code);
+ return false;
+ break;
+ }
+ } else if (rot_input.type == EV_SYN) {
+ syn = true;
+ fired_time = get_timestamp(&rot_input.time);
+ } else {
+ ERR("rot_input event[type = %d, code = %d] is unknown.", rot_input.type, rot_input.code);
+ return false;
+ }
+ }
+
+ AUTOLOCK(m_value_mutex);
+
+ if (quat_a)
+ m_quat_a = rot_raw[0];
+ if (quat_b)
+ m_quat_b = rot_raw[1];
+ if (quat_c)
+ m_quat_c = rot_raw[2];
+ if (quat_d)
+ m_quat_d = rot_raw[3];
+ if (acc_rot)
+ m_accuracy = rot_raw[4] - 1; /* accuracy bias: -1 */
+
+ m_fired_time = fired_time;
+
+ DBG("m_quat_a = %d, m_quat_a = %d, m_quat_a = %d, m_quat_d = %d, m_accuracy = %d, time = %lluus",
+ m_quat_a, m_quat_a, m_quat_a, m_quat_d, m_accuracy, m_fired_time);
+
+ return true;
+}
+
+
+bool rv_raw_sensor_hal::is_data_ready(bool wait)
+{
+ bool ret;
+ ret = update_value(wait);
+ return ret;
+}
+
+int rv_raw_sensor_hal::get_sensor_data(sensor_data_t &data)
+{
+ const float QUAT_SIG_FIGS = 1000000.0f;
+
+ data.accuracy = (m_accuracy == 1) ? 0 : m_accuracy; /* hdst 0 and 1 are needed to calibrate */
+ data.timestamp = m_fired_time;
+ data.value_count = 4;
+ data.values[0] = (float)m_quat_a / QUAT_SIG_FIGS;
+ data.values[1] = (float)m_quat_b / QUAT_SIG_FIGS;
+ data.values[2] = (float)m_quat_c / QUAT_SIG_FIGS;
+ data.values[3] = (float)m_quat_d / QUAT_SIG_FIGS;
+ return 0;
+}
+
+bool rv_raw_sensor_hal::get_properties(sensor_properties_t &properties)
+{
+ properties.name = m_chip_name;
+ properties.vendor = m_vendor;
+ properties.min_range = 0;
+ properties.max_range = 1200;
+ properties.min_interval = 1;
+ properties.resolution = 1;
+ properties.fifo_count = 0;
+ properties.max_batch_count = 0;
+ return true;
+}
+
+extern "C" sensor_module* create(void)
+{
+ rv_raw_sensor_hal *sensor;
+
+ try {
+ sensor = new(std::nothrow) rv_raw_sensor_hal;
+ } catch (int err) {
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
+ return NULL;
+ }
+
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
+
+ module->sensors.push_back(sensor);
+ return module;
+}
--- /dev/null
+/*
+ * rv_raw_sensor_hal
+ *
+ * Copyright (c) 2014 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.
+ *
+ */
+
+#ifndef _RV_RAW_SENSOR_HAL_H_
+#define _RV_RAW_SENSOR_HAL_H_
+
+#include <sensor_hal.h>
+#include <string>
+
+using std::string;
+
+class rv_raw_sensor_hal : public sensor_hal
+{
+public:
+ rv_raw_sensor_hal();
+ virtual ~rv_raw_sensor_hal();
+ string get_model_id(void);
+ sensor_type_t get_type(void);
+ bool enable(void);
+ bool disable(void);
+ bool set_interval(unsigned long val);
+ bool is_data_ready(bool wait);
+ virtual int get_sensor_data(sensor_data_t &data);
+ virtual bool get_properties(sensor_properties_t &properties);
+private:
+ string m_model_id;
+ string m_vendor;
+ string m_chip_name;
+
+ unsigned long m_polling_interval;
+
+ int m_quat_a;
+ int m_quat_b;
+ int m_quat_c;
+ int m_quat_d;
+ int m_accuracy;
+
+ unsigned long long m_fired_time;
+ int m_node_handle;
+
+ string m_enable_node;
+ string m_data_node;
+ string m_interval_node;
+
+ bool m_sensorhub_controlled;
+
+ cmutex m_value_mutex;
+
+ bool update_value(bool wait);
+};
+#endif /*_RV_RAW_SENSOR_HAL_H_*/
+
dbus_util.cpp
server.cpp
command_worker.cpp
+ permission_checker.cpp
main.cpp
)
#include <thread>
#include <string>
#include <utility>
-#include <dlfcn.h>
-#include <set>
+#include <permission_checker.h>
-using namespace std;
using std::string;
-using std::set;
using std::make_pair;
-#define SECURITY_LIB "/usr/lib/libsecurity-server-client.so.1"
-
-set<unsigned int> priority_list;
-
-void *command_worker::m_security_handle = NULL;
-command_worker::security_server_check_privilege_by_sockfd_t command_worker::security_server_check_privilege_by_sockfd = NULL;
command_worker::cmd_handler_t command_worker::m_cmd_handlers[];
sensor_raw_data_map command_worker::m_sensor_raw_data_map;
cpacket command_worker::m_sensor_list;
+set<unsigned int> priority_list;
+
command_worker::command_worker(const csocket& socket)
: m_client_id(CLIENT_ID_INVALID)
, m_permission(SENSOR_PERMISSION_NONE)
static bool init = false;
if (!init) {
- init_security_lib();
init_cmd_handlers();
make_sensor_raw_data_map();
return m_worker.start();
}
-void command_worker::init_security_lib(void)
-{
- m_security_handle = dlopen(SECURITY_LIB, RTLD_LAZY);
-
- if (!m_security_handle) {
- ERR("dlopen(%s) error, cause: %s", SECURITY_LIB, dlerror());
- return;
- }
-
- security_server_check_privilege_by_sockfd =
- (security_server_check_privilege_by_sockfd_t) dlsym(m_security_handle, "security_server_check_privilege_by_sockfd");
-
- if (!security_server_check_privilege_by_sockfd) {
- ERR("Failed to load symbol");
- dlclose(m_security_handle);
- m_security_handle = NULL;
- return;
- }
-}
-
void command_worker::init_cmd_handlers(void)
{
m_cmd_handlers[CMD_GET_ID] = &command_worker::cmd_get_id;
if (inst->m_socket.recv(&header, sizeof(header)) <= 0) {
string info;
inst->get_info(info);
- DBG("%s failed to receive header", info);
+ DBG("%s failed to receive header", info.c_str());
return false;
}
if (inst->m_socket.recv(payload, header.size) <= 0) {
string info;
inst->get_info(info);
- DBG("%s failed to receive data of packet", info);
+ DBG("%s failed to receive data of packet", info.c_str());
delete[] payload;
return false;
}
int command_worker::get_permission(void)
{
- int permission = SENSOR_PERMISSION_STANDARD;
-
- return permission;
+ return permission_checker::get_instance().get_permission(m_socket.get_socket_fd());
}
bool command_worker::is_permission_allowed(void)
class command_worker {
private:
typedef bool (command_worker::*cmd_handler_t)(void *payload);
- typedef int (*security_server_check_privilege_by_sockfd_t)(int sockfd,
- const char *object,
- const char *access_rights);
static const int OP_ERROR = -1;
static const int OP_SUCCESS = 0;
csocket m_socket;
worker_thread m_worker;
sensor_base *m_module;
- static void *m_security_handle;
- static security_server_check_privilege_by_sockfd_t security_server_check_privilege_by_sockfd;
static cmd_handler_t m_cmd_handlers[CMD_CNT];
static cpacket m_sensor_list;
static sensor_raw_data_map m_sensor_raw_data_map;
- static void init_security_lib(void);
static void init_cmd_handlers(void);
static void make_sensor_raw_data_map(void);
static void get_sensor_list(int permissions, cpacket &sensor_list);
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 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 <permission_checker.h>
+#include <sf_common.h>
+#include <common.h>
+#include <sensor_plugin_loader.h>
+#include <sensor_base.h>
+#include <dlfcn.h>
+
+#define SECURITY_LIB "/usr/lib/libsecurity-server-client.so.1"
+
+permission_checker::permission_checker()
+: m_permission_set(0)
+, security_server_check_privilege_by_sockfd(NULL)
+, m_security_handle(NULL)
+
+{
+ init();
+}
+
+permission_checker::~permission_checker()
+{
+ if (m_security_handle)
+ dlclose(m_security_handle);
+}
+
+permission_checker& permission_checker::get_instance()
+{
+ static permission_checker inst;
+ return inst;
+}
+
+bool permission_checker::init_security_lib(void)
+{
+ m_security_handle = dlopen(SECURITY_LIB, RTLD_LAZY);
+
+ if (!m_security_handle) {
+ ERR("dlopen(%s) error, cause: %s", SECURITY_LIB, dlerror());
+ return false;
+ }
+
+ security_server_check_privilege_by_sockfd =
+ (security_server_check_privilege_by_sockfd_t) dlsym(m_security_handle, "security_server_check_privilege_by_sockfd");
+
+ if (!security_server_check_privilege_by_sockfd) {
+ ERR("Failed to load symbol");
+ dlclose(m_security_handle);
+ m_security_handle = NULL;
+ return false;
+ }
+
+ return true;
+
+}
+
+void permission_checker::init()
+{
+ m_permission_infos.push_back(std::make_shared<permission_info> (SENSOR_PERMISSION_STANDARD, false, "", ""));
+ m_permission_infos.push_back(std::make_shared<permission_info> (SENSOR_PERMISSION_BIO, true, "sensord::bio", "rw"));
+
+ vector<sensor_base *> sensors;
+ sensors = sensor_plugin_loader::get_instance().get_sensors(ALL_SENSOR);
+
+ for (int i = 0; i < sensors.size(); ++i)
+ m_permission_set |= sensors[i]->get_permission();
+
+ INFO("Permission Set = %d", m_permission_set);
+
+ if (!init_security_lib())
+ ERR("Failed to init security lib: %s", SECURITY_LIB);
+}
+
+int permission_checker::get_permission(int sock_fd)
+{
+ int permission = SENSOR_PERMISSION_NONE;
+
+ for (int i = 0; i < m_permission_infos.size(); ++i) {
+ if (!m_permission_infos[i]->need_to_check) {
+ permission |= m_permission_infos[i]->permission;
+ } else if ((m_permission_set & m_permission_infos[i]->permission) && security_server_check_privilege_by_sockfd) {
+ if (security_server_check_privilege_by_sockfd(sock_fd, m_permission_infos[i]->name.c_str(), m_permission_infos[i]->access_right.c_str()) == 1) {
+ permission |= m_permission_infos[i]->permission;
+ }
+ }
+ }
+
+ return permission;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 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.
+ *
+ */
+
+#ifndef _PERMISSION_CHECKER_H_
+#define _PERMISSION_CHECKER_H_
+
+#include <string>
+#include <vector>
+#include <memory>
+
+class permission_checker {
+private:
+ class permission_info {
+ public:
+ permission_info(int _permission, bool _need_to_check, std::string _name, std::string _access_right)
+ : permission(_permission)
+ , need_to_check(_need_to_check)
+ , name(_name)
+ , access_right(_access_right)
+ {
+ }
+ int permission;
+ bool need_to_check;
+ std::string name;
+ std::string access_right;
+ };
+
+ typedef std::vector<std::shared_ptr<permission_info>> permission_info_vector;
+
+ typedef int (*security_server_check_privilege_by_sockfd_t)(int sockfd,
+ const char *object,
+ const char *access_rights);
+
+ permission_checker();
+ ~permission_checker();
+ permission_checker(permission_checker const&) {};
+ permission_checker& operator=(permission_checker const&);
+
+ bool init_security_lib(void);
+ void init();
+
+ security_server_check_privilege_by_sockfd_t security_server_check_privilege_by_sockfd;
+ void *m_security_handle;
+
+ permission_info_vector m_permission_infos;
+ int m_permission_set;
+public:
+ static permission_checker& get_instance();
+
+ int get_permission(int sock_fd);
+};
+
+#endif /* COMMAND_WORKER_H_ */
list<cinterval_info> m_list;
public:
- bool add_interval(int client_id, unsigned int interval, bool is_processor = false);
- bool delete_interval(int client_id, bool is_processor = false);
- unsigned int get_interval(int client_id, bool is_processor = false);
+ bool add_interval(int client_id, unsigned int interval, bool is_processor);
+ bool delete_interval(int client_id, bool is_processor);
+ unsigned int get_interval(int client_id, bool is_processor);
unsigned int get_min(void);
};
#endif
}
m_addr.sun_family = AF_UNIX;
- strcpy(m_addr.sun_path, sock_path);
+ int path_size = strlen(sock_path);
+ strncpy(m_addr.sun_path, sock_path, path_size);
+ m_addr.sun_path[path_size - 1] = '\0';
length = strlen(m_addr.sun_path) + sizeof(m_addr.sun_family);
set_blocking_mode(false);
m_addr.sun_family = AF_UNIX;
- strcpy(m_addr.sun_path, sock_path);
+ int path_size = strlen(sock_path);
+ strncpy(m_addr.sun_path, sock_path, path_size);
+ m_addr.sun_path[path_size - 1] = '\0';
+
addr_len = strlen(m_addr.sun_path) + sizeof(m_addr.sun_family);
if (::connect(m_sock_fd,(sockaddr *) &m_addr, addr_len) < 0) {
bool sensor_base::get_properties(sensor_properties_s &properties)
{
- return true;
+ return false;
}
bool sensor_base::is_supported(unsigned int event_type)
virtual bool add_client(unsigned int event_type);
virtual bool delete_client(unsigned int event_type);
- virtual bool add_interval(int client_id, unsigned int interval, bool is_processor = false);
- virtual bool delete_interval(int client_id, bool is_processor = false);
- unsigned int get_interval(int client_id, bool is_processor = false);
+ virtual bool add_interval(int client_id, unsigned int interval, bool is_processor);
+ virtual bool delete_interval(int client_id, bool is_processor);
+ unsigned int get_interval(int client_id, bool is_processor);
void get_sensor_info(sensor_info &info);
GEOMAGNETIC_SENSOR,
LIGHT_SENSOR,
PROXIMITY_SENSOR,
+ THERMOMETER_SENSOR,
GYROSCOPE_SENSOR,
PRESSURE_SENSOR,
+ MOTION_SENSOR,
+ FUSION_SENSOR,
+ PEDOMETER_SENSOR,
CONTEXT_SENSOR,
+ FLAT_SENSOR,
+ BIO_SENSOR,
+ BIO_HRM_SENSOR,
+ AUTO_ROTATION_SENSOR,
GRAVITY_SENSOR,
LINEAR_ACCEL_SENSOR,
+ ROTATION_VECTOR_SENSOR,
ORIENTATION_SENSOR,
+ PIR_SENSOR,
+ PIR_LONG_SENSOR,
TEMPERATURE_SENSOR,
- ROTATION_VECTOR_SENSOR,
- MOTION_SENSOR
+ HUMIDITY_SENSOR,
+ ULTRAVIOLET_SENSOR,
+ DUST_SENSOR,
+ RV_RAW_SENSOR,
+ UNCAL_GYROSCOPE_SENSOR,
+ UNCAL_GEOMAGNETIC_SENSOR
} sensor_type_t;
typedef unsigned int sensor_id_t;
return false;
}
-bool sensor_hal::get_node_path_info(const node_path_info_query &query, node_path_info &info)
+bool sensor_hal::get_node_info(const node_info_query &query, node_info &info)
{
bool ret = false;
- string model_id;
+ int method;
+ string device_num;
+
+ if (!get_input_method(query.key, method, device_num)) {
+ ERR("Failed to get input method for %s", query.key.c_str());
+ return false;
+ }
- if (query.input_method == IIO_METHOD) {
+ info.method = method;
- find_model_id(IIO_METHOD, query.sensor_type, model_id);
+ if (method == IIO_METHOD) {
if (query.sensorhub_controlled)
- ret = get_sensorhub_iio_node_info(model_id, query.sensorhub_interval_node_name, info);
+ ret = get_sensorhub_iio_node_info(query.sensorhub_interval_node_name, device_num, info);
else
- ret = get_iio_node_info(model_id, query.iio_enable_node_name, info);
+ ret = get_iio_node_info(query.iio_enable_node_name, device_num, info);
} else {
if (query.sensorhub_controlled)
- ret = get_sensorhub_input_event_node_info(query.input_event_key, query.sensorhub_interval_node_name, info);
+ ret = get_sensorhub_input_event_node_info(query.sensorhub_interval_node_name, device_num, info);
else
- ret = get_input_event_node_info(query.input_event_key, info);
+ ret = get_input_event_node_info(device_num, info);
}
return ret;
}
-void sensor_hal::show_node_path_info(node_path_info &info)
+void sensor_hal::show_node_info(node_info &info)
{
if (info.data_node_path.size())
INFO("Data node: %s", info.data_node_path.c_str());
INFO("Trigger node: %s", info.trigger_node_path.c_str());
}
-bool sensor_hal::get_iio_node_info(const string &key, const string& enable_node_name, node_path_info &info)
+bool sensor_hal::get_iio_node_info(const string& enable_node_name, const string& device_num, node_info &info)
{
- string device_num;
-
- if (!get_device_num(IIO_METHOD, key, device_num))
- return false;
-
- info.data_node_path = string("/dev/iio:device") + device_num;
-
const string base_dir = string("/sys/bus/iio/devices/iio:device") + device_num + string("/");
- info.base_dir = base_dir;
+ info.data_node_path = string("/dev/iio:device") + device_num;
info.enable_node_path = base_dir + enable_node_name;
info.interval_node_path = base_dir + string("sampling_frequency");
info.buffer_enable_node_path = base_dir + string("buffer/enable");
info.buffer_length_node_path = base_dir + string("buffer/length");
info.trigger_node_path = base_dir + string("trigger/current_trigger");
- info.available_freq_node_path = base_dir + string("sampling_frequency_available");
return true;
}
-bool sensor_hal::get_sensorhub_iio_node_info(const string &key, const string &interval_node_name, node_path_info &info)
+bool sensor_hal::get_sensorhub_iio_node_info(const string &interval_node_name, const string& device_num, node_info &info)
{
- const string base_dir = "/sys/class/sensors/ssp_sensor/";
- string device_num;
-
- if (!get_device_num(IIO_METHOD, key, device_num))
- return false;
+ const string base_dir = string("/sys/bus/iio/devices/iio:device") + device_num + string("/");
+ const string hub_dir = "/sys/class/sensors/ssp_sensor/";
- info.base_dir = base_dir;
info.data_node_path = string("/dev/iio:device") + device_num;
- info.enable_node_path = base_dir + string("enable"); //this may need to be changed
- info.interval_node_path = base_dir + interval_node_name;
+ info.enable_node_path = hub_dir + string("enable");
+ info.interval_node_path = hub_dir + interval_node_name;
+ info.buffer_enable_node_path = base_dir + string("buffer/enable");
+ info.buffer_length_node_path = base_dir + string("buffer/length");
return true;
}
-bool sensor_hal::get_input_event_node_info(const string &key, node_path_info &info)
+bool sensor_hal::get_input_event_node_info(const string& device_num, node_info &info)
{
string base_dir;
- string device_num;
string event_num;
- if (!get_device_num(INPUT_EVENT_METHOD, key, device_num))
- return false;
-
base_dir = string("/sys/class/input/input") + device_num + string("/");
if (!get_event_num(base_dir, event_num))
return true;
}
-bool sensor_hal::get_sensorhub_input_event_node_info(const string &key, const string &interval_node_name, node_path_info &info)
+bool sensor_hal::get_sensorhub_input_event_node_info(const string &interval_node_name, const string& device_num, node_info &info)
{
const string base_dir = "/sys/class/sensors/ssp_sensor/";
- string device_num;
string event_num;
- if (!get_device_num(INPUT_EVENT_METHOD, key, device_num))
- return false;
-
string input_dir = string("/sys/class/input/input") + device_num + string("/");
if (!get_event_num(input_dir, event_num))
}
-bool sensor_hal::find_model_id(int method, const string &sensor_type, string &model_id)
+bool sensor_hal::find_model_id(const string &sensor_type, string &model_id)
{
- const string input_event_dir = "/sys/class/sensors/";
- const string iio_dir = "/sys/bus/iio/devices/";
- string dir_path;
+ string dir_path = "/sys/class/sensors/";
string name_node, name;
string d_name;
DIR *dir = NULL;
struct dirent *dir_entry = NULL;
bool find = false;
- if (method == IIO_METHOD)
- dir_path = iio_dir;
- else
- dir_path = input_event_dir;
-
dir = opendir(dir_path.c_str());
if (!dir) {
DBG("Failed to open dir: %s", dir_path.c_str());
return find;
}
-bool sensor_hal::verify_iio_trigger(const string &trigger_name)
-{
- return true;
-}
-
-bool sensor_hal::get_model_properties(const string &sensor_type, string &model_id, int &input_method)
-{
- if (find_model_id(INPUT_EVENT_METHOD, sensor_type, model_id)) {
- input_method = INPUT_EVENT_METHOD;
- return true;
- } else if (find_model_id(IIO_METHOD, sensor_type, model_id)) {
- input_method = IIO_METHOD;
- return true;
- }
-
- return false;
-}
-
bool sensor_hal::get_event_num(const string &input_path, string &event_num)
{
const string event_prefix = "event";
return find;
}
-bool sensor_hal::get_device_num(int method, const string &key, string &device_num)
+bool sensor_hal::get_input_method(const string &key, int &method, string &device_num)
{
- const string input_event_dir = "/sys/class/input/";
- const string iio_dir = "/sys/bus/iio/devices/";
- const string input_event_prefix = "input";
- const string iio_prefix = "iio:device";
+ input_method_info input_info[2] = {
+ {INPUT_EVENT_METHOD, "/sys/class/input/", "input"},
+ {IIO_METHOD, "/sys/bus/iio/devices/", "iio:device"}
+ };
- string dir_path;
- string prefix;
+ const int input_info_len = sizeof(input_info)/sizeof(input_info[0]);
size_t prefix_size;
string name_node, name;
string d_name;
struct dirent *dir_entry = NULL;
bool find = false;
- if (method == IIO_METHOD) {
- dir_path = iio_dir;
- prefix = iio_prefix;
- } else {
- dir_path = input_event_dir;
- prefix = input_event_prefix;
- }
+ for (int i = 0; i < input_info_len; ++i) {
- prefix_size = prefix.size();
+ prefix_size = input_info[i].prefix.size();
- dir = opendir(dir_path.c_str());
- if (!dir) {
- ERR("Failed to open dir: %s", dir_path.c_str());
- return false;
- }
+ dir = opendir(input_info[i].dir_path.c_str());
+ if (!dir) {
+ ERR("Failed to open dir: %s", input_info[i].dir_path.c_str());
+ return false;
+ }
- while (!find && (dir_entry = readdir(dir))) {
- d_name = string(dir_entry->d_name);
+ find = false;
- if (d_name.compare(0, prefix_size, prefix) == 0) {
- name_node = dir_path + d_name + string("/name");
+ while (!find && (dir_entry = readdir(dir))) {
+ d_name = string(dir_entry->d_name);
- ifstream infile(name_node.c_str());
- if (!infile)
- continue;
+ if (d_name.compare(0, prefix_size, input_info[i].prefix) == 0) {
+ name_node = input_info[i].dir_path + d_name + string("/name");
- infile >> name;
+ ifstream infile(name_node.c_str());
+ if (!infile)
+ continue;
- if (name == key) {
- device_num = d_name.substr(prefix_size, d_name.size() - prefix_size);
- find = true;
- break;
+ infile >> name;
+
+ if (name == key) {
+ device_num = d_name.substr(prefix_size, d_name.size() - prefix_size);
+ find = true;
+ method = input_info[i].method;
+ break;
+ }
}
}
- }
-
- closedir(dir);
-
- return find;
-}
-bool sensor_hal::get_generic_channel_names(const string &scan_dir, const string &suffix, vector<string> &generic_channel_names)
-{
- DIR *dir = NULL;
- struct dirent *dir_entry = NULL;
- string file_node;
- string d_name;
- unsigned int pos;
+ closedir(dir);
- dir = opendir(scan_dir.c_str());
- if (!dir) {
- DBG("Failed to open dir: %s", dir_path.c_str());
- return false;
- }
-
- generic_channel_names.clear();
-
- while (true) {
- dir_entry = readdir(dir);
- if (dir_entry == NULL)
+ if (find)
break;
-
- d_name = string(dir_entry->d_name);
-
- if ((d_name != ".") && (d_name != "..") && (dir_entry->d_ino != 0)) {
- pos = d_name.rfind(suffix.c_str());
- if (pos == string::npos)
- continue;
- generic_channel_names.push_back(d_name.substr(0 , pos));
- }
}
- closedir(dir);
- if (generic_channel_names.size() > 0)
- return true;
- return false;
+
+ return find;
}
#include <common.h>
#include <sensor_internal.h>
#include <string>
-#include <vector>
using std::string;
-using std::vector;
/*
* As of Linux 3.4, there is a new EVIOCSCLOCKID ioctl to set the desired clock
#endif
typedef struct {
+ int method;
string data_node_path;
string enable_node_path;
string interval_node_path;
string buffer_enable_node_path;
string buffer_length_node_path;
string trigger_node_path;
- string available_freq_node_path;
- string base_dir;
-} node_path_info;
+} node_info;
typedef struct {
- int input_method;
bool sensorhub_controlled;
string sensor_type;
- string input_event_key;
+ string key;
string iio_enable_node_name;
string sensorhub_interval_node_name;
-} node_path_info_query;
+} node_info_query;
enum input_method {
- IIO_METHOD,
- INPUT_EVENT_METHOD,
+ IIO_METHOD = 0,
+ INPUT_EVENT_METHOD = 1,
};
+typedef struct {
+ int method;
+ std::string dir_path;
+ std::string prefix;
+} input_method_info;
+
#define DEFAULT_WAIT_TIME 0
class sensor_hal
static unsigned long long get_timestamp(void);
static unsigned long long get_timestamp(timeval *t);
+ static bool find_model_id(const string &sensor_type, string &model_id);
static bool is_sensorhub_controlled(const string &key);
- static bool get_model_properties(const string &sensor_type, string &model_id, int &input_method);
- static bool get_node_path_info(const node_path_info_query &query, node_path_info &info);
- static void show_node_path_info(node_path_info &info);
+ static bool get_node_info(const node_info_query &query, node_info &info);
+ static void show_node_info(node_info &info);
static bool set_node_value(const string &node_path, int value);
static bool set_node_value(const string &node_path, unsigned long long value);
static bool get_node_value(const string &node_path, int &value);
- static bool verify_iio_trigger(const string &trigger_name);
- static bool get_generic_channel_names(const string &scan_dir, const string &suffix, vector<string> &generic_channel_names);
-
private:
- static bool find_model_id(int method, const string &sensor_type, string &model_id);
static bool get_event_num(const string &node_path, string &event_num);
- static bool get_device_num(int method, const string &key, string &device_num);
- static bool get_iio_node_info(const string &key, const string& enable_node_name, node_path_info &info);
- static bool get_sensorhub_iio_node_info(const string &key, const string &interval_node_name, node_path_info &info);
- static bool get_input_event_node_info(const string &key, node_path_info &info);
- static bool get_sensorhub_input_event_node_info(const string &key, const string &interval_node_name, node_path_info &info);
+ static bool get_input_method(const string &key, int &method, string &device_num);
+
+ static bool get_iio_node_info(const string& enable_node_name, const string& device_num, node_info &info);
+ static bool get_sensorhub_iio_node_info(const string &interval_node_name, const string& device_num, node_info &info);
+ static bool get_input_event_node_info(const string& device_num, node_info &info);
+ static bool get_sensorhub_input_event_node_info(const string &interval_node_name, const string& device_num, node_info &info);
};
#endif /*_SENSOR_HAL_CLASS_H_*/
return inst;
}
-bool sensor_plugin_loader::load_module(const string &path, void** module, void** handle)
+bool sensor_plugin_loader::load_module(const string &path, vector<void*> &sensors, void* &handle)
{
void *_handle = dlopen(path.c_str(), RTLD_NOW);
if (!_handle) {
- ERR("Failed with dlopen(%s), dlerror : %s", path.c_str(), dlerror());
+ ERR("Failed to dlopen(%s), dlerror : %s", path.c_str(), dlerror());
return false;
}
dlerror();
- typedef void* create_t(void);
- typedef void destroy_t(void *);
+ create_t create_module = (create_t) dlsym(_handle, "create");
- create_t* init_module = (create_t*) dlsym(_handle, "create");
-
- if (!init_module) {
- ERR("Failed to find \"create\" symbol");
+ if (!create_module) {
+ ERR("Failed to find symbols in %s", path.c_str());
dlclose(_handle);
return false;
}
- destroy_t* exit_module = (destroy_t*) dlsym(_handle, "destroy");
+ sensor_module *module = create_module();
- if (!exit_module) {
- ERR("Failed to find \"destroy\" symbol");
+ if (!module) {
+ ERR("Failed to create module, path is %s\n", path.c_str());
dlclose(_handle);
return false;
}
- void *_module = init_module();
-
- if (!_module) {
- ERR("Failed to init the module, Target file is %s\n", path.c_str());
- exit_module(_module);
- dlclose(_handle);
- return false;
- }
+ sensors.clear();
+ sensors.swap(module->sensors);
- *module = _module;
- *handle = _handle;
+ delete module;
+ handle = _handle;
return true;
}
bool sensor_plugin_loader::insert_module(plugin_type type, const string &path)
{
if (type == PLUGIN_TYPE_HAL) {
- DBG("insert sensor plugin [%s]", path.c_str());
- sensor_hal *module;
+ DBG("Insert HAL plugin [%s]", path.c_str());
+
+ std::vector<void *>hals;
void *handle;
- if (!load_module(path, (void **)&module, &handle))
+ if (!load_module(path, hals, handle))
return false;
- sensor_type_t sensor_type = module->get_type();
- m_sensor_hals.insert(make_pair(sensor_type, module));
+ sensor_hal* hal;
+
+ for (unsigned int i = 0; i < hals.size(); ++i) {
+ hal = static_cast<sensor_hal*> (hals[i]);
+ sensor_type_t sensor_type = hal->get_type();
+ m_sensor_hals.insert(make_pair(sensor_type, hal));
+ }
} else if (type == PLUGIN_TYPE_SENSOR) {
- DBG("insert sensor plugin [%s]", path.c_str());
- sensor_base *module;
+ DBG("Insert Sensor plugin [%s]", path.c_str());
+
+ std::vector<void *> sensors;
void *handle;
- if (!load_module(path, (void**)&module, &handle))
+ if (!load_module(path, sensors, handle))
return false;
- if (!module->init()) {
- ERR("Failed to init [%s] module\n", module->get_name());
- delete module;
- dlclose(handle);
- return false;
- }
- DBG("init [%s] module", module->get_name());
+ sensor_base* sensor;
+
+ for (unsigned int i = 0; i < sensors.size(); ++i) {
+ sensor = static_cast<sensor_base*> (sensors[i]);
+
+ if (!sensor->init()) {
+ ERR("Failed to init [%s] module\n", sensor->get_name());
+ delete sensor;
+ continue;
+ }
- sensor_type_t sensor_type = module->get_type();
+ DBG("init [%s] module", sensor->get_name());
- int idx;
- idx = m_sensors.count(sensor_type);
- module->set_id(idx << SENSOR_INDEX_SHIFT | sensor_type);
- m_sensors.insert(make_pair(sensor_type, module));
+ sensor_type_t sensor_type = sensor->get_type();
+
+ int idx;
+ idx = m_sensors.count(sensor_type);
+ sensor->set_id(idx << SENSOR_INDEX_SHIFT | sensor_type);
+ m_sensors.insert(make_pair(sensor_type, sensor));
+ }
}else {
ERR("Not supported type: %d", type);
return false;
class sensor_plugin_loader
{
private:
- enum plugin_type {
+ typedef enum plugin_type {
PLUGIN_TYPE_HAL,
PLUGIN_TYPE_SENSOR,
- };
+ } plugin_type;
sensor_plugin_loader();
- bool load_module(const string &path, void** module, void** handle);
+ bool load_module(const string &path, vector<void*> &sensors, void* &handle);
bool insert_module(plugin_type type, const string &path);
void show_sensor_info(void);
bool get_paths_from_dir(const string &dir_path, vector<string> &hal_paths, vector<string> &sensor_paths);
#include <vector>
#include <sensor_common.h>
#include <string>
+#include <vector>
#define COMMAND_CHANNEL_PATH "/tmp/sf_command_socket"
#define EVENT_CHANNEL_PATH "/tmp/sf_event_socket"
sensorhub_data_t data;
} sensorhub_event_t;
+typedef struct sensor_module{
+ std::vector<void*> sensors;
+} sensor_module;
+
+typedef sensor_module* (*create_t)(void);
typedef void *(*cmd_func_t)(void *data, void *cb_data);
enum sensor_permission_t {
SENSOR_PERMISSION_NONE = 0,
- SENSOR_PERMISSION_STANDARD = 1,
+ SENSOR_PERMISSION_STANDARD = (1 << 0),
+ SENSOR_PERMISSION_BIO = (1 << 1),
};
+#define BIO_SENSOR_PRIVELEGE_NAME "sensord::bio"
+#define BIO_SENSOR_ACCESS_RIGHT "rw"
+
#endif
#include <sensor_plugin_loader.h>
#define SENSOR_NAME "TEMPERATURE_SENSOR"
-#define NO_OF_DATA_VAL 1
temperature_sensor::temperature_sensor()
: m_sensor_hal(NULL)
{
m_sensor_hal = sensor_plugin_loader::get_instance().get_sensor_hal(TEMPERATURE_SENSOR);
- if (!m_sensor_hal)
- {
+ if (!m_sensor_hal) {
ERR("cannot load sensor_hal[%s]", sensor_base::get_name());
return false;
}
sensor_properties_s properties;
- if (!m_sensor_hal->get_properties(properties))
- {
+ if (!m_sensor_hal->get_properties(properties)) {
ERR("sensor->get_properties() is failed!\n");
return false;
}
AUTOLOCK(m_client_info_mutex);
- if (get_client_cnt(TEMPERATURE_EVENT_RAW_DATA_REPORT_ON_TIME))
- {
+ if (get_client_cnt(TEMPERATURE_EVENT_RAW_DATA_REPORT_ON_TIME)) {
+ event.sensor_id = get_id();
event.event_type = TEMPERATURE_EVENT_RAW_DATA_REPORT_ON_TIME;
raw_to_base(event.data);
push(event);
bool temperature_sensor::on_start(void)
{
- if (!m_sensor_hal->enable())
- {
+ if (!m_sensor_hal->enable()) {
ERR("m_sensor_hal start fail\n");
return false;
}
bool temperature_sensor::on_stop(void)
{
- if (!m_sensor_hal->disable())
- {
+ if (!m_sensor_hal->disable()) {
ERR("m_sensor_hal stop fail\n");
return false;
}
if (ret < 0)
return -1;
- if (type == TEMPERATURE_BASE_DATA_SET)
- {
+ if (type == TEMPERATURE_BASE_DATA_SET) {
raw_to_base(data);
return 0;
}
void temperature_sensor::raw_to_base(sensor_data_t &data)
{
- data.values_num = NO_OF_DATA_VAL;
+ data.values[0] = data.values[0] * m_resolution;
+ data.value_count = 1;
}
-extern "C" void *create(void)
+extern "C" sensor_module* create(void)
{
- temperature_sensor *inst;
+ temperature_sensor *sensor;
- try
- {
- inst = new temperature_sensor();
- }
- catch (int err)
- {
- ERR("temperature_sensor class create fail , errno : %d , errstr : %s\n", err, strerror(err));
+ try {
+ sensor = new(std::nothrow) temperature_sensor;
+ } catch (int err) {
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
return NULL;
}
- return (void*)inst;
-}
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
-extern "C" void destroy(void *inst)
-{
- delete (temperature_sensor*)inst;;
+ module->sensors.push_back(sensor);
+ return module;
}
*/
#include <fcntl.h>
#include <sys/stat.h>
-#include <dirent.h>
#include <linux/input.h>
#include <csensor_config.h>
-#include <fstream>
#include <temperature_sensor_hal.h>
#include <sys/ioctl.h>
-#include <iio_common.h>
-
-using std::ifstream;
#define SENSOR_TYPE_TEMPERATURE "TEMPERATURE"
#define ELEMENT_NAME "NAME"
, m_fired_time(INITIAL_TIME)
{
const string sensorhub_interval_node_name = TEMP_SENSORHUB_POLL_NODE_NAME;
- string file_name;
- node_path_info_query query;
- node_path_info info;
- int input_method = IIO_METHOD;
- if (!get_model_properties(SENSOR_TYPE_TEMPERATURE, m_model_id, input_method)) {
- ERR("Failed to find model_properties");
+ node_info_query query;
+ node_info info;
+
+ if (!find_model_id(SENSOR_TYPE_TEMPERATURE, m_model_id)) {
+ ERR("Failed to find model id");
throw ENXIO;
}
- query.input_method = input_method;
query.sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name);
query.sensor_type = SENSOR_TYPE_TEMPERATURE;
- query.input_event_key = TEMP_INPUT_NAME;
+ query.key = TEMP_INPUT_NAME;
query.iio_enable_node_name = TEMP_IIO_ENABLE_NODE_NAME;
query.sensorhub_interval_node_name = sensorhub_interval_node_name;
- if (!get_node_path_info(query, info)) {
+ if (!get_node_info(query, info)) {
ERR("Failed to get node info");
throw ENXIO;
}
- show_node_path_info(info);
+ show_node_info(info);
m_data_node = info.data_node_path;
m_enable_node = info.enable_node_path;
m_interval_node = info.interval_node_path;
- if(input_method == IIO_METHOD) {
- m_temperature_dir=info.base_dir;
- m_temp_node = m_temperature_dir + string(TEMP_RAW);
- INFO("m_temperature_dir = %s", m_temperature_dir.c_str());
- INFO("m_temp_node = %s", m_temp_node.c_str());
- }
csensor_config &config = csensor_config::get_instance();
if (!config.get(SENSOR_TYPE_TEMPERATURE, m_model_id, ELEMENT_VENDOR, m_vendor)) {
m_raw_data_unit = (float)(raw_data_unit);
- INFO("m_data_node = %s\n",m_data_node.c_str());
-
- if ((m_node_handle = open(m_temp_node.c_str(),O_RDWR)) < 0) {
+ if ((m_node_handle = open(m_data_node.c_str(),O_RDWR)) < 0) {
ERR("Failed to open handle(%d)", m_node_handle);
throw ENXIO;
}
- INFO("m_data_node = %s\n",m_data_node.c_str());
- INFO("m_raw_data_unit = %f\n", m_raw_data_unit);
-
- file_name = m_temperature_dir + string(TEMP_SCALE);
- if (!read_node_value<int>(file_name, m_temp_scale))
- throw ENXIO;
+ int clockId = CLOCK_MONOTONIC;
+ if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0)
+ ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str());
- file_name = m_temperature_dir + string(TEMP_OFFSET);
- if (!read_node_value<float>(file_name, m_temp_offset))
- throw ENXIO;
-
- INFO("m_temp_offset %f",m_temp_offset);
- INFO("m_temp_scale %d",m_temp_scale);
INFO("m_vendor = %s", m_vendor.c_str());
INFO("m_chip_name = %s", m_chip_name.c_str());
INFO("m_raw_data_unit = %f\n", m_raw_data_unit);
bool temperature_sensor_hal::enable(void)
{
- m_fired_time = INITIAL_TIME;
+ AUTOLOCK(m_mutex);
+
+ set_enable_node(m_enable_node, m_sensorhub_controlled, true,
+ SENSORHUB_TEMPERATURE_HUMIDITY_ENABLE_BIT);
+ set_interval(m_polling_interval);
+
+ m_fired_time = 0;
INFO("Temperature sensor real starting");
return true;
}
bool temperature_sensor_hal::disable(void)
{
+ AUTOLOCK(m_mutex);
+
+ set_enable_node(m_enable_node, m_sensorhub_controlled, false,
+ SENSORHUB_TEMPERATURE_HUMIDITY_ENABLE_BIT);
+
INFO("Temperature sensor real stopping");
return true;
}
bool temperature_sensor_hal::set_interval(unsigned long val)
{
+ unsigned long long polling_interval_ns;
+
+ AUTOLOCK(m_mutex);
+
+ polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu);
+
+ if (!set_node_value(m_interval_node, polling_interval_ns)) {
+ ERR("Failed to set polling node: %s\n", m_interval_node.c_str());
+ return false;
+ }
+
+ INFO("Interval is changed from %dms to %dms]", m_polling_interval, val);
+ m_polling_interval = val;
return true;
}
bool temperature_sensor_hal::update_value(bool wait)
{
- int raw_temp_count;
+ int temperature_raw = 0;
+ bool temperature = false;
+ int read_input_cnt = 0;
+ const int INPUT_MAX_BEFORE_SYN = 10;
+ unsigned long long fired_time = 0;
+ bool syn = false;
+
+ struct input_event temperature_event;
+ DBG("temperature event detection!");
+
+ while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) {
+ int len = read(m_node_handle, &temperature_event, sizeof(temperature_event));
+ if (len != sizeof(temperature_event)) {
+ ERR("temperature_file read fail, read_len = %d\n",len);
+ return false;
+ }
+
+ ++read_input_cnt;
+
+ if (temperature_event.type == EV_REL) {
+ switch (temperature_event.code) {
+ case REL_HWHEEL:
+ temperature_raw = (int)temperature_event.value;
+ temperature = true;
+ break;
+ default:
+ ERR("temperature_event event[type = %d, code = %d] is unknown.", temperature_event.type, temperature_event.code);
+ return false;
+ break;
+ }
+ } else if (temperature_event.type == EV_SYN) {
+ syn = true;
+ fired_time = sensor_hal::get_timestamp(&temperature_event.time);
+ } else {
+ ERR("temperature_event event[type = %d, code = %d] is unknown.", temperature_event.type, temperature_event.code);
+ return false;
+ }
+ }
- if (!read_node_value<int>(m_temp_node, raw_temp_count))
+ if (syn == false) {
+ ERR("EV_SYN didn't come until %d inputs had come", read_input_cnt);
return false;
- m_temperature = m_temp_offset + ((float)raw_temp_count)/((float)m_temp_scale);
- INFO("m_temperature %f",m_temperature);
- INFO("m_temp_offset %f",m_temp_offset);
- INFO("raw_temp_count %d",raw_temp_count);
- INFO("m_temp_scale %d",m_temp_scale);
+ }
+
+ AUTOLOCK(m_value_mutex);
+
+ if (temperature)
+ m_temperature = temperature_raw;
+
+ m_fired_time = fired_time;
+
+ DBG("m_temperature = %d, time = %lluus", m_temperature, m_fired_time);
+
return true;
}
return true;
}
-extern "C" void *create(void)
+extern "C" sensor_module* create(void)
{
- temperature_sensor_hal *inst;
+ temperature_sensor_hal *sensor;
try {
- inst = new temperature_sensor_hal();
+ sensor = new(std::nothrow) temperature_sensor_hal;
} catch (int err) {
- ERR("temperature_sensor_hal class create fail , errno : %d , errstr : %s\n", err, strerror(err));
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
return NULL;
}
- return (void*)inst;
-}
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
-extern "C" void destroy(void *inst)
-{
- delete (temperature_sensor_hal*)inst;
+ module->sensors.push_back(sensor);
+ return module;
}
#include <sensor_hal.h>
#include <string>
-#define IIO_DIR "/sys/bus/iio/devices/"
-#define IIO_DEV_BASE_NAME "iio:device"
-#define IIO_DEV_STR_LEN 10
-#define NAME_NODE "/name"
-#define TEMP_OFFSET "in_temp_offset"
-#define TEMP_SCALE "in_temp_scale"
-#define TEMP_RAW "in_temp_raw"
using std::string;
string m_vendor;
string m_chip_name;
- int m_temp_scale;
float m_raw_data_unit;
- float m_temp_offset;
string m_data_node;
string m_enable_node;
string m_interval_node;
- string m_temperature_dir;
- string m_temp_node;
bool m_sensorhub_controlled;
--- /dev/null
+cmake_minimum_required(VERSION 2.6)
+project(ultraviolet CXX)
+
+SET(SENSOR_NAME ultraviolet_sensor)
+SET(SENSOR_HAL_NAME ultraviolet_sensor_hal)
+
+include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+include_directories(${CMAKE_SOURCE_DIR}/src/libsensord)
+
+INCLUDE(FindPkgConfig)
+PKG_CHECK_MODULES(uv_pkgs REQUIRED vconf)
+
+FOREACH(flag ${uv_pkgs_LDFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+FOREACH(flag ${uv_pkgs_CFLAGS})
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}")
+ENDFOREACH(flag)
+
+add_library(${SENSOR_NAME} SHARED
+ ultraviolet_sensor.cpp
+ )
+
+add_library(${SENSOR_HAL_NAME} SHARED
+ ultraviolet_sensor_hal.cpp
+ )
+
+target_link_libraries(${SENSOR_NAME} ${uv_pkgs_LDFLAGS} "-lm")
+target_link_libraries(${SENSOR_HAL_NAME} ${uv_pkgs_LDFLAGS})
+
+install(TARGETS ${SENSOR_NAME} DESTINATION lib/sensord)
+install(TARGETS ${SENSOR_HAL_NAME} DESTINATION lib/sensord)
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 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 <common.h>
+#include <sf_common.h>
+
+#include <ultraviolet_sensor.h>
+#include <sensor_plugin_loader.h>
+#include <algorithm>
+
+using std::bind1st;
+using std::mem_fun;
+
+#define SENSOR_NAME "ULTRAVIOLET_SENSOR"
+
+ultraviolet_sensor::ultraviolet_sensor()
+: m_sensor_hal(NULL)
+, m_resolution(0.0f)
+{
+ m_name = string(SENSOR_NAME);
+
+ register_supported_event(ULTRAVIOLET_EVENT_RAW_DATA_REPORT_ON_TIME);
+
+ physical_sensor::set_poller(ultraviolet_sensor::working, this);
+}
+
+ultraviolet_sensor::~ultraviolet_sensor()
+{
+ INFO("ultraviolet_sensor is destroyed!");
+}
+
+bool ultraviolet_sensor::init()
+{
+ m_sensor_hal = sensor_plugin_loader::get_instance().get_sensor_hal(ULTRAVIOLET_SENSOR);
+
+ if (!m_sensor_hal) {
+ ERR("cannot load sensor_hal[%s]", sensor_base::get_name());
+ return false;
+ }
+
+ sensor_properties_t properties;
+
+ if (!m_sensor_hal->get_properties(properties)) {
+ ERR("sensor->get_properties() is failed!\n");
+ return false;
+ }
+
+ m_resolution = properties.resolution;
+
+ INFO("%s is created!", sensor_base::get_name());
+
+ return true;
+}
+
+sensor_type_t ultraviolet_sensor::get_type(void)
+{
+ return ULTRAVIOLET_SENSOR;
+}
+
+bool ultraviolet_sensor::working(void *inst)
+{
+ ultraviolet_sensor *sensor = (ultraviolet_sensor*)inst;
+ return sensor->process_event();
+}
+
+bool ultraviolet_sensor::process_event(void)
+{
+ sensor_event_t event;
+
+ if (!m_sensor_hal->is_data_ready(true))
+ return true;
+
+ m_sensor_hal->get_sensor_data(event.data);
+
+ AUTOLOCK(m_client_info_mutex);
+
+ if (get_client_cnt(ULTRAVIOLET_EVENT_RAW_DATA_REPORT_ON_TIME)) {
+ event.sensor_id = get_id();
+ event.event_type = ULTRAVIOLET_EVENT_RAW_DATA_REPORT_ON_TIME;
+ raw_to_base(event.data);
+ push(event);
+ }
+
+ return true;
+}
+
+bool ultraviolet_sensor::on_start(void)
+{
+ if (!m_sensor_hal->enable()) {
+ ERR("m_sensor_hal start fail\n");
+ return false;
+ }
+
+ return start_poll();
+}
+
+bool ultraviolet_sensor::on_stop(void)
+{
+ if (!m_sensor_hal->disable()) {
+ ERR("m_sensor_hal stop fail\n");
+ return false;
+ }
+
+ return stop_poll();
+}
+
+bool ultraviolet_sensor::get_properties(sensor_properties_t &properties)
+{
+ return m_sensor_hal->get_properties(properties);
+}
+
+int ultraviolet_sensor::get_sensor_data(unsigned int type, sensor_data_t &data)
+{
+ int ret;
+
+ ret = m_sensor_hal->get_sensor_data(data);
+
+ if (ret < 0)
+ return -1;
+
+ if (type == ULTRAVIOLET_BASE_DATA_SET) {
+ raw_to_base(data);
+ return 0;
+ }
+
+ return -1;
+}
+
+bool ultraviolet_sensor::set_interval(unsigned long interval)
+{
+ AUTOLOCK(m_mutex);
+
+ INFO("Polling interval is set to %dms", interval);
+
+ return m_sensor_hal->set_interval(interval);
+}
+
+void ultraviolet_sensor::raw_to_base(sensor_data_t &data)
+{
+ /*
+ double lsb = data.values[0];
+ double comp_lsb;
+
+ const double c = 0.89;
+ const double e = 2.12;
+ const double f = -132.8;
+
+ if (lsb > 108.8f)
+ comp_lsb = e * lsb + f;
+ else
+ comp_lsb = c * lsb;
+
+ data.values[0] = comp_lsb * m_resolution;
+ */
+ data.values[0] = data.values[0] * m_resolution;
+ data.value_count = 1;
+}
+
+extern "C" sensor_module* create(void)
+{
+ ultraviolet_sensor *sensor;
+
+ try {
+ sensor = new(std::nothrow) ultraviolet_sensor;
+ } catch (int err) {
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
+ return NULL;
+ }
+
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
+
+ module->sensors.push_back(sensor);
+ return module;
+}
--- /dev/null
+/*
+ * sensord
+ *
+ * Copyright (c) 2014 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.
+ *
+ */
+
+#ifndef _ULTRAVIOLET_SENSOR_H_
+#define _ULTRAVIOLET_SENSOR_H_
+
+#include <sensor_common.h>
+
+#include <physical_sensor.h>
+#include <sensor_hal.h>
+
+class ultraviolet_sensor : public physical_sensor {
+public:
+ ultraviolet_sensor();
+ virtual ~ultraviolet_sensor();
+
+ bool init();
+ sensor_type_t get_type(void);
+
+ static bool working(void *inst);
+
+ bool set_interval(unsigned long interval);
+ virtual bool get_properties(sensor_properties_t &properties);
+ int get_sensor_data(unsigned int type, sensor_data_t &data);
+
+private:
+ sensor_hal *m_sensor_hal;
+ float m_resolution;
+
+ virtual bool on_start(void);
+ virtual bool on_stop(void);
+ bool process_event(void);
+ void raw_to_base(sensor_data_t &data);
+};
+
+#endif
+
--- /dev/null
+/*
+ * ultraviolet_sensor_hal
+ *
+ * Copyright (c) 2014 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 <fcntl.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <linux/input.h>
+#include <csensor_config.h>
+#include <ultraviolet_sensor_hal.h>
+#include <sys/ioctl.h>
+#include <fstream>
+
+using std::ifstream;
+
+#define SENSOR_TYPE_ULTRAVIOLET "ULTRAVIOLET"
+#define ELEMENT_NAME "NAME"
+#define ELEMENT_VENDOR "VENDOR"
+#define ELEMENT_RAW_DATA_UNIT "RAW_DATA_UNIT"
+#define ELEMENT_MIN_RANGE "MIN_RANGE"
+#define ELEMENT_MAX_RANGE "MAX_RANGE"
+#define ATTR_VALUE "value"
+
+#define BIAS 1
+
+ultraviolet_sensor_hal::ultraviolet_sensor_hal()
+: m_polling_interval(POLL_1HZ_MS)
+, m_ultraviolet(0)
+, m_fired_time(0)
+, m_node_handle(-1)
+{
+ const string sensorhub_interval_node_name = "uv_poll_delay";
+ csensor_config &config = csensor_config::get_instance();
+
+ node_info_query query;
+ node_info info;
+
+ if (!find_model_id(SENSOR_TYPE_ULTRAVIOLET, m_model_id)) {
+ ERR("Failed to find model id");
+ throw ENXIO;
+
+ }
+
+ query.sensorhub_controlled = m_sensorhub_controlled = is_sensorhub_controlled(sensorhub_interval_node_name);
+ query.sensor_type = SENSOR_TYPE_ULTRAVIOLET;
+ query.key = "uv_sensor";
+ query.iio_enable_node_name = "uv_enable";
+ query.sensorhub_interval_node_name = sensorhub_interval_node_name;
+
+ if (!get_node_info(query, info)) {
+ ERR("Failed to get node info");
+ throw ENXIO;
+ }
+
+ show_node_info(info);
+
+ m_data_node = info.data_node_path;
+ m_enable_node = info.enable_node_path;
+ m_interval_node = info.interval_node_path;
+
+ if (!config.get(SENSOR_TYPE_ULTRAVIOLET, m_model_id, ELEMENT_VENDOR, m_vendor)) {
+ ERR("[VENDOR] is empty\n");
+ throw ENXIO;
+ }
+
+ INFO("m_vendor = %s", m_vendor.c_str());
+
+ if (!config.get(SENSOR_TYPE_ULTRAVIOLET, m_model_id, ELEMENT_NAME, m_chip_name)) {
+ ERR("[NAME] is empty\n");
+ throw ENXIO;
+ }
+
+ INFO("m_chip_name = %s\n",m_chip_name.c_str());
+
+ double min_range;
+
+ if (!config.get(SENSOR_TYPE_ULTRAVIOLET, m_model_id, ELEMENT_MIN_RANGE, min_range)) {
+ ERR("[MIN_RANGE] is empty\n");
+ throw ENXIO;
+ }
+
+ m_min_range = (float)min_range;
+ INFO("m_min_range = %f\n",m_min_range);
+
+ double max_range;
+
+ if (!config.get(SENSOR_TYPE_ULTRAVIOLET, m_model_id, ELEMENT_MAX_RANGE, max_range)) {
+ ERR("[MAX_RANGE] is empty\n");
+ throw ENXIO;
+ }
+
+ m_max_range = (float)max_range;
+ INFO("m_max_range = %f\n",m_max_range);
+
+ double raw_data_unit;
+
+ if (!config.get(SENSOR_TYPE_ULTRAVIOLET, m_model_id, ELEMENT_RAW_DATA_UNIT, raw_data_unit)) {
+ ERR("[RAW_DATA_UNIT] is empty\n");
+ throw ENXIO;
+ }
+
+ m_raw_data_unit = (float)(raw_data_unit);
+
+ if ((m_node_handle = open(m_data_node.c_str(),O_RDWR)) < 0) {
+ ERR("Failed to open handle(%d)", m_node_handle);
+ throw ENXIO;
+ }
+
+ int clockId = CLOCK_MONOTONIC;
+ if (ioctl(m_node_handle, EVIOCSCLOCKID, &clockId) != 0)
+ ERR("Fail to set monotonic timestamp for %s", m_data_node.c_str());
+
+ INFO("m_raw_data_unit = %f\n", m_raw_data_unit);
+ INFO("ultraviolet_sensor_hal is created!\n");
+
+}
+
+ultraviolet_sensor_hal::~ultraviolet_sensor_hal()
+{
+ close(m_node_handle);
+ m_node_handle = -1;
+
+ INFO("ultraviolet_sensor_hal is destroyed!\n");
+}
+
+string ultraviolet_sensor_hal::get_model_id(void)
+{
+ return m_model_id;
+}
+
+
+sensor_type_t ultraviolet_sensor_hal::get_type(void)
+{
+ return ULTRAVIOLET_SENSOR;
+}
+
+bool ultraviolet_sensor_hal::enable(void)
+{
+ AUTOLOCK(m_mutex);
+
+ set_enable_node(m_enable_node, m_sensorhub_controlled, true, SENSORHUB_UV_SENSOR);
+ set_interval(m_polling_interval);
+
+ m_fired_time = 0;
+ INFO("ultraviolet sensor real starting");
+ return true;
+}
+
+bool ultraviolet_sensor_hal::disable(void)
+{
+ AUTOLOCK(m_mutex);
+
+ set_enable_node(m_enable_node, m_sensorhub_controlled, false, SENSORHUB_UV_SENSOR);
+
+ INFO("ultraviolet sensor real stopping");
+ return true;
+}
+
+bool ultraviolet_sensor_hal::set_interval(unsigned long val)
+{
+ unsigned long long polling_interval_ns;
+
+ AUTOLOCK(m_mutex);
+
+ polling_interval_ns = ((unsigned long long)(val) * 1000llu * 1000llu);
+
+ if (!set_node_value(m_interval_node, polling_interval_ns)) {
+ ERR("Failed to set polling resource: %s\n", m_interval_node.c_str());
+ return false;
+ }
+
+ INFO("Interval is changed from %dms to %dms]", m_polling_interval, val);
+ m_polling_interval = val;
+ return true;
+
+}
+
+
+bool ultraviolet_sensor_hal::update_value(bool wait)
+{
+ int ultraviolet_raw = -1;
+ bool ultraviolet = false;
+ int read_input_cnt = 0;
+ const int INPUT_MAX_BEFORE_SYN = 10;
+ unsigned long long fired_time = 0;
+ bool syn = false;
+
+ struct input_event ultraviolet_event;
+ DBG("ultraviolet event detection!");
+
+ while ((syn == false) && (read_input_cnt < INPUT_MAX_BEFORE_SYN)) {
+ int len = read(m_node_handle, &ultraviolet_event, sizeof(ultraviolet_event));
+ if (len != sizeof(ultraviolet_event)) {
+ ERR("ultraviolet file read fail, read_len = %d\n",len);
+ return false;
+ }
+
+ ++read_input_cnt;
+
+ if (ultraviolet_event.type == EV_REL && ultraviolet_event.code == REL_MISC) {
+ ultraviolet_raw = (int)ultraviolet_event.value - BIAS;
+ ultraviolet = true;
+ } else if (ultraviolet_event.type == EV_SYN) {
+ syn = true;
+ fired_time = sensor_hal::get_timestamp(&ultraviolet_event.time);
+ } else {
+ ERR("ultraviolet event[type = %d, code = %d] is unknown.", ultraviolet_event.type, ultraviolet_event.code);
+ return false;
+ }
+ }
+
+ AUTOLOCK(m_value_mutex);
+
+ if (ultraviolet)
+ m_ultraviolet = ultraviolet_raw;
+
+ m_fired_time = fired_time;
+
+ DBG("m_ultraviolet = %d, time = %lluus", m_ultraviolet, m_fired_time);
+
+ return true;
+}
+
+bool ultraviolet_sensor_hal::is_data_ready(bool wait)
+{
+ bool ret;
+ ret = update_value(wait);
+ return ret;
+}
+
+int ultraviolet_sensor_hal::get_sensor_data(sensor_data_t &data)
+{
+ AUTOLOCK(m_value_mutex);
+ data.accuracy = SENSOR_ACCURACY_GOOD;
+ data.timestamp = m_fired_time ;
+ data.value_count = 1;
+ data.values[0] = (float) m_ultraviolet;
+
+ return 0;
+}
+
+
+bool ultraviolet_sensor_hal::get_properties(sensor_properties_t &properties)
+{
+ properties.name = m_chip_name;
+ properties.vendor = m_vendor;
+ properties.min_range = m_min_range;
+ properties.max_range = m_max_range;
+ properties.min_interval = 1;
+ properties.resolution = m_raw_data_unit;
+ properties.fifo_count = 0;
+ properties.max_batch_count = 0;
+
+ return true;
+}
+
+extern "C" sensor_module* create(void)
+{
+ ultraviolet_sensor_hal *sensor;
+
+ try {
+ sensor = new(std::nothrow) ultraviolet_sensor_hal;
+ } catch (int err) {
+ ERR("Failed to create module, err: %d, cause: %s", err, strerror(err));
+ return NULL;
+ }
+
+ sensor_module *module = new(std::nothrow) sensor_module;
+ retvm_if(!module || !sensor, NULL, "Failed to allocate memory");
+
+ module->sensors.push_back(sensor);
+ return module;
+}
--- /dev/null
+/*
+ * ultraviolet_sensor_hal
+ *
+ * Copyright (c) 2014 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.
+ *
+ */
+
+#ifndef _ULTRAVIOLET_SENSOR_HAL_H_
+#define _ULTRAVIOLET_SENSOR_HAL_H_
+
+#include <sensor_hal.h>
+#include <string>
+
+using std::string;
+
+class ultraviolet_sensor_hal : public sensor_hal
+{
+public:
+ ultraviolet_sensor_hal();
+ virtual ~ultraviolet_sensor_hal();
+ string get_model_id(void);
+ sensor_type_t get_type(void);
+ bool enable(void);
+ bool disable(void);
+ bool set_interval(unsigned long val);
+ bool is_data_ready(bool wait);
+ virtual int get_sensor_data(sensor_data_t &data);
+ virtual bool get_properties(sensor_properties_t &properties);
+private:
+ string m_model_id;
+ string m_vendor;
+ string m_chip_name;
+
+ float m_min_range;
+ float m_max_range;
+ float m_raw_data_unit;
+
+ unsigned long m_polling_interval;
+
+ int m_ultraviolet;
+
+ unsigned long long m_fired_time;
+ int m_node_handle;
+
+ string m_enable_node;
+ string m_data_node;
+ string m_interval_node;
+
+ bool m_sensorhub_controlled;
+
+ cmutex m_value_mutex;
+
+ bool update_value(bool wait);
+};
+#endif /*_ULTRAVIOLET_SENSOR_HAL_CLASS_H_*/
+