return ret;
}
+void ClientInfo::getParam(std::vector<Json> &options, const char *key, float *min, float *max)
+{
+ double val;
+
+ for (Json& opt : options) {
+ if (!opt.get(NULL, key, &val))
+ continue;
+ if (min)
+ *min = MIN(*min, static_cast<float>(val));
+ if (max)
+ *max = MAX(*max, static_cast<float>(val));
+ }
+}
+
void ClientInfo::purgeClient(std::string pkgId)
{
IF_FAIL_VOID_TAG(__dbMgr, _W, "DB not initialized");
bool set(std::string subject, std::string pkgId, Json option, int retentionPeriod);
bool remove(std::string subject, std::string pkgId);
+ void getParam(std::vector<Json>& options, const char *key, float *min, float *max);
+
static void purgeClient(std::string pkgId);
private:
#include "pedometer/Pedometer.h"
#include "pressure/Pressure.h"
#include "sleep/Sleep.h"
+#include "heartrate/HeartRate.h"
using namespace ctx;
ADD_PROVIDER(SUBJ_SENSOR_PEDOMETER, PedometerProvider);
ADD_PROVIDER(SUBJ_SENSOR_PRESSURE, PressureProvider);
ADD_PROVIDER(SUBJ_SENSOR_SLEEP_MONITOR, SleepProvider);
+ ADD_PROVIDER(SUBJ_SENSOR_HEART_RATE, HeartRateProvider);
return NULL;
}
/* Check if there is no client anymore */
ret = __clientInfo.get(getSubject(), options);
- IF_FAIL_RETURN(ret != ERR_NONE, ERR_NONE);
- IF_FAIL_RETURN(ret == ERR_NO_DATA, ERR_OPERATION_FAILED);
- /* Stop listening */
- sensorLogger->stop();
+ if (ret == ERR_NONE) {
+ /* Still, one or more clients exist */
+ /* If necessary, the logger restarts its logging logic with updated parameters */
+ sensorLogger->start();
+ return ERR_NONE;
- return ERR_NONE;
+ } else if (ret == ERR_NO_DATA) {
+ /* No client */
+ sensorLogger->stop();
+ return ERR_NONE;
+ }
+
+ return ERR_OPERATION_FAILED;
}
void SensorProvider::removeClient(std::string subject, std::string pkgId)
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <SensorRecorderTypes.h>
+#include <Util.h>
+#include "../TypesInternal.h"
+#include "HeartRateLogger.h"
+#include "HeartRateQuerier.h"
+#include "HeartRate.h"
+
+using namespace ctx;
+
+HeartRateProvider::HeartRateProvider() :
+ SensorProvider(SUBJ_SENSOR_HEART_RATE)
+{
+ IF_FAIL_VOID(isSupported());
+
+ sensorLogger = new(std::nothrow) HeartRateLogger();
+ IF_FAIL_VOID_TAG(sensorLogger, _E, "Memory allocation failed");
+}
+
+HeartRateProvider::~HeartRateProvider()
+{
+}
+
+void HeartRateProvider::getPrivilege(std::vector<const char*> &privilege)
+{
+ privilege.push_back(PRIV_HEALTHINFO);
+}
+
+bool HeartRateProvider::isSupported()
+{
+ return util::getSystemInfoBool("tizen.org/feature/sensor.heart_rate_monitor");
+}
+
+Querier* HeartRateProvider::getQuerier(Json option)
+{
+ HeartRateQuerier *querier = new(std::nothrow) HeartRateQuerier(this, option);
+ IF_FAIL_RETURN_TAG(querier, NULL, _E, "Memory allocation failed");
+ return querier;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_HEARTRATE_PROVIDER_H__
+#define __CONTEXT_HEARTRATE_PROVIDER_H__
+
+#include "../SensorProvider.h"
+
+namespace ctx {
+
+ class HeartRateProvider : public SensorProvider {
+ public:
+ HeartRateProvider();
+ ~HeartRateProvider();
+
+ bool isSupported();
+ void getPrivilege(std::vector<const char*> &privilege);
+
+ protected:
+ Querier* getQuerier(Json option);
+ };
+}
+
+#endif /* _CONTEXT_HEARTRATE_PROVIDER_H_ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <climits>
+#include <sqlite3.h>
+#include <SensorRecorderTypes.h>
+#include "../TypesInternal.h"
+#include "../ClientInfo.h"
+#include "../TimeUtil.h"
+#include "HeartRateLogger.h"
+
+#define SAMPLING_INTERVAL 200 /* ms */
+#define VALID_HR_LB 30 /* BPM */
+#define MIN_VALID_COUNT 3
+#define MAX_TIMER_INTERVAL 1440 /* minutes */
+#define MEASURING_LIMIT 10000 /* ms */
+
+using namespace ctx;
+
+HeartRateLogger::HeartRateLogger() :
+ __timerMgr(NULL),
+ __timerId(-1),
+ __timerInterval(INT_MAX),
+ __expiredTime(0)
+{
+ setSensor(HRM_SENSOR);
+ setPowerSave(false);
+ setSamplingInterval(SAMPLING_INTERVAL);
+
+ /* Create the log table */
+ executeQuery(
+ "CREATE TABLE IF NOT EXISTS " HEART_RATE_RECORD " (" \
+ KEY_UNIV_TIME " INTEGER NOT NULL PRIMARY KEY, " \
+ KEY_HEART_RATE " REAL NOT NULL" \
+ ")");
+
+ ClientInfo clientInfo;
+ if (clientInfo.exist(SUBJ_SENSOR_HEART_RATE))
+ start();
+}
+
+HeartRateLogger::~HeartRateLogger()
+{
+ stop();
+}
+
+bool HeartRateLogger::start()
+{
+ std::vector<Json> options;
+ ClientInfo clientInfo;
+ float interval = MAX_TIMER_INTERVAL;
+
+ if (clientInfo.get(SUBJ_SENSOR_HEART_RATE, options) != ERR_NONE)
+ return false;
+
+ clientInfo.getParam(options, KEY_INTERVAL, &interval, NULL);
+
+ if (!__timerMgr) {
+ __timerMgr = new(std::nothrow) TimerManager;
+ IF_FAIL_RETURN_TAG(__timerMgr, false, _E, "Memory allocation failed");
+ }
+
+ if (interval == __timerInterval)
+ return true;
+
+ __timerInterval = interval;
+
+ _I(GREEN("Start to record (at every %d minutes)"), __timerInterval);
+
+ if (__timerId > 0)
+ __timerMgr->remove(__timerId);
+
+ __timerId = __timerMgr->setFor(__timerInterval, this);
+
+ if (__timerId < 0) {
+ _E("Setting timer failed");
+ __timerInterval = INT_MAX;
+ return false;
+ }
+
+ return true;
+}
+
+void HeartRateLogger::stop()
+{
+ _I(GREEN("Stop recording"));
+
+ if (__timerMgr)
+ delete __timerMgr;
+
+ __timerMgr = NULL;
+ __timerId = -1;
+ __timerInterval = INT_MAX;
+
+ unlisten();
+}
+
+void HeartRateLogger::flushCache(bool force)
+{
+}
+
+bool HeartRateLogger::onTimerExpired(int timerId)
+{
+ IF_FAIL_RETURN(!isRunning(), true);
+
+ if (!listen())
+ _W("Starting sensor failed");
+
+ __expiredTime = TimeUtil::getTime();
+ _I("Measuring starts at %llu", __expiredTime);
+ return true;
+}
+
+void HeartRateLogger::onEvent(sensor_data_t *eventData)
+{
+ static int validCnt = 0;
+ uint64_t receivedTime = TimeUtil::getTime();
+
+ IF_FAIL_CATCH_TAG(receivedTime - __expiredTime < MEASURING_LIMIT, _I, "Measuring failed (timeout)");
+
+ if (eventData->values[0] > VALID_HR_LB)
+ ++validCnt;
+ else
+ validCnt = 0;
+
+ if (validCnt < MIN_VALID_COUNT)
+ return;
+
+ __record(eventData->values[0], receivedTime);
+
+CATCH:
+ removeExpired(SUBJ_SENSOR_HEART_RATE, HEART_RATE_RECORD, KEY_UNIV_TIME);
+ unlisten();
+}
+
+void HeartRateLogger::__record(float heartrate, uint64_t eventTime)
+{
+ char *query = sqlite3_mprintf(
+ "INSERT INTO " HEART_RATE_RECORD \
+ " (" KEY_UNIV_TIME ", " KEY_HEART_RATE ") VALUES (%llu, %.3f)",
+ eventTime, heartrate);
+ executeQuery(query);
+ sqlite3_free(query);
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_HEARTRATE_LOGGER_H__
+#define __CONTEXT_HEARTRATE_LOGGER_H__
+
+#include <TimerManager.h>
+#include "../SensorLogger.h"
+#include "../SensorProxy.h"
+
+namespace ctx {
+
+ class HeartRateLogger : public SensorLogger, public SensorProxy, public ITimerListener {
+ public:
+ HeartRateLogger();
+ ~HeartRateLogger();
+
+ bool start();
+ void stop();
+ void flushCache(bool force = false);
+
+ protected:
+ bool onTimerExpired(int timerId);
+ void onEvent(sensor_data_t *eventData);
+
+ private:
+ void __record(float heartrate, uint64_t eventTime);
+
+ TimerManager *__timerMgr;
+ int __timerId;
+ int __timerInterval;
+ uint64_t __expiredTime;
+ };
+}
+
+#endif /* __CONTEXT_HEARTRATE_LOGGER_H__ */
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sqlite3.h>
+#include <SensorRecorderTypes.h>
+#include "../TypesInternal.h"
+#include "HeartRateQuerier.h"
+
+#define PROJECTION \
+ KEY_HEART_RATE ", " \
+ KEY_UNIV_TIME " AS " KEY_START_TIME ", " \
+ KEY_UNIV_TIME " AS " KEY_END_TIME
+
+using namespace ctx;
+
+HeartRateQuerier::HeartRateQuerier(ContextProvider *provider, Json option) :
+ Querier(provider, option)
+{
+}
+
+HeartRateQuerier::~HeartRateQuerier()
+{
+}
+
+int HeartRateQuerier::queryRaw(int startTime, int endTime)
+{
+ return query(startTime, endTime);
+}
+
+int HeartRateQuerier::query(int startTime, int endTime)
+{
+ char *sql = sqlite3_mprintf(
+ "SELECT " PROJECTION \
+ " FROM " HEART_RATE_RECORD \
+ " WHERE " KEY_UNIV_TIME " > %llu AND " KEY_UNIV_TIME " <= %llu",
+ SEC_TO_MS(static_cast<uint64_t>(startTime)), SEC_TO_MS(static_cast<uint64_t>(endTime)));
+
+ int ret = Querier::query(sql);
+ sqlite3_free(sql);
+
+ return ret;
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __CONTEXT_HEARTRATE_QUERIER_H__
+#define __CONTEXT_HEARTRATE_QUERIER_H__
+
+#include "../Querier.h"
+
+namespace ctx {
+
+ class HeartRateQuerier : public Querier {
+ public:
+ HeartRateQuerier(ContextProvider *provider, Json option);
+ ~HeartRateQuerier();
+
+ int queryRaw(int startTime, int endTime);
+ int query(int startTime, int endTime);
+ };
+}
+
+#endif /* __CONTEXT_HEARTRATE_QUERIER_H__ */