/* * Copyright (c) 2018 Samsung Electronics Co., Ltd. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License") * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include #include #include #include #include #include #include #define UA_MONITORING_TIME 60 /* Default: 60 seconds for scanning for device */ GSList *ua_monitor_list; static ua_monitor_h scanning_monitor = NULL; static int __ua_stop_monitoring(unsigned int bitmask, char *service, ua_detection_type_e detect) { FUNC_ENTRY; int ret; if (detect == UA_PRESENCE_DETECTION) { ret = _ua_get_error_code(_uam_stop_presence_detection(bitmask, service)); if (UA_ERROR_NONE != ret) { /* LCOV_EXCL_START */ UA_ERR("_ua_stop_presence_detection failed with %s(0x%X)", _ua_get_error_string(ret), ret); return ret; /* LCOV_EXCL_STOP */ } } else if (detect == UA_ABSENCE_DETECTION) { ret = _ua_get_error_code(_uam_stop_absence_detection(bitmask, service)); if (UA_ERROR_NONE != ret) { /* LCOV_EXCL_START */ UA_ERR("_ua_stop_presence_detection failed with %s(0x%X)", _ua_get_error_string(ret), ret); return ret; /* LCOV_EXCL_STOP */ } } else UA_ERR("invalid detection type"); FUNC_EXIT; return UA_ERROR_NONE; } static int __ua_start_monitoring(unsigned int bitmask, char *service, ua_detection_type_e detect) { FUNC_ENTRY; int ret; if (detect == UA_PRESENCE_DETECTION) { ret = _ua_get_error_code(_uam_start_presence_detection(bitmask, service)); if (UA_ERROR_NONE != ret) { /* LCOV_EXCL_START */ UA_ERR("_ua_start_presence_detection failed with %s(0x%X)", _ua_get_error_string(ret), ret); return ret; /* LCOV_EXCL_STOP */ } } else if (detect == UA_ABSENCE_DETECTION) { ret = _ua_get_error_code(_uam_start_absence_detection(bitmask, service)); if (UA_ERROR_NONE != ret) { /* LCOV_EXCL_START */ UA_ERR("_ua_start_absence_detection failed with %s(0x%X)", _ua_get_error_string(ret), ret); return ret; /* LCOV_EXCL_STOP */ } } else UA_ERR("invalid detection type"); FUNC_EXIT; return UA_ERROR_NONE; } static void __ua_monitor_internal_presence_ref(ua_monitor_s *monitor) { monitor->internal_presence_started++; } static void __ua_monitor_internal_presence_unref(ua_monitor_s *monitor) { monitor->internal_presence_started--; if (monitor->internal_presence_started < 0) monitor->internal_presence_started = 0; } static unsigned int __ua_sensor_type_to_bitmask(ua_sensor_e sensor_type) { FUNC_ENTRY; unsigned int bitmask; switch (sensor_type) { case UA_SENSOR_BT: bitmask = UAM_SENSOR_BITMASK_BT; break; /* LCOV_EXCL_START */ case UA_SENSOR_BLE: bitmask = UAM_SENSOR_BITMASK_BLE; break; /* LCOV_EXCL_STOP */ case UA_SENSOR_WIFI: bitmask = UAM_SENSOR_BITMASK_WIFI; break; /* LCOV_EXCL_START */ case UA_SENSOR_MOTION: bitmask = UAM_SENSOR_BITMASK_MOTION; break; case UA_SENSOR_LIGHT: bitmask = UAM_SENSOR_BITMASK_LIGHT; break; case UA_SENSOR_AUDIO: bitmask = UAM_SENSOR_BITMASK_AUDIO; break; case UA_SENSOR_ALL: bitmask = UAM_SENSOR_ALL; break; default: UA_WARN("Unsupported sensor [%d]", sensor_type); bitmask = 0x00; /* LCOV_EXCL_STOP */ } FUNC_EXIT; return bitmask; } static void __ua_free_user_state_info_t(gpointer data) { FUNC_ENTRY; ua_user_state_info_s *user_state = data; ret_if(NULL == user_state); g_free(user_state->account); g_slist_free(user_state->found_devices); g_free(user_state); FUNC_EXIT; } static void __ua_user_state_clean() { FUNC_ENTRY; GSList *l; for (l = ua_monitor_list; NULL != l; l = g_slist_next(l)) { ua_monitor_s *monitor = l->data; if (!monitor) continue; g_slist_free_full(monitor->user_state, __ua_free_user_state_info_t); monitor->user_state = NULL; monitor->env_user_cb_sent = FALSE; } FUNC_EXIT; } static bool __ua_check_all_users_absence_state(GSList *user_state, unsigned int bitmask) { FUNC_ENTRY; GSList *l; ua_user_state_info_s *u; if (0 == g_slist_length(user_state)) { UA_INFO("user_state is empty"); return false; } for (l = user_state; l; l = g_slist_next(l)) { u = (ua_user_state_info_s *)l->data; if (u->sensor_bitmask & bitmask) { UA_INFO("User found [%s]", u->account); return false; } } return true; } static ua_user_state_info_s* __ua_monitor_user_state_create(char *account) { ua_user_state_info_s *user_state; user_state = g_malloc0(sizeof(ua_user_state_info_s)); if (!user_state) { UA_ERR("g_malloc0 failed"); return NULL; } user_state->account = g_strdup(account); if (user_state->account == NULL) { UA_ERR("g_malloc0 failed"); __ua_free_user_state_info_t((gpointer)user_state); return NULL; } return user_state; } static gboolean __ua_monitor_check_presence_and_or_condition(ua_monitor_s *monitor, unsigned int connectivity_bitmask) { FUNC_ENTRY; unsigned int env_presence_bitmask = 0; gboolean and_condition = 0; gboolean or_condition = 0; gboolean condition_result = 0; env_presence_bitmask = monitor->presence_detected_bitmask & (UA_SENSOR_MOTION | UA_SENSOR_LIGHT); UA_DBG("Bitmasks: user's sensor [%u], env_pres [%u], " \ "conditions: AND [%u] - OR [%u]", connectivity_bitmask , env_presence_bitmask, monitor->presence_bitmask_and, monitor->presence_bitmask_or); and_condition = monitor->presence_bitmask_and == (monitor->presence_bitmask_and & (connectivity_bitmask | env_presence_bitmask)); or_condition = !monitor->presence_bitmask_or || (monitor->presence_bitmask_or & (connectivity_bitmask | env_presence_bitmask)); UA_DBG("Conditions': AND[%s] [%s] OR[%s]", and_condition ? "true" : "false", monitor->presence_conjunction == UA_OR_OPERATION ? "or" : "and", or_condition ? "true" : "false"); if (monitor->presence_bitmask_and == 0 || monitor->presence_bitmask_or == 0) condition_result = monitor->presence_bitmask_and ? and_condition : or_condition; else if (monitor->presence_conjunction == UA_OR_OPERATION) condition_result = and_condition || or_condition; else condition_result = and_condition && or_condition; if (!condition_result) { UA_DBG("User presence AND/OR conditions failed"); } FUNC_EXIT; return condition_result; } static void __ua_monitor_send_user_presence_cb(ua_monitor_s *monitor, ua_user_state_info_s *user_state) { FUNC_ENTRY; unsigned int env_bitmask = 0; unsigned int filter_bitmask = 0; unsigned int dev_bitmask = 0; GSList *l = 0; GSList *devices = 0; ua_dev_info_s *dev = 0; GSList *sensors = 0; gboolean condition_result = 0; ret_if(NULL == user_state); /** Block user callback if environmental callback already sent*/ if (monitor->env_user_cb_sent) { UA_DBG("Environmental User presence cb already sent"); FUNC_EXIT; return; } ua_user_h user_handle = _ua_get_user_handle_by_account( user_state->account); /** * Check whether user_handle present or not and also check * whether presence has been started or not. */ if (!user_handle || user_state->cb_sent || !monitor->presence_user_cb.callback || !monitor->presence_detection_started) { FUNC_EXIT; return; } /** Check AND/OR condition*/ if (user_state->sensor_bitmask) condition_result = __ua_monitor_check_presence_and_or_condition(monitor, user_state->sensor_bitmask); if (!condition_result) { UA_DBG("User presence AND/OR conditions failed"); FUNC_EXIT; return; } env_bitmask = monitor->presence_detected_bitmask & (UA_SENSOR_MOTION | UA_SENSOR_LIGHT); /** * Filter the list of found_devices according to sensors mentioned in * AND/OR conditions. */ filter_bitmask = monitor->presence_bitmask_and | monitor->presence_bitmask_or; for (l = user_state->found_devices; l; l = g_slist_next(l)) { dev = (ua_dev_info_s *)l->data; if(!dev) continue; UA_DBG("device id [%s], dev type [%u]", dev->device_id, dev->type); dev_bitmask = _ua_dev_type_to_sensor(dev->type); if (dev_bitmask & filter_bitmask) devices = g_slist_prepend(devices, dev); } /** Get sensor list*/ sensors = ua_sensor_get_sensor_handle_list( monitor->presence_detected_bitmask & (user_state->sensor_bitmask | env_bitmask) & filter_bitmask); ((ua_presence_user_detected_cb)monitor->presence_user_cb.callback)( UA_ERROR_NONE, monitor, user_handle, devices, sensors, monitor->presence_user_cb.user_data); user_state->cb_sent = TRUE; monitor->env_user_cb_sent = TRUE; g_slist_free(devices); g_slist_free(sensors); FUNC_EXIT; return; } static void __ua_monitor_send_env_user_presence_cb(ua_monitor_s *monitor) { FUNC_ENTRY; GSList *sensors = 0; gboolean condition_result = 0; unsigned int filter_bitmask = 0; if (monitor->env_user_cb_sent) { UA_DBG("Environmental User presence cb already sent"); FUNC_EXIT; return; } /** Check AND/OR condition*/ condition_result = __ua_monitor_check_presence_and_or_condition(monitor, 0); if (!condition_result) { UA_DBG("presence AND/OR conditions failed"); FUNC_EXIT; return; } /** Get sensor list*/ filter_bitmask = monitor->presence_bitmask_and | monitor->presence_bitmask_or; sensors = ua_sensor_get_sensor_handle_list(monitor->presence_detected_bitmask & filter_bitmask); if (monitor->presence_user_cb.callback) { ((ua_presence_user_detected_cb)monitor->presence_user_cb.callback)( UA_ERROR_NONE, monitor, NULL, NULL, sensors, monitor->presence_user_cb.user_data); monitor->env_user_cb_sent = TRUE; } g_slist_free(sensors); FUNC_EXIT; return; } static void __ua_send_presence_detection() { FUNC_ENTRY; GSList *l; GSList *l1; for (l = ua_monitor_list; NULL != l; l = g_slist_next(l)) { ua_monitor_s *monitor = l->data; if (!monitor) continue; if (monitor->presence_mode != UA_DETECT_MODE_ANY_SENSOR) { UA_INFO("monitor->sensor_bitmask: 0x%8.8X, monitor->presence_detected_bitmask: 0x%8.8X", monitor->sensor_bitmask, monitor->presence_detected_bitmask); if (monitor->sensor_bitmask == monitor->presence_detected_bitmask) { if (monitor->presence_cb) monitor->presence_cb(UA_ERROR_NONE, monitor, monitor->presence_detected_bitmask, NULL, NULL, monitor->user_data); } } if (monitor->presence_user_cb.callback) { __ua_monitor_send_env_user_presence_cb(monitor); for (l1 = monitor->user_state; NULL != l1; l1 = g_slist_next(l1)) { ua_user_state_info_s *user_state = l1->data; if (user_state) { UA_DBG("user_state->account [%s]", user_state->account); __ua_monitor_send_user_presence_cb(monitor, user_state); } } } monitor->presence_detected_bitmask = 0; } FUNC_EXIT; } static void __ua_monitor_send_sensor_presence_cb(ua_monitor_s *monitor, ua_device_h device_handle, ua_sensor_info_s *sensor_info) { FUNC_ENTRY; ua_sensor_e bitmask = sensor_info->bitmask; ua_sensor_h sensor_handle; int ret; ret = ua_sensor_get_by_sensor_info(sensor_info, &sensor_handle); if (UA_ERROR_NONE != ret) { UA_INFO("ua_sensor_get_by_sensor_info returned %s", _ua_get_error_string(ret)); } switch (monitor->presence_mode) { case UA_DETECT_MODE_ALL_SENSOR: /* * Sends presence if it is detected by all sensors irrespective of device/user i.e if * presence will be detected by device 1 for sensor 1 and by device 2 for sensor 2 then * send presence detection callback to application. This will make sure that each sensor is * detected at least one device from registered devices list. */ if (((bitmask == UA_SENSOR_BLE) && (monitor->sensor_bitmask & UA_SENSOR_WIFI)) || ((bitmask == UA_SENSOR_WIFI) && (monitor->sensor_bitmask & UA_SENSOR_BLE))) monitor->presence_detected_bitmask |= (UA_SENSOR_BLE | UA_SENSOR_WIFI); else monitor->presence_detected_bitmask |= bitmask; UA_INFO("UA_DETECT_MODE_ALL_SENSOR [%d][%d]", bitmask, monitor->presence_detected_bitmask); break; case UA_DETECT_MODE_ANY_SENSOR: if ((monitor->presence_detected_bitmask & bitmask) == 0) if (monitor->presence_cb) monitor->presence_cb(UA_ERROR_NONE, monitor, bitmask, device_handle, sensor_handle, monitor->user_data); monitor->presence_detected_bitmask |= bitmask; UA_INFO("UA_DETECT_MODE_ANY_SENSOR [%d][%d]", bitmask, monitor->presence_detected_bitmask); break; default: UA_WARN("Unexpected detection mode: %d", monitor->presence_mode); } FUNC_EXIT; return; } static void __ua_sensor_presence_detected(ua_monitor_s *monitor, ua_sensor_info_s *sensor_info, char *account, unsigned long long timestamp, char *device_id) { FUNC_ENTRY; GSList *l; GSList *l1; int found = 0; int ret = UA_ERROR_NONE; ua_user_state_info_s *user_state = NULL; ua_device_h device_handle = NULL; ua_sensor_e bitmask = sensor_info->bitmask; ret_if(NULL == monitor); if (account) { for (l = monitor->user_state; l; l = g_slist_next(l)) { user_state = (ua_user_state_info_s *)l->data; UA_DBG("user_state->account [%s] account [%s]", user_state->account, account); if (!g_strcmp0(account, user_state->account)) { UA_DBG("Found!!"); found = 1; break; } } if (!found) { user_state = __ua_monitor_user_state_create(account); if (!user_state) { UA_WARN("user_state is invalid"); return; } monitor->user_state = g_slist_append(monitor->user_state, user_state); } user_state->sensor_bitmask |= bitmask; ret = ua_device_get_by_device_id(device_id, bitmask, &device_handle); UA_INFO("ua_device_get_by_device_id returned %s", _ua_get_error_string(ret)); if (device_handle) user_state->found_devices = g_slist_prepend(user_state->found_devices, device_handle); ua_user_h user_handle = _ua_get_user_handle_by_account(user_state->account); _ua_set_user_last_presence_timestamp(user_handle, timestamp); } if (!monitor->presence_detection_started) { FUNC_EXIT; return; } __ua_monitor_send_sensor_presence_cb(monitor, device_handle, sensor_info); if (account && user_state) { __ua_monitor_send_user_presence_cb(monitor, user_state); } if (!account) { __ua_monitor_send_env_user_presence_cb(monitor); for (l1 = monitor->user_state; NULL != l1; l1 = g_slist_next(l1)) { ua_user_state_info_s *user_state = l1->data; if (user_state) { UA_DBG("user_state->account [%s]", user_state->account); __ua_monitor_send_user_presence_cb(monitor, user_state); } } } FUNC_EXIT; } static void __ua_monitor_send_user_absence_cb(ua_monitor_s *monitor, ua_user_state_info_s *user_state) { FUNC_ENTRY; unsigned int env_absence_bitmask = 0; unsigned int filter_bitmask = 0; unsigned int user_sensor_bitmask = user_state->sensor_bitmask; gboolean and_condition = 0; gboolean or_condition = 0; gboolean condition_result = 0; GSList *sensors = 0; ua_user_h user_handle = _ua_get_user_handle_by_account( user_state->account); /** * Check whether user_handle present or not and also check * whether presence has been started or not. */ if (!user_handle || !monitor->absence_detection_started) { FUNC_EXIT; return; } /** * user_sensor_bitmask provides number of detected sensors, * so we need to invert the user_sensor_bitmask to calculate absence. */ user_sensor_bitmask = ~user_sensor_bitmask & (UA_SENSOR_BT | UA_SENSOR_BLE | UA_SENSOR_WIFI); env_absence_bitmask = monitor->absence_detected_bitmask & (UA_SENSOR_MOTION | UA_SENSOR_LIGHT); UA_DBG("Bitmasks: user's sensor(absence) [%u], env_absence [%u], " \ "conditions: AND [%u] - OR [%u]", user_sensor_bitmask, env_absence_bitmask, monitor->absence_bitmask_and, monitor->absence_bitmask_or); and_condition = monitor->absence_bitmask_and == (monitor->absence_bitmask_and & (user_sensor_bitmask | env_absence_bitmask)); or_condition = !monitor->absence_bitmask_or || (monitor->absence_bitmask_or & (user_sensor_bitmask | env_absence_bitmask)); UA_DBG("Conditions': AND[%s] [%s] OR[%s]", and_condition ? "true" : "false", monitor->absence_conjunction == UA_OR_OPERATION ? "or" : "and", or_condition ? "true" : "false"); if (monitor->absence_bitmask_and == 0 || monitor->absence_bitmask_or == 0) condition_result = monitor->absence_bitmask_and ? and_condition : or_condition; else if (monitor->absence_conjunction == UA_OR_OPERATION) condition_result = and_condition || or_condition; else condition_result = and_condition && or_condition; if (!condition_result) { UA_DBG("User absence AND/OR conditions failed"); FUNC_EXIT; return; } /** Get sensor list*/ filter_bitmask = monitor->absence_bitmask_and | monitor->absence_bitmask_or; sensors = ua_sensor_get_sensor_handle_list( monitor->absence_detected_bitmask & (user_sensor_bitmask | env_absence_bitmask) & filter_bitmask); ((ua_absence_user_detected_cb)monitor->absence_user_cb.callback)( UA_ERROR_NONE, monitor, user_handle, sensors, monitor->absence_user_cb.user_data); FUNC_EXIT; return; } static void __ua_send_absence_detection() { FUNC_ENTRY; GSList *l; GSList *l1; for (l = ua_monitor_list; NULL != l; l = g_slist_next(l)) { ua_monitor_s *monitor = l->data; if (!monitor) continue; UA_INFO("monitor->sensor_bitmask: 0x%8.8X, monitor->absence_detected_bitmask: 0x%8.8X", monitor->sensor_bitmask, monitor->absence_detected_bitmask); if (monitor->absence_mode == UA_DETECT_MODE_ALL_SENSOR) { if (monitor->sensor_bitmask & UA_SENSOR_BLE) { if (__ua_check_all_users_absence_state(monitor->user_state, UA_SENSOR_BLE)) monitor->absence_detected_bitmask |= UA_SENSOR_BLE; } if (monitor->sensor_bitmask & UA_SENSOR_WIFI) { if (__ua_check_all_users_absence_state(monitor->user_state, UA_SENSOR_WIFI)) monitor->absence_detected_bitmask |= UA_SENSOR_WIFI; } UA_INFO("monitor->sensor_bitmask: 0x%8.8X, monitor->absence_detected_bitmask: 0x%8.8X", monitor->sensor_bitmask, monitor->absence_detected_bitmask); if (monitor->sensor_bitmask == monitor->absence_detected_bitmask) { if (monitor->absence_cb) monitor->absence_cb(UA_ERROR_NONE, monitor, monitor->absence_detected_bitmask, NULL, monitor->user_data); } } if (monitor->absence_user_cb.callback) { for (l1 = monitor->user_state; NULL != l1; l1 = g_slist_next(l1)) { ua_user_state_info_s *user_state = l1->data; UA_INFO("Scanning user list..."); if (user_state) __ua_monitor_send_user_absence_cb(monitor, user_state); } } monitor->absence_detected_bitmask = 0; } FUNC_EXIT; } static void __ua_sensor_absence_detected(ua_monitor_s *monitor, ua_sensor_info_s *sensor_info, char *account) { FUNC_ENTRY; bool all_absence; GSList *l; int ret = UA_ERROR_NONE; int found = 0; ua_user_state_info_s *user_state = NULL; ua_sensor_e bitmask = sensor_info->bitmask; ret_if(NULL == monitor); ua_sensor_h sensor_handle; if (account) { for (l = monitor->user_state; l; l = g_slist_next(l)) { user_state = (ua_user_state_info_s *)l->data; if (!g_strcmp0(account, user_state->account)) { found = 1; break; } } if (!found) { user_state = __ua_monitor_user_state_create(account); if (!user_state) return; monitor->user_state = g_slist_append(monitor->user_state, user_state); } user_state->sensor_bitmask &= ~bitmask; } else { monitor->absence_detected_bitmask |= bitmask; } ret = ua_sensor_get_by_sensor_info(sensor_info, &sensor_handle); if (UA_ERROR_NONE != ret) { UA_INFO("ua_sensor_get_by_sensor_info returned %s", _ua_get_error_string(ret)); } switch (monitor->absence_mode) { case UA_DETECT_MODE_ALL_SENSOR: break; case UA_DETECT_MODE_ANY_SENSOR: /* First add user info to local users list and then invoke callback */ if (account) { all_absence = __ua_check_all_users_absence_state(monitor->user_state, bitmask); if (all_absence) { if (monitor->absence_cb) monitor->absence_cb(UA_ERROR_NONE, monitor, bitmask, sensor_handle, monitor->user_data); } } else { if (monitor->absence_cb) monitor->absence_cb(UA_ERROR_NONE, monitor, bitmask, sensor_handle, monitor->user_data); } break; default: UA_WARN("Unexpected detection mode: %d", monitor->absence_mode); } FUNC_EXIT; } void _ua_monitor_handle_scanned_device(int result, uam_device_info_s *uam_info) { FUNC_ENTRY; ua_dev_info_s *dev = NULL; ua_monitor_s *monitor = scanning_monitor; result = _ua_get_error_code(result); if (UA_ERROR_NONE != result) return; UA_INFO("Mobile id[%s] Mac[%s]", uam_info->device_id, uam_info->mac); dev = _ua_get_device_info_from_uam(uam_info); if (dev == NULL) { UA_WARN("Unexpected, cannot find uam_device"); return; } if (monitor && monitor->scan_device_cb) { ((ua_scan_completed_cb)monitor->scan_device_cb)( UA_ACTIVE_SCAN_TYPE_DEVICE_FOUND, monitor, dev, monitor->user_data); UA_PRINT_DEVICE_HANDLE(dev); UA_INFO("Invoked scan_device_cb callback"); } else { UA_WARN("Unexpected, scan started but callbacks are NULL"); } _ua_free_ua_device_info_t((gpointer)dev); FUNC_EXIT; } void _ua_monitor_handle_scan_complete(int result) { FUNC_ENTRY; ua_monitor_s *monitor = scanning_monitor; result = _ua_get_error_code(result); if (UA_ERROR_NONE != result) return; if (monitor && monitor->scan_device_cb) { ((ua_scan_completed_cb)monitor->scan_device_cb)( UA_ACTIVE_SCAN_TYPE_COMPLETED, monitor, NULL, monitor->user_data); UA_INFO("Invoked scan_device_cb callback"); /* Reset callback when scan complete*/ monitor->scan_device_cb = NULL; monitor->user_data = NULL; monitor->scan_device_started = FALSE; scanning_monitor = NULL; } else { UA_WARN("Unexpected, scan running but callbacks are NULL"); } FUNC_EXIT; } void _ua_monitor_handle_user_presence_detected(uam_sensor_info_s *info, char *service, char *account, unsigned long long timestamp, char *device_id) { FUNC_ENTRY; GSList *l; ua_sensor_info_s *sensor_info; ua_sensor_e bitmask; ret_if(NULL == info); sensor_info = _uam_to_ua_sensor_info(info); ret_if(NULL == sensor_info); bitmask = sensor_info->bitmask; for (l = ua_monitor_list; l; l = g_slist_next(l)) { ua_monitor_s *monitor = l->data; if (!monitor || (!monitor->presence_detection_started && !monitor->internal_presence_started)) continue; if (0 == (bitmask & monitor->sensor_bitmask)) continue; if (!service || !g_strcmp0(service, monitor->service)) { /* Presence detection ongoing */ __ua_sensor_presence_detected(monitor, sensor_info, account, timestamp, device_id); } } _ua_free_sensor_info(sensor_info); FUNC_EXIT; } void _ua_monitor_handle_user_absence_detected(uam_sensor_info_s *info, char *service, char *account) { FUNC_ENTRY; GSList *l; ua_sensor_info_s *sensor_info; ua_sensor_e bitmask; ret_if(NULL == info); sensor_info = _uam_to_ua_sensor_info(info); ret_if(NULL == sensor_info); bitmask = sensor_info->bitmask; for (l = ua_monitor_list; l; l = g_slist_next(l)) { ua_monitor_s *monitor = l->data; if (!monitor || !monitor->absence_detection_started) continue; if (0 == (bitmask & monitor->sensor_bitmask)) continue; if (!service || !g_strcmp0(service, monitor->service)) { /* Absence detection ongoing */ __ua_sensor_absence_detected(monitor, sensor_info, account); } } _ua_free_sensor_info(sensor_info); FUNC_EXIT; } void _ua_monitor_handle_detection_stopped() { FUNC_ENTRY; __ua_send_presence_detection(); __ua_send_absence_detection(); __ua_user_state_clean(); FUNC_EXIT; } #if 0 static void __ua_remove_sensor(ua_monitor_s *monitor, ua_sensor_e sensor_type) { FUNC_ENTRY; int ret; int is_presence = 0; int is_absence = 0; void *presence_callback = NULL; void *presence_user_data = NULL; void *absence_callback = NULL; void *absence_user_data = NULL; ua_detection_mode_e mode_presence; ua_detection_mode_e mode_absence; if (monitor->presence_detection_started) { /* Stop detection first */ if (monitor->presence_cb) { /* Presence detection ongoing */ presence_callback = monitor->presence_cb; presence_user_data = monitor->user_data; mode_presence = monitor->presence_mode; ret = ua_monitor_stop_presence_detection(monitor); UA_INFO("ua_monitor_stop_presence_detection returned %s", _ua_get_error_string(ret)); is_presence = 1; } else { UA_WARN("Unexpected, detection started but cbs are NULL"); } } if (monitor->absence_detection_started) { /* Stop detection first */ if (monitor->absence_cb) { /* absence detection ongoing */ absence_callback = monitor->absence_cb; absence_user_data = monitor->user_data; mode_absence = monitor->absence_mode; ret = ua_monitor_stop_presence_detection(monitor); UA_INFO("ua_monitor_stop_presence_detection returned %s", _ua_get_error_string(ret)); is_absence = 1; } else { UA_WARN("Unexpected, detection started but cbs are NULL"); } } if (is_presence || is_absence) { ret = ua_monitor_remove_sensor(monitor, sensor_type); UA_INFO("ua_monitor_remove_sensor returned %s", _ua_get_error_string(ret)); } if (0 != monitor->sensor_bitmask) { if (is_presence) { ret = ua_monitor_start_presence_detection( monitor, monitor->service, mode_presence, presence_callback, presence_user_data); UA_INFO("ua_monitor_start_presence_detection returned %s", _ua_get_error_string(ret)); } if (is_absence) { ret = ua_monitor_start_absence_detection( monitor, monitor->service, mode_absence, absence_callback, absence_user_data); UA_INFO("ua_monitor_start_absence_detection returned %s", _ua_get_error_string(ret)); } } if (!is_presence && !is_absence) { /* Monitoring is already stopped, just remove sensor from monitor */ ret = ua_monitor_remove_sensor(monitor, sensor_type); UA_INFO("ua_monitor_remove_sensor returned %s", _ua_get_error_string(ret)); } FUNC_EXIT; } #endif void _ua_monitor_handle_sensor_state(unsigned int bitmask, gboolean ready) { FUNC_ENTRY; ua_sensor_e sensor_type; GSList *l; sensor_type = _uam_to_ua_sensor(bitmask); for (l = ua_monitor_list; l; l = g_slist_next(l)) { ua_monitor_s *monitor = l->data; if (!monitor) continue; if (monitor->sensor_state_cb.callback) ((ua_monitor_sensor_state_changed_cb)monitor->sensor_state_cb.callback)( (bool)ready, sensor_type, (ua_monitor_h)monitor, monitor->sensor_state_cb.user_data); } FUNC_EXIT; } void _ua_monitor_handle_sensor_status_changed(uam_sensor_info_s *info) { FUNC_ENTRY; int ret; GSList *l; ua_sensor_h dummy; ua_sensor_info_s *sensor_info; ret_if(NULL == info); sensor_info = _uam_to_ua_sensor_info(info); ret_if(NULL == sensor_info); ret = ua_sensor_get_by_sensor_info(sensor_info, &dummy); if (UA_ERROR_NONE != ret) { UA_INFO("ua_sensor_get_by_sensor_info returned %s", _ua_get_error_string(ret)); } UA_INFO("sensor which state has changed [%x]", sensor_info->bitmask); for (l = ua_monitor_list; l; l = g_slist_next(l)) { ua_monitor_s *monitor = l->data; if (!monitor) { UA_WARN("skip!! monitor is null"); continue; } if (!monitor->presence_detection_started) { UA_WARN("skip!! because detection does not start [%x]", monitor->sensor_bitmask); continue; } if (0 == (sensor_info->bitmask & monitor->sensor_bitmask)) { UA_WARN("skip!! the reported sensor is not added [%x]", monitor->sensor_bitmask); continue; } if (monitor->sensor_status_cb.callback) ((ua_sensor_status_changed_cb)monitor->sensor_status_cb.callback)( (ua_monitor_h)monitor, (ua_sensor_h)sensor_info, monitor->sensor_state_cb.user_data); } _ua_free_sensor_info(sensor_info); FUNC_EXIT; } void _ua_free_ua_monitor_t(gpointer data) { FUNC_ENTRY; ua_monitor_s *monitor = data; ret_if(NULL == monitor); //TODO lk, where are these timers used? if (monitor->presence_detection_timer) { /* LCOV_EXCL_START */ g_source_remove(monitor->presence_detection_timer); monitor->presence_detection_timer = 0; /* LCOV_EXCL_STOP */ } if (monitor->absence_detection_timer) { /* LCOV_EXCL_START */ g_source_remove(monitor->absence_detection_timer); monitor->absence_detection_timer = 0; /* LCOV_EXCL_STOP */ } /* One monitor can observe only one service. */ g_free(monitor->service); /* Free user-state information */ g_slist_free_full(monitor->user_state, __ua_free_user_state_info_t); g_free(monitor); FUNC_EXIT; } int ua_monitor_is_sensor_available( ua_sensor_e sensor, bool *available ) { FUNC_ENTRY; unsigned int available_sensors = 0; int ret; unsigned int bitmask; UA_VALIDATE_INPUT_PARAMETER(available); bitmask = __ua_sensor_type_to_bitmask(sensor); retv_if(!bitmask, UA_ERROR_INVALID_PARAMETER); ret = _ua_get_error_code(_uam_get_available_sensors(&available_sensors)); if (UA_ERROR_NONE != ret) { /* LCOV_EXCL_START */ UA_ERR("_uam_get_available_sensors failed"); return ret; /* LCOV_EXCL_STOP */ } if (0 == (available_sensors & bitmask)) *available = false; // LCOV_EXCL_LINE else *available = true; FUNC_EXIT; return UA_ERROR_NONE; } int ua_set_app_info(const char *app_id, unsigned short uid) { FUNC_ENTRY; UA_VALIDATE_INPUT_PARAMETER(app_id); int ret = _ua_get_error_code(_uam_register_app(app_id, uid)); if (UA_ERROR_NONE != ret) { /* LCOV_EXCL_START */ UA_ERR("_uam_register_app failed"); return ret; /* LCOV_EXCL_STOP */ } FUNC_EXIT; return UA_ERROR_NONE; } int ua_unset_app_info(const char *app_id, unsigned short uid) { FUNC_ENTRY; UA_VALIDATE_INPUT_PARAMETER(app_id); int ret = _ua_get_error_code(_uam_deregister_app(app_id, uid)); if (UA_ERROR_NONE != ret) { /* LCOV_EXCL_START */ UA_ERR("_uam_deregister_app failed"); return ret; /* LCOV_EXCL_STOP */ } FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_create(ua_monitor_h *handle) { FUNC_ENTRY; ua_monitor_s *monitor = NULL; unsigned int available_sensors = 0; UA_VALIDATE_INPUT_PARAMETER(handle); monitor = g_malloc0(sizeof(ua_monitor_s)); if (!monitor) { /* LCOV_EXCL_START */ UA_ERR("g_malloc0 failed"); return UA_ERROR_OUT_OF_MEMORY; /* LCOV_EXCL_STOP */ } /* Add monitor to list of monitors */ ua_monitor_list = g_slist_append(ua_monitor_list, monitor); _uam_get_available_sensors(&available_sensors); monitor->presence_bitmask_and = 0; monitor->presence_bitmask_or = (available_sensors & UA_SENSOR_BLE) | (available_sensors & UA_SENSOR_WIFI); monitor->absence_bitmask_and = (available_sensors & UA_SENSOR_BLE) | (available_sensors & UA_SENSOR_WIFI); monitor->absence_bitmask_or = 0; *handle = (ua_monitor_h)monitor; FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_destroy(ua_monitor_h handle) { FUNC_ENTRY; ua_monitor_s *monitor = (ua_monitor_s *)handle; UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); ua_monitor_list = g_slist_remove(ua_monitor_list, monitor); _ua_free_ua_monitor_t(monitor); FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_set_sensor_state_cb(ua_monitor_h handle, ua_monitor_sensor_state_changed_cb callback, void *user_data) { FUNC_ENTRY; ua_monitor_s *monitor = (ua_monitor_s *)handle; UA_VALIDATE_INPUT_PARAMETER(callback); UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); monitor->sensor_state_cb.callback = callback; monitor->sensor_state_cb.user_data = user_data; FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_unset_sensor_state_cb(ua_monitor_h handle) { FUNC_ENTRY; ua_monitor_s *monitor = (ua_monitor_s *)handle; UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); monitor->sensor_state_cb.callback = NULL; monitor->sensor_state_cb.user_data = NULL; FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_set_user_absence_detected_cb(ua_monitor_h handle, ua_absence_user_detected_cb callback, void *user_data) { FUNC_ENTRY; ua_monitor_s *monitor = (ua_monitor_s *)handle; UA_VALIDATE_INPUT_PARAMETER(callback); UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); if (monitor->absence_user_cb.callback != NULL) { FUNC_EXIT; return UA_ERROR_INVALID_PARAMETER; } monitor->absence_user_cb.callback = callback; monitor->absence_user_cb.user_data = user_data; if (monitor->absence_detection_started && !monitor->internal_presence_started && !monitor->presence_detection_started) __ua_start_monitoring(monitor->sensor_bitmask, monitor->service, UA_PRESENCE_DETECTION); __ua_monitor_internal_presence_ref(monitor); FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_set_user_presence_detected_cb(ua_monitor_h handle, ua_presence_user_detected_cb callback, void *user_data) { FUNC_ENTRY; ua_monitor_s *monitor = (ua_monitor_s *)handle; UA_VALIDATE_INPUT_PARAMETER(callback); UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); monitor->presence_user_cb.callback = callback; monitor->presence_user_cb.user_data = user_data; FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_unset_user_absence_detected_cb(ua_monitor_h handle) { FUNC_ENTRY; ua_monitor_s *monitor = (ua_monitor_s *)handle; UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); if (monitor->absence_user_cb.callback == NULL) { FUNC_EXIT; return UA_ERROR_NONE; } monitor->absence_user_cb.callback = NULL; monitor->absence_user_cb.user_data = NULL; __ua_monitor_internal_presence_unref(monitor); if (!monitor->internal_presence_started && !monitor->presence_detection_started) __ua_stop_monitoring(monitor->sensor_bitmask, monitor->service, UA_PRESENCE_DETECTION); FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_unset_user_presence_detected_cb(ua_monitor_h handle) { FUNC_ENTRY; ua_monitor_s *monitor = (ua_monitor_s *)handle; UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); monitor->presence_user_cb.callback = NULL; monitor->presence_user_cb.user_data = NULL; FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_set_user_presence_condition( ua_monitor_h handle, unsigned int bitmask_and, unsigned int bitmask_or, ua_condition_conjunction_e conjunction_op) { FUNC_ENTRY; ua_monitor_s *monitor = (ua_monitor_s *)handle; unsigned int available_sensors = 0; UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); retv_if(conjunction_op < UA_OR_OPERATION, UA_ERROR_INVALID_PARAMETER); retv_if(conjunction_op > UA_AND_OPERATION, UA_ERROR_INVALID_PARAMETER); if (bitmask_and & bitmask_or) { UA_ERR("AND/OR bitmask same"); FUNC_EXIT; return UA_ERROR_INVALID_PARAMETER; } if (!(bitmask_and | bitmask_or)) { UA_ERR("Both of AND/OR bitmask are zero"); FUNC_EXIT; return UA_ERROR_INVALID_PARAMETER; } _uam_get_available_sensors(&available_sensors); if (bitmask_and != (available_sensors & bitmask_and)) { UA_ERR("AND bitmask out of range"); FUNC_EXIT; return UA_ERROR_INVALID_PARAMETER; } if (bitmask_or != (available_sensors & bitmask_or)) { UA_ERR("OR bitmask out of range"); FUNC_EXIT; return UA_ERROR_INVALID_PARAMETER; } monitor->presence_bitmask_and = bitmask_and; monitor->presence_bitmask_or = bitmask_or; monitor->presence_conjunction = conjunction_op; FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_set_user_absence_condition( ua_monitor_h handle, unsigned int bitmask_and, unsigned int bitmask_or, ua_condition_conjunction_e conjunction_op) { FUNC_ENTRY; ua_monitor_s *monitor = (ua_monitor_s *)handle; unsigned int available_sensors = 0; UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); retv_if(conjunction_op < UA_OR_OPERATION, UA_ERROR_INVALID_PARAMETER); retv_if(conjunction_op > UA_AND_OPERATION, UA_ERROR_INVALID_PARAMETER); if (bitmask_and & bitmask_or) { UA_ERR("AND/OR bitmask same"); FUNC_EXIT; return UA_ERROR_INVALID_PARAMETER; } if (!(bitmask_and | bitmask_or)) { UA_ERR("Both of AND/OR bitmask are zero"); FUNC_EXIT; return UA_ERROR_INVALID_PARAMETER; } _uam_get_available_sensors(&available_sensors); if (bitmask_and != (available_sensors & bitmask_and)) { UA_ERR("AND bitmask out of range"); FUNC_EXIT; return UA_ERROR_INVALID_PARAMETER; } if (bitmask_or != (available_sensors & bitmask_or)) { UA_ERR("OR bitmask out of range"); FUNC_EXIT; return UA_ERROR_INVALID_PARAMETER; } monitor->absence_bitmask_and = bitmask_and; monitor->absence_bitmask_or = bitmask_or; monitor->absence_conjunction = conjunction_op; FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_set_sensor_status_cb(ua_monitor_h handle, ua_sensor_status_changed_cb callback, void *user_data) { FUNC_ENTRY; ua_monitor_s *monitor = (ua_monitor_s *)handle; UA_VALIDATE_INPUT_PARAMETER(callback); UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); monitor->sensor_status_cb.callback = callback; monitor->sensor_status_cb.user_data = user_data; FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_unset_sensor_status_cb(ua_monitor_h handle) { FUNC_ENTRY; ua_monitor_s *monitor = (ua_monitor_s *)handle; UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); monitor->sensor_status_cb.callback = NULL; monitor->sensor_status_cb.user_data = NULL; FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_add_sensor( ua_monitor_h handle, ua_sensor_e sensor_type) { FUNC_ENTRY; ua_monitor_s *monitor = (ua_monitor_s *)handle; unsigned int bitmask; unsigned int available_sensors = 0; UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); bitmask = __ua_sensor_type_to_bitmask(sensor_type); retv_if(0 != (monitor->sensor_bitmask & bitmask), UA_ERROR_ALREADY_DONE); if (UA_ERROR_NONE != _ua_get_error_code( _uam_get_available_sensors(&available_sensors))) UA_WARN("_uam_get_available_sensors failed"); // LCOV_EXCL_LINE retv_if(0 == (available_sensors & bitmask), UA_ERROR_NOT_READY); monitor->sensor_bitmask |= bitmask; FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_remove_sensor( ua_monitor_h handle, ua_sensor_e sensor_type) { FUNC_ENTRY; ua_monitor_s *monitor = (ua_monitor_s *)handle; unsigned int bitmask; UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); bitmask = __ua_sensor_type_to_bitmask(sensor_type); retv_if(0 == (monitor->sensor_bitmask & bitmask), UA_ERROR_ALREADY_DONE); monitor->sensor_bitmask &= ~bitmask; FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_foreach_sensor( ua_monitor_h handle, ua_monitor_foreach_sensor_cb foreach_cb, void *user_data) { FUNC_ENTRY; ua_monitor_s *monitor = (ua_monitor_s *)handle; unsigned int bitmask; int sensor; UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_INPUT_PARAMETER(foreach_cb); UA_VALIDATE_HANDLE(handle, ua_monitor_list); bitmask = monitor->sensor_bitmask; for (sensor = UA_SENSOR_BT; sensor < UA_SENSOR_MAX; sensor <<= 1) { if (bitmask & sensor) { bitmask &= ~sensor; if (!foreach_cb(sensor, user_data)) break; } } FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_start_scan_devices( ua_monitor_h handle, int scan_time, ua_scan_completed_cb callback, void *user_data) { FUNC_ENTRY; int ret; ua_monitor_s *monitor = (ua_monitor_s *)handle; UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); UA_VALIDATE_INPUT_PARAMETER(callback); retv_if(scan_time <= 0, UA_ERROR_INVALID_PARAMETER); retv_if(scanning_monitor != NULL, UA_ERROR_NOT_PERMITTED); retv_if(TRUE == monitor->scan_device_started, UA_ERROR_NOW_IN_PROGRESS); retv_if(0 == monitor->sensor_bitmask, UA_ERROR_NO_DATA); scan_time *= UA_SCAN_TIME_MULTIPLIER; /* scan_time converted into seconds */ ret = _ua_get_error_code(_uam_start_search_active_devices(monitor->sensor_bitmask, scan_time)); if (UA_ERROR_NONE != ret) { /* LCOV_EXCL_START */ UA_ERR("Failed with error: %s(0x%X)", _ua_get_error_string(ret), ret); return ret; /* LCOV_EXCL_STOP */ } monitor->scan_device_cb = callback; monitor->user_data = user_data; monitor->scan_device_started = TRUE; scanning_monitor = monitor; FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_cancel_scan_devices(ua_monitor_h handle) { FUNC_ENTRY; int ret; ua_monitor_s *monitor = (ua_monitor_s *)handle; UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); retv_if(FALSE == monitor->scan_device_started, UA_ERROR_NOT_IN_PROGRESS); ret = _ua_get_error_code(_uam_stop_search_active_devices(monitor->sensor_bitmask)); if (UA_ERROR_NONE != ret) { /* LCOV_EXCL_START */ UA_ERR("Failed with error: %s(0x%X)", _ua_get_error_string(ret), ret); return ret; /* LCOV_EXCL_STOP */ } monitor->scan_device_cb = NULL; monitor->user_data = NULL; monitor->scan_device_started = FALSE; scanning_monitor = NULL; FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_start_presence_detection( ua_monitor_h handle, ua_service_h service_handle, ua_detection_mode_e mode, ua_presence_detected_cb callback, void *user_data) { FUNC_ENTRY; int ret; ua_monitor_s *monitor = (ua_monitor_s *)handle; ua_service_info_s *service_info = (ua_service_info_s *)service_handle; ua_detection_type_e detect = UA_PRESENCE_DETECTION; char *service; GSList *ua_services_list = _ua_service_get_services(); unsigned int available_sensors = 0; UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); retv_if(TRUE == monitor->presence_detection_started, UA_ERROR_NOW_IN_PROGRESS); if (service_handle) { UA_VALIDATE_HANDLE(service_handle, ua_services_list); service = g_strdup(service_info->name); } else service = NULL; if (monitor->service) if ((service && g_strcmp0(monitor->service, service)) || (!service && g_strcmp0(monitor->service, UA_SERVICE_DEFAULT))) { g_free(service); return UA_ERROR_NOT_PERMITTED; } if (UA_DETECT_MODE_INVALID <= mode) { g_free(service); return UA_ERROR_INVALID_PARAMETER; } if (0 == monitor->sensor_bitmask) { g_free(service); return UA_ERROR_NO_DATA; } if (!monitor->service) { if (service == NULL) monitor->service = g_strndup(UA_SERVICE_DEFAULT, UA_MAX_SERVICE_LEN); else monitor->service = g_strndup(service, UA_MAX_SERVICE_LEN); } if (UA_ERROR_NONE != _ua_get_error_code( _uam_get_available_sensors(&available_sensors))) UA_WARN("_uam_get_available_sensors failed"); if (!monitor->internal_presence_started || !monitor->absence_detection_started) { ret = __ua_start_monitoring(available_sensors, monitor->service, detect); if (UA_ERROR_NONE != ret) { /* LCOV_EXCL_START */ UA_ERR("Failed with error: %s(0x%X)", _ua_get_error_string(ret), ret); g_free(service); return ret; /* LCOV_EXCL_STOP */ } } monitor->presence_mode = mode; monitor->presence_cb = callback; monitor->user_data = user_data; monitor->presence_detection_started = TRUE; g_free(service); FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_start_absence_detection( ua_monitor_h handle, ua_service_h service_handle, ua_detection_mode_e mode, ua_absence_detected_cb callback, void *user_data) { FUNC_ENTRY; int ret; ua_monitor_s *monitor = (ua_monitor_s *)handle; ua_service_info_s *service_info = (ua_service_info_s *)service_handle; ua_detection_type_e detect = UA_ABSENCE_DETECTION; char *service; GSList *ua_services_list = _ua_service_get_services(); unsigned int available_sensors = 0; UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); retv_if(TRUE == monitor->absence_detection_started, UA_ERROR_NOW_IN_PROGRESS); if (service_handle) { UA_VALIDATE_HANDLE(service_handle, ua_services_list); service = g_strdup(service_info->name); } else service = NULL; if (monitor->service) if ((service && g_strcmp0(monitor->service, service)) || (!service && g_strcmp0(monitor->service, UA_SERVICE_DEFAULT))) { /* LCOV_EXCL_START */ g_free(service); return UA_ERROR_NOT_PERMITTED; /* LCOV_EXCL_STOP */ } if (UA_DETECT_MODE_INVALID <= mode) { /* LCOV_EXCL_START */ UA_ERR("Invalied mode [%d]", mode); g_free(service); return UA_ERROR_INVALID_PARAMETER; /* LCOV_EXCL_STOP */ } if (0 == monitor->sensor_bitmask) { /* LCOV_EXCL_START */ UA_ERR("monitor->sensor_bitmask is 0"); g_free(service); return UA_ERROR_NO_DATA; /* LCOV_EXCL_STOP */ } if (!monitor->service) { if (service == NULL) monitor->service = g_strndup(UA_SERVICE_DEFAULT, UA_MAX_SERVICE_LEN); else monitor->service = g_strndup(service, UA_MAX_SERVICE_LEN); } if (UA_ERROR_NONE != _ua_get_error_code( _uam_get_available_sensors(&available_sensors))) UA_WARN("_uam_get_available_sensors failed"); ret = __ua_start_monitoring(available_sensors, monitor->service, detect); if (mode == UA_DETECT_MODE_ALL_SENSOR) __ua_monitor_internal_presence_ref(monitor); if (monitor->internal_presence_started) if (!monitor->presence_detection_started) __ua_start_monitoring(monitor->sensor_bitmask, monitor->service, UA_PRESENCE_DETECTION); if (UA_ERROR_NONE != ret) { /* LCOV_EXCL_START */ UA_ERR("Failed with error: %s(0x%X)", _ua_get_error_string(ret), ret); g_free(service); return ret; /* LCOV_EXCL_STOP */ } monitor->absence_mode = mode; monitor->absence_cb = callback; monitor->user_data = user_data; monitor->absence_detection_started = TRUE; g_free(service); FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_stop_presence_detection(ua_monitor_h handle) { FUNC_ENTRY; int ret; ua_monitor_s *monitor = (ua_monitor_s *)handle; ua_detection_type_e detect = UA_PRESENCE_DETECTION; unsigned int available_sensors = 0; UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); retv_if(FALSE == monitor->presence_detection_started, UA_ERROR_NOT_IN_PROGRESS); if (UA_ERROR_NONE != _ua_get_error_code( _uam_get_available_sensors(&available_sensors))) UA_WARN("_uam_get_available_sensors failed"); if (!monitor->internal_presence_started || !monitor->absence_detection_started) { ret = __ua_stop_monitoring(available_sensors, monitor->service, detect); if (UA_ERROR_NONE != ret) { /* LCOV_EXCL_START */ UA_ERR("Failed with error: %s(0x%X)", _ua_get_error_string(ret), ret); return ret; /* LCOV_EXCL_STOP */ } } monitor->presence_mode = UA_DETECT_MODE_INVALID; monitor->presence_cb = NULL; monitor->user_data = NULL; monitor->presence_detection_started = FALSE; g_slist_free_full(monitor->user_state, __ua_free_user_state_info_t); monitor->user_state = NULL; monitor->env_user_cb_sent = FALSE; if (!monitor->absence_detection_started) { g_free(monitor->service); monitor->service = NULL; } FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_stop_absence_detection(ua_monitor_h handle) { FUNC_ENTRY; int ret; ua_monitor_s *monitor = (ua_monitor_s *)handle; ua_detection_type_e detect = UA_ABSENCE_DETECTION; unsigned int available_sensors = 0; UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); retv_if(FALSE == monitor->absence_detection_started, UA_ERROR_NOT_IN_PROGRESS); retv_if(NULL == monitor->absence_cb, UA_ERROR_NOT_IN_PROGRESS); if (UA_ERROR_NONE != _ua_get_error_code( _uam_get_available_sensors(&available_sensors))) UA_WARN("_uam_get_available_sensors failed"); ret = __ua_stop_monitoring(available_sensors, monitor->service, detect); if (UA_ERROR_NONE != ret) { /* LCOV_EXCL_START */ UA_ERR("Failed with error: %s(0x%X)", _ua_get_error_string(ret), ret); return ret; /* LCOV_EXCL_STOP */ } if (monitor->internal_presence_started) if (!monitor->presence_detection_started) __ua_stop_monitoring(monitor->sensor_bitmask, monitor->service, UA_PRESENCE_DETECTION); if (monitor->absence_mode == UA_DETECT_MODE_ALL_SENSOR) __ua_monitor_internal_presence_unref(monitor); monitor->absence_mode = UA_DETECT_MODE_INVALID; monitor->absence_cb = NULL; monitor->user_data = NULL; monitor->absence_detection_started = FALSE; if (!monitor->presence_detection_started) { g_free(monitor->service); monitor->service = NULL; } FUNC_EXIT; return UA_ERROR_NONE; } int ua_monitor_set_brightness_threshold(ua_monitor_h handle, int presence_threshold, int absence_threshold) { FUNC_ENTRY; int ret; ua_monitor_s *monitor = (ua_monitor_s *)handle; UA_VALIDATE_INPUT_PARAMETER(handle); UA_VALIDATE_HANDLE(handle, ua_monitor_list); retv_if(0 == (monitor->sensor_bitmask & UAM_SENSOR_BITMASK_LIGHT), UA_ERROR_NO_DATA); ret = _ua_get_error_code(_uam_request_set_detection_threshold( UAM_SENSOR_BITMASK_LIGHT, presence_threshold, absence_threshold)); if (UA_ERROR_NONE != ret) { UA_ERR("Set failed"); return ret; } FUNC_EXIT; return UA_ERROR_NONE; } int ua_enable_low_power_mode(void) { FUNC_ENTRY; int ret; ret = _ua_get_error_code(_uam_set_low_power_mode(UA_SENSOR_ALL, true)); if (UA_ERROR_NONE != ret) { /* LCOV_EXCL_START */ UA_ERR("_uam_set_low_power_mode failed"); return ret; /* LCOV_EXCL_STOP */ } FUNC_EXIT; return UA_ERROR_NONE; } int ua_disable_low_power_mode(void) { FUNC_ENTRY; int ret; ret = _ua_get_error_code(_uam_set_low_power_mode(UA_SENSOR_ALL, false)); if (UA_ERROR_NONE != ret) { /* LCOV_EXCL_START */ UA_ERR("_uam_set_low_power_mode failed"); return ret; /* LCOV_EXCL_STOP */ } FUNC_EXIT; return UA_ERROR_NONE; } int ua_set_low_power_mode(unsigned int bitmask, bool on_off) { FUNC_ENTRY; int ret; ret = _ua_get_error_code(_uam_set_low_power_mode(bitmask, on_off)); if (UA_ERROR_NONE != ret) { /* LCOV_EXCL_START */ UA_ERR("_uam_set_low_power_mode failed"); return ret; /* LCOV_EXCL_STOP */ } FUNC_EXIT; return UA_ERROR_NONE; } int ua_set_detection_cycle(ua_service_h service, unsigned int cycle_time) { FUNC_ENTRY; int ret; ua_service_info_s* service_info = (ua_service_info_s*)service; UA_VALIDATE_INPUT_PARAMETER(service); retv_if(cycle_time < UA_MIN_DETECTION_CYCLE, UA_ERROR_INVALID_PARAMETER); retv_if(cycle_time % UA_DETECTION_CYCLE_STEP != 0, UA_ERROR_INVALID_PARAMETER); ret = _ua_get_error_code(_uam_set_service_detection_cycle( service_info->name, cycle_time)); if (UA_ERROR_NONE != ret) { UA_ERR("_uam_set_service_detection_cycle returned %s", _ua_get_error_string(ret)); return ret; } FUNC_EXIT; return UA_ERROR_NONE; } int ua_get_detection_cycle(ua_service_h service, unsigned int* cycle_time) { FUNC_ENTRY; int ret; ua_service_info_s* service_info = (ua_service_info_s*)service; UA_VALIDATE_INPUT_PARAMETER(service); UA_VALIDATE_INPUT_PARAMETER(cycle_time); ret = _ua_get_error_code(_uam_get_service_detection_cycle( service_info->name, cycle_time)); if (UA_ERROR_NONE != ret) { UA_ERR("_uam_get_service_detection_cycle returned %s", _ua_get_error_string(ret)); return ret; } FUNC_EXIT; return UA_ERROR_NONE; } int ua_set_detection_window(unsigned int window) { FUNC_ENTRY; int ret; retv_if(window <= 0, UA_ERROR_INVALID_PARAMETER); retv_if(window > UA_MAX_DETECTION_WINDOW, UA_ERROR_INVALID_PARAMETER); retv_if(window % UA_DETECTION_WINDOW_STEP != 0, UA_ERROR_INVALID_PARAMETER); ret = _ua_get_error_code(_uam_set_detection_window(window)); if (UA_ERROR_NONE != ret) { UA_ERR("_uam_set_detection_window returned %s", _ua_get_error_string(ret)); return ret; } FUNC_EXIT; return UA_ERROR_NONE; } int ua_get_detection_window(unsigned int* window) { FUNC_ENTRY; int ret; UA_VALIDATE_INPUT_PARAMETER(window); ret = _ua_get_error_code(_uam_get_detection_window(window)); if (UA_ERROR_NONE != ret) { UA_ERR("_uam_get_detection_window returned %s", _ua_get_error_string(ret)); return ret; } FUNC_EXIT; return UA_ERROR_NONE; } int ua_reset_database(void) { FUNC_ENTRY; int ret; ret = _ua_get_error_code(_uam_db_reset()); if (UA_ERROR_NONE != ret) { UA_ERR("_uam_db_reset() returned %s", _ua_get_error_string(ret)); return ret; } FUNC_EXIT; return UA_ERROR_NONE; } int ua_add_ibeacon_adv_data( unsigned int adv_len, const char *ibeacon_adv) { FUNC_ENTRY; int ret; UA_VALIDATE_INPUT_PARAMETER(ibeacon_adv); retv_if(!adv_len || adv_len > UA_IBEACON_ADV_MAX_LEN, UA_ERROR_INVALID_PARAMETER); ret = _ua_get_error_code(_uam_add_ibeacon_adv_data(adv_len, ibeacon_adv)); if (UA_ERROR_NONE != ret) { UA_ERR("_uam_add_ibeacon_adv_data returned %s", _ua_get_error_string(ret)); return ret; } FUNC_EXIT; return UA_ERROR_NONE; } /* LCOV_EXCL_STOP */