diff options
author | Inkyun Kil <inkyun.kil@samsung.com> | 2019-10-18 10:56:19 +0900 |
---|---|---|
committer | Inkyun Kil <inkyun.kil@samsung.com> | 2019-10-18 10:56:19 +0900 |
commit | 500e7d2206beb26dec2615baa7df440b99999a39 (patch) | |
tree | 04fabc844d06838ae17eeb5f86e5ea92528c4923 | |
parent | ef09b2d4ec6c45f8a859132505a4ddcae4f7d501 (diff) | |
parent | 14a1fc78ceb4b8106a408b6017e853422e0c0f43 (diff) | |
download | alarm-manager-500e7d2206beb26dec2615baa7df440b99999a39.tar.gz alarm-manager-500e7d2206beb26dec2615baa7df440b99999a39.tar.bz2 alarm-manager-500e7d2206beb26dec2615baa7df440b99999a39.zip |
Merge branch 'feature/refactor_v1' into tizen
Change-Id: Iaa9e5255cd8ba5163cd7a28e85284dc041bbdb84
56 files changed, 15083 insertions, 7139 deletions
diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index 064881e..0000000 --- a/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -Jayoun Lee <airjany@samsung.com> -Sewook Park <sewook7.park@samsung.com> -Jaeho Lee <jaeho81.lee@samsung.com> diff --git a/CMakeLists.txt b/CMakeLists.txt index 733dcf3..116490b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,56 +1,43 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) - -SET (this_target alarm-server) - -INCLUDE_DIRECTORIES( - include -) - -SET(DEPS_PKGS "glib-2.0 dlog aul bundle appsvc pkgmgr-info pkgmgr vconf gio-2.0 gio-unix-2.0 capi-system-device libtzplatform-config libsystemd-login eventsystem notification capi-system-info sqlite3 cert-svc-vcore cynara-session cynara-client cynara-creds-gdbus") - -IF(_APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG) -ADD_DEFINITIONS("-D_APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG") -ENDIF(_APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG) - -message("${DEPS_PKGS}") +PROJECT(alarm C CXX) INCLUDE(FindPkgConfig) -pkg_check_modules(pkgs REQUIRED ${DEPS_PKGS}) -FOREACH(flag ${pkgs_CFLAGS}) - SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag} -Wall -Werror") -ENDFOREACH(flag) +IF(BUILD_GTESTS) + SET(EXTRA_CFLAGS "-Werror-implicit-function-declaration") +ELSE(BUILD_GTESTS) + SET(EXTRA_CFLAGS "-Werror-implicit-function-declaration -fvisibility=hidden") +ENDIF(BUILD_GTESTS) -AUX_SOURCE_DIRECTORY(./ SRCS) +IF(BUILD_GCOV) + ADD_DEFINITIONS("-DTIZEN_TEST_GCOV") +ENDIF(BUILD_GCOV) -ADD_CUSTOM_COMMAND( - WORKING_DIRECTORY - OUTPUT alarm-mgr-stub.c - COMMAND gdbus-codegen --interface-prefix org.tizen. - --generate-c-code alarm-mgr-stub - ./alarm_mgr.xml - COMMENT "Generating Server GDBus .c/.h") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pie") -ADD_EXECUTABLE (${this_target} ${SRCS} alarm-mgr-stub.c) -ADD_DEPENDENCIES(${this_target} alarm) +SET(LIBRARY ${PROJECT_NAME}) +SET(SERVER "${PROJECT_NAME}-server") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fpie") +IF(_APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG) + ADD_DEFINITIONS("-D_APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG") +ENDIF(_APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG) -TARGET_LINK_LIBRARIES(${this_target} ${pkgs_LDFLAGS}) -TARGET_LINK_LIBRARIES(${this_target} "-lrt -lm -pie -Wl,-z,relro") -TARGET_LINK_LIBRARIES(${this_target} alarm) +IF(NOT DEFINED DBUS_INTERFACE) + MESSAGE("No DBUS_INTERFACE. Check build system") + SET(DBUS_INTERFACE "org.tizen.${PROJECT_NAME}.manager") +ENDIF(NOT DEFINED DBUS_INTERFACE) -ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(server) +ADD_SUBDIRECTORY(lib) ADD_SUBDIRECTORY(tool) -ADD_SUBDIRECTORY(alarm-session-agent) ADD_SUBDIRECTORY(conf) +ADD_SUBDIRECTORY(session-agent) -CONFIGURE_FILE(alarm-service.conf.in alarm-service.conf @ONLY) -INSTALL(TARGETS ${this_target} DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) IF(_APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG) - INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/alarmmgr_log_dump.sh DESTINATION ${TZ_SYS_ETC}/dump.d/module.d/) + INSTALL(FILES ${CMAKE_SOURCE_DIR}/alarmmgr_log_dump.sh DESTINATION ${TZ_SYS_ETC}/dump.d/module.d/) ENDIF(_APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG) -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/alarm-service.conf DESTINATION ${SYSCONF_INSTALL_DIR}/dbus-1/system.d/) -CONFIGURE_FILE(org.tizen.alarm.manager.service.in org.tizen.alarm.manager.service @ONLY) -INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/org.tizen.alarm.manager.service DESTINATION ${SHARE_INSTALL_PREFIX}/dbus-1/system-services/) +#IF(BUILD_GTESTS) +# ADD_SUBDIRECTORY(unittest) +#ENDIF(BUILD_GTESTS) diff --git a/alarm-manager-registry.c b/alarm-manager-registry.c deleted file mode 100644 index 6702481..0000000 --- a/alarm-manager-registry.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * alarm-manager - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Venkatesha Sarpangala <sarpangala.v@samsung.com>, Jayoun Lee <airjany@samsung.com>, - * Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com> - * - * 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 <time.h> -#include <signal.h> -#include <string.h> -#include <sys/types.h> - -#include <sqlite3.h> -#include <glib.h> -#if !GLIB_CHECK_VERSION(2, 31, 0) -#include <glib/gmacros.h> -#endif - -#include "alarm.h" -#include "alarm-internal.h" - -#define MAX_GCONF_PATH_LEN 256 - -extern GSList *g_disabled_alarm_list; - -extern __alarm_server_context_t alarm_context; -extern sqlite3 *alarmmgr_db; - -bool _save_alarms(__alarm_info_t *__alarm_info); -bool _update_alarms(__alarm_info_t *__alarm_info); -bool _delete_alarms(alarm_id_t alarm_id); -void _load_alarms_from_registry(void); - -bool _save_alarms(__alarm_info_t *__alarm_info) -{ - char *error_message = NULL; - alarm_info_t *alarm_info = - (alarm_info_t *) &(__alarm_info->alarm_info); - alarm_date_t *start = &alarm_info->start; - alarm_mode_t *mode = &alarm_info->mode; - - char *query = sqlite3_mprintf("insert into alarmmgr( alarm_id, start,\ - end, uid, pid, global, is_disabled, caller_pkgid, callee_pkgid, app_unique_name,\ - app_service_name, app_service_name_mod, bundle, noti_len, noti, year,\ - month, day, hour, min, sec, msec, day_of_week, repeat,\ - alarm_type, reserved_info, dst_service_name, dst_service_name_mod)\ - values (%d,%d,%d,%d,%d,%d,0,%Q,%Q,%Q,%Q,%Q,%Q,%d,%Q,%d,%d,%d,%d,%d,%d,%d,%d,%d,\ - %d,%d,%Q,%Q)",\ - __alarm_info->alarm_id, - (int)__alarm_info->start, - (int)__alarm_info->end, - __alarm_info->uid, - __alarm_info->pid, - __alarm_info->global, - CHECK_NULL_STRING(__alarm_info->caller_pkgid), - CHECK_NULL_STRING(__alarm_info->callee_pkgid), - CHECK_NULL_STRING(__alarm_info->app_unique_name), - CHECK_NULL_STRING(__alarm_info->app_service_name), - CHECK_NULL_STRING(__alarm_info->app_service_name_mod), - CHECK_NULL_STRING(__alarm_info->bundle), - __alarm_info->noti ? strlen(__alarm_info->noti) : 0, - CHECK_NULL_STRING(__alarm_info->noti), - start->year, - start->month, - start->day, - start->hour, - start->min, - start->sec, - alarm_info->msec, - mode->u_interval.day_of_week, - mode->repeat, - alarm_info->alarm_type, - alarm_info->reserved_info, - CHECK_NULL_STRING(__alarm_info->dst_service_name), - CHECK_NULL_STRING(__alarm_info->dst_service_name_mod)); - - if (SQLITE_OK != sqlite3_exec(alarmmgr_db, query, NULL, NULL, &error_message)) { - SECURE_LOGE("sqlite3_exec() is failed. query = %s, error message = %s", query, error_message); - sqlite3_free(error_message); - sqlite3_free(query); - return false; - } - - sqlite3_free(query); - return true; -} - -bool _update_alarms(__alarm_info_t *__alarm_info) -{ - char *error_message = NULL; - alarm_info_t *alarm_info = - (alarm_info_t *) &(__alarm_info->alarm_info); - alarm_date_t *start = &alarm_info->start; - alarm_mode_t *mode = &alarm_info->mode; - - char *query = sqlite3_mprintf("update alarmmgr set start=%d, end=%d,\ - uid=%d, pid=%d, global=%d, is_disabled=0, caller_pkgid=%Q, callee_pkgid=%Q, app_unique_name=%Q, app_service_name=%Q, app_service_name_mod=%Q,\ - bundle=%Q, noti_len=%d, noti=%Q, year=%d, month=%d, day=%d, hour=%d, min=%d, sec=%d, msec=%d,\ - day_of_week=%d, repeat=%d, alarm_type=%d,\ - reserved_info=%d, dst_service_name=%Q, dst_service_name_mod=%Q\ - where alarm_id=%d",\ - (int)__alarm_info->start, - (int)__alarm_info->end, - __alarm_info->uid, - __alarm_info->pid, - __alarm_info->global, - CHECK_NULL_STRING(__alarm_info->caller_pkgid), - CHECK_NULL_STRING(__alarm_info->callee_pkgid), - CHECK_NULL_STRING(__alarm_info->app_unique_name), - CHECK_NULL_STRING(__alarm_info->app_service_name), - CHECK_NULL_STRING(__alarm_info->app_service_name_mod), - CHECK_NULL_STRING(__alarm_info->bundle), - __alarm_info->noti ? strlen(__alarm_info->noti) : 0, - CHECK_NULL_STRING(__alarm_info->noti), - start->year, - start->month, - start->day, - start->hour, - start->min, - start->sec, - alarm_info->msec, - mode->u_interval.day_of_week, - mode->repeat, - alarm_info->alarm_type, - alarm_info->reserved_info, - CHECK_NULL_STRING(__alarm_info->dst_service_name), - CHECK_NULL_STRING(__alarm_info->dst_service_name_mod), - __alarm_info->alarm_id); - - if (SQLITE_OK != sqlite3_exec(alarmmgr_db, query, NULL, NULL, &error_message)) { - SECURE_LOGE("sqlite3_exec() is failed. query = %s, error message = %s", query, error_message); - sqlite3_free(error_message); - sqlite3_free(query); - return false; - } - - sqlite3_free(query); - return true; -} - -bool _delete_alarms(alarm_id_t alarm_id) -{ - char *error_message = NULL; - char *query = sqlite3_mprintf("delete from alarmmgr where alarm_id=%d", alarm_id); - - if (SQLITE_OK != sqlite3_exec(alarmmgr_db, query, NULL, NULL, &error_message)) { - SECURE_LOGE("sqlite3_exec() is failed. query = %s, error message = %s", query, error_message); - sqlite3_free(error_message); - sqlite3_free(query); - return false; - } - - sqlite3_free(query); - return true; -} - -void _load_alarms_from_registry() -{ - int i = 0; - int col_idx; - const char *query = "select * from alarmmgr"; - const char *null_str = "null"; - sqlite3_stmt *stmt = NULL; - const char *tail = NULL; - alarm_info_t *alarm_info = NULL; - __alarm_info_t *__alarm_info = NULL; - alarm_date_t *start = NULL; - alarm_mode_t *mode = NULL; - int is_disabled; - char caller_pkgid[MAX_PKG_ID_LEN] = {0,}; - char callee_pkgid[MAX_PKG_ID_LEN] = {0,}; - char app_unique_name[MAX_SERVICE_NAME_LEN] = {0,}; - char app_service_name[MAX_SERVICE_NAME_LEN] = {0,}; - char app_service_name_mod[MAX_SERVICE_NAME_LEN] = {0,}; - char dst_service_name[MAX_SERVICE_NAME_LEN] = {0,}; - char dst_service_name_mod[MAX_SERVICE_NAME_LEN] = {0,}; - char bundle[MAX_BUNDLE_NAME_LEN] = {0,}; - int noti_len; - char *noti; - - if (SQLITE_OK != sqlite3_prepare(alarmmgr_db, query, strlen(query), &stmt, &tail)) { - ALARM_MGR_EXCEPTION_PRINT("sqlite3_prepare() is failed."); - return; - } - - for (i = 0; SQLITE_ROW == sqlite3_step(stmt); i++) { - col_idx = 0; - __alarm_info = (__alarm_info_t *)calloc(1, sizeof(__alarm_info_t)); - - if (G_UNLIKELY(__alarm_info == NULL)) { - ALARM_MGR_EXCEPTION_PRINT("Memory allocation failed."); - goto done; - } - alarm_info = (alarm_info_t *) &(__alarm_info->alarm_info); - start = &alarm_info->start; - mode = &alarm_info->mode; - - __alarm_info->alarm_id = sqlite3_column_int(stmt, col_idx++); - __alarm_info->start = sqlite3_column_int(stmt, col_idx++); - __alarm_info->end = sqlite3_column_int(stmt, col_idx++); - __alarm_info->uid = sqlite3_column_int(stmt, col_idx++); - __alarm_info->pid = sqlite3_column_int(stmt, col_idx++); - __alarm_info->global = sqlite3_column_int(stmt, col_idx++); - is_disabled = sqlite3_column_int(stmt, col_idx++); - - strncpy(caller_pkgid, (const char *)sqlite3_column_text(stmt, col_idx++), - MAX_PKG_ID_LEN - 1); - strncpy(callee_pkgid, (const char *)sqlite3_column_text(stmt, col_idx++), - MAX_PKG_ID_LEN - 1); - strncpy(app_unique_name, (const char *)sqlite3_column_text(stmt, col_idx++), - MAX_SERVICE_NAME_LEN - 1); - strncpy(app_service_name, (const char *)sqlite3_column_text(stmt, col_idx++), - MAX_SERVICE_NAME_LEN - 1); - strncpy(app_service_name_mod, (const char *)sqlite3_column_text(stmt, col_idx++), - MAX_SERVICE_NAME_LEN - 1); - strncpy(bundle, (const char *)sqlite3_column_text(stmt, col_idx++), - MAX_BUNDLE_NAME_LEN - 1); - noti_len = sqlite3_column_int(stmt, col_idx++); - noti_len = noti_len ? noti_len : strlen(null_str); - noti = calloc(1, noti_len + 1); - strncpy(noti, (const char *)sqlite3_column_text(stmt, col_idx++), - noti_len); - start->year = sqlite3_column_int(stmt, col_idx++); - start->month = sqlite3_column_int(stmt, col_idx++); - start->day = sqlite3_column_int(stmt, col_idx++); - start->hour = sqlite3_column_int(stmt, col_idx++); - start->min = sqlite3_column_int(stmt, col_idx++); - start->sec = sqlite3_column_int(stmt, col_idx++); - alarm_info->msec = sqlite3_column_int(stmt, col_idx++); - mode->u_interval.day_of_week = sqlite3_column_int(stmt, col_idx++); - mode->repeat = sqlite3_column_int(stmt, col_idx++); - alarm_info->alarm_type = sqlite3_column_int(stmt, col_idx++); - alarm_info->reserved_info = sqlite3_column_int(stmt, col_idx++); - strncpy(dst_service_name, (const char *)sqlite3_column_text(stmt, col_idx++), - MAX_SERVICE_NAME_LEN - 1); - strncpy(dst_service_name_mod, (const char *)sqlite3_column_text(stmt, col_idx++), - MAX_SERVICE_NAME_LEN - 1); - - __alarm_info->caller_pkgid = STRDUP_WITH_NULLCMP(caller_pkgid); - __alarm_info->callee_pkgid = STRDUP_WITH_NULLCMP(callee_pkgid); - __alarm_info->app_unique_name = STRDUP_WITH_NULLCMP(app_unique_name); - __alarm_info->app_service_name = STRDUP_WITH_NULLCMP(app_service_name); - __alarm_info->app_service_name_mod = - STRDUP_WITH_NULLCMP(app_service_name_mod); - __alarm_info->dst_service_name = STRDUP_WITH_NULLCMP(dst_service_name); - __alarm_info->dst_service_name_mod = - STRDUP_WITH_NULLCMP(dst_service_name_mod); - __alarm_info->bundle = STRDUP_WITH_NULLCMP(bundle); - __alarm_info->noti = STRDUP_WITH_NULLCMP(noti); - free(noti); - - if (is_disabled) { - _alarm_next_duetime(__alarm_info); - g_disabled_alarm_list = g_slist_append(g_disabled_alarm_list, __alarm_info); - ALARM_MGR_EXCEPTION_PRINT("Save alarm_id[%d] caller[%s] callee[%s]", __alarm_info->alarm_id, caller_pkgid, callee_pkgid); - } else { - _alarm_next_duetime(__alarm_info); - alarm_context.alarms = g_slist_append(alarm_context.alarms, __alarm_info); - } - } -done: - _alarm_schedule(); - if (sqlite3_finalize(stmt) != SQLITE_OK) - ALARM_MGR_EXCEPTION_PRINT("sqlite3_finalize() is failed."); - - return; -} - -void _update_db_for_disabled_alarm(alarm_id_t alarm_id, bool disabled) -{ - char *error_message = NULL; - - ALARM_MGR_EXCEPTION_PRINT("Update (%d) is_disabled to (%d)", alarm_id, disabled); - char *query = sqlite3_mprintf("update alarmmgr set is_disabled=%d where alarm_id=%d", disabled, alarm_id); - - if (SQLITE_OK != sqlite3_exec(alarmmgr_db, query, NULL, NULL, &error_message)) { - SECURE_LOGE("Failed to update the DB table. error message = %s", error_message); - sqlite3_free(error_message); - } - - sqlite3_free(query); - return; -} diff --git a/alarm-manager-timer.c b/alarm-manager-timer.c deleted file mode 100644 index 02c40af..0000000 --- a/alarm-manager-timer.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2000 - 2016 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 <stdio.h> -#include <stdlib.h> -#include <time.h> -#include <signal.h> -#include <string.h> -#include <sys/types.h> -#include <errno.h> -#include <sys/timerfd.h> -#include <glib.h> - -#include "alarm.h" -#include "alarm-internal.h" - -extern bool g_dummy_timer_is_set; - -bool _alarm_destory_timer(timer_t timer) -{ - if (timer_delete(timer) == 0) - return true; - else - return false; -} - -bool _alarm_disable_timer(__alarm_server_context_t alarm_context) -{ - struct itimerspec time_spec; - - time_spec.it_value.tv_sec = 0; - time_spec.it_value.tv_nsec = 0; - time_spec.it_interval.tv_sec = time_spec.it_interval.tv_nsec = 0; - - if (timerfd_settime(alarm_context.timer, 0, &time_spec, NULL) < 0) { - perror("disable timer has failed\n"); - return false; - } - - return true; -} - -bool _alarm_set_timer(__alarm_server_context_t *alarm_context, int timer, time_t due_time) -{ - struct itimerspec time_spec; - time_t current_time; - double interval; - char due_time_r[100] = { 0 }; - struct tm ts_ret; - extern int errno; - - time(¤t_time); - - interval = difftime(due_time, current_time); - ALARM_MGR_LOG_PRINT("[alarm-server][timer]: remain time from current is %f , due_time is %ld.", interval, due_time); - - /*set timer as absolute time */ - /*we create dummy timer when the interval is longer than one day. */ - /*the timer will be expired in half day. */ - - localtime_r(&due_time, &ts_ret); - - if (interval > 60 * 60 * 24) { - interval = 60 * 60 * 12; - g_dummy_timer_is_set = true; - strftime(due_time_r, 30, "%c", &ts_ret); - ALARM_MGR_LOG_PRINT("create dummy alarm timer(%d), due_time(%s)", timer, due_time_r); - } else { - g_dummy_timer_is_set = false; - } - - time_spec.it_value.tv_sec = due_time; - time_spec.it_value.tv_nsec = 0; - time_spec.it_interval.tv_sec = time_spec.it_interval.tv_nsec = 0; - - if (interval > 0 && timerfd_settime(timer, TFD_TIMER_ABSTIME, &time_spec, NULL) != 0) { - ALARM_MGR_EXCEPTION_PRINT("set timer has failed : timer(%d), due_time(%ld) , errno(%d).", timer, due_time, errno); - return false; - } - /* we set c_due_time to due_time due to allow newly created alarm can - be schedlued when its interval is less than the current alarm */ - alarm_context->c_due_time = due_time; - return true; -} diff --git a/alarm-manager.c b/alarm-manager.c deleted file mode 100644 index 39f698c..0000000 --- a/alarm-manager.c +++ /dev/null @@ -1,4606 +0,0 @@ -/* - * Copyright (c) 2000 - 2016 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. - */ - -#define _GNU_SOURCE -#include <stdio.h> -#include <stdlib.h> -#include <time.h> -#include <signal.h> -#include <string.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <unistd.h> -#include <sys/timerfd.h> -#include <poll.h> -#include <stdint.h> - -#include <tzplatform_config.h> -#include <aul.h> -#include <aul_svc.h> -#include <bundle.h> -#include <bundle_internal.h> -#include <vconf.h> -#include <vconf-keys.h> -#include <dlfcn.h> -#include <pkgmgr-info.h> -#include <package-manager.h> -#include <device/display.h> -#include <systemd/sd-login.h> -#include <eventsystem.h> -#include <notification.h> -#include <notification_ipc.h> -#include <notification_internal.h> -#include <system_info.h> -#include <sqlite3.h> -#include <cert-svc/ccert.h> -#include <cert-svc/cinstance.h> -#include <cynara-session.h> -#include <cynara-client.h> -#include <cynara-creds-gdbus.h> - -#include <glib.h> -#if !GLIB_CHECK_VERSION(2, 31, 0) -#include <glib/gmacros.h> -#endif - -#include "gio/gio.h" -#include "alarm.h" -#include "alarm-internal.h" -#include "alarm-mgr-stub.h" - - -#define SIG_TIMER 0x32 -#define WAKEUP_ALARM_APP_ID "org.tizen.alarm.ALARM" -/* alarm ui application's alarm's dbus_service name instead of 21 - * (alarm application's app_id) value */ - -__alarm_server_context_t alarm_context; -bool g_dummy_timer_is_set = FALSE; - -GSList *g_scheduled_alarm_list; -GSList *g_expired_alarm_list; -GSList *g_disabled_alarm_list; - -#ifndef RTC_WKALM_BOOT_SET -#define RTC_WKALM_BOOT_SET _IOW('p', 0x80, struct rtc_wkalrm) -#endif - -/* - * 2008. 6. 3 sewook7.park - * When the alarm becoms sleeping mode, alarm timer is not expired. - * So using RTC, phone is awaken before alarm rings. - */ -#include <errno.h> -#include <linux/rtc.h> -#include <sys/ioctl.h> -#include <fcntl.h> - -static const char default_rtc[] = "/dev/rtc"; -static int gfd = -1; -#define _APPFW_FEATURE_WAKEUP_USING_RTC (_get_profile() != PROFILE_TV) - -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG -#define ALARMMGR_LOG_BUFFER_SIZE 10000 -#define ALARMMGR_LOG_BUFFER_STRING_SIZE 200 -#define ALARMMGR_LOG_TAG_SIZE 20 -#define ALARMMGR_LOG_MESSAGE_SIZE 120 -#define ALARMMGR_LOG_FILE_PATH "/run/alarmmgr_log/alarmmgr.log" -static int log_index = 0; -static int log_fd = 0; -#endif - -/* display lock and unlock */ -#define DEVICED_BUS_NAME "org.tizen.system.deviced" -#define DEVICED_PATH_DISPLAY "/Org/Tizen/System/DeviceD/Display" -#define DEVICED_INTERFACE_DISPLAY "org.tizen.system.deviced.display" -#define DEVICED_LOCK_STATE "lockstate" -#define DEVICED_UNLOCK_STATE "unlockstate" -#define DEVICED_DBUS_REPLY_TIMEOUT (120*1000) -#define DEVICED_LCD_OFF "lcdoff" -#define DEVICED_STAY_CUR_STATE "staycurstate" -#define DEVICED_SLEEP_MARGIN "sleepmargin" - -/* link path for timezone info */ -#define TIMEZONE_INFO_LINK_PATH tzplatform_mkpath(TZ_SYS_ETC, "localtime") - -/* GDBus Declaration */ -#define ALARM_MGR_DBUS_PATH "/org/tizen/alarm/manager" -#define ALARM_MGR_DBUS_NAME "org.tizen.alarm.manager" -static AlarmManager *interface; - -sqlite3 *alarmmgr_db; -bool is_time_changed = false; /* for calculating next duetime */ - -#define BILLION 1000000000 /* for calculating nano seconds */ -static time_t periodic_alarm_standard_time = 0; -static bool is_db_corrupted = false; - -static int __is_ui_app(const char *appid, uid_t uid); -static long __get_proper_interval(long interval, int alarm_type); -static void __alarm_add_to_list(__alarm_info_t *__alarm_info); -static void __alarm_generate_alarm_id(__alarm_info_t *__alarm_info, alarm_id_t *alarm_id); -static __alarm_info_t *__alarm_update_in_list(int uid, alarm_id_t alarm_id, - alarm_info_t *alarm_info, int update_flag, int *error_code); -static bool __alarm_remove_from_list(uid_t uid, alarm_id_t alarm_id, - int *error_code); -static bool __alarm_set_start_and_end_time(alarm_info_t *alarm_info, - __alarm_info_t *__alarm_info); -static bool __alarm_update_due_time_of_all_items_in_list(double diff_time); -static bool __alarm_create(alarm_info_t *alarm_info, alarm_id_t *alarm_id, uid_t uid, - int pid, periodic_method_e method, long requested_interval, int is_ref, - char *app_service_name, char *app_service_name_mod, - const char *dst_service_name, const char *dst_service_name_mod, - int *error_code); -static bool __alarm_create_appsvc(alarm_info_t *alarm_info, alarm_id_t *alarm_id, - long requested_interval, uid_t uid, int pid, char *bundle_data, int *error_code); - -static bool __alarm_delete(uid_t uid, alarm_id_t alarm_id, int *error_code); -static bool __alarm_update(uid_t uid, int pid, alarm_id_t alarm_id, - alarm_info_t *alarm_info, int update_flag, int *error_code); -static void __alarm_send_noti_to_application(const char *app_service_name, alarm_id_t alarm_id, int msec, uid_t uid); -static void __alarm_expired(); -static gboolean __alarm_handler_idle(gpointer user_data); -static void __on_system_time_external_changed(keynode_t *node, void *data); -static void __initialize_timer(); -static void __initialize_alarm_list(); -static void __initialize_scheduled_alarm_list(); -static bool __initialize_noti(); - -static bool __initialize_dbus(); -static bool __initialize_db(); -static void __initialize(); -void _release_alarm_info_t(); -void on_bus_name_owner_changed(GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, - const gchar *interface_name, const gchar *signal_name, GVariant *parameters, gpointer user_data); -bool __get_caller_unique_name(int pid, char *unique_name, int size, bool *is_app, uid_t uid); -static bool __permit_by_config(pkgmgrinfo_appinfo_h handle, uid_t uid); -static int __db_busyhandler(void *pData, int count); -static notification_h __get_notification(guchar *data, int datalen); - -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG -static void __initialize_module_log(void); -static bool __save_module_log(const char *tag, const char *messgae); -#endif - -int __display_lock_state(char *state, char *flag, unsigned int timeout); -int __display_unlock_state(char *state, char *flag); - -int __set_time(time_t _time); - -struct running_info_t { - int pid; - char *appid; - bool is_running; -}; - -struct filtered_alarm_app_s { - int is_ui_app; - uid_t uid; -}; - -GHashTable *appid_cache_table; - -typedef struct { - int pid; - bool is_app; - char *unique_name; -} appid_cache_t; - -typedef enum { - PROFILE_UNKNOWN = 0, - PROFILE_MOBILE, - PROFILE_WEARABLE, - PROFILE_TV, - PROFILE_IVI, - PROFILE_COMMON, -} profile_t; - -static profile_t _get_profile() -{ - static profile_t saved = PROFILE_UNKNOWN; - char *profileName; - int r; - - if (__builtin_expect(saved != PROFILE_UNKNOWN, 1)) - return saved; - - r = system_info_get_platform_string("http://tizen.org/feature/profile", - &profileName); - if (r != SYSTEM_INFO_ERROR_NONE) { - ALARM_MGR_LOG_PRINT("Failed to get profile info. error(%d)", r); - return saved; - } - - switch (*profileName) { - case 'm': - case 'M': - saved = PROFILE_MOBILE; - break; - case 'w': - case 'W': - saved = PROFILE_WEARABLE; - break; - case 't': - case 'T': - saved = PROFILE_TV; - break; - case 'i': - case 'I': - saved = PROFILE_IVI; - break; - default: // common or unknown ==> ALL ARE COMMON. - saved = PROFILE_COMMON; - } - free(profileName); - - return saved; -} - -static bool __get_cached_unique_name(int pid, char *unique_name, int size, bool *is_app, uid_t uid) -{ - appid_cache_t *data = NULL; - data = (appid_cache_t *)g_hash_table_lookup(appid_cache_table, &pid); - if (data) { - snprintf(unique_name, MAX_APP_ID, "%s", data->unique_name); - if (is_app) - *is_app = data->is_app; - ALARM_MGR_LOG_PRINT("Get cached unique_name: %s, pid:%d", unique_name, pid); - return true; - } - - ALARM_MGR_LOG_PRINT("There is no cached unique_name for pid(%d)", pid); - return __get_caller_unique_name(pid, unique_name, size, is_app, uid); -} - -gboolean __hash_table_remove_cb(gpointer key, gpointer value, gpointer user_data) -{ - char *target_name = user_data; - appid_cache_t *data = value; - if (target_name && data && strcmp(target_name, data->unique_name) == 0) { - ALARM_MGR_LOG_PRINT("Remove cached data of [%s]", target_name); - return true; - } - return false; -} - -void __hashtable_foreach_cb(gpointer key, gpointer value, gpointer user_data) -{ - appid_cache_t *data = value; - if (data) - ALARM_MGR_LOG_PRINT("# %s(%d) - %d", data->unique_name, data->pid, data->is_app); -} - -void __free_cached_value(gpointer data) -{ - appid_cache_t *value = data; - - if (value) { - if (value->unique_name) - free(value->unique_name); - free(value); - } -} - -static void __rtc_set() -{ - if (_APPFW_FEATURE_WAKEUP_USING_RTC) { - const char *rtc = default_rtc; - struct tm due_tm; -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; -#endif -#ifdef _SIMUL /* RTC does not work in simulator. */ - ALARM_MGR_EXCEPTION_PRINT("because it is simulator's mode, we don't set RTC."); - return; -#endif - - if (gfd < 0) { - gfd = open(rtc, O_RDWR); - if (gfd < 0) { - ALARM_MGR_EXCEPTION_PRINT("RTC open failed."); - return; - } - } - - /* Read the RTC time/date */ - int retval = 0; - char buf[1024]; -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - char *timebuf = ctime(&alarm_context.c_due_time); - if (timebuf) { - timebuf[strlen(timebuf) - 1] = '\0'; /* to avoid new line */ - snprintf(log_message, sizeof(log_message), "wakeup time: %d, %s", (int)alarm_context.c_due_time, timebuf); - } -#endif - - ALARM_MGR_LOG_PRINT("alarm_context.c_due_time is %d.", (int)alarm_context.c_due_time); - - if (alarm_context.c_due_time != -1) { - struct rtc_wkalrm rtc_wkalarm = { 0, }; - rtc_wkalarm.enabled = 0; - rtc_wkalarm.time.tm_year = 1900; - rtc_wkalarm.time.tm_mon = 0; - rtc_wkalarm.time.tm_mday = 1; - rtc_wkalarm.time.tm_hour = 0; - rtc_wkalarm.time.tm_min = 0; - rtc_wkalarm.time.tm_sec = 0; - - retval = ioctl(gfd, RTC_WKALM_SET, &rtc_wkalarm); - if (retval == -1) { - if (errno == ENOTTY) - ALARM_MGR_EXCEPTION_PRINT("Alarm IRQs is not supported."); - - ALARM_MGR_EXCEPTION_PRINT("RTC_WKALM_SET disabled ioctl is failed. errno = %s", strerror_r(errno, buf, sizeof(buf))); -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - __save_module_log("FAIL: SET RTC", log_message); -#endif - return; - } - ALARM_MGR_LOG_PRINT("[alarm-server]RTC_WKALM_SET disabled ioctl is successfully done."); - - time_t due_time = alarm_context.c_due_time; - gmtime_r(&due_time, &due_tm); - - ALARM_MGR_LOG_PRINT("Setted RTC Alarm date/time is %d-%d-%d, %02d:%02d:%02d (UTC).", - due_tm.tm_mday, due_tm.tm_mon + 1, due_tm.tm_year + 1900, - due_tm.tm_hour, due_tm.tm_min, due_tm.tm_sec); - - rtc_wkalarm.enabled = 1; - rtc_wkalarm.time.tm_year = due_tm.tm_year; - rtc_wkalarm.time.tm_mon = due_tm.tm_mon; - rtc_wkalarm.time.tm_mday = due_tm.tm_mday; - rtc_wkalarm.time.tm_hour = due_tm.tm_hour; - rtc_wkalarm.time.tm_min = due_tm.tm_min; - rtc_wkalarm.time.tm_sec = due_tm.tm_sec; - retval = ioctl(gfd, RTC_WKALM_SET, &rtc_wkalarm); - if (retval == -1) { - if (errno == ENOTTY) - ALARM_MGR_EXCEPTION_PRINT("Alarm IRQs is not supported."); - - ALARM_MGR_EXCEPTION_PRINT("RTC ALARM_SET ioctl is failed. errno = %s", strerror_r(errno, buf, sizeof(buf))); -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - __save_module_log("FAIL: SET RTC", log_message); -#endif - return; - } - ALARM_MGR_LOG_PRINT("[alarm-server]RTC ALARM_SET ioctl is successfully done."); -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - __save_module_log("SET RTC", log_message); -#endif - } else { - ALARM_MGR_EXCEPTION_PRINT("[alarm-server]alarm_context.c_due_time is" - "less than 10 sec. RTC alarm does not need to be set"); - } - } else { - ALARM_MGR_LOG_PRINT("[alarm-server] RTC does not work."); - } - return; -} - -int __set_time(time_t _time) -{ - int ret = 0; - struct timeval tv; - struct tm tm, *gmtime_res; - - tv.tv_sec = _time; - tv.tv_usec = 0; - - gmtime_res = gmtime_r(&(tv.tv_sec), &tm); - if (!gmtime_res) - ALARM_MGR_EXCEPTION_PRINT("gmtime_r is failed. [%d]", errno); - - ret = settimeofday(&tv, NULL); - if (ret < 0) - ALARM_MGR_EXCEPTION_PRINT("settimeofday is failed.[%d]", errno); - - if (_APPFW_FEATURE_WAKEUP_USING_RTC) { - /* Using /dev/alarm, this function changes both OS time and RTC. */ - const char *rtc0 = default_rtc; - struct rtc_time _rtc_time; -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,}; - char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; -#endif - char buf[1024]; - - if (gfd < 0) { - gfd = open(rtc0, O_RDWR); - if (gfd < 0) { - ALARM_MGR_EXCEPTION_PRINT("Opening the /dev/alarm is failed."); - perror("\t"); - return 1; - } - } - - memset(&_rtc_time, 0, sizeof(_rtc_time)); - _rtc_time.tm_sec = tm.tm_sec; - _rtc_time.tm_min = tm.tm_min; - _rtc_time.tm_hour = tm.tm_hour; - _rtc_time.tm_mday = tm.tm_mday; - _rtc_time.tm_mon = tm.tm_mon; - _rtc_time.tm_year = tm.tm_year; - _rtc_time.tm_wday = tm.tm_wday; - _rtc_time.tm_yday = tm.tm_yday; - _rtc_time.tm_isdst = tm.tm_isdst; - - ret = ioctl(gfd, RTC_SET_TIME, &_rtc_time); - if (ret == -1) { - ALARM_MGR_EXCEPTION_PRINT("ALARM_SET_RTC ioctl is failed. errno = %s", strerror_r(errno, buf, sizeof(buf))); -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - strncpy(log_tag, "FAIL: SET RTC", sizeof(log_tag) - 1); -#endif - perror("\t"); - } -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - else - strncpy(log_tag, "SET RTC", sizeof(log_tag) - 1); - - char *timebuf = ctime(&_time); - if (timebuf) { - timebuf[strlen(timebuf) - 1] = '\0'; /* to avoid new line */ - snprintf(log_message, sizeof(log_message), "RTC & OS =%d, %s", (int)_time, timebuf); - } - - __save_module_log(log_tag, log_message); -#endif - } else { - ALARM_MGR_LOG_PRINT("[alarm-server] RTC does not work."); - } - - return 1; -} - -bool __alarm_clean_list() -{ - g_slist_free_full(alarm_context.alarms, _release_alarm_info_t); - return true; -} - -static void __alarm_generate_alarm_id(__alarm_info_t *__alarm_info, alarm_id_t *alarm_id) -{ - bool unique_id = false; - __alarm_info_t *entry = NULL; - GSList *iter = NULL; - - __alarm_info->alarm_id = g_random_int_range(0, INT_MAX) + 1; - ALARM_MGR_LOG_PRINT("__alarm_info->alarm_id is %d", __alarm_info->alarm_id); - - while (unique_id == false) { - unique_id = true; - - for (iter = alarm_context.alarms; iter != NULL; - iter = g_slist_next(iter)) { - entry = iter->data; - if (entry->alarm_id == __alarm_info->alarm_id) { - __alarm_info->alarm_id++; - unique_id = false; - } - } - } - - *alarm_id = __alarm_info->alarm_id; - - return; -} - -static void __alarm_add_to_list(__alarm_info_t *__alarm_info) -{ - alarm_info_t *alarm_info = &__alarm_info->alarm_info; - __alarm_info_t *entry = NULL; - GSList *iter = NULL; - - ALARM_MGR_LOG_PRINT("[alarm-server]: Before add alarm_id(%d)", __alarm_info->alarm_id); - - alarm_context.alarms = g_slist_append(alarm_context.alarms, __alarm_info); - ALARM_MGR_LOG_PRINT("[alarm-server]: After add alarm_id(%d)", __alarm_info->alarm_id); - - /* alarm list */ - for (iter = alarm_context.alarms; iter != NULL; iter = g_slist_next(iter)) { - entry = iter->data; - ALARM_MGR_LOG_PRINT("[alarm-server]: alarm_id(%d).", entry->alarm_id); - } - - if (!(alarm_info->alarm_type & ALARM_TYPE_VOLATILE)) { - if (!_save_alarms(__alarm_info)) - ALARM_MGR_EXCEPTION_PRINT("Saving alarm_id(%d) in DB is failed.", __alarm_info->alarm_id); - } -} - -static bool __check_bundle_for_update(const gchar *b_data, uid_t uid) -{ - const char *callee_appid; - bundle *b; - bool ret = false; - - if (b_data == NULL) - return true; - - b = bundle_decode((bundle_raw *)b_data, strlen(b_data)); - if (b == NULL) - return false; - - callee_appid = appsvc_get_appid(b); - if (callee_appid == NULL) { - bundle_free(b); - return false; - } - - if (__is_ui_app(callee_appid, uid)) - ret = true; - - bundle_free(b); - return ret; -} - -static __alarm_info_t *__alarm_update_in_list(int uid, alarm_id_t alarm_id, - alarm_info_t *alarm_info, int update_flag, int *error_code) -{ - bool found = false; - GSList *iter = NULL; - __alarm_info_t *entry = NULL; - alarm_info_t *_alarm_info = NULL; - - for (iter = alarm_context.alarms; iter != NULL; - iter = g_slist_next(iter)) { - entry = iter->data; - if (entry->uid == uid && - entry->alarm_id == alarm_id) { - found = true; - _alarm_info = &entry->alarm_info; - - if (update_flag == ALARM_UPDATE_FLAG_TIME || - ALARM_UPDATE_FLAG_WEEK) { - if (!__check_bundle_for_update(entry->bundle, - entry->uid)) { - *error_code = ERR_ALARM_NOT_PERMITTED_APP; - return NULL; - } - } - - if (update_flag == ALARM_UPDATE_FLAG_TIME) { - __alarm_set_start_and_end_time(alarm_info, entry); - memcpy(_alarm_info, alarm_info, sizeof(alarm_info_t)); - } else if (update_flag == ALARM_UPDATE_FLAG_PERIOD) { - _alarm_info->alarm_type |= ALARM_TYPE_INEXACT; - _alarm_info->alarm_type |= ALARM_TYPE_PERIOD; - _alarm_info->mode.repeat = ALARM_REPEAT_MODE_REPEAT; - _alarm_info->mode.u_interval.interval = - __get_proper_interval(alarm_info->mode.u_interval.interval, - _alarm_info->alarm_type); - } else if (update_flag == ALARM_UPDATE_FLAG_WEEK) { - _alarm_info->alarm_type &= ~ALARM_TYPE_INEXACT; - _alarm_info->mode = alarm_info->mode; - } else if (update_flag == ALARM_UPDATE_FLAG_CLEAR_PERIOD) { - if (_alarm_info->mode.repeat == ALARM_REPEAT_MODE_REPEAT) { - _alarm_info->mode.repeat = ALARM_REPEAT_MODE_ONCE; - _alarm_info->mode.u_interval.interval = 0; - } - } else if (update_flag == ALARM_UPDATE_FLAG_CLEAR_WEEK_FLAG) { - if (_alarm_info->mode.repeat == ALARM_REPEAT_MODE_WEEKLY) { - _alarm_info->mode.repeat = ALARM_REPEAT_MODE_ONCE; - _alarm_info->mode.u_interval.interval = 0; - } - } - break; - } - } - - if (!found) { - if (error_code) - *error_code = ERR_ALARM_INVALID_ID; - return NULL; - } - - if (!(alarm_info->alarm_type & ALARM_TYPE_VOLATILE)) { - if (!_update_alarms(entry)) - ALARM_MGR_EXCEPTION_PRINT("Updating alarm_id(%d) in DB is failed.", alarm_id); - } - - return entry; -} - -static bool __alarm_remove_from_list(uid_t uid, alarm_id_t alarm_id, - int *error_code) -{ - bool found = false; - - alarm_info_t *alarm_info = NULL; - - GSList *iter = NULL; - __alarm_info_t *entry = NULL; - - /*list alarms */ - ALARM_MGR_LOG_PRINT("[alarm-server]: before del : alarm id(%d)", alarm_id); - - for (iter = alarm_context.alarms; iter != NULL; iter = g_slist_next(iter)) { - entry = iter->data; - if (entry->uid == uid && entry->alarm_id == alarm_id) { - alarm_info = &entry->alarm_info; - - ALARM_MGR_LOG_PRINT("[alarm-server]:Remove alarm id(%d)", entry->alarm_id); - - if (!(alarm_info->alarm_type & ALARM_TYPE_VOLATILE)) - _delete_alarms(alarm_id); - - alarm_context.alarms = g_slist_remove(alarm_context.alarms, iter->data); - _release_alarm_info_t(entry); - found = true; - break; - } - - } - - ALARM_MGR_LOG_PRINT("[alarm-server]: after del\n"); - - if (!found) { - if (error_code) - *error_code = ERR_ALARM_INVALID_ID; - return false; - } - - return true; -} - -static bool __alarm_set_start_and_end_time(alarm_info_t *alarm_info, - __alarm_info_t *__alarm_info) -{ - alarm_date_t *start = &alarm_info->start; - alarm_date_t *end = &alarm_info->end; - - struct tm alarm_tm = { 0, }; - - if (start->year != 0) { - if ((alarm_info->alarm_type & ALARM_TYPE_RELATIVE) && alarm_info->reserved_info != 0) { - __alarm_info->start = alarm_info->reserved_info; - } else { - alarm_tm.tm_year = start->year - 1900; - alarm_tm.tm_mon = start->month - 1; - alarm_tm.tm_mday = start->day; - - alarm_tm.tm_hour = start->hour; - alarm_tm.tm_min = start->min; - alarm_tm.tm_sec = start->sec; - alarm_tm.tm_isdst = -1; - - __alarm_info->start = mktime(&alarm_tm); - } - } else { - __alarm_info->start = 0; - } - - if (end->year != 0) { - alarm_tm.tm_year = end->year - 1900; - alarm_tm.tm_mon = end->month - 1; - alarm_tm.tm_mday = end->day; - - alarm_tm.tm_hour = end->hour; - alarm_tm.tm_min = end->min; - alarm_tm.tm_sec = end->sec; - - __alarm_info->end = mktime(&alarm_tm); - } else { - __alarm_info->end = 0; - } - - return true; -} - -/* -static bool alarm_get_tz_info(int *gmt_idx, int *dst) -{ - GConfValue *value1 = NULL; - GConfValue *value2 = NULL; - GConfClient* gConfClient = NULL; - GError* err = NULL; - - gConfClient = gconf_client_get_default(); - - if(gConfClient) { - value1 = gconf_client_get(gConfClient, SETTINGS_CLOCKTIMEZONE, - &err); - if (err) { - ALARM_MGR_LOG_PRINT("__on_system_time_changed: - gconf_client_get() failed: - error:[%s]\n", err->message); - g_error_free(err); - err = NULL; - } - *gmt_idx = gconf_value_get_int(value1); - ALARM_MGR_LOG_PRINT("gconf return gmt_idx =%d\n ", *gmt_idx); - - value2 = gconf_client_get(gConfClient, - SETTINGS_DAYLIGHTSTATUS, &err); - if (err) { - ALARM_MGR_LOG_PRINT("__on_system_time_changed: - gconf_client_get() failed: error:[%s]\n", err->message); - g_error_free(err); - err = NULL; - } - - *dst = gconf_value_get_int(value2); - ALARM_MGR_LOG_PRINT("gconf return dst =%d\n ", *dst); - - if(gConfClient != NULL) { - g_object_unref(gConfClient); - gConfClient = NULL; - } - } - else - ALARM_MGR_LOG_PRINT("check the gconf setting failed!!!!! \n "); - - if(value1) { - gconf_value_free(value1); - value1 = NULL; - } - if(value2) { - gconf_value_free(value2); - value2 = NULL; - } - - return true; -} -*/ - -gboolean __update_relative_alarms(gpointer user_data) -{ - GSList *iter = NULL; - __alarm_info_t *entry = NULL; - char *error_message = NULL; - - if (sqlite3_exec(alarmmgr_db, "BEGIN EXCLUSIVE", NULL, NULL, &error_message) != SQLITE_OK) { - SECURE_LOGE("sqlite3_exec() is failed. error message = %s", error_message); - sqlite3_free(error_message); - return false; - } - - for (iter = alarm_context.alarms; iter != NULL; iter = g_slist_next(iter)) { - entry = iter->data; - alarm_info_t *alarm_info = &(entry->alarm_info); - if (alarm_info->alarm_type & ALARM_TYPE_RELATIVE) - _update_alarms(entry); - } - - if (sqlite3_exec(alarmmgr_db, "COMMIT", NULL, NULL, &error_message) != SQLITE_OK) { - SECURE_LOGE("sqlite3_exec() is failed. error message = %s", error_message); - sqlite3_free(error_message); - return false; - } - - return false; -} - -static bool __alarm_update_due_time_of_all_items_in_list(double diff_time) -{ - time_t current_time; - time_t min_time = -1; - time_t due_time = 0; - GSList *iter = NULL; - __alarm_info_t *entry = NULL; - struct tm *p_time = NULL ; - struct tm due_time_result ; - is_time_changed = true; - - if (periodic_alarm_standard_time != 0) - periodic_alarm_standard_time += diff_time; - - tzset(); - for (iter = alarm_context.alarms; iter != NULL; iter = g_slist_next(iter)) { - entry = iter->data; - alarm_info_t *alarm_info = &(entry->alarm_info); - if (alarm_info->alarm_type & ALARM_TYPE_RELATIVE) { - entry->due_time += diff_time; - - alarm_date_t *start = &alarm_info->start; /**< start time of the alarm */ - alarm_date_t *end = &alarm_info->end; /**< end time of the alarm */ - - p_time = localtime_r(&entry->due_time, &due_time_result); - if (p_time != NULL) { - start->year = p_time->tm_year + 1900; - start->month = p_time->tm_mon + 1; - start->day = p_time->tm_mday; - start->hour = p_time->tm_hour; - start->min = p_time->tm_min; - start->sec = p_time->tm_sec; - } - if (entry->start != 0) - entry->start = entry->due_time; - - if (entry->end != 0) { - entry->end += diff_time; - p_time = localtime_r(&entry->end, &due_time_result); - if (p_time != NULL) { - end->year = p_time->tm_year + 1900; - end->month = p_time->tm_mon + 1; - end->day = p_time->tm_mday; - end->hour = p_time->tm_hour; - end->min = p_time->tm_min; - end->sec = p_time->tm_sec; - } - } - } - _alarm_next_duetime(entry); - } - - time(¤t_time); - - for (iter = alarm_context.alarms; iter != NULL; iter = g_slist_next(iter)) { - entry = iter->data; - due_time = entry->due_time; - - double interval = 0; - - ALARM_MGR_LOG_PRINT("alarm[%d] with duetime(%ld) at current(%ld)", entry->alarm_id, due_time, current_time); - if (due_time == 0) { /* 0 means this alarm has been disabled */ - continue; - } - - interval = difftime(due_time, current_time); - - if (interval < 0) { - ALARM_MGR_EXCEPTION_PRINT("The duetime of alarm(%d) is OVER.", entry->alarm_id); - continue; - } - - interval = difftime(due_time, min_time); - - if ((interval < 0) || min_time == -1) - min_time = due_time; - } - - is_time_changed = false; - alarm_context.c_due_time = min_time; - - g_idle_add(__update_relative_alarms, NULL); - return true; -} - -static void __set_caller_info(bundle *b, int pid, uid_t uid, - const char *appid, const char *pkgid) -{ - char buf[12]; - - snprintf(buf, sizeof(buf), "%u", uid); - bundle_del(b, AUL_K_ORG_CALLER_UID); - bundle_add(b, AUL_K_ORG_CALLER_UID, buf); - - bundle_del(b, AUL_K_ORG_CALLER_APPID); - bundle_add(b, AUL_K_ORG_CALLER_APPID, appid); - - if (pkgid) { - bundle_del(b, AUL_K_ORG_CALLER_PKGID); - bundle_add(b, AUL_K_ORG_CALLER_PKGID, pkgid); - } -} - -static bool __alarm_create_appsvc(alarm_info_t *alarm_info, alarm_id_t *alarm_id, - long requested_interval, uid_t uid, int pid, char *bundle_data, int *error_code) -{ - time_t current_time; - time_t due_time; - struct tm ts_ret; - char due_time_r[100] = { 0 }; - char app_name[512] = { 0 }; - bundle *b; - const char *callee_appid = NULL; - char *caller_pkgid = NULL; - char *callee_pkgid = NULL; - pkgmgrinfo_pkginfo_h caller_handle; - pkgmgrinfo_pkginfo_h callee_handle; - bundle_raw *b_data = NULL; - int datalen = 0; - bool caller_is_app = false; - - __alarm_info_t *__alarm_info = NULL; - - __alarm_info = (__alarm_info_t *)calloc(1, sizeof(__alarm_info_t)); - if (__alarm_info == NULL) { - SECURE_LOGE("Caution!! app_pid=%d, calloc failed. it seems to be OOM.", pid); - *error_code = ERR_ALARM_SYSTEM_FAIL; - return false; - } - - __alarm_info->uid = uid; - __alarm_info->pid = pid; - __alarm_info->alarm_id = -1; - __alarm_info->requested_interval = requested_interval; - __alarm_info->global = false; - - if (__get_cached_unique_name(pid, app_name, sizeof(app_name), &caller_is_app, uid) == false) { - *error_code = ERR_ALARM_SYSTEM_FAIL; - _release_alarm_info_t(__alarm_info); - return false; - } - __alarm_info->app_unique_name = strdup(app_name); - - /* caller */ - if (caller_is_app) { - if (pkgmgrinfo_appinfo_get_usr_appinfo(app_name, uid, &caller_handle) == PMINFO_R_OK) { - if (pkgmgrinfo_appinfo_get_pkgid(caller_handle, &caller_pkgid) == PMINFO_R_OK) { - if (caller_pkgid) - __alarm_info->caller_pkgid = strdup(caller_pkgid); - } - pkgmgrinfo_appinfo_destroy_appinfo(caller_handle); - } - } - - /* callee */ - b = bundle_decode((bundle_raw *)bundle_data, strlen(bundle_data)); - callee_appid = appsvc_get_appid(b); - if (pkgmgrinfo_appinfo_get_usr_appinfo(callee_appid, uid, &callee_handle) == PMINFO_R_OK) { - if (pkgmgrinfo_appinfo_get_pkgid(callee_handle, &callee_pkgid) == PMINFO_R_OK) { - if (callee_pkgid) - __alarm_info->callee_pkgid = strdup(callee_pkgid); - } - pkgmgrinfo_appinfo_destroy_appinfo(callee_handle); - } - - if (b && caller_is_app) { - __set_caller_info(b, pid, uid, app_name, - __alarm_info->caller_pkgid); - bundle_del(b, AUL_K_REQUEST_TYPE); - bundle_add(b, AUL_K_REQUEST_TYPE, "indirect-request"); - } - - SECURE_LOGD("caller_pkgid = %s, callee_pkgid = %s", - __alarm_info->caller_pkgid, __alarm_info->callee_pkgid); - - bundle_encode(b, &b_data, &datalen); - if (b_data) - __alarm_info->bundle = strdup((const gchar *)b_data); - - bundle_free(b); - if (b_data) { - free(b_data); - b_data = NULL; - } - - __alarm_set_start_and_end_time(alarm_info, __alarm_info); - memcpy(&(__alarm_info->alarm_info), alarm_info, sizeof(alarm_info_t)); - __alarm_generate_alarm_id(__alarm_info, alarm_id); - - time(¤t_time); - - if (alarm_context.c_due_time < current_time) { - ALARM_MGR_EXCEPTION_PRINT("Caution!! alarm_context.c_due_time " - "(%ld) is less than current time(%ld)", alarm_context.c_due_time, current_time); - alarm_context.c_due_time = -1; - } - - due_time = _alarm_next_duetime(__alarm_info); - __alarm_add_to_list(__alarm_info); - - if (due_time == 0) { - ALARM_MGR_EXCEPTION_PRINT("[alarm-server]:Create a new alarm: " - "due_time is 0, alarm(%d) \n", *alarm_id); - return true; - } else if (current_time == due_time) { - ALARM_MGR_EXCEPTION_PRINT("[alarm-server]:Create alarm: " - "current_time(%ld) is same as due_time(%ld)", current_time, - due_time); - return true; - } else if (difftime(due_time, current_time) < 0) { - ALARM_MGR_EXCEPTION_PRINT("[alarm-server]: Expired Due Time.[Due time=%ld, Current Time=%ld]!!!Do not add to schedule list\n", due_time, current_time); - return true; - } else { - localtime_r(&due_time, &ts_ret); - strftime(due_time_r, 30, "%c", &ts_ret); - SECURE_LOGD("[alarm-server]:Create a new alarm: " - "alarm(%d) due_time(%s)", *alarm_id, - due_time_r); - } - - ALARM_MGR_LOG_PRINT("[alarm-server]:alarm_context.c_due_time(%ld), due_time(%ld)", alarm_context.c_due_time, due_time); - - if (alarm_context.c_due_time == -1 || due_time < alarm_context.c_due_time) { - _clear_scheduled_alarm_list(); - _add_to_scheduled_alarm_list(__alarm_info); - _alarm_set_timer(&alarm_context, alarm_context.timer, due_time); - alarm_context.c_due_time = due_time; - __rtc_set(); - } else if (due_time == alarm_context.c_due_time) { - _add_to_scheduled_alarm_list(__alarm_info); - } - - return true; -} - -static bool __alarm_create(alarm_info_t *alarm_info, alarm_id_t *alarm_id, uid_t uid, - int pid, periodic_method_e method, long requested_interval, int is_ref, - char *app_service_name, char *app_service_name_mod, - const char *dst_service_name, const char *dst_service_name_mod, - int *error_code) -{ - time_t current_time; - time_t due_time; - char unique_name[MAX_APP_ID] = { 0 }; - char *caller_pkgid = NULL; - pkgmgrinfo_pkginfo_h caller_handle; - bool caller_is_app = false; - - __alarm_info_t *__alarm_info = NULL; - - __alarm_info = (__alarm_info_t *)calloc(1, sizeof(__alarm_info_t)); - if (__alarm_info == NULL) { - SECURE_LOGE("Caution!! app_pid=%d, calloc " - "failed. it seems to be OOM\n", pid); - *error_code = ERR_ALARM_SYSTEM_FAIL; - return false; - } - __alarm_info->uid = uid; - __alarm_info->pid = pid; - __alarm_info->alarm_id = -1; - __alarm_info->method = method; - __alarm_info->requested_interval = requested_interval; - __alarm_info->is_ref = is_ref; - __alarm_info->global = false; - - if (__get_cached_unique_name(pid, unique_name, sizeof(unique_name), - &caller_is_app, uid) == false) { - *error_code = ERR_ALARM_SYSTEM_FAIL; - _release_alarm_info_t(__alarm_info); - return false; - } - - /* Get caller_appid to get caller's package id. There is no callee. */ - if (caller_is_app) { - if (pkgmgrinfo_appinfo_get_usr_appinfo(unique_name, uid, &caller_handle) == PMINFO_R_OK) { - if (pkgmgrinfo_appinfo_get_pkgid(caller_handle, &caller_pkgid) == PMINFO_R_OK) { - if (caller_pkgid) - __alarm_info->caller_pkgid = strdup(caller_pkgid); - } - pkgmgrinfo_appinfo_destroy_appinfo(caller_handle); - } - } - - SECURE_LOGD("caller_pkgid = %s, callee_pkgid = null", __alarm_info->caller_pkgid); - - __alarm_info->app_unique_name = strdup(unique_name); - if (app_service_name) - __alarm_info->app_service_name = strdup(app_service_name); - if (app_service_name_mod) - __alarm_info->app_service_name_mod = strdup(app_service_name_mod); - if (dst_service_name) - __alarm_info->dst_service_name = strdup(dst_service_name); - if (dst_service_name_mod) - __alarm_info->dst_service_name_mod = strdup(dst_service_name_mod); - - __alarm_set_start_and_end_time(alarm_info, __alarm_info); - memcpy(&(__alarm_info->alarm_info), alarm_info, sizeof(alarm_info_t)); - __alarm_generate_alarm_id(__alarm_info, alarm_id); - - time(¤t_time); - - SECURE_LOGD("[alarm-server]:pid=%d, app_unique_name=%s, " - "app_service_name=%s,dst_service_name=%s, c_due_time=%ld", \ - pid, __alarm_info->app_unique_name, \ - __alarm_info->app_service_name, \ - __alarm_info->dst_service_name, \ - alarm_context.c_due_time); - - if (alarm_context.c_due_time < current_time) { - ALARM_MGR_EXCEPTION_PRINT("Caution!! alarm_context.c_due_time " - "(%ld) is less than current time(%ld)", alarm_context.c_due_time, current_time); - alarm_context.c_due_time = -1; - } - - due_time = _alarm_next_duetime(__alarm_info); - __alarm_add_to_list(__alarm_info); - - if (due_time == 0) { - ALARM_MGR_EXCEPTION_PRINT("[alarm-server]:Create a new alarm: due_time is 0, alarm(%d).", *alarm_id); - return true; - } else if (current_time == due_time) { - ALARM_MGR_EXCEPTION_PRINT("[alarm-server]:Create alarm: current_time(%ld) is same as due_time(%ld).", - current_time, due_time); - return true; - } else if (difftime(due_time, current_time) < 0) { - ALARM_MGR_EXCEPTION_PRINT("[alarm-server]: Expired Due Time.[Due time=%ld, Current Time=%ld]!!!Do not add to schedule list.", - due_time, current_time); - return true; - } else { - char due_time_r[100] = { 0 }; - struct tm ts_ret; - localtime_r(&due_time, &ts_ret); - strftime(due_time_r, 30, "%c", &ts_ret); - SECURE_LOGD("[alarm-server]:Create a new alarm: alarm(%d) due_time(%s)", *alarm_id, due_time_r); - } - - ALARM_MGR_LOG_PRINT("[alarm-server]:alarm_context.c_due_time(%ld), due_time(%ld)", alarm_context.c_due_time, due_time); - - if (alarm_context.c_due_time == -1 || due_time < alarm_context.c_due_time) { - _clear_scheduled_alarm_list(); - _add_to_scheduled_alarm_list(__alarm_info); - _alarm_set_timer(&alarm_context, alarm_context.timer, due_time); - alarm_context.c_due_time = due_time; - __rtc_set(); - } else if (due_time == alarm_context.c_due_time) { - _add_to_scheduled_alarm_list(__alarm_info); - } - - return true; -} - -static char *__create_new_noti_data(char *noti_data, pid_t pid, uid_t uid) -{ - GVariant *noti_gv; - guchar *decoded_data; - int decoded_datalen; - notification_h noti = NULL; - char *new_noti_data = NULL; - guchar* data = NULL; - int datalen; - - decoded_data = g_base64_decode(noti_data, (gsize *)&decoded_datalen); - if (decoded_data == NULL) - return NULL; - - noti = __get_notification(decoded_data, decoded_datalen); - if (noti == NULL) - goto end; - - notification_set_indirect_request(noti, pid, uid); - - noti_gv = notification_ipc_make_gvariant_from_noti(noti, false); - if (noti_gv == NULL) - goto end; - - datalen = g_variant_get_size(noti_gv); - if (datalen < 0) - goto end; - - data = malloc(datalen); - if (data == NULL) - goto end; - - g_variant_store(noti_gv, data); - new_noti_data = g_base64_encode(data, datalen); - -end: - if (data) - free(data); - if (noti) - notification_free(noti); - if (decoded_data) - g_free(decoded_data); - - return new_noti_data; -} - -static bool __alarm_create_noti(alarm_info_t *alarm_info, alarm_id_t *alarm_id, - long requested_interval, uid_t uid, int pid, char *noti_data, int *error_code) -{ - time_t current_time; - time_t due_time; - struct tm ts_ret; - char due_time_r[100] = { 0 }; - char app_name[512] = { 0 }; - char *caller_pkgid = NULL; - pkgmgrinfo_pkginfo_h caller_handle; - bool caller_is_app = false; - char *new_noti_data = NULL; - - __alarm_info_t *__alarm_info = NULL; - - __alarm_info = (__alarm_info_t *)calloc(1, sizeof(__alarm_info_t)); - if (__alarm_info == NULL) { - SECURE_LOGE("Caution!! app_pid=%d, calloc " - "failed. it seems to be OOM\n", pid); - *error_code = ERR_ALARM_SYSTEM_FAIL; - return false; - } - __alarm_info->uid = uid; - __alarm_info->pid = pid; - __alarm_info->alarm_id = -1; - __alarm_info->requested_interval = requested_interval; - __alarm_info->global = false; - - if (__get_cached_unique_name(pid, app_name, sizeof(app_name), &caller_is_app, uid) == false) { - *error_code = ERR_ALARM_SYSTEM_FAIL; - _release_alarm_info_t(__alarm_info); - return false; - } - __alarm_info->app_unique_name = strdup(app_name); - - if (caller_is_app) { - if (pkgmgrinfo_appinfo_get_usr_appinfo(app_name, uid, &caller_handle) == PMINFO_R_OK) { - if (pkgmgrinfo_appinfo_get_pkgid(caller_handle, &caller_pkgid) == PMINFO_R_OK) { - if (caller_pkgid) - __alarm_info->caller_pkgid = strdup(caller_pkgid); - } - pkgmgrinfo_appinfo_destroy_appinfo(caller_handle); - } - } - - SECURE_LOGD("caller_pkgid = %s, callee_pkgid = null", - __alarm_info->caller_pkgid); - - if (noti_data) { - if (caller_is_app) { - new_noti_data = __create_new_noti_data(noti_data, pid, - uid); - } - - if (new_noti_data) - __alarm_info->noti = new_noti_data; - else - __alarm_info->noti = strdup(noti_data); - } - - __alarm_set_start_and_end_time(alarm_info, __alarm_info); - memcpy(&(__alarm_info->alarm_info), alarm_info, sizeof(alarm_info_t)); - __alarm_generate_alarm_id(__alarm_info, alarm_id); - - time(¤t_time); - - SECURE_LOGD("[alarm-server]:pid=%d, app_unique_name=%s, " - "app_service_name=%s,dst_service_name=%s, c_due_time=%ld", \ - pid, __alarm_info->app_unique_name, \ - __alarm_info->app_service_name, \ - __alarm_info->dst_service_name, \ - alarm_context.c_due_time); - - if (alarm_context.c_due_time < current_time) { - ALARM_MGR_EXCEPTION_PRINT("Caution!! alarm_context.c_due_time " - "(%ld) is less than current time(%ld)", alarm_context.c_due_time, current_time); - alarm_context.c_due_time = -1; - } - - due_time = _alarm_next_duetime(__alarm_info); - __alarm_add_to_list(__alarm_info); - - if (due_time == 0) { - ALARM_MGR_EXCEPTION_PRINT("[alarm-server]:Create a new alarm: due_time is 0, alarm(%d).", *alarm_id); - return true; - } else if (current_time == due_time) { - ALARM_MGR_EXCEPTION_PRINT("[alarm-server]:Create alarm: current_time(%ld) is same as due_time(%ld).", - current_time, due_time); - return true; - } else if (difftime(due_time, current_time) < 0) { - ALARM_MGR_EXCEPTION_PRINT("[alarm-server]: Expired Due Time.[Due time=%ld, Current Time=%ld]!!!Do not add to schedule list.", - due_time, current_time); - return true; - } else { - localtime_r(&due_time, &ts_ret); - strftime(due_time_r, 30, "%c", &ts_ret); - SECURE_LOGD("[alarm-server]:Create a new alarm: alarm(%d) due_time(%s)", *alarm_id, due_time_r); - } - - ALARM_MGR_LOG_PRINT("[alarm-server]:alarm_context.c_due_time(%ld), due_time(%ld)", alarm_context.c_due_time, due_time); - - if (alarm_context.c_due_time == -1 || due_time < alarm_context.c_due_time) { - _clear_scheduled_alarm_list(); - _add_to_scheduled_alarm_list(__alarm_info); - _alarm_set_timer(&alarm_context, alarm_context.timer, due_time); - alarm_context.c_due_time = due_time; - __rtc_set(); - } else if (due_time == alarm_context.c_due_time) { - _add_to_scheduled_alarm_list(__alarm_info); - } - - return true; -} - -static bool __alarm_update(uid_t uid, int pid, alarm_id_t alarm_id, - alarm_info_t *alarm_info, int update_flag, int *error_code) -{ - time_t current_time; - time_t due_time; - - __alarm_info_t *__alarm_info = NULL; - bool result = false; - - time(¤t_time); - - if (alarm_context.c_due_time < current_time) { - ALARM_MGR_EXCEPTION_PRINT("Caution!! alarm_context.c_due_time " - "(%ld) is less than current time(%ld)", alarm_context.c_due_time, current_time); - alarm_context.c_due_time = -1; - } - - __alarm_info = __alarm_update_in_list(uid, alarm_id, alarm_info, - update_flag, error_code); - if (!__alarm_info) { - ALARM_MGR_EXCEPTION_PRINT("[alarm-server]: requested alarm_id " - "(%d) does not exist. so this value is invalid id.", alarm_id); - return false; - } - - due_time = _alarm_next_duetime(__alarm_info); - - result = _remove_from_scheduled_alarm_list(uid, alarm_id); - - if (result == true && g_slist_length(g_scheduled_alarm_list) == 0) { - /*there is no scheduled alarm */ - _alarm_disable_timer(alarm_context); - _alarm_schedule(); - - ALARM_MGR_LOG_PRINT("[alarm-server]:Update alarm: alarm(%d).", alarm_id); - - __rtc_set(); - - if (due_time == 0) - ALARM_MGR_EXCEPTION_PRINT("[alarm-server]:Update alarm: due_time is 0."); - - return true; - } - - if (due_time == 0) { - ALARM_MGR_EXCEPTION_PRINT("[alarm-server]:Update alarm: " - "due_time is 0, alarm(%d)\n", alarm_id); - return true; - } else if (current_time == due_time) { - ALARM_MGR_EXCEPTION_PRINT("[alarm-server]:Update alarm: " - "current_time(%ld) is same as due_time(%ld)", current_time, - due_time); - return true; - } else if (difftime(due_time, current_time) < 0) { - ALARM_MGR_EXCEPTION_PRINT("[alarm-server]: Expired Due Time.[Due time=%ld, Current Time=%ld]!!!Do not add to schedule list\n", due_time, current_time); - return true; - } else { - char due_time_r[100] = { 0 }; - struct tm ts_ret; - localtime_r(&due_time, &ts_ret); - strftime(due_time_r, 30, "%c", &ts_ret); - SECURE_LOGD("[alarm-server]:Update alarm: alarm(%d) " - "due_time(%s)\n", alarm_id, due_time_r); - } - - ALARM_MGR_LOG_PRINT("[alarm-server]:alarm_context.c_due_time(%ld), due_time(%ld)", alarm_context.c_due_time, due_time); - - if (alarm_context.c_due_time == -1 || due_time < alarm_context.c_due_time) { - _clear_scheduled_alarm_list(); - _add_to_scheduled_alarm_list(__alarm_info); - _alarm_set_timer(&alarm_context, alarm_context.timer, due_time); - alarm_context.c_due_time = due_time; - ALARM_MGR_LOG_PRINT("[alarm-server1]:alarm_context.c_due_time " - "(%ld), due_time(%ld)", alarm_context.c_due_time, due_time); - } else if (due_time == alarm_context.c_due_time) { - _add_to_scheduled_alarm_list(__alarm_info); - ALARM_MGR_LOG_PRINT("[alarm-server2]:alarm_context.c_due_time " - "(%ld), due_time(%ld)", alarm_context.c_due_time, due_time); - } - - __rtc_set(); - - return true; -} - -static bool __alarm_set_global_to_db(__alarm_info_t *alarm_info, bool global) -{ - - char *error_message = NULL; - char *query = sqlite3_mprintf("update alarmmgr set global=%d where alarm_id=%d", - alarm_info->global, alarm_info->alarm_id); - - if (SQLITE_OK != sqlite3_exec(alarmmgr_db, query, NULL, NULL, &error_message)) { - SECURE_LOGE("sqlite3_exec() is failed. query = %s, error message = %s", query, error_message); - sqlite3_free(query); - sqlite3_free(error_message); - return false; - } - - sqlite3_free(query); - return true; -} - - -static bool __alarm_delete(uid_t uid, alarm_id_t alarm_id, int *error_code) -{ - bool result = false; - - SECURE_LOGD("[alarm-server]:delete alarm: alarm(%d) uid(%d)\n", alarm_id, uid); - result = _remove_from_scheduled_alarm_list(uid, alarm_id); - - if (!__alarm_remove_from_list(uid, alarm_id, error_code)) { - - SECURE_LOGE("[alarm-server]:delete alarm: " - "alarm(%d) uid(%d) has failed with error_code(%d)\n", - alarm_id, uid, *error_code); - return false; - } - - if (result == true && g_slist_length(g_scheduled_alarm_list) == 0) { - _alarm_disable_timer(alarm_context); - _alarm_schedule(); - __rtc_set(); - } - - return true; -} - -static bool __can_skip_expired_cb(alarm_id_t alarm_id) -{ - GSList *gs_iter = NULL; - __alarm_info_t *entry = NULL; - alarm_info_t *alarm = NULL; - - for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { - entry = gs_iter->data; - if (entry->alarm_id == alarm_id) { - alarm = &(entry->alarm_info); - time_t ts = 0; - struct tm ts_tm; - int dur = entry->requested_interval; - int from, to; - - if (dur == 0 || !(alarm->alarm_type & ALARM_TYPE_PERIOD) || entry->method == CUT_OFF) - return false; - - ts_tm.tm_hour = alarm->start.hour; - ts_tm.tm_min = alarm->start.min; - ts_tm.tm_sec = alarm->start.sec; - - ts_tm.tm_year = alarm->start.year - 1900; - ts_tm.tm_mon = alarm->start.month - 1; - ts_tm.tm_mday = alarm->start.day; - ts_tm.tm_isdst = -1; - - ts = mktime(&ts_tm); - - from = (ts / dur) * dur; - to = from + dur; - - if (ts >= from && ts < to && from > ts - alarm->mode.u_interval.interval) - return false; - - return true; - } - } - - return false; -} - -static gboolean __send_noti_to_session_bus(char *service_name, - alarm_id_t alarm_id, int msec, uid_t uid) -{ - int fd; - int ret; - int len; - struct sockaddr_un saddr; - uint8_t *data; - GVariant *gv; - uint8_t *gv_data; - - fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); - if (fd < 0) - return FALSE; - - saddr.sun_family = AF_UNIX; - snprintf(saddr.sun_path, sizeof(saddr.sun_path), - "/run/alarm_agent/%d", uid); - - ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)); - if (ret < 0) { - ALARM_MGR_EXCEPTION_PRINT("connect failed - (errno %d)", errno); - close(fd); - return FALSE; - } - - gv = g_variant_new("(iis)", alarm_id, msec, service_name); - if (!gv) { - close(fd); - return FALSE; - } - - len = g_variant_get_size(gv); - - gv_data = NULL; - if (len > 0) - gv_data = malloc(len); - - if (!gv_data) { - g_variant_unref(gv); - close(fd); - return FALSE; - } - - g_variant_store(gv, gv_data); - g_variant_unref(gv); - - data = malloc(len + 4); - if (!data) { - close(fd); - free(gv_data); - return FALSE; - } - - memcpy(data, &len, 4); - memcpy(data + 4, gv_data, len); - free(gv_data); - - if (send(fd, data, len + 4, 0) == -1) { - ALARM_MGR_EXCEPTION_PRINT("sendto() failed (errno %d)", errno); - free(data); - close(fd); - return FALSE; - } - - free(data); - close(fd); - return TRUE; -} - -static void __alarm_send_noti_to_application(const char *app_service_name, - alarm_id_t alarm_id, int msec, uid_t uid) -{ - char service_name[MAX_SERVICE_NAME_LEN] = {0,}; - gboolean ret; - - if (app_service_name == NULL || strlen(app_service_name) == 0) { - ALARM_MGR_EXCEPTION_PRINT("This alarm destination is invalid."); - return; - } - - if (__can_skip_expired_cb(alarm_id)) - return; - - strncpy(service_name, app_service_name, sizeof(service_name) - 1); - SECURE_LOGI("[alarm server][send expired_alarm(alarm_id=%d) to app_service_name(%s)]", alarm_id, service_name); - - if (uid >= REGULAR_UID_MIN) { - ret = __send_noti_to_session_bus(service_name, alarm_id, msec, uid); - if (ret != TRUE) - ALARM_MGR_EXCEPTION_PRINT("failed to send alarm expired noti for %d, %s", - alarm_id, service_name); - } else { - g_dbus_connection_call(alarm_context.connection, - service_name, - "/org/tizen/alarm/client", - "org.tizen.alarm.client", - "alarm_expired", - g_variant_new("(iis)", alarm_id, msec, service_name), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - NULL, - NULL); - } -} - -static int __get_caller_uid(const char *name) -{ - guint uid; - GVariant *ret; - GError *error = NULL; - - ret = g_dbus_connection_call_sync( - alarm_context.connection, - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus", - "GetConnectionUnixUser", - g_variant_new("(s)", name), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (!ret) { - ALARM_MGR_EXCEPTION_PRINT("failed to get caller uid"); - if (error) { - ALARM_MGR_EXCEPTION_PRINT("dbus error message : %s", error->message); - g_error_free(error); - } - return -1; - } - g_variant_get(ret, "(u)", &uid); - g_variant_unref(ret); - - return uid; -} - -static int __get_caller_pid(const char *name) -{ - guint pid; - GVariant *ret; - GError *error = NULL; - - ret = g_dbus_connection_call_sync(alarm_context.connection, - "org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus", - "GetConnectionUnixProcessID", - g_variant_new("(s)", name), - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - &error); - if (!ret) { - ALARM_MGR_EXCEPTION_PRINT("failed to get caller pid"); - if (error) { - ALARM_MGR_EXCEPTION_PRINT("dbus error message : %s", error->message); - g_error_free(error); - } - return -1; - } - g_variant_get(ret, "(u)", &pid); - g_variant_unref(ret); - - return pid; -} - -static int __is_ui_app(const char *appid, uid_t uid) -{ - if (appid == NULL) - return 0; - - int ret = 0; - pkgmgrinfo_appinfo_h appinfo_h = NULL; - - ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &appinfo_h); - - if (ret < 0) - return 0; - - char *component = NULL; - int found = 0; - - ret = pkgmgrinfo_appinfo_get_component_type(appinfo_h, &component); - if (ret == 0 && component != NULL && strncmp(component, "uiapp", 5) == 0) - found = 1; - - if (appinfo_h) - pkgmgrinfo_appinfo_destroy_appinfo(appinfo_h); - - return found; -} - -static int __compare_api_version(int *result, int pid, uid_t uid) -{ - int ret = 0; - pkgmgrinfo_pkginfo_h pkginfo = NULL; - char pkgid[512] = {0, }; - char *pkg_version; - - if (aul_app_get_pkgid_bypid_for_uid(pid, pkgid, sizeof(pkgid), uid) != AUL_R_OK) { - ALARM_MGR_EXCEPTION_PRINT("aul_app_get_pkgid_bypid() is failed. PID %d may not be app.", getpid()); - } else { - ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &pkginfo); - if (ret != PMINFO_R_OK) { - ALARM_MGR_EXCEPTION_PRINT("Failed to get pkginfo\n"); - } else { - ret = pkgmgrinfo_pkginfo_get_api_version(pkginfo, &pkg_version); - if (ret != PMINFO_R_OK) - ALARM_MGR_EXCEPTION_PRINT("Failed to check api version [%d]\n", ret); - *result = strverscmp(pkg_version, "2.4"); - pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); - } - } - return ret; -} - -static int __bg_category_func(const char *name, void *user_data) -{ - bg_category_cb_info_t *info = (bg_category_cb_info_t *)user_data; - ALARM_MGR_LOG_PRINT("appid[%s], bg name = %s", info->appid, name); - if (name && strncmp("enable", name, strlen(name)) && - strncmp("disable", name, strlen(name))) { - info->has_bg = true; - return -1; - } - - return 0; -} - -static bool __is_permitted(const char *app_id, int alarm_type, uid_t uid) -{ - pkgmgrinfo_appinfo_h handle = NULL; - int ret; - bool _return = false; - - if (app_id == NULL) { - ALARM_MGR_EXCEPTION_PRINT("app_id is NULL. Only expicit launch is permitted\n"); - return false; - } - - ret = pkgmgrinfo_appinfo_get_usr_appinfo(app_id, uid, &handle); - if (ret != PMINFO_R_OK) { - ALARM_MGR_EXCEPTION_PRINT("Failed to get appinfo [%s]\n", app_id); - } else { - char *app_type = NULL; - ret = pkgmgrinfo_appinfo_get_component_type(handle, &app_type); - if (app_type && strcmp("uiapp", app_type) == 0) { - if (alarm_type & ALARM_TYPE_EXACT_SERVICE_APP) { - ALARM_MGR_EXCEPTION_PRINT("[%s] is ui application. it is not allowed", app_id); - _return = false; - goto out; - } - ALARM_MGR_LOG_PRINT("[%s] is ui application. It is allowed", app_id); - _return = true; - goto out; - } else if (app_type && strcmp("svcapp", app_type) == 0) { - ALARM_MGR_LOG_PRINT("[%s] is service application.", app_id); - - if (__permit_by_config(handle, uid)) { - ALARM_MGR_LOG_PRINT("service applications are allowed"); - _return = true; - goto out; - } - - bg_category_cb_info_t info = { - .appid = app_id, - .has_bg = false - }; - - if (alarm_type & ALARM_TYPE_INEXACT || alarm_type & ALARM_TYPE_EXACT_SERVICE_APP) { - ret = pkgmgrinfo_appinfo_foreach_background_category(handle, __bg_category_func, &info); - if (ret == PMINFO_R_OK && info.has_bg) { - ALARM_MGR_LOG_PRINT("[%s] has background categories. It is allowed", app_id); - _return = true; - goto out; - } else { - ALARM_MGR_EXCEPTION_PRINT("Failed to foreach background category. [%s] is not allowed", app_id); - } - } - } - } - -out: - if (handle) - pkgmgrinfo_appinfo_destroy_appinfo(handle); - - return _return; -} - - - -static int __find_login_user(uid_t *uid) -{ - uid_t *uids; - int ret, i; - char *state; - - ret = sd_get_uids(&uids); - if (ret <= 0) - return -1; - - for (i = 0; i < ret; i++) { - if (sd_uid_get_state(uids[i], &state) < 0) { - free(uids); - return -1; - } else { - if (!strncmp(state, "online", 6)) { - *uid = uids[i]; - free(uids); - free(state); - return 0; - } - } - } - free(uids); - free(state); - return -1; -} - -static notification_h __get_notification(guchar *data, int datalen) -{ - int ret; - GVariant *noti_gv = NULL; - GVariant *body = NULL; - notification_h noti; - - if (data == NULL || datalen <= 0) - return NULL; - - noti_gv = g_variant_new_from_data(G_VARIANT_TYPE("(v)"), - data, datalen, TRUE, NULL, NULL); - - if (noti_gv == NULL) - return NULL; - - g_variant_get(noti_gv, "(v)", &body); - - if (body == NULL) { - g_variant_unref(noti_gv); - return NULL; - } - - noti = notification_create(NOTIFICATION_TYPE_NOTI); - if (noti == NULL) { - g_variant_unref(body); - g_variant_unref(noti_gv); - return NULL; - } - - ret = notification_ipc_make_noti_from_gvariant(noti, body); - - if (ret != NOTIFICATION_ERROR_NONE) { - g_variant_unref(body); - g_variant_unref(noti_gv); - notification_free(noti); - return NULL; - } - - g_variant_unref(body); - g_variant_unref(noti_gv); - - return noti; -} - -static int __post_notification(guchar *data, int datalen, uid_t uid) -{ - int ret; - notification_h noti; - int expire_mode = ALARM_EXPIRE_MODE_NORMAL; - - noti = __get_notification(data, datalen); - if (noti == NULL) - return -1; - - if (vconf_get_int(VCONFKEY_ALARM_EXPIRE_MODE, &expire_mode) != 0) - ALARM_MGR_EXCEPTION_PRINT("Failed to get value of VCONFKEY_ALARM_EXPIRE_MODE"); - - ALARM_MGR_LOG_PRINT("Value of alarm_expire_mode [%d]", expire_mode); - - if (expire_mode == ALARM_EXPIRE_MODE_NORMAL) - device_display_change_state(DISPLAY_STATE_NORMAL); - - ret = notification_post_for_uid(noti, uid); - - notification_free(noti); - - return ret; -} - -static int __app_info_iter(const aul_app_info *info, void *data) -{ - struct running_info_t *app_info = (struct running_info_t *)data; - - if (app_info->pid == info->pid && - strcmp(app_info->appid, info->appid) == 0) - app_info->is_running = true; - - return 0; -} - -static void __alarm_expired() -{ - int ret; - const char *destination_app_service_name = NULL; - alarm_id_t alarm_id = -1; - int app_pid = 0; - __alarm_info_t *__alarm_info = NULL; - char alarm_id_val[32]; - int b_len = 0; - bundle *b = NULL; - char *appid = NULL; - uid_t target_uid; -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; -#endif - - ALARM_MGR_LOG_PRINT("[alarm-server]: Enter"); - - time_t current_time; - double interval; - - time(¤t_time); - - interval = difftime(alarm_context.c_due_time, current_time); - ALARM_MGR_LOG_PRINT("[alarm-server]: c_due_time(%ld), current_time(%ld), interval(%f)", - alarm_context.c_due_time, current_time, interval); - - if (alarm_context.c_due_time > current_time + 1) { - ALARM_MGR_EXCEPTION_PRINT("[alarm-server]: False Alarm. due time is (%ld) seconds future", - alarm_context.c_due_time - current_time); - goto done; - } - /* 10 seconds is maximum permitted delay from timer expire to this function */ - if (alarm_context.c_due_time + 10 < current_time) { - ALARM_MGR_EXCEPTION_PRINT("[alarm-server]: False Alarm. due time is (%ld) seconds past.", - current_time - alarm_context.c_due_time); - goto done; - } - - GSList *iter = NULL; - __scheduled_alarm_t *alarm = NULL; - - for (iter = g_scheduled_alarm_list; iter != NULL; iter = g_slist_next(iter)) { - alarm = iter->data; - alarm_id = alarm->alarm_id; - __alarm_info = alarm->__alarm_info; - app_pid = __alarm_info->pid; - - /* Case #1. The process is an application launched by app_control. - * It registered an alarm using launch-based APIs like alarm_schedule_xxx, alarmmgr_xxx_appsvc. */ - if (__alarm_info->bundle != NULL) { - b_len = strlen(__alarm_info->bundle); - - b = bundle_decode((bundle_raw *)(__alarm_info->bundle), b_len); - - if (b == NULL) { - ALARM_MGR_EXCEPTION_PRINT("Error!!!..Unable to decode the bundle!!\n"); - } else { - snprintf(alarm_id_val, sizeof(alarm_id_val), "%d", alarm_id); - - if (bundle_add_str(b, "http://tizen.org/appcontrol/data/alarm_id", alarm_id_val)) { - ALARM_MGR_EXCEPTION_PRINT("Unable to add alarm id to the bundle\n"); - } else { - int result = 0; - int expire_mode = ALARM_EXPIRE_MODE_NORMAL; - if (vconf_get_int(VCONFKEY_ALARM_EXPIRE_MODE, &expire_mode) != 0) - ALARM_MGR_EXCEPTION_PRINT("Failed to get value of VCONFKEY_ALARM_EXPIRE_MODE"); - - ALARM_MGR_LOG_PRINT("Value of alarm_expire_mode [%d]", expire_mode); - - if (__compare_api_version(&result, app_pid, __alarm_info->uid) < 0) { - ALARM_MGR_EXCEPTION_PRINT("Unable to check api version\n"); - result = -1; - } - - if (result < 0) { - /* before 2.4 */ - if (aul_svc_run_service_async_for_uid(b, 0, NULL, NULL, __alarm_info->uid) < 0) - ALARM_MGR_EXCEPTION_PRINT("Unable to run app svc\n"); - else - ALARM_MGR_LOG_PRINT("Successfuly run app svc\n"); - } else { - /* since 2.4 */ - appid = (char *)appsvc_get_appid(b); - if ((__alarm_info->alarm_info.alarm_type & ALARM_TYPE_NOLAUNCH) && !aul_app_is_running(appid)) { - ALARM_MGR_EXCEPTION_PRINT("This alarm is ignored\n"); - } else if (!(__alarm_info->alarm_info.alarm_type & ALARM_TYPE_INEXACT) || - !__can_skip_expired_cb(__alarm_info->alarm_id)) { - if (__alarm_info->global) { - if (__find_login_user(&target_uid) < 0) { - ALARM_MGR_EXCEPTION_PRINT("Fail to get login user\n"); - ret = -1; - } else { - ret = aul_svc_run_service_async_for_uid(b, 0, NULL, NULL, target_uid); - } - } else { - ret = aul_svc_run_service_async_for_uid(b, 0, NULL, NULL, __alarm_info->uid); - } - - if (ret < 0) { - ALARM_MGR_EXCEPTION_PRINT("Unable to launch app [%s] \n", appid); - } else { - ALARM_MGR_LOG_PRINT("Successfuly ran app svc\n"); - if (__is_ui_app(appid, __alarm_info->uid) && - expire_mode == ALARM_EXPIRE_MODE_NORMAL) - device_display_change_state(DISPLAY_STATE_NORMAL); - } - } - } - } - bundle_free(b); - } - } else if (__alarm_info->noti != NULL) { - guchar *noti_data; - int datalen; - ret = -1; - - noti_data = g_base64_decode(__alarm_info->noti, - (gsize *)&datalen); - if (noti_data) { - ret = __post_notification(noti_data, datalen, __alarm_info->uid); - free(noti_data); - } - - if (ret < 0) - ALARM_MGR_EXCEPTION_PRINT("Failed to post notification\n"); - } else { - char appid[MAX_SERVICE_NAME_LEN] = { 0, }; - pkgmgrinfo_appinfo_h appinfo_handle = NULL; - struct running_info_t app_info; - - if (__alarm_info->dst_service_name == NULL) { - SECURE_LOGD("[alarm-server]:destination is null, so we send expired alarm to %s.", - __alarm_info->app_service_name); - destination_app_service_name = __alarm_info->app_service_name_mod; - } else { - SECURE_LOGD("[alarm-server]:destination :%s", - __alarm_info->dst_service_name); - destination_app_service_name = __alarm_info->dst_service_name_mod; - } - - /* - * we should consider a situation that - * destination_app_service_name is owner_name like (:xxxx) and - * application's pid which registered this alarm was killed.In that case, - * we don't need to send the expire event because the process was killed. - * this causes needless message to be sent. - */ - SECURE_LOGD("[alarm-server]: destination_app_service_name :%s, app_pid=%d", destination_app_service_name, app_pid); - - if (__alarm_info->dst_service_name == NULL) { - if (__alarm_info->app_service_name != NULL && strlen(__alarm_info->app_service_name) > 6) - strncpy(appid, __alarm_info->app_service_name + 6, sizeof(appid) - 1); - } else { - if (strlen(__alarm_info->dst_service_name) > 6) - strncpy(appid, __alarm_info->dst_service_name + 6, sizeof(appid) - 1); - } - - ret = PMINFO_R_ERROR; - if (__alarm_info->uid >= REGULAR_UID_MIN) { - ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, - __alarm_info->uid, &appinfo_handle); - } - ALARM_MGR_LOG_PRINT("appid : %s (%p)", appid, appinfo_handle); - if (appinfo_handle) - pkgmgrinfo_appinfo_destroy_appinfo(appinfo_handle); - - /* Case #2. The process was killed && App type - * This app is launched and owner of DBus connection is changed. and then, expiration noti is sent by DBus. */ - - app_info.is_running = false; - if (ret == PMINFO_R_OK) { - app_info.pid = __alarm_info->pid; - app_info.appid = appid; - aul_app_get_all_running_app_info_for_uid(__app_info_iter, - &app_info, __alarm_info->uid); - } - - if (ret == PMINFO_R_OK && !app_info.is_running) { - __expired_alarm_t *expire_info; - char alarm_id_str[32] = { 0, }; - - if (__alarm_info->alarm_info.alarm_type & ALARM_TYPE_WITHCB) { - __alarm_remove_from_list(__alarm_info->uid, alarm_id, NULL); - goto done; - } - - expire_info = malloc(sizeof(__expired_alarm_t)); - if (G_UNLIKELY(NULL == expire_info)) { - ALARM_MGR_ASSERT_PRINT("[alarm-server]:Malloc failed!Can't notify alarm expiry info\n"); - goto done; - } - memset(expire_info, '\0', sizeof(__expired_alarm_t)); - strncpy(expire_info->service_name, destination_app_service_name, MAX_SERVICE_NAME_LEN-1); - expire_info->alarm_id = alarm_id; - expire_info->uid = __alarm_info->uid; - g_expired_alarm_list = g_slist_append(g_expired_alarm_list, expire_info); - - snprintf(alarm_id_str, 31, "%d", alarm_id); - - SECURE_LOGD("before aul_launch appid(%s) alarm_id_str(%s)", appid, alarm_id_str); - - bundle *kb; - kb = bundle_create(); - bundle_add_str(kb, "__ALARM_MGR_ID", alarm_id_str); - - if (__alarm_info->global) { - if (__find_login_user(&target_uid) < 0) - ALARM_MGR_EXCEPTION_PRINT("Fail to get login user\n"); - else - aul_launch_app_for_uid(appid, kb, target_uid); /* on_bus_name_owner_changed will be called. */ - } else { - aul_launch_app_for_uid(appid, kb, __alarm_info->uid); /* on_bus_name_owner_changed will be called. */ - } - - bundle_free(kb); - } else { - /* Case #3. The process is alive or was killed && non-app type(daemon) - * Expiration noti is sent by DBus. it makes the process alive. (dbus auto activation) */ - ALARM_MGR_LOG_PRINT("before alarm_send_noti_to_application"); - ALARM_MGR_LOG_PRINT("WAKEUP pid: %d", __alarm_info->pid); - - aul_update_freezer_status(__alarm_info->pid, "wakeup"); - __alarm_send_noti_to_application(destination_app_service_name, - alarm_id, __alarm_info->alarm_info.msec, __alarm_info->uid); /* dbus auto activation */ - ALARM_MGR_LOG_PRINT("after __alarm_send_noti_to_application"); - } - } - - ALARM_MGR_LOG_PRINT("alarm_id[%d] is expired.", alarm_id); - -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - snprintf(log_message, sizeof(log_message), "alarmID: %d, pid: %d, duetime: %ld", alarm_id, app_pid, __alarm_info->due_time); - __save_module_log("EXPIRED", log_message); -#endif - - if (__alarm_info->alarm_info.mode.repeat == ALARM_REPEAT_MODE_ONCE) - __alarm_remove_from_list(__alarm_info->uid, alarm_id, NULL); - else - _alarm_next_duetime(__alarm_info); - } - -done: - _clear_scheduled_alarm_list(); - alarm_context.c_due_time = -1; - - ALARM_MGR_LOG_PRINT("[alarm-server]: Leave"); -} - -static gboolean __alarm_handler_idle(gpointer user_data) -{ - GPollFD *gpollfd = (GPollFD *) user_data; - uint64_t exp; - time_t current_time; - - if (gpollfd == NULL) { - ALARM_MGR_EXCEPTION_PRINT("gpollfd is NULL"); - return false; - } - - if (read(gpollfd->fd, &exp, sizeof(uint64_t)) < 0) { - ALARM_MGR_EXCEPTION_PRINT("Reading the fd is failed."); - return false; - } - - ALARM_MGR_LOG_PRINT("Lock the display not to enter LCD OFF"); - if (__display_lock_state(DEVICED_LCD_OFF, DEVICED_STAY_CUR_STATE, 0) != ALARMMGR_RESULT_SUCCESS) - ALARM_MGR_EXCEPTION_PRINT("__display_lock_state() is failed"); - - if (g_dummy_timer_is_set == true) { - ALARM_MGR_LOG_PRINT("dummy alarm timer has expired."); - } else { - ALARM_MGR_LOG_PRINT("__alarm_handler_idle"); - __alarm_expired(); - } - - _alarm_schedule(); - - /* - * Previous alarm can be expired late as tolerance of RTC. - * In this case, Expire alarms forcibly if real duetime is same to current time. - */ - time(¤t_time); - if (alarm_context.c_due_time == current_time) { - ALARM_MGR_LOG_PRINT("Expire alarms forcibly when duetime is same to current time(%ld).", current_time); - __alarm_expired(); - _alarm_schedule(); - } - - __rtc_set(); - - ALARM_MGR_LOG_PRINT("Unlock the display from LCD OFF"); - if (__display_unlock_state(DEVICED_LCD_OFF, DEVICED_SLEEP_MARGIN) != ALARMMGR_RESULT_SUCCESS) - ALARM_MGR_EXCEPTION_PRINT("__display_unlock_state() is failed"); - - return false; -} - -static void __on_system_time_external_changed(keynode_t *node, void *data) -{ - double diff_time = 0.0; - time_t cur_time = 0; - - _alarm_disable_timer(alarm_context); - - if (node) { - diff_time = vconf_keynode_get_dbl(node); - } else { - if (vconf_get_dbl(VCONFKEY_SYSTEM_TIMECHANGE_EXTERNAL, &diff_time) != 0) { - ALARM_MGR_EXCEPTION_PRINT("Failed to get value of VCONFKEY_SYSTEM_TIMECHANGE_EXTERNAL."); - return; - } - } - - tzset(); - time(&cur_time); - - ALARM_MGR_LOG_PRINT("diff_time is %f, New time is %s\n", diff_time, ctime(&cur_time)); - - ALARM_MGR_LOG_PRINT("[alarm-server] System time has been changed externally\n"); - ALARM_MGR_LOG_PRINT("1.alarm_context.c_due_time is %ld\n", - alarm_context.c_due_time); - - __set_time(cur_time); - - vconf_set_int(VCONFKEY_SYSTEM_TIME_CHANGED, (int)diff_time); - bundle *b = NULL; - b = bundle_create(); - bundle_add_str(b, EVT_KEY_TIME_CHANGED, EVT_VAL_TIME_CHANGED_TRUE); - eventsystem_send_system_event(SYS_EVENT_TIME_CHANGED, b); - bundle_free(b); - - __alarm_update_due_time_of_all_items_in_list(diff_time); - - ALARM_MGR_LOG_PRINT("2.alarm_context.c_due_time is %ld\n", - alarm_context.c_due_time); - _clear_scheduled_alarm_list(); - _alarm_schedule(); - __rtc_set(); - - return; -} - -static int __on_app_enable_cb(uid_t target_uid, int req_id, - const char *pkg_type, const char *pkgid, const char *appid, - const char *key, const char *val, const void *pmsg, void *data) -{ - SECURE_LOGD("appid:%s, key:%s, val:%s, req_id: %d", appid, key, val, req_id); - - GSList *gs_iter = NULL; - __alarm_info_t *entry = NULL; - int duetime = 0; - bool is_restored = false; - - if (key && strncmp(key, "end", 3) == 0 && val && strncmp(val, "ok", 2) == 0) { - SECURE_LOGD("Enable appid(%s)", appid); - for (gs_iter = g_disabled_alarm_list; gs_iter != NULL; ) { - entry = gs_iter->data; - - gs_iter = g_slist_next(gs_iter); - if (strncmp(appid, entry->app_unique_name, strlen(appid)) == 0) { - duetime = _alarm_next_duetime(entry); - SECURE_LOGD("Restore alarm_id(%d) duetime(%d) appid(%s)", entry->alarm_id, duetime, appid); - alarm_context.alarms = g_slist_append(alarm_context.alarms, entry); - g_disabled_alarm_list = g_slist_remove(g_disabled_alarm_list, entry); - - if (!(entry->alarm_info.alarm_type & ALARM_TYPE_VOLATILE)) - _update_db_for_disabled_alarm(entry->alarm_id, false); - is_restored = true; - } - } - - if (is_restored) { - _alarm_disable_timer(alarm_context); - _clear_scheduled_alarm_list(); - _alarm_schedule(); - __rtc_set(); - } - } - - return 0; -} - -static int __on_app_disable_cb(uid_t target_uid, int req_id, - const char *pkg_type, const char *pkgid, const char *appid, - const char *key, const char *val, const void *pmsg, void *data) -{ - SECURE_LOGD("appid:%s, key:%s, val:%s, req_id: %d", appid, key, val, req_id); - - GSList *gs_iter = NULL; - __alarm_info_t *entry = NULL; - bool is_disabled = false; - - if (key && strncmp(key, "end", 3) == 0 && val && strncmp(val, "ok", 2) == 0) { - SECURE_LOGD("Disable appid(%s)", appid); - for (gs_iter = alarm_context.alarms; gs_iter != NULL; ) { - entry = gs_iter->data; - - gs_iter = g_slist_next(gs_iter); - if (strncmp(appid, entry->app_unique_name, strlen(appid)) == 0) { - if (!(entry->alarm_info.alarm_type & ALARM_TYPE_VOLATILE)) - _update_db_for_disabled_alarm(entry->alarm_id, true); - g_disabled_alarm_list = g_slist_append(g_disabled_alarm_list, entry); - alarm_context.alarms = g_slist_remove(alarm_context.alarms, entry); - is_disabled = true; - } - } - - if (is_disabled) { - _alarm_disable_timer(alarm_context); - _clear_scheduled_alarm_list(); - _alarm_schedule(); - __rtc_set(); - } - } - - return 0; -} - -static int __on_app_uninstalled(uid_t target_uid, int req_id, const char *pkg_type, - const char *pkgid, const char *key, const char *val, - const void *pmsg, void *user_data) -{ - GSList *gs_iter = NULL; - __alarm_info_t *entry = NULL; - alarm_info_t *alarm_info = NULL; - bool is_deleted = false; - - SECURE_LOGD("pkg_type(%s), pkgid(%s), key(%s), value(%s)", pkg_type, pkgid, key, val); - - if (strncmp(key, "end", 3) == 0 && strncmp(val, "ok", 2) == 0) { - for (gs_iter = alarm_context.alarms; gs_iter != NULL;) { - entry = gs_iter->data; - - const char *caller_pkgid = entry->caller_pkgid; - const char *callee_pkgid = entry->callee_pkgid; - - gs_iter = g_slist_next(gs_iter); - if ((caller_pkgid && strncmp(pkgid, caller_pkgid, strlen(pkgid)) == 0) || - (callee_pkgid && strncmp(pkgid, callee_pkgid, strlen(pkgid)) == 0)) { - if (_remove_from_scheduled_alarm_list(entry->uid, entry->alarm_id)) - is_deleted = true; - - alarm_info = &entry->alarm_info; - if (!(alarm_info->alarm_type & ALARM_TYPE_VOLATILE)) { - if (!_delete_alarms(entry->alarm_id)) - SECURE_LOGE("_delete_alarms() is failed. pkgid[%s], alarm_id[%d]", pkgid, entry->alarm_id); - } - - if (g_hash_table_remove(appid_cache_table, &entry->pid) == true) - ALARM_MGR_LOG_PRINT("Remove cachd data of pid[%d]", entry->pid); - - SECURE_LOGD("Remove pkgid[%s], alarm_id[%d]", pkgid, entry->alarm_id); - alarm_context.alarms = g_slist_remove(alarm_context.alarms, entry); - _release_alarm_info_t(entry); - - } - } - - if (is_deleted && (g_slist_length(g_scheduled_alarm_list) == 0)) { - _alarm_disable_timer(alarm_context); - _alarm_schedule(); - __rtc_set(); - } - } - - return ALARMMGR_RESULT_SUCCESS; -} - -bool __get_caller_unique_name(int pid, char *unique_name, int size, bool *is_app, uid_t uid) -{ - char caller_appid[256] = {0,}; - appid_cache_t *entry; - - if (unique_name == NULL) { - ALARM_MGR_EXCEPTION_PRINT("unique_name should not be NULL."); - return false; - } - - if (aul_app_get_appid_bypid_for_uid(pid, caller_appid, - sizeof(caller_appid), uid) == AUL_R_OK) { - /* When a caller is an application, the unique name is appID. */ - if (is_app) - *is_app = true; - strncpy(unique_name, caller_appid, size - 1); - } else { - /* Otherwise, the unique name is /proc/pid/cmdline. */ - char proc_file[512] = {0,}; - char process_name[512] = {0,}; - int fd = 0; - int i = 0; - - if (is_app) - *is_app = false; - - snprintf(proc_file, 512, "/proc/%d/cmdline", pid); - - fd = open(proc_file, O_RDONLY); - if (fd < 0) { - SECURE_LOGE("Caution!! pid(%d) seems to be killed.", - pid); - return false; - } else { - if (read(fd, process_name, sizeof(process_name) - 1) <= 0) { - ALARM_MGR_EXCEPTION_PRINT("Unable to get the process name."); - close(fd); - return false; - } - close(fd); - - while (process_name[i] != '\0') { - if (process_name[i] == ' ') { - process_name[i] = '\0'; - break; - } - ++i; - } - strncpy(unique_name, process_name, size - 1); - } - } - - g_hash_table_foreach_remove(appid_cache_table, __hash_table_remove_cb, (gpointer)unique_name); - entry = (appid_cache_t *)calloc(1, sizeof(appid_cache_t)); - if (entry) { - entry->unique_name = strdup(unique_name); - entry->is_app = is_app ? *is_app : false; - entry->pid = pid; - g_hash_table_insert(appid_cache_table, &entry->pid, (gpointer)entry); - } - - SECURE_LOGD("unique_name= %s", unique_name); - return true; -} - -static bool __permit_by_config(pkgmgrinfo_appinfo_h handle, uid_t uid) -{ - if (access(tzplatform_mkpath(TZ_SYS_RO_SHARE, - "alarm-manager/alarm-config-service-restricted"), F_OK) == 0) { - ALARM_MGR_LOG_PRINT("This profile restrict alarms for service applications\n"); - return false; - } - - if (access(tzplatform_mkpath(TZ_SYS_RO_SHARE, - "alarm-manager/alarm-config-platform-service-permitted"), F_OK) == 0) { - ALARM_MGR_LOG_PRINT("This profile permit alarm for service applications which has platform cert\n"); - char *pkgid; - int r; - const char *cert_value; - pkgmgrinfo_certinfo_h certinfo; - CertSvcInstance instance; - CertSvcCertificate certificate; - CertSvcVisibility visibility = CERTSVC_VISIBILITY_PUBLIC; - - r = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid); - if (r != PMINFO_R_OK) { - ALARM_MGR_EXCEPTION_PRINT("Failed to get certinfo pkgid"); - return false; - } - - r = pkgmgrinfo_pkginfo_create_certinfo(&certinfo); - if (r != PMINFO_R_OK) { - ALARM_MGR_EXCEPTION_PRINT("Failed to create certinfo"); - return false; - } - - r = pkgmgrinfo_pkginfo_load_certinfo(pkgid, certinfo, uid); - if (r != PMINFO_R_OK) { - ALARM_MGR_EXCEPTION_PRINT("Failed to load certinfo"); - pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); - return false; - } - - r = pkgmgrinfo_pkginfo_get_cert_value(certinfo, - PMINFO_DISTRIBUTOR_ROOT_CERT, &cert_value); - if (r != PMINFO_R_OK || cert_value == NULL) { - ALARM_MGR_EXCEPTION_PRINT("Failed to get cert value"); - pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); - return false; - } - - r = certsvc_instance_new(&instance); - if (r != CERTSVC_SUCCESS) { - ALARM_MGR_EXCEPTION_PRINT("certsvc_instance_new() is failed."); - pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); - return false; - } - - r = certsvc_certificate_new_from_memory(instance, - (const unsigned char *)cert_value, - strlen(cert_value), - CERTSVC_FORM_DER_BASE64, - &certificate); - if (r != CERTSVC_SUCCESS) { - ALARM_MGR_EXCEPTION_PRINT("certsvc_certificate_new_from_memory() is failed."); - pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); - certsvc_instance_free(instance); - return false; - } - - r = certsvc_certificate_get_visibility(certificate, &visibility); - if (r != CERTSVC_SUCCESS) - ALARM_MGR_EXCEPTION_PRINT("certsvc_certificate_get_visibility() is failed."); - - pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); - certsvc_instance_free(instance); - certsvc_certificate_free(certificate); - - ALARM_MGR_EXCEPTION_PRINT("visibility is %d", visibility); - if (visibility & CERTSVC_VISIBILITY_PLATFORM) { - return true; - } - } - - if (access(tzplatform_mkpath(TZ_SYS_RO_SHARE, - "alarm-manager/alarm-config-all-service-permitted"), F_OK) == 0) { - ALARM_MGR_LOG_PRINT("This profile permit alarms for all service applications\n"); - return true; - } - - return false; -} - -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG -static void __initialize_module_log(void) -{ - char buf[1024]; - - log_fd = open(ALARMMGR_LOG_FILE_PATH, O_CREAT | O_WRONLY, 0644); - if (log_fd == -1) { - ALARM_MGR_EXCEPTION_PRINT("Opening the file for alarmmgr log is failed. err: %s", strerror_r(errno, buf, sizeof(buf))); - return; - } - - int offset = lseek(log_fd, 0, SEEK_END); - if (offset != 0) { - log_index = (int)(offset / ALARMMGR_LOG_BUFFER_STRING_SIZE); - if (log_index >= ALARMMGR_LOG_BUFFER_SIZE) { - log_index = 0; - lseek(log_fd, 0, SEEK_SET); - } - } - return; -} - -static bool __save_module_log(const char *tag, const char *message) -{ - char buffer[ALARMMGR_LOG_BUFFER_STRING_SIZE] = {0,}; - time_t now; - char buf[1024]; - - if (log_fd == -1) { - ALARM_MGR_EXCEPTION_PRINT("The file is not ready."); - return false; - } - - if (log_index != 0) - lseek(log_fd, 0, SEEK_CUR); - else - lseek(log_fd, 0, SEEK_SET); - - time(&now); - snprintf(buffer, ALARMMGR_LOG_BUFFER_STRING_SIZE, "[%-6d] %-20s %-120s %d-%s", log_index, tag, message, (int)now, ctime(&now)); - - int ret = write(log_fd, buffer, strlen(buffer)); - if (ret < 0) { - ALARM_MGR_EXCEPTION_PRINT("Writing the alarmmgr log is failed. err: %s", strerror_r(errno, buf, sizeof(buf))); - return false; - } - - if (++log_index >= ALARMMGR_LOG_BUFFER_SIZE) - log_index = 0; - - return true; -} -#endif /* _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG */ - -int __display_lock_state(char *state, char *flag, unsigned int timeout) -{ - GDBusMessage *msg = NULL; - GDBusMessage *reply = NULL; - GVariant *body = NULL; - int ret = ALARMMGR_RESULT_SUCCESS; - int val = -1; - - msg = g_dbus_message_new_method_call(DEVICED_BUS_NAME, DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY, DEVICED_LOCK_STATE); - if (!msg) { - ALARM_MGR_EXCEPTION_PRINT("g_dbus_message_new_method_call() is failed. (%s:%s-%s)", DEVICED_BUS_NAME, DEVICED_INTERFACE_DISPLAY, DEVICED_LOCK_STATE); - return ERR_ALARM_SYSTEM_FAIL; - } - - g_dbus_message_set_body(msg, g_variant_new("(sssi)", state, flag, "NULL", timeout)); - - reply = g_dbus_connection_send_message_with_reply_sync(alarm_context.connection, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, DEVICED_DBUS_REPLY_TIMEOUT, NULL, NULL, NULL); - if (!reply) { - ALARM_MGR_EXCEPTION_PRINT("No reply. g_dbus_connection_send_message_with_reply_sync() is failed."); - ret = ERR_ALARM_SYSTEM_FAIL; - } else { - body = g_dbus_message_get_body(reply); - if (!body) { - ALARM_MGR_EXCEPTION_PRINT("g_dbus_message_get_body() is failed."); - ret = ERR_ALARM_SYSTEM_FAIL; - } else { - g_variant_get(body, "(i)", &val); - if (val != 0) { - ALARM_MGR_EXCEPTION_PRINT("Failed to lock display"); - ret = ERR_ALARM_SYSTEM_FAIL; - } else { - ALARM_MGR_LOG_PRINT("Lock LCD OFF is successfully done"); - } - } - } - - g_dbus_connection_flush_sync(alarm_context.connection, NULL, NULL); - g_object_unref(msg); - if (reply) - g_object_unref(reply); - - return ret; -} - -int __display_unlock_state(char *state, char *flag) -{ - GDBusMessage *msg = NULL; - GDBusMessage *reply = NULL; - GVariant *body = NULL; - int ret = ALARMMGR_RESULT_SUCCESS; - int val = -1; - - msg = g_dbus_message_new_method_call(DEVICED_BUS_NAME, DEVICED_PATH_DISPLAY, DEVICED_INTERFACE_DISPLAY, DEVICED_UNLOCK_STATE); - if (!msg) { - ALARM_MGR_EXCEPTION_PRINT("g_dbus_message_new_method_call() is failed. (%s:%s-%s)", DEVICED_BUS_NAME, DEVICED_INTERFACE_DISPLAY, DEVICED_UNLOCK_STATE); - return ERR_ALARM_SYSTEM_FAIL; - } - - g_dbus_message_set_body(msg, g_variant_new("(ss)", state, flag)); - - reply = g_dbus_connection_send_message_with_reply_sync(alarm_context.connection, msg, G_DBUS_SEND_MESSAGE_FLAGS_NONE, DEVICED_DBUS_REPLY_TIMEOUT, NULL, NULL, NULL); - if (!reply) { - ALARM_MGR_EXCEPTION_PRINT("No reply. g_dbus_connection_send_message_with_reply_sync() is failed."); - ret = ERR_ALARM_SYSTEM_FAIL; - } else { - body = g_dbus_message_get_body(reply); - if (!body) { - ALARM_MGR_EXCEPTION_PRINT("g_dbus_message_get_body() is failed."); - ret = ERR_ALARM_SYSTEM_FAIL; - } else { - g_variant_get(body, "(i)", &val); - if (val != 0) { - ALARM_MGR_EXCEPTION_PRINT("Failed to unlock display"); - ret = ERR_ALARM_SYSTEM_FAIL; - } else { - ALARM_MGR_LOG_PRINT("Unlock LCD OFF is successfully done"); - } - } - } - - g_dbus_connection_flush_sync(alarm_context.connection, NULL, NULL); - g_object_unref(msg); - if (reply) - g_object_unref(reply); - - return ret; -} - -static long __get_proper_interval(long interval, int alarm_type) -{ - GSList *gs_iter = NULL; - __alarm_info_t *entry = NULL; - long maxInterval = 60; - - for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { - entry = gs_iter->data; - if (entry->alarm_info.alarm_type & ALARM_TYPE_PERIOD) { - if (entry->alarm_info.mode.u_interval.interval <= interval && - entry->alarm_info.mode.u_interval.interval > maxInterval) - maxInterval = entry->alarm_info.mode.u_interval.interval; - } - } - - while ((maxInterval * 2 <= interval && maxInterval < LONG_MAX / 2) || - (alarm_type & ALARM_TYPE_INEXACT && maxInterval < MIN_INEXACT_INTERVAL)) - maxInterval *= 2; - - return maxInterval; -} - -gboolean __alarm_expired_directly(gpointer user_data) -{ - if (g_scheduled_alarm_list == NULL || g_scheduled_alarm_list->data == NULL) - return false; - - int time_sec = (int)(intptr_t)user_data; - __scheduled_alarm_t *alarm = g_scheduled_alarm_list->data; - __alarm_info_t *alarm_info = alarm->__alarm_info; - - /* Expire alarms with duetime equal to newtime by force */ - if (alarm_info->due_time == time_sec) { - if (__display_lock_state(DEVICED_LCD_OFF, DEVICED_STAY_CUR_STATE, 0) != ALARMMGR_RESULT_SUCCESS) - ALARM_MGR_EXCEPTION_PRINT("__display_lock_state() is failed"); - - if (g_dummy_timer_is_set == true) { - ALARM_MGR_LOG_PRINT("dummy alarm timer has expired."); - } else { - ALARM_MGR_LOG_PRINT("due_time=%ld is expired.", alarm_info->due_time); - __alarm_expired(); - } - - _alarm_schedule(); - __rtc_set(); - - if (__display_unlock_state(DEVICED_LCD_OFF, DEVICED_SLEEP_MARGIN) != ALARMMGR_RESULT_SUCCESS) - ALARM_MGR_EXCEPTION_PRINT("__display_unlock_state() is failed"); - } - - return false; -} - -void __reschedule_alarms_with_newtime(int cur_time, int new_time, double diff_time) -{ -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; -#endif - - vconf_set_int(VCONFKEY_SYSTEM_TIME_CHANGED, (int)diff_time); - bundle *b = NULL; - b = bundle_create(); - bundle_add_str(b, EVT_KEY_TIME_CHANGED, EVT_VAL_TIME_CHANGED_TRUE); - eventsystem_send_system_event(SYS_EVENT_TIME_CHANGED, b); - bundle_free(b); - - __alarm_update_due_time_of_all_items_in_list(diff_time); /* Rescheduling alarms with ALARM_TYPE_RELATIVE */ - ALARM_MGR_LOG_PRINT("Next duetime is %ld", alarm_context.c_due_time); - - _clear_scheduled_alarm_list(); - _alarm_schedule(); - __rtc_set(); - -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - char *timebuf = ctime((const time_t *)&new_time); - if (timebuf) { - timebuf[strlen(timebuf) - 1] = '\0'; /* to avoid newline */ - snprintf(log_message, sizeof(log_message), "Current: %d, New: %d, %s, diff: %f", cur_time, new_time, timebuf, diff_time); - } - __save_module_log("CHANGE TIME", log_message); -#endif - - g_idle_add(__alarm_expired_directly, (gpointer)(intptr_t)new_time); /* Expire alarms with duetime equal to newtime directly */ - return; -} - -static int __cynara_check(GDBusMethodInvocation *invocation, pid_t pid) -{ - int ret = 0; - char *user = NULL; - char *client = NULL; - char *client_session = NULL; - cynara *p_cynara = NULL; - const char *sender_unique_name; - GDBusConnection *connection; - const char *notitification_priv = "http://tizen.org/privilege/notification"; - - connection = g_dbus_method_invocation_get_connection(invocation); - sender_unique_name = g_dbus_method_invocation_get_sender(invocation); - - ret = cynara_initialize(&p_cynara, NULL); - if (ret != CYNARA_API_SUCCESS) { - ALARM_MGR_EXCEPTION_PRINT("cynara_initialize() failed"); - goto cynara_out; - } - - ret = cynara_creds_gdbus_get_user(connection, sender_unique_name, - USER_METHOD_DEFAULT, &user); - if (ret != CYNARA_API_SUCCESS) { - ALARM_MGR_EXCEPTION_PRINT("cynara_creds_gdbus_get_user() failed"); - goto cynara_out; - } - - ret = cynara_creds_gdbus_get_client(connection, sender_unique_name, - CLIENT_METHOD_DEFAULT, &client); - if (ret != CYNARA_API_SUCCESS) { - ALARM_MGR_EXCEPTION_PRINT("cynara_creds_gdbus_get_client() failed"); - goto cynara_out; - } - - ALARM_MGR_LOG_PRINT("user :%s , client :%s ,unique_name : %s, pid() : %d", - user, client, sender_unique_name, pid); - - client_session = cynara_session_from_pid(pid); - if (!client_session) { - ALARM_MGR_EXCEPTION_PRINT("cynara_session_from_pid() failed"); - ret = CYNARA_API_INVALID_PARAM; - goto cynara_out; - } - - ret = cynara_check(p_cynara, client, client_session, user, - notitification_priv); - if (ret == CYNARA_API_ACCESS_ALLOWED) - ALARM_MGR_LOG_PRINT("CYNARA_ACCESS_ALLOWED"); - else - ALARM_MGR_LOG_PRINT("CYNARA_NOT_ALLOWED [%d]", ret); - -cynara_out: - if (client_session) - g_free(client_session); - if (client) - g_free(client); - if (user) - g_free(user); - if (p_cynara) - cynara_finish(p_cynara); - - return ret; -} - -static int __check_modifiable(uid_t uid, pid_t pid, int alarm_id) -{ - bool caller_is_app = false; - char app_name[MAX_APP_ID] = { 0 }; - GSList *gs_iter = NULL; - __alarm_info_t *entry = NULL; - char *caller_pkgid = NULL; - pkgmgrinfo_pkginfo_h caller_handle; - - if (__get_cached_unique_name(pid, app_name, sizeof(app_name), - &caller_is_app, uid) == false) - return ERR_ALARM_SYSTEM_FAIL; - - if (!caller_is_app) { - ALARM_MGR_LOG_PRINT("Daemon process is possible to modify alarms[%s]", - app_name); - return ALARMMGR_RESULT_SUCCESS; - } else { - if (pkgmgrinfo_appinfo_get_usr_appinfo(app_name, uid, &caller_handle) != PMINFO_R_OK) { - ALARM_MGR_EXCEPTION_PRINT("Failed to get appinfo %s", app_name); - return ERR_ALARM_SYSTEM_FAIL; - } else { - if (pkgmgrinfo_appinfo_get_pkgid(caller_handle, &caller_pkgid) != PMINFO_R_OK) { - ALARM_MGR_EXCEPTION_PRINT("Failed to get pkgid %s", app_name); - pkgmgrinfo_appinfo_destroy_appinfo(caller_handle); - return ERR_ALARM_SYSTEM_FAIL; - } - } - } - - for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { - entry = gs_iter->data; - if (entry->uid == uid && entry->alarm_id == alarm_id && - strcmp(caller_pkgid, entry->caller_pkgid) == 0) { - ALARM_MGR_LOG_PRINT("Found alarm of app (uid:%d, pid:%d, caller_pkgid:%s) ", uid, pid, caller_pkgid); - pkgmgrinfo_appinfo_destroy_appinfo(caller_handle); - return ALARMMGR_RESULT_SUCCESS; - } - } - - ALARM_MGR_EXCEPTION_PRINT("[%s] is not permitted to modify alarm_id[%d]", app_name, alarm_id); - pkgmgrinfo_appinfo_destroy_appinfo(caller_handle); - - return ERR_ALARM_NOT_PERMITTED_APP; -} - -gboolean alarm_manager_alarm_set_rtc_time(AlarmManager *pObj, GDBusMethodInvocation *invoc, - int year, int mon, int day, - int hour, int min, int sec, - gpointer user_data) { - int return_code = ALARMMGR_RESULT_SUCCESS; -/* Indentation ingored to help understand the patch. */ -if (_APPFW_FEATURE_WAKEUP_USING_RTC) { - const char *rtc = default_rtc; - struct rtc_wkalrm rtc_wkalarm; - int retval = 0; - struct tm tm, *alarm_tm = NULL; -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,}; - char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; -#endif - /*extract day of the week, day in the year & daylight saving time from system*/ - time_t current_time; - char buf[1024]; - - current_time = time(NULL); - alarm_tm = gmtime_r(¤t_time, &tm); - if (alarm_tm == NULL) { - ALARM_MGR_EXCEPTION_PRINT("alarm_tm is NULL"); - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", return_code)); - return true; - } - - - alarm_tm->tm_year = year; - alarm_tm->tm_mon = mon; - alarm_tm->tm_mday = day; - alarm_tm->tm_hour = hour; - alarm_tm->tm_min = min; - alarm_tm->tm_sec = sec; - - /*convert to calendar time representation*/ - time_t rtc_time = mktime(alarm_tm); - - if (gfd < 0) { - gfd = open(rtc, O_RDWR); - if (gfd < 0) { - ALARM_MGR_EXCEPTION_PRINT("RTC open failed."); - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", return_code)); - return true; - } - } - - rtc_wkalarm.enabled = 1; - rtc_wkalarm.time.tm_year = year; - rtc_wkalarm.time.tm_mon = mon; - rtc_wkalarm.time.tm_mday = day; - rtc_wkalarm.time.tm_hour = hour; - rtc_wkalarm.time.tm_min = min; - rtc_wkalarm.time.tm_sec = sec; - - retval = ioctl(gfd, RTC_WKALM_SET, &rtc_wkalarm); - if (retval == -1) { - if (errno == ENOTTY) - ALARM_MGR_EXCEPTION_PRINT("Alarm IRQs is not supported."); - - ALARM_MGR_EXCEPTION_PRINT("RTC ALARM_SET ioctl is failed. errno = %s", strerror_r(errno, buf, sizeof(buf))); - return_code = ERR_ALARM_SYSTEM_FAIL; -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - strncpy(log_tag, "FAIL: SET RTC", sizeof(log_tag) - 1); -#endif - } else { - ALARM_MGR_LOG_PRINT("[alarm-server]RTC alarm is setted"); -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - strncpy(log_tag, "SET RTC", sizeof(log_tag) - 1); -#endif - } - -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - snprintf(log_message, sizeof(log_message), "wakeup rtc time: %d, %s", (int)rtc_time, ctime(&rtc_time)); - __save_module_log(log_tag, log_message); -#endif -} else { - ALARM_MGR_LOG_PRINT("[alarm-server] RTC does not work."); - return_code = ERR_ALARM_SYSTEM_FAIL; -} - - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", return_code)); - return true; -} - -static int accrue_msec = 0; /* To check a millisecond part of current time at changing the system time(sec) */ - -gboolean alarm_manager_alarm_set_time(AlarmManager *pObj, GDBusMethodInvocation *invoc, int time_sec, gpointer user_data) -{ - double diff_time = 0.0; - struct timeval cur_time = {0,}; - int return_code = ALARMMGR_RESULT_SUCCESS; - - _alarm_disable_timer(alarm_context); /* Disable the timer to reschedule the alarm before the time is changed. */ - - tzset(); - gettimeofday(&cur_time, NULL); - - accrue_msec += (cur_time.tv_usec / 1000); /* Accrue the millisecond to compensate the time */ - if (accrue_msec > 500) { - diff_time = difftime(time_sec, cur_time.tv_sec) - 1; - accrue_msec -= 1000; - } else { - diff_time = difftime(time_sec, cur_time.tv_sec); - } - - __set_time(time_sec); /* Change both OS time and RTC */ - ALARM_MGR_LOG_PRINT("[TIMESTAMP]Current time(%ld), New time(%d)(%s), diff_time(%f)", - cur_time.tv_sec, time_sec, ctime((const time_t *)&time_sec), diff_time); - - __reschedule_alarms_with_newtime(cur_time.tv_sec, time_sec, diff_time); - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", return_code)); - return true; -} - -gboolean alarm_manager_alarm_set_time_with_propagation_delay(AlarmManager *pObj, GDBusMethodInvocation *invoc, - guint new_sec, guint new_nsec, guint req_sec, guint req_nsec, gpointer user_data) -{ - double diff_time = 0.0; - struct timespec cur_time = {0,}; - struct timespec delay = {0,}; - struct timespec sleep_time = {0,}; - guint real_newtime = 0; - accrue_msec = 0; /* reset accrued msec */ - - _alarm_disable_timer(alarm_context); /* Disable the timer to reschedule the alarm before the time is changed. */ - - tzset(); - clock_gettime(CLOCK_REALTIME, &cur_time); - - /* Check validation of requested time */ - if (req_sec > cur_time.tv_sec || (req_sec == cur_time.tv_sec && req_nsec > cur_time.tv_nsec)) { - ALARM_MGR_EXCEPTION_PRINT("The requeted time(%d.%09d) must be equal to or less than current time(%ld.%09ld).", - req_sec, req_nsec, cur_time.tv_sec, cur_time.tv_nsec); - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ERR_ALARM_INVALID_PARAM)); - return true; - } - - /* Compensate propagation delay */ - if (req_nsec > cur_time.tv_nsec) { - delay.tv_sec = cur_time.tv_sec - 1 - req_sec; - delay.tv_nsec = cur_time.tv_nsec + BILLION - req_nsec; - } else { - delay.tv_sec = cur_time.tv_sec - req_sec; - delay.tv_nsec = cur_time.tv_nsec - req_nsec; - } - - if (new_nsec + delay.tv_nsec >= BILLION) { - real_newtime = new_sec + delay.tv_sec + 2; - sleep_time.tv_nsec = BILLION - ((delay.tv_nsec + new_nsec) - BILLION); - } else { - real_newtime = new_sec + delay.tv_sec + 1; - sleep_time.tv_nsec = BILLION - (delay.tv_nsec + new_nsec); - } - - nanosleep(&sleep_time, NULL); /* Wait until 0 nsec to match both OS time and RTC(sec) */ - - __set_time(real_newtime); /* Change both OS time and RTC */ - - diff_time = difftime(new_sec, req_sec); - ALARM_MGR_LOG_PRINT("[TIMESTAMP]Current time(%ld.%09ld), New time(%d.%09d), Real Newtime(%d), diff_time(%f)", - cur_time.tv_sec, cur_time.tv_nsec, new_sec, new_nsec, real_newtime, diff_time); - ALARM_MGR_LOG_PRINT("Requested(%d.%09d) Delay(%ld.%09ld) Sleep(%09ld)", req_sec, req_nsec, delay.tv_sec, delay.tv_nsec, sleep_time.tv_nsec); - __reschedule_alarms_with_newtime(cur_time.tv_sec, real_newtime, diff_time); - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ALARMMGR_RESULT_SUCCESS)); - return true; -} - -gboolean alarm_manager_alarm_set_timezone(AlarmManager *pObject, GDBusMethodInvocation *invoc, char *tzpath_str, gpointer user_data) -{ - int retval = 0; - int return_code = ALARMMGR_RESULT_SUCCESS; - struct stat statbuf; -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,}; - char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; -#endif - - ALARM_MGR_LOG_PRINT("[TIMESTAMP]Set the timezone to %s.", tzpath_str); - - if (lstat(tzpath_str, &statbuf) == -1 && errno == ENOENT) { - ALARM_MGR_EXCEPTION_PRINT("Invalid tzpath, %s", tzpath_str); - return_code = ERR_ALARM_INVALID_PARAM; - goto done; - } - - retval = lstat(TIMEZONE_INFO_LINK_PATH, &statbuf); - if (retval == 0 || (retval == -1 && errno != ENOENT)) { - /* unlink the current link */ - if (unlink(TIMEZONE_INFO_LINK_PATH) < 0) { - ALARM_MGR_EXCEPTION_PRINT("unlink() is failed."); - return_code = ERR_ALARM_SYSTEM_FAIL; - goto done; - } - } - - /* create a new symlink when the /opt/etc/localtime is empty. */ - if (symlink(tzpath_str, TIMEZONE_INFO_LINK_PATH) < 0) { - ALARM_MGR_EXCEPTION_PRINT("Failed to create an symlink of %s.", tzpath_str); - return_code = ERR_ALARM_SYSTEM_FAIL; - goto done; - } - - tzset(); - - /* Rescheduling alarms */ - _alarm_disable_timer(alarm_context); - __alarm_update_due_time_of_all_items_in_list(0); - ALARM_MGR_LOG_PRINT("next expiring due_time is %ld", alarm_context.c_due_time); - - _clear_scheduled_alarm_list(); - _alarm_schedule(); - __rtc_set(); - - vconf_set_int(VCONFKEY_SYSTEM_TIME_CHANGED, 0); - bundle *b = NULL; - b = bundle_create(); - bundle_add_str(b, EVT_KEY_TIME_CHANGED, EVT_VAL_TIME_CHANGED_TRUE); - eventsystem_send_system_event(SYS_EVENT_TIME_CHANGED, b); - bundle_free(b); - - b = bundle_create(); - bundle_add_str(b, EVT_KEY_TIME_ZONE, tzpath_str); - eventsystem_send_system_event(SYS_EVENT_TIME_ZONE, b); - bundle_free(b); - -done: - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", return_code)); -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - if (return_code == ALARMMGR_RESULT_SUCCESS) - strncpy(log_tag, "SET TIMEZONE", sizeof(log_tag) - 1); - else - strncpy(log_tag, "FAIL: SET TIMEZONE", sizeof(log_tag) - 1); - - snprintf(log_message, sizeof(log_message), "Set the timezone to %s.", tzpath_str); - __save_module_log(log_tag, log_message); -#endif - - return true; -} - -gboolean alarm_manager_alarm_create_appsvc(AlarmManager *pObject, GDBusMethodInvocation *invoc, - int start_year, - int start_month, int start_day, - int start_hour, int start_min, - int start_sec, int end_year, int end_month, - int end_day, int mode_day_of_week, - unsigned int mode_interval, - int mode_repeat, int alarm_type, - int reserved_info, - char *bundle_data, - gpointer user_data) -{ - alarm_info_t alarm_info; - int return_code = ALARMMGR_RESULT_SUCCESS; - int alarm_id = 0; -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,}; - char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; -#endif - int uid; - int pid; - int result; - bundle *b; - const char *callee_appid; - const char *name = g_dbus_method_invocation_get_sender(invoc); - - uid = __get_caller_uid(name); - pid = __get_caller_pid(name); - if (uid < 0 || pid < 0) { - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, return_code)); - return true; - } - - b = bundle_decode((bundle_raw *)bundle_data, strlen(bundle_data)); - if (b == NULL) { - int ret_bundle = get_last_result(); - ALARM_MGR_EXCEPTION_PRINT("Failed to decode bundle_data[Error:%d]\n", ret_bundle); - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, return_code)); - return true; - } else { - callee_appid = appsvc_get_appid(b); - - if (__compare_api_version(&result, pid, uid) < 0) { - ALARM_MGR_EXCEPTION_PRINT("Unable to check api version\n"); - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, return_code)); - bundle_free(b); - return true; - } - - if (result < 0) { - if (alarm_type & ALARM_TYPE_INEXACT) - alarm_type ^= ALARM_TYPE_INEXACT; - } else { /* Since 2.4 */ - if (!__is_permitted(callee_appid, alarm_type, uid)) { - ALARM_MGR_EXCEPTION_PRINT("[%s] is not permitted \n", callee_appid); - return_code = ERR_ALARM_NOT_PERMITTED_APP; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, return_code)); - bundle_free(b); - return true; - } - } - - bundle_free(b); - } - - - alarm_info.start.year = start_year; - alarm_info.start.month = start_month; - alarm_info.start.day = start_day; - alarm_info.start.hour = start_hour; - alarm_info.start.min = start_min; - alarm_info.start.sec = start_sec; - - alarm_info.end.year = end_year; - alarm_info.end.month = end_month; - alarm_info.end.day = end_day; - - alarm_info.mode.u_interval.day_of_week = mode_day_of_week; - alarm_info.mode.repeat = mode_repeat; - - alarm_info.alarm_type = alarm_type; - alarm_info.reserved_info = reserved_info; - - if ((alarm_info.alarm_type & ALARM_TYPE_INEXACT)) { - alarm_info.alarm_type |= ALARM_TYPE_PERIOD; - alarm_info.mode.u_interval.interval = - __get_proper_interval(mode_interval, alarm_info.alarm_type); - } else if (mode_interval <= 0) { - alarm_info.mode.u_interval.interval = 0; - } - - if (!__alarm_create_appsvc(&alarm_info, &alarm_id, mode_interval, uid, pid, bundle_data, &return_code)) { - ALARM_MGR_EXCEPTION_PRINT("Unable to create alarm! return_code[%d]", return_code); -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - strncpy(log_tag, "FAIL: CREATE", sizeof(log_tag) - 1); -#endif - } else { -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - strncpy(log_tag, "CREATE", sizeof(log_tag) - 1); -#endif - } - - g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, return_code)); - -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - snprintf(log_message, sizeof(log_message), "alarmID: %d, uid: %d, pid: %d, duetime: %d-%d-%d %02d:%02d:%02d", - alarm_id, uid, pid, start_year, start_month, start_day, start_hour, start_min, start_sec); - __save_module_log(log_tag, log_message); -#endif - - return true; -} - -gboolean alarm_manager_alarm_create_noti(AlarmManager *pObject, GDBusMethodInvocation *invoc, - int start_year, - int start_month, int start_day, - int start_hour, int start_min, - int start_sec, int end_year, int end_month, - int end_day, int mode_day_of_week, - unsigned int mode_interval, - int mode_repeat, int alarm_type, - int reserved_info, - char *noti_data, - gpointer user_data) -{ - alarm_info_t alarm_info; - int ret; - int return_code = ALARMMGR_RESULT_SUCCESS; - int alarm_id = 0; -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,}; - char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; -#endif - int uid; - int pid; - const char *name = g_dbus_method_invocation_get_sender(invoc); - - uid = __get_caller_uid(name); - pid = __get_caller_pid(name); - if (uid < 0 || pid < 0) { - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, return_code)); - return true; - } - - ret = __cynara_check(invoc, pid); - if (ret != CYNARA_API_ACCESS_ALLOWED) { - if (ret == CYNARA_API_ACCESS_DENIED) - return_code = ERR_ALARM_NOT_PERMITTED_APP; - else - return_code = ERR_ALARM_SYSTEM_FAIL; - - g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, return_code)); - return true; - } - - alarm_info.start.year = start_year; - alarm_info.start.month = start_month; - alarm_info.start.day = start_day; - alarm_info.start.hour = start_hour; - alarm_info.start.min = start_min; - alarm_info.start.sec = start_sec; - - alarm_info.end.year = end_year; - alarm_info.end.month = end_month; - alarm_info.end.day = end_day; - - alarm_info.mode.u_interval.day_of_week = mode_day_of_week; - alarm_info.mode.repeat = mode_repeat; - - alarm_info.alarm_type = alarm_type; - alarm_info.reserved_info = reserved_info; - - if ((alarm_info.alarm_type & ALARM_TYPE_INEXACT)) { - alarm_info.alarm_type |= ALARM_TYPE_PERIOD; - alarm_info.mode.u_interval.interval = - __get_proper_interval(mode_interval, alarm_info.alarm_type); - } else if (mode_interval <= 0) { - alarm_info.mode.u_interval.interval = 0; - } - - if (!__alarm_create_noti(&alarm_info, &alarm_id, mode_interval, uid, pid, noti_data, &return_code)) { - ALARM_MGR_EXCEPTION_PRINT("Unable to create alarm! return_code[%d]", return_code); -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - strncpy(log_tag, "FAIL: CREATE", sizeof(log_tag) - 1); -#endif - } else { -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - strncpy(log_tag, "CREATE", sizeof(log_tag) - 1); -#endif - } - - g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, return_code)); - -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - snprintf(log_message, sizeof(log_message), "alarmID: %d, uid: %d, pid: %d, duetime: %d-%d-%d %02d:%02d:%02d", - alarm_id, uid, pid, start_year, start_month, start_day, start_hour, start_min, start_sec); - __save_module_log(log_tag, log_message); -#endif - - return true; -} - -gboolean alarm_manager_alarm_create(AlarmManager *obj, GDBusMethodInvocation *invoc, - char *app_service_name, char *app_service_name_mod, int start_year, - int start_month, int start_day, - int start_hour, int start_min, - int start_sec, int msec, int end_year, int end_month, - int end_day, int mode_day_of_week, - int mode_repeat, int alarm_type, - int reserved_info, - char *reserved_service_name, char *reserved_service_name_mod, - gpointer user_data) -{ - alarm_info_t alarm_info; - int return_code = ALARMMGR_RESULT_SUCCESS; - int alarm_id = 0; -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,}; - char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; -#endif - int uid; - int pid; - const char *name = g_dbus_method_invocation_get_sender(invoc); - char *_reserved_service_name = NULL; - char *_reserved_service_name_mod = NULL; - - pid = __get_caller_pid(name); - uid = __get_caller_uid(name); - if (uid < 0 || pid < 0) { - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, return_code)); - return true; - } - - alarm_info.start.year = start_year; - alarm_info.start.month = start_month; - alarm_info.start.day = start_day; - alarm_info.start.hour = start_hour; - alarm_info.start.min = start_min; - alarm_info.start.sec = start_sec; - - alarm_info.msec = msec; - - alarm_info.end.year = end_year; - alarm_info.end.month = end_month; - alarm_info.end.day = end_day; - - alarm_info.mode.u_interval.day_of_week = mode_day_of_week; - alarm_info.mode.repeat = mode_repeat; - - alarm_info.alarm_type = alarm_type; - alarm_info.reserved_info = reserved_info; - - if (strcmp(reserved_service_name, "null") == 0) - _reserved_service_name = NULL; - if (strcmp(reserved_service_name_mod, "null") == 0) - _reserved_service_name_mod = NULL; - - if (!__alarm_create(&alarm_info, &alarm_id, uid, pid, 0, 0, 0, app_service_name, app_service_name_mod, - _reserved_service_name, _reserved_service_name_mod, &return_code)) { - ALARM_MGR_EXCEPTION_PRINT("Unable to create alarm! return_code[%d]", return_code); -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - strncpy(log_tag, "FAIL: CREATE", sizeof(log_tag) - 1); -#endif - } else { -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - strncpy(log_tag, "CREATE", sizeof(log_tag) - 1); -#endif - } - - g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, return_code)); - -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - snprintf(log_message, sizeof(log_message), "alarmID: %d, uid: %d, pid: %d, duetime: %d-%d-%d %02d:%02d:%02d", - alarm_id, uid, pid, start_year, start_month, start_day, start_hour, start_min, start_sec); - __save_module_log(log_tag, log_message); -#endif - - return true; -} - -time_t _get_periodic_alarm_standard_time(void) -{ - /* To avoid start time of all devices are same. */ - if (periodic_alarm_standard_time == 0) - periodic_alarm_standard_time = g_random_int_range(0, BILLION) + 1; - - ALARM_MGR_LOG_PRINT("periodic_standard_time : [%ld]", periodic_alarm_standard_time); - return periodic_alarm_standard_time; -} - -gboolean alarm_manager_alarm_create_periodic(AlarmManager *obj, GDBusMethodInvocation *invoc, - char *app_service_name, char *app_service_name_mod, int interval, - int is_ref, int method, gpointer user_data) -{ - alarm_info_t alarm_info; - int return_code = ALARMMGR_RESULT_SUCCESS; - int alarm_id = 0; -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,}; - char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; -#endif - int uid; - int pid; - const char *name = g_dbus_method_invocation_get_sender(invoc); - - uid = __get_caller_uid(name); - pid = __get_caller_pid(name); - if (uid < 0 || pid < 0) { - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, return_code)); - return true; - } - - struct tm standard_tm; - time_t standard_time = _get_periodic_alarm_standard_time(); - localtime_r(&standard_time, &standard_tm); - - alarm_info.reserved_info = standard_time; - - alarm_info.start.year = standard_tm.tm_year + 1900; - alarm_info.start.month = standard_tm.tm_mon + 1; - alarm_info.start.day = standard_tm.tm_mday; - alarm_info.start.hour = standard_tm.tm_hour; - alarm_info.start.min = standard_tm.tm_min; - alarm_info.start.sec = standard_tm.tm_sec; - - alarm_info.msec = 0; - - alarm_info.end.year = 0; - alarm_info.end.month = 0; - alarm_info.end.day = 0; - - alarm_info.alarm_type = ALARM_TYPE_VOLATILE; - alarm_info.alarm_type |= ALARM_TYPE_RELATIVE; - alarm_info.alarm_type |= ALARM_TYPE_WITHCB; - alarm_info.alarm_type |= ALARM_TYPE_PERIOD; - - if (interval <= 0) { - alarm_info.mode.repeat = ALARM_REPEAT_MODE_ONCE; - alarm_info.mode.u_interval.interval = 0; - } else { - alarm_info.mode.repeat = ALARM_REPEAT_MODE_REPEAT; - if (is_ref) - alarm_info.mode.u_interval.interval = interval * 60; - else - alarm_info.mode.u_interval.interval = __get_proper_interval(interval * 60, alarm_info.alarm_type); - } - - if (!__alarm_create(&alarm_info, &alarm_id, uid, pid, method, interval * 60, is_ref, - app_service_name, app_service_name_mod, - NULL, NULL, &return_code)) { - ALARM_MGR_EXCEPTION_PRINT("Unable to create alarm! return_code[%d]", return_code); -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - strncpy(log_tag, "FAIL: CREATE", sizeof(log_tag) - 1); -#endif - } else { -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - strncpy(log_tag, "CREATE", sizeof(log_tag) - 1); -#endif - } - - g_dbus_method_invocation_return_value(invoc, - g_variant_new("(ii)", alarm_id, return_code)); -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - snprintf(log_message, sizeof(log_message), "alarmID: %d, uid: %d, pid: %d, duetime: %d-%d-%d %02d:%02d:%02d", - alarm_id, uid, pid, alarm_info.start.year, alarm_info.start.month, - alarm_info.start.day, alarm_info.start.hour, - alarm_info.start.min, alarm_info.start.sec); - __save_module_log(log_tag, log_message); -#endif - return true; -} - -gboolean alarm_manager_alarm_delete(AlarmManager *obj, GDBusMethodInvocation *invoc, - alarm_id_t alarm_id, gpointer user_data) -{ - int return_code = ALARMMGR_RESULT_SUCCESS; -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,}; - char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; -#endif - int uid; - int pid; - const char *name = g_dbus_method_invocation_get_sender(invoc); - - uid = __get_caller_uid(name); - pid = __get_caller_pid(name); - if (uid < 0 || pid < 0) { - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", return_code)); - return true; - } - - return_code = __check_modifiable(uid, pid, alarm_id); - if (return_code != ALARMMGR_RESULT_SUCCESS) { - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", return_code)); - return true; - } - - if (!__alarm_delete(uid, alarm_id, &return_code)) { - ALARM_MGR_EXCEPTION_PRINT("Unable to delete the alarm! alarm_id[%d], return_code[%d]", alarm_id, return_code); -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - strncpy(log_tag, "FAIL: DELETE", sizeof(log_tag) - 1); -#endif - } else { - ALARM_MGR_LOG_PRINT("alarm_id[%d] is removed.", alarm_id); -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - strncpy(log_tag, "DELETE", sizeof(log_tag) - 1); -#endif - } - - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", return_code)); - -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - snprintf(log_message, sizeof(log_message), "alarmID: %d, uid: %d, pid: %d", alarm_id, uid, pid); - __save_module_log(log_tag, log_message); -#endif - - return true; -} - -gboolean alarm_manager_alarm_delete_all(AlarmManager *obj, GDBusMethodInvocation *invoc, - gpointer user_data) -{ - GSList *gs_iter = NULL; - char app_name[512] = { 0 }; - alarm_info_t *alarm_info = NULL; - __alarm_info_t *entry = NULL; - bool is_deleted = false; - int return_code = ALARMMGR_RESULT_SUCCESS; -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; -#endif - int uid; - int pid; - const char *name = g_dbus_method_invocation_get_sender(invoc); - - uid = __get_caller_uid(name); - pid = __get_caller_pid(name); - if (uid < 0 || pid < 0) { - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", return_code)); - return true; - } - - if (__get_cached_unique_name(pid, app_name, sizeof(app_name), NULL, uid) == false) { - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", return_code)); -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - snprintf(log_message, sizeof(log_message), "pid: %d. Can not get the unique_name.", pid); - __save_module_log("FAIL: DELETE ALL", log_message); -#endif - return true; - } - - SECURE_LOGD("Called by process (pid:%d, unique_name=%s)", pid, app_name); - - for (gs_iter = alarm_context.alarms; gs_iter != NULL;) { - bool is_found = false; - entry = gs_iter->data; - const char *tmp_appname = entry->app_unique_name; - SECURE_LOGD("Try to remove app_name[%s], alarm_id[%d]\n", tmp_appname, entry->alarm_id); - if (tmp_appname && strncmp(app_name, tmp_appname, strlen(tmp_appname)) == 0) { - if (_remove_from_scheduled_alarm_list(uid, entry->alarm_id)) - is_deleted = true; - - alarm_info = &entry->alarm_info; - if (!(alarm_info->alarm_type & ALARM_TYPE_VOLATILE)) { - if (!_delete_alarms(entry->alarm_id)) - SECURE_LOGE("_delete_alarms() is failed. pid[%d], alarm_id[%d]", pid, entry->alarm_id); - } - is_found = true; - } - - gs_iter = g_slist_next(gs_iter); - - if (is_found) { - ALARM_MGR_LOG_PRINT("alarm_id[%d] is removed.", entry->alarm_id); - SECURE_LOGD("Removing is done. app_name[%s], alarm_id [%d]\n", tmp_appname, entry->alarm_id); - alarm_context.alarms = g_slist_remove(alarm_context.alarms, entry); - _release_alarm_info_t(entry); - } - } - - if (is_deleted && (g_slist_length(g_scheduled_alarm_list) == 0)) { - _alarm_disable_timer(alarm_context); - _alarm_schedule(); - } - -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - snprintf(log_message, sizeof(log_message), "uid: %d, pid: %d, unique_name: %s", uid, pid, app_name); - __save_module_log("DELETE ALL", log_message); -#endif - - __rtc_set(); - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", return_code)); - return true; -} - -gboolean alarm_manager_alarm_update(AlarmManager *pObj, GDBusMethodInvocation *invoc, - alarm_id_t alarm_id, - int start_year, int start_month, - int start_day, int start_hour, - int start_min, int start_sec, int end_year, - int end_month, int end_day, - int mode_interval, - int mode_repeat, - int alarm_type, int reserved_info, - int update_flag, - gpointer user_data) -{ - int return_code = ALARMMGR_RESULT_SUCCESS; - alarm_info_t alarm_info; -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,}; - char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; -#endif - int uid; - int pid; - const char *name = g_dbus_method_invocation_get_sender(invoc); - - uid = __get_caller_uid(name); - pid = __get_caller_pid(name); - if (uid < 0 || pid < 0) { - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", return_code)); - return true; - } - - return_code = __check_modifiable(uid, pid, alarm_id); - if (return_code != ALARMMGR_RESULT_SUCCESS) { - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", return_code)); - return true; - } - - alarm_info.start.year = start_year; - alarm_info.start.month = start_month; - alarm_info.start.day = start_day; - alarm_info.start.hour = start_hour; - alarm_info.start.min = start_min; - alarm_info.start.sec = start_sec; - - alarm_info.end.year = end_year; - alarm_info.end.month = end_month; - alarm_info.end.day = end_day; - - alarm_info.mode.u_interval.interval = mode_interval; - alarm_info.mode.repeat = mode_repeat; - - alarm_info.alarm_type = alarm_type; - alarm_info.reserved_info = reserved_info; - - if (!__alarm_update(uid, pid, alarm_id, &alarm_info, - update_flag, &return_code)) { - ALARM_MGR_EXCEPTION_PRINT("Unable to update the alarm! alarm_id[%d], return_code[%d]", alarm_id, return_code); -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - strncpy(log_tag, "FAIL: UPDATE", sizeof(log_tag) - 1); -#endif - } else { -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - strncpy(log_tag, "UPDATE", sizeof(log_tag) - 1); -#endif - } - - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", return_code)); - -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - snprintf(log_message, sizeof(log_message), "alarmID: %d, uid: %d, pid: %d, duetime: %d-%d-%d %02d:%02d:%02d", - alarm_id, uid, pid, start_year, start_month, start_day, start_hour, start_min, start_sec); - __save_module_log(log_tag, log_message); -#endif - - return true; -} - -gboolean alarm_manager_alarm_get_number_of_ids(AlarmManager *pObject, GDBusMethodInvocation *invoc, - gpointer user_data) -{ - GSList *gs_iter = NULL; - char app_name[256] = { 0 }; - __alarm_info_t *entry = NULL; - int num_of_ids = 0; - int return_code = ALARMMGR_RESULT_SUCCESS; - int uid; - int pid; - const char *name = g_dbus_method_invocation_get_sender(invoc); - - uid = __get_caller_uid(name); - pid = __get_caller_pid(name); - if (uid < 0 || pid < 0) { - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", num_of_ids, return_code)); - return true; - } - - if (__get_cached_unique_name(pid, app_name, sizeof(app_name), NULL, uid) == false) { - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", num_of_ids, return_code)); - return true; - } - - SECURE_LOGD("Called by process (uid:%d, pid:%d, unique_name:%s)", uid, pid, app_name); - - for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { - entry = gs_iter->data; - SECURE_LOGD("app_name=%s, app_unique_name=%s", app_name, entry->app_unique_name); - if (entry->uid == uid && - strncmp(app_name, entry->app_unique_name, strlen(app_name)) == 0) { - (num_of_ids)++; - SECURE_LOGD("inc number of alarms of app (uid:%d, pid:%d, unique_name:%s) is %d.", uid, pid, app_name, num_of_ids); - } - } - - SECURE_LOGD("number of alarms of the process (uid:%d, pid:%d, unique_name:%s) is %d.", uid, pid, app_name, num_of_ids); - g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", num_of_ids, return_code)); - return true; -} - -gboolean alarm_manager_alarm_get_list_of_ids(AlarmManager *pObject, GDBusMethodInvocation *invoc, - int max_number_of_ids, gpointer user_data) -{ - GSList *gs_iter = NULL; - char app_name[512] = { 0 }; - __alarm_info_t *entry = NULL; - int index = 0; - GVariant *arr = NULL; - GVariantBuilder *builder = NULL; - int num_of_ids = 0; - int return_code = ALARMMGR_RESULT_SUCCESS; - int uid; - int pid; - const char *name = g_dbus_method_invocation_get_sender(invoc); - - uid = __get_caller_uid(name); - pid = __get_caller_pid(name); - if (uid < 0 || pid < 0) { - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(@aiii)", g_variant_new("ai", NULL), num_of_ids, return_code)); - return true; - } - - if (max_number_of_ids <= 0) { - SECURE_LOGE("called for uid(%d) pid(%d), but max_number_of_ids(%d) is less than 0.", uid, pid, max_number_of_ids); - g_dbus_method_invocation_return_value(invoc, g_variant_new("(@aiii)", g_variant_new("ai", NULL), num_of_ids, return_code)); - return true; - } - - if (__get_cached_unique_name(pid, app_name, sizeof(app_name), NULL, uid) == false) { - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(@aiii)", g_variant_new("ai", NULL), num_of_ids, return_code)); - return true; - } - - SECURE_LOGD("Called by process (uid: %d, pid:%d, unique_name=%s).", uid, pid, app_name); - - builder = g_variant_builder_new(G_VARIANT_TYPE("ai")); - for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { - entry = gs_iter->data; - if (entry->uid == uid && - strncmp(app_name, (entry->app_unique_name), strlen(app_name)) == 0) { - g_variant_builder_add(builder, "i", entry->alarm_id); - index++; - SECURE_LOGE("called for alarmid(%d), but max_number_of_ids(%d) index %d.", entry->alarm_id, max_number_of_ids, index); - } - } - - arr = g_variant_new("ai", builder); - num_of_ids = index; - - SECURE_LOGE("Called by uid (%d), pid (%d), but max_number_of_ids(%d) return code %d.", uid, pid, num_of_ids, return_code); - g_dbus_method_invocation_return_value(invoc, g_variant_new("(@aiii)", arr, num_of_ids, return_code)); - - g_variant_builder_unref(builder); - return true; -} - -gboolean alarm_manager_alarm_get_appsvc_info(AlarmManager *pObject, GDBusMethodInvocation *invoc, - alarm_id_t alarm_id, gpointer user_data) -{ - bool found = false; - GSList *gs_iter = NULL; - __alarm_info_t *entry = NULL; - int return_code = ALARMMGR_RESULT_SUCCESS; - gchar *b_data = NULL; - int uid; - const char *name = g_dbus_method_invocation_get_sender(invoc); - - uid = __get_caller_uid(name); - if (uid < 0) { - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(si)", b_data, return_code)); - return true; - } - - SECURE_LOGD("called for uid(%d), alarm_id(%d)\n", uid, alarm_id); - - for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { - entry = gs_iter->data; - if (entry->uid == uid && entry->alarm_id == alarm_id) { - found = true; - b_data = g_strdup(entry->bundle); - break; - } - } - - if (found) { - if (b_data == NULL) { - ALARM_MGR_EXCEPTION_PRINT("The alarm(%d) is an regular alarm, not svc alarm.", alarm_id); - return_code = ERR_ALARM_INVALID_TYPE; - } - } else { - ALARM_MGR_EXCEPTION_PRINT("The alarm(%d) is not found.", alarm_id); - return_code = ERR_ALARM_INVALID_ID; - } - - g_dbus_method_invocation_return_value(invoc, g_variant_new("(si)", b_data, return_code)); - g_free(b_data); - return true; -} - -gboolean alarm_manager_alarm_get_noti_info(AlarmManager *pObject, GDBusMethodInvocation *invoc, - alarm_id_t alarm_id, gpointer user_data) -{ - bool found = false; - GSList *gs_iter = NULL; - __alarm_info_t *entry = NULL; - int return_code = ALARMMGR_RESULT_SUCCESS; - gchar *noti_data = NULL; - int uid; - const char *name = g_dbus_method_invocation_get_sender(invoc); - - uid = __get_caller_uid(name); - if (uid < 0) { - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(si)", noti_data, return_code)); - return true; - } - - SECURE_LOGD("called for uid(%d), alarm_id(%d)\n", uid, alarm_id); - - for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { - entry = gs_iter->data; - if (entry->uid == uid && entry->alarm_id == alarm_id) { - found = true; - if (entry->noti) - noti_data = strdup(entry->noti); - break; - } - } - - if (found) { - if (noti_data == NULL) { - ALARM_MGR_EXCEPTION_PRINT("The alarm(%d) is an regular alarm, not svc alarm.", alarm_id); - return_code = ERR_ALARM_INVALID_TYPE; - } - } else { - ALARM_MGR_EXCEPTION_PRINT("The alarm(%d) is not found.", alarm_id); - return_code = ERR_ALARM_INVALID_ID; - } - - g_dbus_method_invocation_return_value(invoc, g_variant_new("(si)", noti_data, return_code)); - g_free(noti_data); - return true; -} - -gboolean alarm_manager_alarm_get_info(AlarmManager *pObject, GDBusMethodInvocation *invoc, - alarm_id_t alarm_id, gpointer user_data) -{ - GSList *gs_iter = NULL; - __alarm_info_t *entry = NULL; - alarm_info_t *alarm_info = NULL; - int return_code = ALARMMGR_RESULT_SUCCESS; - int uid; - const char *name = g_dbus_method_invocation_get_sender(invoc); - - uid = __get_caller_uid(name); - if (uid < 0) { - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(iiiiiiiiiiiiii)", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, return_code)); - return true; - } - - SECURE_LOGD("called for uid(%d), alarm_id(%d)\n", uid, alarm_id); - for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { - entry = gs_iter->data; - if (entry->uid == uid && entry->alarm_id == alarm_id) { - alarm_info = &(entry->alarm_info); - break; - } - } - - if (alarm_info == NULL) { - ALARM_MGR_EXCEPTION_PRINT("The alarm(%d) is not found.", alarm_id); - return_code = ERR_ALARM_INVALID_ID; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(iiiiiiiiiiiiii)", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, return_code)); - } else { - ALARM_MGR_LOG_PRINT("The alarm(%d) is found.", alarm_id); - g_dbus_method_invocation_return_value(invoc, g_variant_new("(iiiiiiiiiiiiii)", alarm_info->start.year, alarm_info->start.month, - alarm_info->start.day, alarm_info->start.hour, alarm_info->start.min, alarm_info->start.sec, alarm_info->end.year, alarm_info->end.month, - alarm_info->end.day, alarm_info->mode.u_interval.day_of_week, alarm_info->mode.repeat, alarm_info->alarm_type, alarm_info->reserved_info, return_code)); - } - - return true; -} - -gboolean alarm_manager_alarm_get_next_duetime(AlarmManager *pObject, GDBusMethodInvocation *invoc, - alarm_id_t alarm_id, gpointer user_data) -{ - GSList *gs_iter = NULL; - __alarm_info_t *entry = NULL; - __alarm_info_t *find_item = NULL; - int return_code = ALARMMGR_RESULT_SUCCESS; - time_t duetime = 0; - int uid; - const char *name = g_dbus_method_invocation_get_sender(invoc); - - uid = __get_caller_uid(name); - if (uid < 0) { - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", duetime, return_code)); - return true; - } - - SECURE_LOGD("called for alarm_id(%d)\n", alarm_id); - for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { - entry = gs_iter->data; - if (entry->uid == uid && entry->alarm_id == alarm_id) { - find_item = entry; - break; - } - } - - if (find_item == NULL) { - ALARM_MGR_EXCEPTION_PRINT("The alarm(%d) is not found.", alarm_id); - return_code = ERR_ALARM_INVALID_ID; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", duetime, return_code)); - return true; - } - - duetime = _alarm_next_duetime(find_item); - ALARM_MGR_LOG_PRINT("Next duetime : %s", ctime(&duetime)); - - g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", duetime, return_code)); - return true; -} - -gboolean alarm_manager_alarm_get_all_info(AlarmManager *pObject, GDBusMethodInvocation *invoc, gpointer user_data) -{ - sqlite3 *alarmmgr_tool_db; - char *db_path = NULL; - char db_path_tmp[50] = {0,}; - time_t current_time = 0; - struct tm current_tm; - const char *query_for_creating_table = "create table alarmmgr_tool \ - (alarm_id integer primary key,\ - duetime_epoch integer,\ - duetime text,\ - start_epoch integer,\ - end_epoch integer,\ - pid integer,\ - global integer,\ - caller_pkgid text,\ - callee_pkgid text,\ - app_unique_name text,\ - app_service_name text,\ - dst_service_name text,\ - day_of_week integer,\ - repeat integer,\ - alarm_type integer)"; - const char *query_for_deleting_table = "drop table alarmmgr_tool"; - int return_code = ALARMMGR_RESULT_SUCCESS; - GSList *gs_iter = NULL; - __alarm_info_t *entry = NULL; - char *error_message = NULL; - int uid; - const char *name = g_dbus_method_invocation_get_sender(invoc); - - uid = __get_caller_uid(name); - if (uid < 0) { - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(si)", db_path, return_code)); - return true; - } - - /* Open a DB */ - time(¤t_time); - localtime_r(¤t_time, ¤t_tm); - snprintf(db_path_tmp, sizeof(db_path_tmp), "/tmp/alarmmgr_%d%d%d_%02d%02d%02d.db", - current_tm.tm_year + 1900, current_tm.tm_mon + 1, current_tm.tm_mday, current_tm.tm_hour, current_tm.tm_min, current_tm.tm_sec); - db_path = strdup(db_path_tmp); - - if (sqlite3_open(db_path, &alarmmgr_tool_db) != SQLITE_OK) { - ALARM_MGR_EXCEPTION_PRINT("Failed to open [%s]", db_path); - return_code = ERR_ALARM_SYSTEM_FAIL; - goto done; - } - /* Register busy handler */ - if (sqlite3_busy_handler(alarmmgr_tool_db, __db_busyhandler, NULL) != SQLITE_OK) { - ALARM_MGR_EXCEPTION_PRINT("Failed to register the busy handler"); - return_code = ERR_ALARM_SYSTEM_FAIL; - goto done; - } - - /* Drop a table */ - if (sqlite3_exec(alarmmgr_tool_db, query_for_deleting_table, NULL, NULL, &error_message) != SQLITE_OK) { - ALARM_MGR_EXCEPTION_PRINT("Deleting the table is failed. error message = %s", error_message); - sqlite3_free(error_message); - } - - /* Create a table if it does not exist */ - if (sqlite3_exec(alarmmgr_tool_db, query_for_creating_table, NULL, NULL, &error_message) != SQLITE_OK) { - ALARM_MGR_EXCEPTION_PRINT("Creating the table is failed. error message = %s", error_message); - sqlite3_free(error_message); - sqlite3_close(alarmmgr_tool_db); - return_code = ERR_ALARM_SYSTEM_FAIL; - goto done; - } - - /* Get information of all alarms and save those into the DB. */ - int index = 0; - for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { - entry = gs_iter->data; - if (uid >= REGULAR_UID_MIN && entry->uid != uid) - continue; - ++index; - SECURE_LOGD("#%d alarm id[%d] app_name[%s] duetime[%ld]", - index, entry->alarm_id, entry->app_unique_name, entry->start); - - alarm_info_t *alarm_info = (alarm_info_t *) &(entry->alarm_info); - alarm_mode_t *mode = &alarm_info->mode; - - char *query = sqlite3_mprintf("insert into alarmmgr_tool( alarm_id, duetime_epoch, duetime, start_epoch,\ - end_epoch, pid, global, caller_pkgid, callee_pkgid, app_unique_name, app_service_name, dst_service_name, day_of_week, repeat, alarm_type)\ - values (%d,%d,%Q,%d,%d,%d,%d,%Q,%Q,%Q,%Q,%Q,%d,%d,%d)", - entry->alarm_id, - (int)entry->due_time, - ctime(&(entry->due_time)), - (int)entry->start, - (int)entry->end, - (int)entry->pid, - (bool)entry->global, - CHECK_NULL_STRING(entry->caller_pkgid), - CHECK_NULL_STRING(entry->callee_pkgid), - CHECK_NULL_STRING(entry->app_unique_name), - CHECK_NULL_STRING(entry->app_service_name), - CHECK_NULL_STRING(entry->dst_service_name), - mode->u_interval.day_of_week, - mode->repeat, - entry->alarm_info.alarm_type); - - if (sqlite3_exec(alarmmgr_tool_db, query, NULL, NULL, &error_message) != SQLITE_OK) { - SECURE_LOGE("sqlite3_exec() is failed. error message = %s", error_message); - sqlite3_free(error_message); - } - - sqlite3_free(query); - } - return_code = ALARMMGR_RESULT_SUCCESS; - -done: - g_dbus_method_invocation_return_value(invoc, g_variant_new("(si)", db_path, return_code)); - if (alarmmgr_tool_db) - sqlite3_close(alarmmgr_tool_db); - if (db_path) - free(db_path); - return true; -} - -gboolean alarm_manager_alarm_set_global(AlarmManager *pObject, GDBusMethodInvocation *invoc, - alarm_id_t alarm_id, bool global, gpointer user_data) -{ - GSList *gs_iter = NULL; - __alarm_info_t *entry = NULL; - alarm_info_t *alarm_info = NULL; - int retval = 0; - int return_code = ALARMMGR_RESULT_SUCCESS; - int uid; - const char *name = g_dbus_method_invocation_get_sender(invoc); - char *callee_pkgid; - - uid = __get_caller_uid(name); - if (uid < 0) { - return_code = ERR_ALARM_SYSTEM_FAIL; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", return_code)); - return true; - } - - SECURE_LOGD("called for uid(%d), alarm_id(%d)\n", uid, alarm_id); - for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { - entry = gs_iter->data; - if (entry->uid == uid && entry->alarm_id == alarm_id) { - alarm_info = &(entry->alarm_info); - break; - } - } - - if (alarm_info == NULL) { - ALARM_MGR_EXCEPTION_PRINT("The alarm(%d) is not found.", alarm_id); - return_code = ERR_ALARM_INVALID_ID; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", return_code)); - } else { - ALARM_MGR_LOG_PRINT("The alarm(%d) is found.", alarm_id); - - if (entry->callee_pkgid == NULL) - callee_pkgid = entry->app_service_name + 6; - else - callee_pkgid = entry->callee_pkgid; - - ALARM_MGR_LOG_PRINT("The alarm pkgid : %s.", callee_pkgid); - - pkgmgrinfo_pkginfo_h handle; - retval = pkgmgrinfo_pkginfo_get_usr_pkginfo(callee_pkgid, uid, &handle); - if (retval != PMINFO_R_OK) { - ALARM_MGR_EXCEPTION_PRINT("Failed to get pkginfo\n"); - return_code = ERR_ALARM_INVALID_ID; - } else { - bool is_global = 0; - retval = pkgmgrinfo_pkginfo_is_global(handle, &is_global); - if (retval == PMINFO_R_OK && is_global) { - entry->global = global; - if (!__alarm_set_global_to_db(entry, global)) - return_code = ERR_ALARM_SYSTEM_FAIL; - } else if (retval == PMINFO_R_OK && !is_global) { - return_code = ERR_ALARM_NOT_PERMITTED_APP; - } - pkgmgrinfo_pkginfo_destroy_pkginfo(handle); - } - g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", return_code)); - } - - return true; -} - -gboolean alarm_manager_alarm_get_global(AlarmManager *pObject, GDBusMethodInvocation *invoc, - alarm_id_t alarm_id, gpointer user_data) -{ - GSList *gs_iter = NULL; - __alarm_info_t *entry = NULL; - __alarm_info_t *find_item = NULL; - int return_code = ALARMMGR_RESULT_SUCCESS; - bool global = false; - - SECURE_LOGD("called for alarm_id(%d)\n", alarm_id); - for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { - entry = gs_iter->data; - if (entry->alarm_id == alarm_id) { - find_item = entry; - break; - } - } - - if (find_item == NULL) { - ALARM_MGR_EXCEPTION_PRINT("The alarm(%d) is not found.", alarm_id); - return_code = ERR_ALARM_INVALID_ID; - g_dbus_method_invocation_return_value(invoc, g_variant_new("(bi)", global, return_code)); - return true; - } - - global = find_item->global; - ALARM_MGR_LOG_PRINT("Is global : %d", global); - - g_dbus_method_invocation_return_value(invoc, g_variant_new("(bi)", global, return_code)); - return true; -} - - -static void __timer_glib_finalize(GSource *src) -{ - GSList *fd_list; - GPollFD *tmp; - - fd_list = src->poll_fds; - do { - tmp = (GPollFD *) fd_list->data; - g_free(tmp); - - fd_list = fd_list->next; - } while (fd_list); - - return; -} - -static gboolean __timer_glib_check(GSource *src) -{ - GSList *fd_list; - GPollFD *tmp; - - fd_list = src->poll_fds; - do { - tmp = (GPollFD *) fd_list->data; - if (tmp->revents & (POLLIN | POLLPRI)) - return TRUE; - - fd_list = fd_list->next; - } while (fd_list); - - return FALSE; -} - -static gboolean __timer_glib_dispatch(GSource *src, GSourceFunc callback, - gpointer data) -{ - callback(data); - return TRUE; -} - -static gboolean __timer_glib_prepare(GSource *src, gint *timeout) -{ - return FALSE; -} - -GSourceFuncs funcs = { - .prepare = __timer_glib_prepare, - .check = __timer_glib_check, - .dispatch = __timer_glib_dispatch, - .finalize = __timer_glib_finalize -}; - -static void __initialize_timer() -{ - int fd; - GSource *src; - GPollFD *gpollfd; - int ret; - - fd = timerfd_create(CLOCK_REALTIME, 0); - if (fd == -1) { - ALARM_MGR_EXCEPTION_PRINT("timerfd_create() is failed.\n"); - exit(1); - } - src = g_source_new(&funcs, sizeof(GSource)); - - gpollfd = (GPollFD *) g_malloc(sizeof(GPollFD)); - if (gpollfd == NULL) { - ALARM_MGR_EXCEPTION_PRINT("Out of memory\n"); - exit(1); - } - gpollfd->events = POLLIN; - gpollfd->fd = fd; - - g_source_add_poll(src, gpollfd); - g_source_set_callback(src, (GSourceFunc) __alarm_handler_idle, - (gpointer) gpollfd, NULL); - g_source_set_priority(src, G_PRIORITY_HIGH); - - ret = g_source_attach(src, NULL); - if (ret == 0) { - ALARM_MGR_EXCEPTION_PRINT("g_source_attach() is failed.\n"); - return; - } - - g_source_unref(src); - - alarm_context.timer = fd; -} - -static void __initialize_alarm_list() -{ - alarm_context.alarms = NULL; - alarm_context.c_due_time = -1; - - _load_alarms_from_registry(); - - __rtc_set(); /*Set RTC1 Alarm with alarm due time for alarm-manager initialization*/ -} - -static void __initialize_scheduled_alarm_list() -{ - _init_scheduled_alarm_list(); -} - -static bool __initialize_noti() -{ - /* VCONFKEY_SYSTEM_TIMECHANGE_EXTERNAL is set by OSP app-service. */ - if (vconf_notify_key_changed - (VCONFKEY_SYSTEM_TIMECHANGE_EXTERNAL, __on_system_time_external_changed, NULL) < 0) { - ALARM_MGR_LOG_PRINT("Failed to add callback for time external changing event."); - } - - /* If the caller or callee app is uninstalled, all registered alarms will be canceled. */ - pkgmgr_client *pc = pkgmgr_client_new(PC_LISTENING); - pkgmgr_client_set_status_type(pc, PKGMGR_CLIENT_STATUS_UNINSTALL); - pkgmgr_client_listen_status(pc, __on_app_uninstalled, NULL); - - pkgmgr_client_set_status_type(pc, PKGMGR_CLIENT_STATUS_ENABLE_APP); - pkgmgr_client_listen_app_status(pc, __on_app_enable_cb, NULL); - - pkgmgr_client_set_status_type(pc, PKGMGR_CLIENT_STATUS_DISABLE_APP); - pkgmgr_client_listen_app_status(pc, __on_app_disable_cb, NULL); - return true; -} - -void on_bus_name_owner_changed(GDBusConnection *connection, - const gchar *sender_name, - const gchar *object_path, - const gchar *interface_name, - const gchar *signal_name, - GVariant *parameters, - gpointer user_data) -{ - GSList *entry = NULL; - __expired_alarm_t *expire_info = NULL; - char *service_name = NULL; - - /* On expiry, the killed app can be launched by aul. Then, the owner of the bus name which was registered by the app is changed. - * In this case, "NameOwnerChange" signal is broadcasted. */ - if (signal_name && strcmp(signal_name , "NameOwnerChanged") == 0) { - g_variant_get(parameters, "(sss)", &service_name, NULL, NULL); - - for (entry = g_expired_alarm_list; entry; entry = entry->next) { - if (entry->data) { - expire_info = (__expired_alarm_t *) entry->data; - SECURE_LOGD("expired service(%s), owner changed service(%s)", expire_info->service_name, service_name); - - if (strcmp(expire_info->service_name, service_name) == 0) { - SECURE_LOGE("expired service name(%s) alarm_id (%d)", expire_info->service_name, expire_info->alarm_id); - __alarm_send_noti_to_application(expire_info->service_name, expire_info->alarm_id, 0, expire_info->uid); - g_expired_alarm_list = g_slist_remove(g_expired_alarm_list, entry->data); - g_free(expire_info); - } - } - } - g_free(service_name); - } -} - -static bool __initialize_dbus() -{ - GDBusConnection *connection = NULL; - GError *error = NULL; - guint subsc_id; - ALARM_MGR_LOG_PRINT("__initialize_dbus Enter"); - - connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); - if (connection == NULL) { - ALARM_MGR_EXCEPTION_PRINT("g_bus_get_sync() is failed"); - if (error) { - ALARM_MGR_EXCEPTION_PRINT("dbus error message : %s", error->message); - g_error_free(error); - } - return false; - } - - interface = alarm_manager_skeleton_new(); - if (interface == NULL) { - ALARM_MGR_EXCEPTION_PRINT("Creating a skeleton object is failed."); - g_object_unref(connection); - return false; - } - - g_signal_connect(interface, "handle_alarm_create", G_CALLBACK(alarm_manager_alarm_create), NULL); - g_signal_connect(interface, "handle_alarm_create_periodic", G_CALLBACK(alarm_manager_alarm_create_periodic), NULL); - g_signal_connect(interface, "handle_alarm_create_appsvc", G_CALLBACK(alarm_manager_alarm_create_appsvc), NULL); - g_signal_connect(interface, "handle_alarm_create_noti", G_CALLBACK(alarm_manager_alarm_create_noti), NULL); - g_signal_connect(interface, "handle_alarm_delete", G_CALLBACK(alarm_manager_alarm_delete), NULL); - g_signal_connect(interface, "handle_alarm_delete_all", G_CALLBACK(alarm_manager_alarm_delete_all), NULL); - g_signal_connect(interface, "handle_alarm_get_appsvc_info", G_CALLBACK(alarm_manager_alarm_get_appsvc_info), NULL); - g_signal_connect(interface, "handle_alarm_get_info", G_CALLBACK(alarm_manager_alarm_get_info), NULL); - g_signal_connect(interface, "handle_alarm_get_noti_info", G_CALLBACK(alarm_manager_alarm_get_noti_info), NULL); - g_signal_connect(interface, "handle_alarm_get_list_of_ids", G_CALLBACK(alarm_manager_alarm_get_list_of_ids), NULL); - g_signal_connect(interface, "handle_alarm_get_next_duetime", G_CALLBACK(alarm_manager_alarm_get_next_duetime), NULL); - g_signal_connect(interface, "handle_alarm_get_number_of_ids", G_CALLBACK(alarm_manager_alarm_get_number_of_ids), NULL); - g_signal_connect(interface, "handle_alarm_set_rtc_time", G_CALLBACK(alarm_manager_alarm_set_rtc_time), NULL); - g_signal_connect(interface, "handle_alarm_set_time", G_CALLBACK(alarm_manager_alarm_set_time), NULL); - g_signal_connect(interface, "handle_alarm_set_timezone", G_CALLBACK(alarm_manager_alarm_set_timezone), NULL); - g_signal_connect(interface, "handle_alarm_update", G_CALLBACK(alarm_manager_alarm_update), NULL); - g_signal_connect(interface, "handle_alarm_get_all_info", G_CALLBACK(alarm_manager_alarm_get_all_info), NULL); - g_signal_connect(interface, "handle_alarm_set_time_with_propagation_delay", G_CALLBACK(alarm_manager_alarm_set_time_with_propagation_delay), NULL); - g_signal_connect(interface, "handle_alarm_set_global", G_CALLBACK(alarm_manager_alarm_set_global), NULL); - g_signal_connect(interface, "handle_alarm_get_global", G_CALLBACK(alarm_manager_alarm_get_global), NULL); - - subsc_id = g_dbus_connection_signal_subscribe(connection, - "org.freedesktop.DBus", "org.freedesktop.DBus", - "NameOwnerChanged", "/org/freedesktop/DBus", NULL, - G_DBUS_SIGNAL_FLAGS_NONE, on_bus_name_owner_changed, NULL, NULL); - if (subsc_id == 0) { - ALARM_MGR_EXCEPTION_PRINT("Subscribing to signal for invoking callback is failed."); - g_object_unref(interface); - interface = NULL; - g_object_unref(connection); - return false; - } - - if (!g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(interface), connection, ALARM_MGR_DBUS_PATH, NULL)) { - ALARM_MGR_EXCEPTION_PRINT("Exporting the interface is failed."); - g_object_unref(interface); - interface = NULL; - g_object_unref(connection); - return false; - } - - guint owner_id = g_bus_own_name_on_connection(connection, - ALARM_MGR_DBUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE, - NULL, NULL, NULL, NULL); - - if (owner_id == 0) { - ALARM_MGR_EXCEPTION_PRINT("Acquiring the own name is failed."); - g_object_unref(interface); - interface = NULL; - g_object_unref(connection); - return false; - } - - alarm_context.connection = connection; - - return true; -} - -#define ALARMMGR_DB_FILE tzplatform_mkpath(TZ_SYS_DB, ".alarmmgr.db") -#define QUERY_CREATE_TABLE_ALARMMGR "create table if not exists alarmmgr \ - (alarm_id integer primary key,\ - start integer,\ - end integer,\ - uid integer,\ - pid integer,\ - global integer,\ - is_disabled integer,\ - caller_pkgid text,\ - callee_pkgid text,\ - app_unique_name text,\ - app_service_name text,\ - app_service_name_mod text,\ - bundle text, \ - noti_len integer,\ - noti text, \ - year integer,\ - month integer,\ - day integer,\ - hour integer,\ - min integer,\ - sec integer,\ - msec integer,\ - day_of_week integer,\ - repeat integer,\ - alarm_type integer,\ - reserved_info integer,\ - dst_service_name text, \ - dst_service_name_mod text \ - )" - -static int __db_busyhandler(void *pData, int count) -{ - if (5 - count > 0) { - struct timespec time = { - .tv_sec = 0, - .tv_nsec = (count + 1) * 100 * 1000 * 1000 - }; - nanosleep(&time, NULL); - ALARM_MGR_LOG_PRINT("alarmmgr_db: busy handler called. count: %d", count + 1); - return 1; - } else { - ALARM_MGR_LOG_PRINT("alarmmgr_db: busy handler will return SQLITE_BUSY error"); - return 0; - } -} - -int check_callback(void *pid, int argc, char **argv, char **notUsed2) -{ - if (strcmp(argv[0], "ok") != 0) { - ALARM_MGR_EXCEPTION_PRINT("check integrity result : %s" , argv[0]); - is_db_corrupted = true; - return -1; - } else { - ALARM_MGR_LOG_PRINT("check integrity result : %s" , argv[0]); - } - - return 0; -} - -static bool __initialize_db() -{ - char *error_message = NULL; - int ret; - - /* Create or Open the DB file */ - ret = sqlite3_open(ALARMMGR_DB_FILE, &alarmmgr_db); - if (ret != SQLITE_OK) { - ALARM_MGR_EXCEPTION_PRINT("Failed to open [%s]. error: %s", ALARMMGR_DB_FILE, sqlite3_errmsg(alarmmgr_db)); - if (ret == SQLITE_CORRUPT) - goto recover; - else - return false; - } - /* Register busy handler */ - ret = sqlite3_busy_handler(alarmmgr_db, __db_busyhandler, NULL); - if (ret != SQLITE_OK) { - ALARM_MGR_EXCEPTION_PRINT("Failed to register the busy handler"); - if (ret == SQLITE_CORRUPT) { - goto recover; - } else { - sqlite3_close(alarmmgr_db); - return false; - } - } - /* Create alarmmgr table */ - ret = sqlite3_exec(alarmmgr_db, QUERY_CREATE_TABLE_ALARMMGR, NULL, NULL, &error_message); - if (ret != SQLITE_OK) { - ALARM_MGR_EXCEPTION_PRINT("Don't execute query = %s, error message = %s", QUERY_CREATE_TABLE_ALARMMGR, error_message); - if (ret == SQLITE_CORRUPT || ret == SQLITE_NOTADB) { - goto recover; - } else { - sqlite3_close(alarmmgr_db); - sqlite3_free(error_message); - return false; - } - } - - /* Check integrity of DB */ - ret = sqlite3_exec(alarmmgr_db, "PRAGMA integrity_check", check_callback, NULL, 0); - if (ret != SQLITE_OK || is_db_corrupted) { - ALARM_MGR_EXCEPTION_PRINT("Loss alarm db's integrity"); - goto recover; - } - - return true; - -recover: - if (alarmmgr_db) - sqlite3_close(alarmmgr_db); - if (error_message) - sqlite3_free(error_message); - unlink(ALARMMGR_DB_FILE); - - ret = sqlite3_open(ALARMMGR_DB_FILE, &alarmmgr_db); - if (ret != SQLITE_OK) { - ALARM_MGR_EXCEPTION_PRINT("[recover] Failed to open [%s]. error: %s", ALARMMGR_DB_FILE, sqlite3_errmsg(alarmmgr_db)); - return false; - } - - ret = sqlite3_busy_handler(alarmmgr_db, __db_busyhandler, NULL); - if (ret != SQLITE_OK) { - ALARM_MGR_EXCEPTION_PRINT("[recover] Failed to register the busy handler"); - sqlite3_close(alarmmgr_db); - return false; - } - - ret = sqlite3_exec(alarmmgr_db, QUERY_CREATE_TABLE_ALARMMGR, NULL, NULL, &error_message); - if (ret != SQLITE_OK) { - ALARM_MGR_EXCEPTION_PRINT("[recover] Don't execute query = %s, error message = %s", QUERY_CREATE_TABLE_ALARMMGR, error_message); - sqlite3_close(alarmmgr_db); - sqlite3_free(error_message); - return false; - } - - return true; -} - -static void __initialize() -{ -#if !(GLIB_CHECK_VERSION(2, 36, 0)) - g_type_init(); -#endif - - //For debug - int expire_mode = ALARM_EXPIRE_MODE_NORMAL; - vconf_get_int(VCONFKEY_ALARM_EXPIRE_MODE, &expire_mode); - ALARM_MGR_LOG_PRINT("alarm_expire_mode : %d", expire_mode); - - __initialize_timer(); - if (__initialize_dbus() == false) { - /* because dbus's initialize - * failed, we cannot continue any more. */ - ALARM_MGR_EXCEPTION_PRINT("because __initialize_dbus failed, " - "alarm-server cannot be runned.\n"); - exit(1); - } - -#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG - __initialize_module_log(); /* for module log */ -#endif - - __initialize_scheduled_alarm_list(); - __initialize_db(); - __initialize_alarm_list(); - __initialize_noti(); - - if (!appid_cache_table) { - appid_cache_table = g_hash_table_new_full(g_int_hash, g_int_equal, - NULL, __free_cached_value); - } -} - -void _release_alarm_info_t(__alarm_info_t *entry) -{ - if (!entry) - return; - - if (entry->caller_pkgid) - free(entry->caller_pkgid); - if (entry->callee_pkgid) - free(entry->callee_pkgid); - if (entry->app_unique_name) - free(entry->app_unique_name); - if (entry->app_service_name) - free(entry->app_service_name); - if (entry->app_service_name_mod) - free(entry->app_service_name_mod); - if (entry->dst_service_name) - free(entry->dst_service_name); - - if (entry->dst_service_name_mod) - free(entry->dst_service_name_mod); - if (entry->bundle) - free(entry->bundle); - if (entry->noti) - free(entry->noti); - - free(entry); -} - -int main() -{ - GMainLoop *mainloop = NULL; - - ALARM_MGR_LOG_PRINT("Enter main loop\n"); - - mainloop = g_main_loop_new(NULL, FALSE); - - __initialize(); - - g_main_loop_run(mainloop); - - return 0; -} diff --git a/alarm-session-agent/CMakeLists.txt b/alarm-session-agent/CMakeLists.txt deleted file mode 100644 index 7a25ebc..0000000 --- a/alarm-session-agent/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -PKG_CHECK_MODULES(D_PKGS REQUIRED gio-2.0 glib-2.0 dlog bundle libsystemd-daemon) - -FOREACH(flag ${D_PKGS_CFLAGS}) - SET(DAEMON_CFLAGS "${DAEMON_CFLAGS} ${flag}") -ENDFOREACH() - -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/lib/include) - -SET(TARGET "alarm_session_agent") -SET(SRC - agent.c -) -ADD_EXECUTABLE(${TARGET} ${SRC}) -SET_TARGET_PROPERTIES(${TARGET} PROPERTIES - LINK_FLAGS "-fPIE" - COMPILE_FLAGS "${DAEMON_CFLAGS}" -) -TARGET_LINK_LIBRARIES(${TARGET} ${PKGS_LDFLAGS} ${D_PKGS_LDFLAGS} -ldl -pie) -INSTALL(TARGETS ${TARGET} DESTINATION bin) - diff --git a/alarm_mgr.xml b/alarm_mgr.xml deleted file mode 100644 index bcdee08..0000000 --- a/alarm_mgr.xml +++ /dev/null @@ -1,183 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" ?> -<node name="/org/tizen/alarm/manager"> - <interface name="org.tizen.alarm.manager"> - <method name="alarm_create_periodic"> - <arg type="s" name="app_service_name" direction="in" /> - <arg type="s" name="app_service_name_mod" direction="in" /> - <arg type="i" name="interval" direction="in" /> - <arg type="i" name="is_ref" direction="in" /> - <arg type="i" name="method" direction="in" /> - <arg type="i" name="alarm_id" direction="out" /> - <arg type="i" name="return_code" direction="out" /> - </method> - <method name="alarm_create"> - <arg type="s" name="app_service_name" direction="in" /> - <arg type="s" name="app_service_name_mod" direction="in" /> - <arg type="i" name="alarm_info_start_year" direction="in" /> - <arg type="i" name="alarm_info_start_month" direction="in" /> - <arg type="i" name="alarm_info_start_day" direction="in" /> - <arg type="i" name="alarm_info_start_hour" direction="in" /> - <arg type="i" name="alarm_info_start_min" direction="in" /> - <arg type="i" name="alarm_info_start_sec" direction="in" /> - <arg type="i" name="alarm_info_msec" direction="in" /> - <arg type="i" name="alarm_info_end_year" direction="in" /> - <arg type="i" name="alarm_info_end_month" direction="in" /> - <arg type="i" name="alarm_info_end_day" direction="in" /> - <arg type="i" name="alarm_info_mode_day_of_week" direction="in" /> - <arg type="i" name="alarm_info_mode_repeat" direction="in" /> - <arg type="i" name="alarm_info_alarm_type" direction="in" /> - <arg type="i" name="alarm_info_reserved_info" direction="in" /> - <arg type="s" name="alarm_info_reserved_service_name" direction="in" /> - <arg type="s" name="alarm_info_reserved_service_name_mod" direction="in" /> - <arg type="i" name="alarm_id" direction="out" /> - <arg type="i" name="return_code" direction="out" /> - </method> - <method name="alarm_create_appsvc"> - <arg type="i" name="alarm_info_start_year" direction="in" /> - <arg type="i" name="alarm_info_start_month" direction="in" /> - <arg type="i" name="alarm_info_start_day" direction="in" /> - <arg type="i" name="alarm_info_start_hour" direction="in" /> - <arg type="i" name="alarm_info_start_min" direction="in" /> - <arg type="i" name="alarm_info_start_sec" direction="in" /> - <arg type="i" name="alarm_info_end_year" direction="in" /> - <arg type="i" name="alarm_info_end_month" direction="in" /> - <arg type="i" name="alarm_info_end_day" direction="in" /> - <arg type="i" name="alarm_info_mode_day_of_week" direction="in" /> - <arg type="i" name="alarm_info_mode_interval" direction="in" /> - <arg type="i" name="alarm_info_mode_repeat" direction="in" /> - <arg type="i" name="alarm_info_alarm_type" direction="in" /> - <arg type="i" name="alarm_info_reserved_info" direction="in" /> - <arg type="s" name="alarm_info_bundle_data" direction="in" /> - <arg type="i" name="alarm_id" direction="out" /> - <arg type="i" name="return_code" direction="out" /> - </method> - <method name="alarm_create_noti"> - <arg type="i" name="alarm_info_start_year" direction="in" /> - <arg type="i" name="alarm_info_start_month" direction="in" /> - <arg type="i" name="alarm_info_start_day" direction="in" /> - <arg type="i" name="alarm_info_start_hour" direction="in" /> - <arg type="i" name="alarm_info_start_min" direction="in" /> - <arg type="i" name="alarm_info_start_sec" direction="in" /> - <arg type="i" name="alarm_info_end_year" direction="in" /> - <arg type="i" name="alarm_info_end_month" direction="in" /> - <arg type="i" name="alarm_info_end_day" direction="in" /> - <arg type="i" name="alarm_info_mode_day_of_week" direction="in" /> - <arg type="i" name="alarm_info_mode_interval" direction="in" /> - <arg type="i" name="alarm_info_mode_repeat" direction="in" /> - <arg type="i" name="alarm_info_alarm_type" direction="in" /> - <arg type="i" name="alarm_info_reserved_info" direction="in" /> - <arg type="s" name="alarm_info_noti_data" direction="in" /> - <arg type="i" name="alarm_id" direction="out" /> - <arg type="i" name="return_code" direction="out" /> - </method> - <method name="alarm_delete"> - <arg type="i" name="alarm_id" direction="in" /> - <arg type="i" name="alarm_info_return_code" direction="out" /> - </method> - <method name="alarm_delete_all"> - <arg type="i" name="alarm_info_return_code" direction="out" /> - </method> - <method name="alarm_update"> - <arg type="i" name="alarm_id" direction="in" /> - <arg type="i" name="alarm_info_start_year" direction="in" /> - <arg type="i" name="alarm_info_start_month" direction="in" /> - <arg type="i" name="alarm_info_start_day" direction="in" /> - <arg type="i" name="alarm_info_start_hour" direction="in" /> - <arg type="i" name="alarm_info_start_min" direction="in" /> - <arg type="i" name="alarm_info_start_sec" direction="in" /> - <arg type="i" name="alarm_info_end_year" direction="in" /> - <arg type="i" name="alarm_info_end_month" direction="in" /> - <arg type="i" name="alarm_info_end_day" direction="in" /> - <arg type="i" name="alarm_info_mode_day_of_week" direction="in" /> - <arg type="i" name="alarm_info_mode_repeat" direction="in" /> - <arg type="i" name="alarm_info_alarm_type" direction="in" /> - <arg type="i" name="alarm_info_reserved_info" direction="in" /> - <arg type="i" name="update_flag" direction="in" /> - <arg type="i" name="return_code" direction="out" /> - </method> - <method name="alarm_get_number_of_ids"> - <arg type="i" name="number_of_ids" direction="out" /> - <arg type="i" name="return_code" direction="out" /> - </method> - <method name="alarm_get_list_of_ids"> - <arg type="i" name="max_number_of_ids" direction="in" /> - <arg type="ai" name="alarm_id" direction="out" /> - <arg type="i" name="number_of_ids" direction="out" /> - <arg type="i" name="return_code" direction="out" /> - </method> - <method name="alarm_get_appsvc_info"> - <arg type="i" name="alarm_id" direction="in" /> - <arg type="s" name="b_data" direction="out" /> - <arg type="i" name="return_code" direction="out" /> - </method> - <method name="alarm_get_noti_info"> - <arg type="i" name="alarm_id" direction="in" /> - <arg type="s" name="noti_data" direction="out" /> - <arg type="i" name="return_code" direction="out" /> - </method> - <method name="alarm_get_info"> - <arg type="i" name="alarm_id" direction="in" /> - <arg type="i" name="alarm_info_start_year" direction="out" /> - <arg type="i" name="alarm_info_start_month" direction="out" /> - <arg type="i" name="alarm_info_start_day" direction="out" /> - <arg type="i" name="alarm_info_start_hour" direction="out" /> - <arg type="i" name="alarm_info_start_min" direction="out" /> - <arg type="i" name="alarm_info_start_sec" direction="out" /> - <arg type="i" name="alarm_info_end_year" direction="out" /> - <arg type="i" name="alarm_info_end_month" direction="out" /> - <arg type="i" name="alarm_info_end_day" direction="out" /> - <arg type="i" name="alarm_info_mode_day_of_week" direction="out" /> - <arg type="i" name="alarm_info_mode_repeat" direction="out" /> - <arg type="i" name="alarm_info_alarm_type" direction="out" /> - <arg type="i" name="alarm_info_reserved_info" direction="out" /> - <arg type="i" name="return_code" direction="out" /> - </method> - <method name="alarm_set_rtc_time"> - <arg type="i" name="alarm_info_year" direction="in" /> - <arg type="i" name="alarm_info_month" direction="in" /> - <arg type="i" name="alarm_info_day" direction="in" /> - <arg type="i" name="alarm_info_hour" direction="in" /> - <arg type="i" name="alarm_info_min" direction="in" /> - <arg type="i" name="alarm_info_sec" direction="in" /> - <arg type="i" name="return_code" direction="out" /> - </method> - <method name="alarm_get_next_duetime"> - <arg type="i" name="alarm_id" direction="in" /> - <arg type="i" name="duetime" direction="out" /> - <arg type="i" name="return_code" direction="out" /> - </method> - <method name="alarm_get_all_info"> - <arg type="s" name="db_path" direction="out" /> - <arg type="i" name="return_code" direction="out" /> - </method> - <method name="alarm_set_time"> - <arg type="i" name="time" direction="in" /> - <arg type="i" name="return_code" direction="out" /> - </method> - <method name="alarm_set_time_with_propagation_delay"> - <arg type="u" name="new_sec" direction="in" /> - <arg type="u" name="new_nsec" direction="in" /> - <arg type="u" name="req_sec" direction="in" /> - <arg type="u" name="req_nsec" direction="in" /> - <arg type="i" name="return_code" direction="out" /> - </method> - <method name="alarm_set_timezone"> - <arg type="s" name="tzpath_str" direction="in" /> - <arg type="i" name="return_code" direction="out" /> - </method> - <method name="alarm_set_global"> - <arg type="i" name="alarm_id" direction="in" /> - <arg type="b" name="global" direction="in" /> - <arg type="i" name="return_code" direction="out" /> - </method> - <method name="alarm_get_global"> - <arg type="i" name="alarm_id" direction="in" /> - <arg type="b" name="global" direction="out" /> - <arg type="i" name="return_code" direction="out" /> - </method> - <signal name="alarm_expired"> - <arg type="i" name="alarm_id" /> - <arg type="s" name="app_service_name" /> - </signal> - </interface> -</node> diff --git a/alarmmgr_log_dump.sh b/alarmmgr_log_dump.sh index 985e5ac..1a8c788 100644..100755 --- a/alarmmgr_log_dump.sh +++ b/alarmmgr_log_dump.sh @@ -3,7 +3,7 @@ PATH=/bin:/usr/bin:/sbin:/usr/sbin ALARMMGR_DUMP=$1/alarmmgr mkdir -p $ALARMMGR_DUMP -cp -f /run/alarmmgr_log/alarmmgr.log $ALARMMGR_DUMP +cp -f /var/log/appfw/alarmmgr_log/alarmmgr.log $ALARMMGR_DUMP alarmmgr_get_all_info mv -f /tmp/alarmmgr_* $ALARMMGR_DUMP diff --git a/include/alarm-internal.h b/include/alarm-internal.h index b5e18fc..d8959ff 100644 --- a/include/alarm-internal.h +++ b/include/alarm-internal.h @@ -1,10 +1,5 @@ /* - * alarm-manager - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Venkatesha Sarpangala <sarpangala.v@samsung.com>, Jayoun Lee <airjany@samsung.com>, - * Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com> + * Copyright (c) 2000 - 2019 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. @@ -17,19 +12,13 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. - * */ +#pragma once -#ifndef _ALARM_INTERNAL_H -#define _ALARM_INTERNAL_H - -#define MAX_SNOOZE_CNT 5 -#define REPEAT_MODE_ONCE 0x80 - -#define SIG_TIMER 0x32 -#define ALARM_INFO_MAX 100 +#ifdef __cplusplus +extern "C" { +#endif -#include "alarm.h" #include <glib.h> #include <dlog.h> #include <bundle.h> @@ -37,39 +26,20 @@ #include <notification.h> #include <gio/gio.h> -#define INIT_ALARM_LIST_SIZE 64 -#define INIT_SCHEDULED_ALARM_LIST_SIZE 32 -#define MAX_BUNDLE_NAME_LEN 2048 -#define MAX_SERVICE_NAME_LEN 256 -#define MAX_PKG_NAME_LEN MAX_SERVICE_NAME_LEN-8 -#define MAX_PKG_ID_LEN 256 -#define MIN_INEXACT_INTERVAL 600 -#define REGULAR_UID_MIN 5000 -#define MAX_APP_ID 256 - -#define SYSTEM_TIME_CHANGED "setting_time_changed" +#include "alarm.h" #ifdef LOG_TAG #undef LOG_TAG #endif #define LOG_TAG "ALARM_MANAGER" -/*Application ID for native application which is not launched by application -server.*/ -#define ALARM_NATIVE_APP_ID 99999 -/* Application Instance ID for native application which is not launched by -application server.*/ -#define ALARM_NATIVE_APP_INST_ID 99999 -/* Prefix of dbus service name of native application.*/ -#define ALARM_NATIVE_APP_DBUS_SVC_NAME_PREFIX "NATIVE" - -/* how to send expire event : gproxy or low level dbus -* if you want to use gproxy for receiving expire_event, please enable -* _EXPIRE_ALARM_INTERFACE_IS_DBUS_GPROXY_ feature -* otherwise, lowlevel dbus interface will be used for receiving expire_event. -* Now we use low level dbus instead of gproxy -*/ -/*#define _EXPIRE_ALARM_INTERFACE_IS_DBUS_GPROXY_ */ +#define MAX_BUNDLE_NAME_LEN 2048 +#define MAX_SERVICE_NAME_LEN 512 +#define MAX_PKG_NAME_LEN MAX_SERVICE_NAME_LEN-8 +#define MAX_PKG_ID_LEN 512 +#define MAX_APP_ID_LEN 512 +#define MIN_INEXACT_INTERVAL 600 +#define REGULAR_UID_MIN 5000 typedef struct { GDBusConnection *connection; @@ -83,57 +53,24 @@ typedef struct { char *app_service_name_mod; } alarm_context_t; -typedef union { - int day_of_week; /**< days of a week */ - time_t interval; -} alarm_interval_u; - -/** -* This struct has mode of an alarm -*/ -typedef struct { - alarm_interval_u u_interval; - alarm_repeat_mode_t repeat; /**< repeat mode */ -} alarm_mode_t; - -typedef struct { - alarm_set_time_cb_t callback; - void *user_data; - GDBusProxy *proxy; -} alarm_set_time_data_t; - enum async_param_type { SET_SYSTIME = 0, SET_SYSTIME_WITH_PROPAGATION_DELAY, }; -/** -* This enumeration has alarm type +typedef enum { + PROFILE_UNKNOWN = 0, + PROFILE_MOBILE, + PROFILE_WEARABLE, + PROFILE_TV, + PROFILE_IVI, + PROFILE_COMMON, +} profile_t; -typedef enum -{ - ALARM_TYPE_DEFAULT = 0x0, - ALARM_TYPE_RELATIVE = 0x01, - ALARM_TYPE_VOLATILE = 0x02, -}alarm_type_t; -*/ #define ALARM_TYPE_RELATIVE 0x80000000 /**< relative */ #define ALARM_TYPE_WITHCB 0x40000000 /**< withcb */ #define ALARM_TYPE_PERIOD 0x10000000 /**< periodic */ -/** -* This struct has the information of an alarm -*/ - -typedef struct { - alarm_date_t start; /**< start time of the alarm */ - alarm_date_t end; /**< end time of the alarm */ - alarm_mode_t mode; /**< mode of alarm */ - int msec; - int alarm_type; /**< alarm type*/ - int reserved_info; /** 1st duetime(UTC epochtime) */ -} alarm_info_t; - bool _send_alarm_create(alarm_context_t context, alarm_info_t *alarm, alarm_id_t *id, const char *dst_service_name, const char *dst_service_name_mod, int *error_code); bool _send_alarm_create_appsvc(alarm_context_t context, alarm_info_t *alarm_info, @@ -145,23 +82,22 @@ bool _send_alarm_update(alarm_context_t context, alarm_id_t alarm_id, bool _send_alarm_delete(alarm_context_t context, alarm_id_t alarm_id, int *error_code); bool _send_alarm_delete_all(alarm_context_t context, int *error_code); bool _send_alarm_get_list_of_ids(alarm_context_t context, int maxnum_of_ids, - alarm_id_t *alarm_id, int *num_of_ids, int *error_code); + GVariantIter **iter, int *num_of_ids, int *error_code); bool _send_alarm_get_number_of_ids(alarm_context_t context, int *num_of_ids, int *error_code); bool _send_alarm_get_info(alarm_context_t context, alarm_id_t alarm_id, alarm_info_t *alarm_info, int *error_code); bool _send_alarm_get_next_duetime(alarm_context_t context, alarm_id_t alarm_id, time_t* duetime, int *error_code); bool _send_alarm_get_all_info(alarm_context_t context, char ** db_path, int *error_code); bool _send_alarm_reset(alarm_context_t context, int *error_code); bool _remove_from_scheduled_alarm_list(uid_t uid, alarm_id_t alarm_id); -void _load_alarms_from_registry(); bundle *_send_alarm_get_appsvc_info(alarm_context_t context, alarm_id_t alarm_id, int *error_code); notification_h _send_alarm_get_noti_info(alarm_context_t context, alarm_id_t alarm_id, int *error_code); bool _send_alarm_set_rtc_time(alarm_context_t context, alarm_date_t *time, int *error_code); -bool _send_alarm_set_time_with_propagation_delay(alarm_context_t context, unsigned int new_sec, unsigned int new_nsec, unsigned int req_sec, unsigned int req_nsec, int *error_code); -bool _send_alarm_set_time_with_propagation_delay_async(alarm_context_t context, unsigned int new_sec, unsigned int new_nsec, unsigned int req_sec, unsigned int req_nsec, alarm_set_time_cb_t result_cb, void *user_data); +bool _send_alarm_set_time_with_propagation_delay(alarm_context_t context, struct timespec new_time, struct timespec req_time, int *error_code); +bool _send_alarm_set_time_with_propagation_delay_async(alarm_context_t context, struct timespec new_time, struct timespec req_time, alarm_set_time_cb_t result_cb, void *user_data); bool _send_alarm_set_timezone(alarm_context_t context, char *tzpath_str, int *error_code); bool _send_alarm_create_periodic(alarm_context_t context, int interval, int is_ref, int method, alarm_id_t *alarm_id, int *error_code); -bool _send_alarm_set_time(alarm_context_t context, int new_time, int *error_code); -bool _send_alarm_set_time_async(alarm_context_t context, int new_time, alarm_set_time_cb_t result_cb, void *user_data); +bool _send_alarm_set_time(alarm_context_t context, time_t new_time, int *error_code); +bool _send_alarm_set_time_async(alarm_context_t context, time_t new_time, alarm_set_time_cb_t result_cb, void *user_data); bool _send_alarm_set_global(alarm_context_t context, int alarm_id, bool global, int *error_code); bool _send_alarm_get_global(alarm_context_t context, int alarm_id, bool *global, int *error_code); @@ -172,7 +108,6 @@ typedef struct { alarm_id_t alarm_id; uid_t uid; - int pid; char *caller_pkgid; char *callee_pkgid; char *app_unique_name; @@ -191,6 +126,7 @@ typedef struct { long requested_interval; int is_ref; bool global; + bool zombie_mode; } __alarm_info_t; typedef struct { @@ -211,7 +147,6 @@ typedef struct { bool used; alarm_id_t alarm_id; uid_t uid; - int pid; __alarm_info_t *__alarm_info; } __scheduled_alarm_t; @@ -228,38 +163,47 @@ typedef struct _bg_category_cb_info_t { void _release_alarm_info_t(); -time_t _alarm_next_duetime(__alarm_info_t *alarm_info); -bool _alarm_schedule(); -bool _clear_scheduled_alarm_list(); -bool _add_to_scheduled_alarm_list(__alarm_info_t *__alarm_info); +void _alarm_set_next_duetime(__alarm_info_t *alarm_info); +void _alarm_schedule(); +void _clear_scheduled_alarm_list(); +void _add_to_scheduled_alarm_list(__alarm_info_t *__alarm_info); -bool _save_alarms(__alarm_info_t *__alarm_info); -bool _delete_alarms(alarm_id_t alarm_id); -bool _update_alarms(__alarm_info_t *__alarm_info); - -bool _alarm_destory_timer(timer_t timer); -bool _alarm_set_timer(__alarm_server_context_t *alarm_context, int timer, time_t due_time); -bool _alarm_disable_timer(__alarm_server_context_t alarm_context); -bool _init_scheduled_alarm_list(); +void _alarm_set_timer(int timer, time_t due_time); +void _alarm_disable_timer(); +int _initialize_timer(); +void _alarm_initialize(); time_t _get_periodic_alarm_standard_time(void); - -void _update_db_for_disabled_alarm(alarm_id_t alarm_id, bool disabled_by_ups); - -#ifdef _DEBUG_MODE_ -#define ALARM_MGR_LOG_PRINT(FMT, ARG...) do { printf("%5d", getpid()); printf - ("%s() : "FMT"\n", __FUNCTION__, ##ARG); } while (false) -#define ALARM_MGR_EXCEPTION_PRINT(FMT, ARG...) do { printf("%5d", getpid()); - printf("%s() : "FMT"\n", __FUNCTION__, ##ARG); } while (false) -#define ALARM_MGR_ASSERT_PRINT(FMT, ARG...) do { printf("%5d", getpid()); printf - ("%s() : "FMT"\n", __FUNCTION__, ##ARG); } while (false) -#else -#define ALARM_MGR_LOG_PRINT(FMT, ARG...) LOGD(FMT, ##ARG) -#define ALARM_MGR_EXCEPTION_PRINT(FMT, ARG...) LOGW(FMT, ##ARG) -#define ALARM_MGR_ASSERT_PRINT(FMT, ARG...) LOGE(FMT, ##ARG) -#endif +bool _can_skip_expired_cb(alarm_id_t alarm_id); + +void _alarm_expired(); +void _rtc_set(); + +int alarm_manager_alarm_create(GVariant *parameters, uid_t uid, pid_t pid, int *alarm_id); +int alarm_manager_alarm_create_appsvc(GVariant *parameters, uid_t uid, pid_t pid, int *alarm_id); +int alarm_manager_alarm_create_periodic(GVariant *parameters, uid_t uid, pid_t pid, int *alarm_id); +int alarm_manager_alarm_create_noti(GVariant *parameters, uid_t uid, pid_t pid, int *alarm_id); +int alarm_manager_alarm_delete(GVariant *parameters, uid_t uid, pid_t pid); +int alarm_manager_alarm_delete_all(GVariant *parameters, uid_t uid, pid_t pid); +int alarm_manager_alarm_update(GVariant *parameters, uid_t uid, pid_t pid); +int alarm_manager_alarm_get_number_of_ids(uid_t uid, pid_t pid, int *num_of_ids); +int alarm_manager_alarm_get_list_of_ids(GVariant *parameters, uid_t uid, pid_t pid, GVariant **alarm_array, int *num_of_alarm); +int alarm_manager_alarm_get_appsvc_info(GVariant *parameters, uid_t uid, gchar **b_data); +int alarm_manager_alarm_get_noti_info(GVariant *parameters, uid_t uid, gchar **noti_data); +int alarm_manager_alarm_get_info(GVariant *parameters, uid_t uid, alarm_info_t *alarm_info); +int alarm_manager_alarm_get_next_duetime(GVariant *parameters, uid_t uid, time_t *duetime); +int alarm_manager_alarm_get_all_info(uid_t uid, char **db_path); +int alarm_manager_alarm_set_rtc_time(GVariant *parameters); +int alarm_manager_alarm_set_time(GVariant* parameters, pid_t pid); +int alarm_manager_alarm_set_time_with_propagation_delay(GVariant* parameters, pid_t pid); +int alarm_manager_alarm_set_timezone(GVariant* parameters); +int alarm_manager_alarm_set_global(GVariant *parameters, uid_t uid); +int alarm_manager_alarm_get_global(GVariant *parameters, gboolean *global); #define CHECK_NULL_STRING(x) x ? x : "null" #define STRDUP_WITH_NULLCMP(a) strcmp(a, "null") ? strdup(a) : NULL -#endif /*_ALARM_INTERNAL_H*/ +#ifdef __cplusplus +} +#endif + diff --git a/include/alarm.h b/include/alarm.h index dfde838..e6cac64 100644 --- a/include/alarm.h +++ b/include/alarm.h @@ -1,10 +1,5 @@ /* - * alarm-manager - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Venkatesha Sarpangala <sarpangala.v@samsung.com>, Jayoun Lee <airjany@samsung.com>, - * Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com> + * Copyright (c) 2000 - 2019 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. @@ -17,14 +12,8 @@ * 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 ALARM_LIB_H -#define ALARM_LIB_H +#pragma once /** * @open @@ -153,6 +142,7 @@ int main(int argc, char** argv) #include <stdbool.h> #include <time.h> #include <notification.h> +#include <gio/gio.h> #ifdef __cplusplus extern "C" { @@ -254,9 +244,35 @@ enum { ALARM_UPDATE_FLAG_CLEAR_WEEK_FLAG, }; +typedef union { + int day_of_week; /**< days of a week */ + time_t interval; +} alarm_interval_u; + +/** +* This struct has mode of an alarm +*/ +typedef struct { + alarm_interval_u u_interval; + alarm_repeat_mode_t repeat; /**< repeat mode */ +} alarm_mode_t; + +typedef struct { + alarm_set_time_cb_t callback; + void *user_data; + GDBusProxy *proxy; +} alarm_set_time_data_t; -typedef struct alarm_info_t alarm_entry_t; +typedef struct { + alarm_date_t start; /**< start time of the alarm */ + alarm_date_t end; /**< end time of the alarm */ + alarm_mode_t mode; /**< mode of alarm */ + int msec; + int alarm_type; /**< alarm type*/ + time_t reserved_info; /** 1st duetime(UTC epochtime) */ +} alarm_info_t; +#define alarm_entry_t alarm_info_t /** * @@ -1545,6 +1561,7 @@ int alarmmgr_set_rtc_time(alarm_date_t *time); * @retval #ERR_ALARM_SYSTEM_FAIL System failure */ int alarmmgr_set_systime(int new_time); +int alarmmgr_set_systime64(time_t new_time); /** * This function asynchronously changes the system time which tranferred by other module @@ -1558,6 +1575,7 @@ int alarmmgr_set_systime(int new_time); * @retval #ERR_ALARM_SYSTEM_FAIL System failure */ int alarmmgr_set_systime_async(int new_time, alarm_set_time_cb_t result_cb, void *user_param); +int alarmmgr_set_systime64_async(time_t new_time, alarm_set_time_cb_t result_cb, void *user_param); /** * This function changes the system time and compensates the time using propagation delay. @@ -1686,6 +1704,3 @@ int alarmmgr_update_alarm(alarm_id_t alarm_id, #ifdef __cplusplus } #endif - - -#endif/* ALARM_LIB_H*/ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt new file mode 100644 index 0000000..5a82e1a --- /dev/null +++ b/lib/CMakeLists.txt @@ -0,0 +1,31 @@ +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/server) + +AUX_SOURCE_DIRECTORY(./ LIB_SRCS) + +PKG_CHECK_MODULES(lib_pkgs REQUIRED glib-2.0 gobject-2.0 dlog bundle appsvc gio-2.0 + gio-unix-2.0 libtzplatform-config notification cert-svc-vcore) + +FOREACH(flag ${lib_pkgs_CFLAGS_OTHER}) + IF(${flag} MATCHES "\\-D+") + ADD_DEFINITIONS(${flag}) + ENDIF(${flag} MATCHES "\\-D+") +ENDFOREACH(flag) + +INCLUDE_DIRECTORIES(${lib_pkgs_INCLUDE_DIRS}) +LINK_DIRECTORIES(${lib_pkgs_LIBRARY_DIRS}) + +ADD_LIBRARY(${LIBRARY} SHARED ${LIB_SRCS}) +TARGET_LINK_LIBRARIES(${LIBRARY} ${lib_pkgs_LDFLAGS}) +SET_TARGET_PROPERTIES(${LIBRARY} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_PATH}") +SET_TARGET_PROPERTIES(${LIBRARY} PROPERTIES VERSION ${FULLVER} SOVERSION ${MAJORVER} CLEAN_DIRECT_OUTPUT 1) +INSTALL(TARGETS ${LIBRARY} DESTINATION ${LIB_INSTALL_DIR}) + +# pkgconfig file +CONFIGURE_FILE(alarm-service.pc.in alarm-service.pc @ONLY) +INSTALL(FILES alarm-service.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) + +# header files +INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION ${INCLUDE_INSTALL_DIR} + FILES_MATCHING PATTERN "*.h" PATTERN "*-internal.h" EXCLUDE) diff --git a/lib/alarm-lib-dbus.c b/lib/alarm-lib-dbus.c new file mode 100644 index 0000000..9633b68 --- /dev/null +++ b/lib/alarm-lib-dbus.c @@ -0,0 +1,923 @@ +/* + * Copyright (c) 2019 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 <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <string.h> +#include <glib.h> +#include <notification.h> +#include <notification_ipc.h> + +#include "alarm.h" +#include "alarm-internal.h" + +static int __dbus_call_sync(GDBusProxy *proxy, const gchar *method_name, + GVariant *param, GVariant **reply) +{ + int error_code = ALARMMGR_RESULT_SUCCESS; + GError *error = NULL; + + *reply = g_dbus_proxy_call_sync(proxy, method_name, param, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error); + if (error) { + if (error->code == G_DBUS_ERROR_ACCESS_DENIED) + error_code = ERR_ALARM_NO_PERMISSION; + else + error_code = ERR_ALARM_SYSTEM_FAIL; + + LOGE("%s : g_dbus_proxy_call_sync() failed.\ + error_code[%d]. error->message is %s(%d)", + method_name, error_code, error->message, error->code); + + g_error_free(error); + } + + return error_code; +} + +bool _send_alarm_create_noti(alarm_context_t context, alarm_info_t *alarm_info, + alarm_id_t *alarm_id, notification_h noti, int *error_code) +{ + int return_code = -1; + GVariant *noti_gv = NULL; + char *noti_data; + guchar *data; + int datalen = 0; + GVariant *param = NULL; + GVariant *reply = NULL; + + noti_gv = notification_ipc_make_gvariant_from_noti(noti, true); + if (!noti_gv) { + if (error_code) + *error_code = ERR_ALARM_SYSTEM_FAIL; + return false; + } + + datalen = g_variant_get_size(noti_gv); + if (datalen < 0) + return false; + + data = malloc(datalen); + if (!data) + return false; + + g_variant_store(noti_gv, data); + noti_data = g_base64_encode((guchar *)data, datalen); + + param = g_variant_new("(iiiiiiiiiixiixs)", + alarm_info->start.year, + alarm_info->start.month, + alarm_info->start.day, + alarm_info->start.hour, + alarm_info->start.min, + alarm_info->start.sec, + alarm_info->end.year, + alarm_info->end.month, + alarm_info->end.day, + alarm_info->mode.u_interval.day_of_week, + (gint64)alarm_info->mode.u_interval.interval, + alarm_info->mode.repeat, + alarm_info->alarm_type, + (gint64)alarm_info->reserved_info, + (char *)noti_data); + + if (noti_data) + free(noti_data); + if (data) + free(data); + g_variant_unref(noti_gv); + + return_code = __dbus_call_sync(context.proxy, "alarm_create_noti", + param, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(ii)", alarm_id, &return_code); + + LOGD("alarm_create_noti() success. alarm_id[%d], return_code[%d].", + *alarm_id, return_code); + + if (return_code != 0) { + if (error_code) + *error_code = return_code; + + g_variant_unref(reply); + return false; + } + + g_variant_unref(reply); + return true; +} + +bool _send_alarm_create_appsvc(alarm_context_t context, alarm_info_t *alarm_info, + alarm_id_t *alarm_id, bundle *b, int *error_code) +{ + int return_code = -1; + bundle_raw *b_data = NULL; + int datalen = 0; + GVariant *param = NULL; + GVariant *reply = NULL; + + if (bundle_encode(b, &b_data, &datalen)) { + LOGE("Unable to encode the bundle data\n"); + if (error_code) + *error_code = ERR_ALARM_SYSTEM_FAIL; + return false; + } + + param = g_variant_new("(iiiiiiiiiixiixs)", + alarm_info->start.year, + alarm_info->start.month, + alarm_info->start.day, + alarm_info->start.hour, + alarm_info->start.min, + alarm_info->start.sec, + alarm_info->end.year, + alarm_info->end.month, + alarm_info->end.day, + alarm_info->mode.u_interval.day_of_week, + (gint64)alarm_info->mode.u_interval.interval, + alarm_info->mode.repeat, + alarm_info->alarm_type, + (gint64)alarm_info->reserved_info, + (char *)b_data); + + if (b_data) + free(b_data); + + return_code = __dbus_call_sync(context.proxy, "alarm_create_appsvc", + param, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(ii)", alarm_id, &return_code); + + LOGD("alarm_create_appsvc() success. alarm_id[%d], return_code[%d].", + *alarm_id, return_code); + + if (return_code != 0) { + if (error_code) + *error_code = return_code; + + g_variant_unref(reply); + return false; + } + + g_variant_unref(reply); + return true; +} + +bool _send_alarm_create(alarm_context_t context, alarm_info_t *alarm_info, + alarm_id_t *alarm_id, const char *dst_service_name, const char *dst_service_name_mod, + int *error_code) +{ + int return_code = -1; + GVariant *param = NULL; + GVariant *reply = NULL; + + /*TODO: Dbus bus name validation is must & will be added to avoid alarm-server crash*/ + if (context.app_service_name == NULL + && strlen(dst_service_name) == 4 + && strncmp(dst_service_name, "null", 4) == 0) { + LOGE("Invalid arg. Provide valid destination or call alarmmgr_init()\n"); + if (error_code) + *error_code = ERR_ALARM_INVALID_PARAM; + return false; + } + + param = g_variant_new("(ssiiiiiiiiiiiiixss)", + context.app_service_name, + context.app_service_name_mod, + alarm_info->start.year, + alarm_info->start.month, + alarm_info->start.day, + alarm_info->start.hour, + alarm_info->start.min, + alarm_info->start.sec, + alarm_info->msec, + alarm_info->end.year, + alarm_info->end.month, + alarm_info->end.day, + alarm_info->mode.u_interval.day_of_week, + alarm_info->mode.repeat, + alarm_info->alarm_type, + (gint64)alarm_info->reserved_info, + dst_service_name, dst_service_name_mod); + + return_code = __dbus_call_sync(context.proxy, "alarm_create", + param, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(ii)", alarm_id, &return_code); + + LOGD("alarm_create() dbus sync success. alarm_id[%d], return_code[%d].", + *alarm_id, return_code); + + if (return_code != 0) { + if (error_code) + *error_code = return_code; + + g_variant_unref(reply); + return false; + } + + g_variant_unref(reply); + return true; +} + +bool _send_alarm_create_periodic(alarm_context_t context, int interval, int is_ref, + int method, alarm_id_t *alarm_id, int *error_code) +{ + int return_code = -1; + GVariant *param = NULL; + GVariant *reply = NULL; + + if (context.app_service_name == NULL) { + LOGE("Invalid arg. Provide valid destination or call alarmmgr_init()\n"); + if (error_code) + *error_code = ERR_ALARM_INVALID_PARAM; + return false; + } + + param = g_variant_new("(ssiii)", + context.app_service_name, + context.app_service_name_mod, + interval, is_ref, method); + + return_code = __dbus_call_sync(context.proxy, "alarm_create_periodic", + param, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(ii)", alarm_id, &return_code); + + LOGD("alarm_create_periodic() dbus sync success. alarm_id[%d], return_code[%d].", + *alarm_id, return_code); + + if (return_code != 0) { + if (error_code) + *error_code = return_code; + + g_variant_unref(reply); + return false; + } + + g_variant_unref(reply); + return true; +} + +bundle *_send_alarm_get_appsvc_info(alarm_context_t context, alarm_id_t alarm_id, int *error_code) +{ + int return_code = -1; + bundle *b = NULL; + gchar *b_data = NULL; + GVariant *param = NULL; + GVariant *reply = NULL; + + param = g_variant_new("(i)", alarm_id); + + return_code = __dbus_call_sync(context.proxy, "alarm_get_appsvc_info", + param, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(si)", &b_data, &return_code); + + LOGD("alarm_get_appsvc_info() dbus sync success. return_code[%d].", + return_code); + + if (return_code != 0) { + if (error_code) + *error_code = return_code; + } else { + b = bundle_decode((bundle_raw *)b_data, strlen(b_data)); + } + + if (b_data) + g_free(b_data); + + g_variant_unref(reply); + return b; +} + +notification_h _send_alarm_get_noti_info(alarm_context_t context, alarm_id_t alarm_id, int *error_code) +{ + int return_code = -1; + int datalen; + GVariant *noti_gv = NULL; + GVariant *body = NULL; + notification_h noti = NULL; + gchar *noti_data = NULL; + guchar *data; + GVariant *param = NULL; + GVariant *reply = NULL; + + param = g_variant_new("(i)", alarm_id); + + return_code = __dbus_call_sync(context.proxy, "alarm_get_noti_info", + param, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(si)", ¬i_data, &return_code); + + LOGD("alarm_get_noti_info() dbus sync success. return_code[%d].", + return_code); + + if (return_code != 0) { + if (error_code) + *error_code = return_code; + } else { + data = g_base64_decode(noti_data, (gsize *)&datalen); + + noti_gv = g_variant_new_from_data(G_VARIANT_TYPE("(v)"), + data, datalen, + TRUE, NULL, NULL); + + g_variant_get(noti_gv, "(v)", &body); + + noti = notification_create(NOTIFICATION_TYPE_NOTI); + notification_ipc_make_noti_from_gvariant(noti, body); + + g_free(data); + g_variant_unref(noti_gv); + } + + if (noti_data) + g_free(noti_data); + + g_variant_unref(reply); + return noti; +} + +bool _send_alarm_set_rtc_time(alarm_context_t context, alarm_date_t *time, int *error_code) +{ + int return_code = -1; + GVariant *param = NULL; + GVariant *reply = NULL; + + param = g_variant_new("(iiiiii)", time->year, time->month, time->day, + time->hour, time->min, time->sec); + + return_code = __dbus_call_sync(context.proxy, "alarm_set_rtc_time", + param, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(i)", &return_code); + + LOGD("alarm_set_rtc_time() dbus sync success. return_code[%d].", + return_code); + + if (return_code != 0) { + if (error_code) + *error_code = return_code; + + g_variant_unref(reply); + return false; + } + + g_variant_unref(reply); + return true; +} + +bool _send_alarm_delete(alarm_context_t context, alarm_id_t alarm_id, int *error_code) +{ + int return_code = -1; + GVariant *param = NULL; + GVariant *reply = NULL; + + param = g_variant_new("(i)", alarm_id); + + return_code = __dbus_call_sync(context.proxy, "alarm_delete", + param, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(i)", &return_code); + + LOGD("alarm_delete() dbus sync success. return_code[%d].", + return_code); + + if (return_code != 0) { + if (error_code) + *error_code = return_code; + + g_variant_unref(reply); + return false; + } + + g_variant_unref(reply); + return true; +} + +bool _send_alarm_delete_all(alarm_context_t context, int *error_code) +{ + int return_code = -1; + GVariant *reply = NULL; + + return_code = __dbus_call_sync(context.proxy, "alarm_delete_all", + NULL, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(i)", &return_code); + + LOGD("alarm_delete_all() dbus sync success. return_code[%d].", + return_code); + + if (return_code != 0) { + if (error_code) + *error_code = return_code; + + g_variant_unref(reply); + return false; + } + + g_variant_unref(reply); + return true; +} + +bool _send_alarm_get_list_of_ids(alarm_context_t context, int maxnum_of_ids, + GVariantIter **iter, int *num_of_ids, + int *error_code) +{ + int return_code = -1; + GVariantIter *iter_temp = NULL; + GVariant *arr = NULL; + GVariant *param = NULL; + GVariant *reply = NULL; + + param = g_variant_new("(i)", maxnum_of_ids); + + return_code = __dbus_call_sync(context.proxy, "alarm_get_list_of_ids", + param, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(@aiii)", &arr, num_of_ids, &return_code); + g_variant_get(arr, "ai", &iter_temp); + + LOGD("alarm_get_list_of_ids() dbus sync success. return_code[%d].", + return_code); + + if (return_code != 0) { + if (error_code) + *error_code = return_code; + + g_variant_unref(reply); + return false; + } + + *iter = iter_temp; + + g_variant_unref(reply); + + return true; +} + +bool _send_alarm_get_number_of_ids(alarm_context_t context, int *num_of_ids, + int *error_code) +{ + int return_code = -1; + GVariant *reply = NULL; + + return_code = __dbus_call_sync(context.proxy, "alarm_get_number_of_ids", + NULL, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(ii)", num_of_ids, &return_code); + + LOGD("alarm_get_number_of_ids() dbus sync success.\ + num_of_ids[%d] return_code[%d].", + *num_of_ids, return_code); + + if (return_code != 0) { + if (error_code) + *error_code = return_code; + + g_variant_unref(reply); + return false; + } + + g_variant_unref(reply); + return true; +} + +bool _send_alarm_get_info(alarm_context_t context, alarm_id_t alarm_id, + alarm_info_t *alarm_info, int *error_code) +{ + int return_code = -1; + GVariant *param = NULL; + GVariant *reply = NULL; + gint64 tmp_reserved_info; + param = g_variant_new("(i)", alarm_id); + + return_code = __dbus_call_sync(context.proxy, "alarm_get_info", + param, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(iiiiiiiiiiiixi)", + &alarm_info->start.year, + &alarm_info->start.month, + &alarm_info->start.day, + &alarm_info->start.hour, + &alarm_info->start.min, + &alarm_info->start.sec, + &alarm_info->end.year, + &alarm_info->end.month, + &alarm_info->end.day, + &alarm_info->mode.u_interval.day_of_week, + &alarm_info->mode.repeat, + &alarm_info->alarm_type, + &tmp_reserved_info, + &return_code); + alarm_info->reserved_info = (time_t)tmp_reserved_info; + + LOGD("alarm_get_info() dbus sync success. return_code[%d].", + return_code); + + if (return_code != 0) { + if (error_code) + *error_code = return_code; + + g_variant_unref(reply); + return false; + } + + g_variant_unref(reply); + return true; +} + +bool _send_alarm_get_next_duetime(alarm_context_t context, alarm_id_t alarm_id, + time_t *duetime, int *error_code) +{ + int return_code = -1; + GVariant *param = NULL; + GVariant *reply = NULL; + gint64 _duetime = 0; + + param = g_variant_new("(i)", alarm_id); + + return_code = __dbus_call_sync(context.proxy, "alarm_get_next_duetime", + param, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(xi)", &_duetime, &return_code); + + LOGD("alarm_get_next_duetime() dbus sync success. return_code[%d].", + return_code); + + if (return_code != 0) { + if (error_code) + *error_code = return_code; + + g_variant_unref(reply); + return false; + } + + *duetime = (time_t)_duetime; + g_variant_unref(reply); + return true; +} + +bool _send_alarm_get_all_info(alarm_context_t context, char **db_path, int *error_code) +{ + int return_code = -1; + GVariant *reply = NULL; + char *_db_path = NULL; + + return_code = __dbus_call_sync(context.proxy, "alarm_get_all_info", + NULL, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(si)", &_db_path, &return_code); + + LOGD("alarm_get_all_info() dbus sync success. db_path[%s] return_code[%d].", + *db_path, return_code); + + if (return_code != ALARMMGR_RESULT_SUCCESS) { + if (error_code) + *error_code = return_code; + + g_variant_unref(reply); + return false; + } + + *db_path = _db_path; + g_variant_unref(reply); + return true; +} + +bool _send_alarm_set_time(alarm_context_t context, time_t new_time, int *error_code) +{ + int return_code = -1; + GVariant *param = NULL; + GVariant *reply = NULL; + + param = g_variant_new("(x)", (gint64)new_time); + + return_code = __dbus_call_sync(context.proxy, "alarm_set_time", + param, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(i)", &return_code); + + LOGD("alarm_set_time() dbus sync success. return_code[%d].", + return_code); + + if (return_code != ALARMMGR_RESULT_SUCCESS) { + if (error_code) + *error_code = return_code; + + g_variant_unref(reply); + return false; + } + + g_variant_unref(reply); + return true; +} + +static void _alarm_set_time_cb(GObject *source_object, GAsyncResult *res, + gpointer user_data) +{ + int return_code = -1; + GError *error = NULL; + GVariant *reply = NULL; + alarm_set_time_data_t *func_data = (alarm_set_time_data_t *)user_data; + + reply = g_dbus_proxy_call_finish(func_data->proxy, res, &error); + if (error) { + LOGE("dbus error message: %s", error->message); + g_error_free(error); + return_code = ERR_ALARM_SYSTEM_FAIL; + } else { + g_variant_get(reply, "(i)", &return_code); + LOGD("alarm_set_time_async() dbus success. return_code[%d].", + return_code); + } + + if (func_data->callback != NULL) + func_data->callback(return_code, func_data->user_data); + + g_variant_unref(reply); + g_free(func_data); +} + +bool _send_alarm_set_time_async(alarm_context_t context, time_t new_time, alarm_set_time_cb_t result_cb, void *user_data) +{ + alarm_set_time_data_t *func_data; + GVariant *param; + + func_data = g_try_new0(alarm_set_time_data_t, 1); + + if (func_data == NULL) + return false; + + func_data->callback = result_cb; + func_data->user_data = user_data; + func_data->proxy = context.proxy; + + param = g_variant_new("(x)", (gint64)new_time); + + g_dbus_proxy_call(context.proxy, "alarm_set_time", param, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, _alarm_set_time_cb, func_data); + + return true; +} + +bool _send_alarm_set_time_with_propagation_delay(alarm_context_t context, struct timespec new_time, struct timespec req_time, int *error_code) +{ + int return_code = -1; + GVariant *param = NULL; + GVariant *reply = NULL; + + param = g_variant_new("(xxxx)", (gint64)new_time.tv_sec, (gint64)new_time.tv_nsec, + (gint64)req_time.tv_sec, (gint64)req_time.tv_nsec); + + return_code = __dbus_call_sync(context.proxy, "alarm_set_time_with_propagation_delay", + param, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(i)", &return_code); + + LOGD("alarm_set_time_with_propagation_delay dbus sync() success.\ + return_code[%d]", return_code); + + if (return_code != ALARMMGR_RESULT_SUCCESS) { + if (error_code) + *error_code = return_code; + + g_variant_unref(reply); + return false; + } + + g_variant_unref(reply); + return true; +} + +static void _alarm_set_time_with_delay_cb(GObject *source_object, GAsyncResult *res, + gpointer user_data) +{ + int return_code = -1; + GError *error = NULL; + GVariant *reply = NULL; + alarm_set_time_data_t *func_data = (alarm_set_time_data_t *)user_data; + + reply = g_dbus_proxy_call_finish(func_data->proxy, res, &error); + if (error) { + LOGE("dbus error message: %s", error->message); + g_error_free(error); + return_code = ERR_ALARM_SYSTEM_FAIL; + } else { + g_variant_get(reply, "(i)", &return_code); + + LOGD("alarm_set_time_with_propagation_delay_async() dbus success.\ + return_code[%d].", return_code); + } + + if (func_data->callback != NULL) + func_data->callback(return_code, func_data->user_data); + + g_variant_unref(reply); + g_free(func_data); +} + +bool _send_alarm_set_time_with_propagation_delay_async(alarm_context_t context, struct timespec new_time, struct timespec req_time, alarm_set_time_cb_t result_cb, void *user_data) +{ + alarm_set_time_data_t *func_data; + GVariant *param = NULL; + + func_data = g_try_new0(alarm_set_time_data_t, 1); + + if (func_data == NULL) + return false; + + func_data->callback = result_cb; + func_data->user_data = user_data; + func_data->proxy = context.proxy; + + param = g_variant_new("(xxxx)", (gint64)new_time.tv_sec, (gint64)new_time.tv_nsec, + (gint64)req_time.tv_sec, (gint64)req_time.tv_nsec); + + g_dbus_proxy_call(context.proxy, "alarm_set_time_with_propagation_delay", param, + G_DBUS_CALL_FLAGS_NONE, -1, NULL, _alarm_set_time_with_delay_cb, func_data); + + return true; +} + +bool _send_alarm_set_timezone(alarm_context_t context, char *tzpath_str, int *error_code) +{ + int return_code = -1; + GVariant *param = NULL; + GVariant *reply = NULL; + + param = g_variant_new("(s)", tzpath_str); + + return_code = __dbus_call_sync(context.proxy, "alarm_set_timezone", + param, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(i)", &return_code); + + LOGD("alarm_set_timezone dbus sync() success. tz_path[%s] return_code[%d]", + tzpath_str, return_code); + + if (return_code != ALARMMGR_RESULT_SUCCESS) { + if (error_code) + *error_code = return_code; + + g_variant_unref(reply); + return false; + } + + g_variant_unref(reply); + return true; +} + +bool _send_alarm_set_global(alarm_context_t context, const alarm_id_t alarm_id, bool global, int *error_code) +{ + int return_code = -1; + GVariant *param = NULL; + GVariant *reply = NULL; + + param = g_variant_new("(ib)", alarm_id, (gboolean)global); + + return_code = __dbus_call_sync(context.proxy, "alarm_set_global", + param, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(i)", &return_code); + + LOGD("alarm_set_global dbus sync() success. alarm_id[%d], global[%d]\ + return_code[%d]", alarm_id, global, return_code); + + if (return_code != ALARMMGR_RESULT_SUCCESS) { + if (error_code) + *error_code = return_code; + + g_variant_unref(reply); + return false; + } + + g_variant_unref(reply); + return true; +} + +bool _send_alarm_get_global(alarm_context_t context, const alarm_id_t alarm_id, bool *global, int *error_code) +{ + int return_code = -1; + GVariant *param = NULL; + GVariant *reply = NULL; + + param = g_variant_new("(i)", alarm_id); + + return_code = __dbus_call_sync(context.proxy, "alarm_get_global", + param, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(bi)", global, &return_code); + + LOGD("alarm_get_global dbus sync() success. alarm_id[%d], global[%d]\ + return_code[%d]", alarm_id, *global, return_code); + + if (return_code != 0) { + if (error_code) + *error_code = return_code; + + g_variant_unref(reply); + return false; + } + + g_variant_unref(reply); + return true; +} + +bool _send_alarm_update(alarm_context_t context, alarm_id_t alarm_id, + alarm_info_t *alarm_info, int update_flag, int *error_code) +{ + int return_code = -1; + GVariant *param = NULL; + GVariant *reply = NULL; + + param = g_variant_new("(iiiiiiiiiixiixi)", + alarm_id, + alarm_info->start.year, + alarm_info->start.month, + alarm_info->start.day, + alarm_info->start.hour, + alarm_info->start.min, + alarm_info->start.sec, + alarm_info->end.year, + alarm_info->end.month, + alarm_info->end.day, + (gint64)alarm_info->mode.u_interval.interval, + alarm_info->mode.repeat, + alarm_info->alarm_type, + (gint64)alarm_info->reserved_info, + update_flag); + + return_code = __dbus_call_sync(context.proxy, "alarm_update", + param, &reply); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return false; + + g_variant_get(reply, "(i)", &return_code); + + LOGD("alarm_update dbus sync() success. alarm_id[%d], return_code[%d]", + alarm_id, return_code); + + if (return_code != 0) { + if (error_code) + *error_code = return_code; + + g_variant_unref(reply); + return false; + } + + g_variant_unref(reply); + return true; +} diff --git a/src/alarm-lib.c b/lib/alarm-lib.c index a36c899..40cec26 100755..100644 --- a/src/alarm-lib.c +++ b/lib/alarm-lib.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2016 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2000 - 2019 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> @@ -28,7 +27,6 @@ #include "alarm.h" #include "alarm-internal.h" -#include "alarm-mgr-stub.h" #include <bundle.h> #include <appsvc.h> #include <aul.h> @@ -36,14 +34,12 @@ #include <pkgmgr-info.h> #include <notification.h> #include <tzplatform_config.h> -#include <cert-svc/ccert.h> -#include <cert-svc/cinstance.h> #ifndef EXPORT_API #define EXPORT_API __attribute__ ((visibility("default"))) #endif -static char g_appid[MAX_APP_ID]; +static char g_appid[MAX_APP_ID_LEN]; static int flag_appid_checked; static alarm_context_t alarm_context; @@ -99,12 +95,60 @@ static const GDBusInterfaceVTable interface_vtable = { NULL }; -void _initialize_alarm_info(alarm_info_t *alarm) +void _initialize_alarm_info(alarm_info_t *alarm_info, int alarm_type, + time_t trigger_at_time, time_t interval, bool precision) { - memset(alarm, 0, sizeof(alarm_info_t)); + struct timeval current_time; + struct tm duetime_tm; - alarm->mode.repeat = ALARM_REPEAT_MODE_ONCE; - alarm->alarm_type = ALARM_TYPE_DEFAULT; + gettimeofday(¤t_time, NULL); + + memset(alarm_info, 0, sizeof(alarm_info_t)); + + alarm_info->mode.repeat = ALARM_REPEAT_MODE_ONCE; + alarm_info->alarm_type = alarm_type; + + if (current_time.tv_usec > 500 * 1000) { + /* When the millisecond part of the current_time is bigger than 500ms, + * the duetime increases by extra 1sec. */ + current_time.tv_sec += (trigger_at_time + 1); + } else { + current_time.tv_sec += trigger_at_time; + } + alarm_info->reserved_info = current_time.tv_sec; + + tzset(); /* Processes the TZ environment variable, and Set timezone, daylight, and tzname. */ + localtime_r(¤t_time.tv_sec, &duetime_tm); + + alarm_info->start.year = duetime_tm.tm_year + 1900; + alarm_info->start.month = duetime_tm.tm_mon + 1; + alarm_info->start.day = duetime_tm.tm_mday; + + alarm_info->end.year = 0; + alarm_info->end.month = 0; + alarm_info->end.day = 0; + + alarm_info->start.hour = duetime_tm.tm_hour; + alarm_info->start.min = duetime_tm.tm_min; + alarm_info->start.sec = duetime_tm.tm_sec; + + if (interval <= 0) { + alarm_info->mode.repeat = ALARM_REPEAT_MODE_ONCE; + alarm_info->mode.u_interval.interval = 0; + } else { + alarm_info->mode.repeat = ALARM_REPEAT_MODE_REPEAT; + alarm_info->mode.u_interval.interval = interval; + } + + alarm_info->msec = precision ? (int)current_time.tv_usec / 1000 : 0; + + LOGD("trigger_at_time(%ld), start(%d-%d-%d, %02d:%02d:%02d),\ + repeat(%d), interval(%ld), type(%d)", + trigger_at_time, alarm_info->start.day, alarm_info->start.month, + alarm_info->start.year, alarm_info->start.hour, + alarm_info->start.min, alarm_info->start.sec, + alarm_info->mode.repeat, alarm_info->mode.u_interval.interval, + alarm_info->alarm_type); } static void __add_resultcb(alarm_id_t alarm_id, alarm_cb_t cb_func, void *data) @@ -129,7 +173,7 @@ static alarm_cb_info_t *__find_resultcb(alarm_id_t alarm_id) tmp = alarmcb_head; while (tmp) { if (tmp->alarm_id == alarm_id) { - ALARM_MGR_LOG_PRINT("matched alarm id = %d", alarm_id); + LOGD("matched alarm id = %d", alarm_id); return tmp; } tmp = tmp->next; @@ -186,20 +230,18 @@ static void __handle_expiry_method_call(GDBusConnection *conn, int msec; g_variant_get(param, "(ii&s)", &alarm_id, &msec, &package_name); - ALARM_MGR_LOG_PRINT("[alarm-lib] : Alarm expired for [%s] : Alarm id [%d]", package_name, alarm_id); + LOGD("[alarm-lib] : Alarm expired for [%s] : Alarm id [%d]", package_name, alarm_id); + + if (msec > 0) { + gettimeofday(¤t_time, NULL); + msec = msec - (int)current_time.tv_usec / 1000; + } if (alarm_context.alarm_handler != NULL) { if (msec > 0) { - gettimeofday(¤t_time, NULL); - msec = msec - (int)current_time.tv_usec / 1000; - if (msec > 0) { - alarm_context.handler_id = alarm_id; - g_timeout_add_full(G_PRIORITY_HIGH, (guint)msec, - __handle_millisec_accuracy, NULL, NULL); - } else { - alarm_context.alarm_handler(alarm_id, - alarm_context.user_param); - } + alarm_context.handler_id = alarm_id; + g_timeout_add_full(G_PRIORITY_HIGH, (guint)msec, + __handle_millisec_accuracy, NULL, NULL); } else { alarm_context.alarm_handler(alarm_id, alarm_context.user_param); @@ -209,16 +251,10 @@ static void __handle_expiry_method_call(GDBusConnection *conn, info = __find_resultcb(alarm_id); if (info && info->cb_func) { if (msec > 0) { - gettimeofday(¤t_time, NULL); - msec = msec - (int)current_time.tv_usec / 1000; - if (msec > 0) { - g_timeout_add_full(G_PRIORITY_HIGH, (guint)msec, - __handle_millisec_accuracy, info, NULL); - } else { - info->cb_func(alarm_id, info->priv_data); - } + g_timeout_add_full(G_PRIORITY_HIGH, (guint)msec, + __handle_millisec_accuracy, info, NULL); } else { - ALARM_MGR_EXCEPTION_PRINT("[alarm-lib] Call expired callback"); + LOGW("[alarm-lib] Call expired callback"); info->cb_func(alarm_id, info->priv_data); } } @@ -293,6 +329,28 @@ static bool __alarm_validate_time(alarm_date_t *date, int *error_code) return true; } +static int __check_validation(alarm_info_t *alarm_info, const char *function) +{ + int error_code; + + if (!__alarm_validate_date(&alarm_info->start, &error_code)) { + LOGE("%s : start date error\n", function); + return error_code; + } + + if (!__alarm_validate_time(&alarm_info->start, &error_code)) { + LOGE("%s : start time error\n", function); + return error_code; + } + + if (!__alarm_validate_date(&alarm_info->end, &error_code)) { + LOGE("%s : end date error\n", function); + return error_code; + } + + return ALARMMGR_RESULT_SUCCESS; +} + static int __alarm_context_init() { if (sub_initialized) @@ -308,7 +366,7 @@ static int __alarm_context_init() NULL); if (alarm_context.proxy == NULL) { - ALARM_MGR_EXCEPTION_PRINT("Creating a proxy is failed."); + LOGE("Creating a proxy is failed."); g_object_unref(alarm_context.connection); return ERR_ALARM_SYSTEM_FAIL; } @@ -328,7 +386,7 @@ static void __bus_get_for_async_api(GObject *source_object, GAsyncResult *res, alarm_context.connection = g_bus_get_finish(res, &error); if (!alarm_context.connection) { - ALARM_MGR_EXCEPTION_PRINT("dbus error message: %s", error->message); + LOGE("dbus error message: %s", error->message); g_error_free(error); g_variant_unref(param->v); g_free(param); @@ -346,16 +404,20 @@ static void __bus_get_for_async_api(GObject *source_object, GAsyncResult *res, if (param->type == SET_SYSTIME_WITH_PROPAGATION_DELAY) { struct timespec new_time; struct timespec req_time; - g_variant_get(param->v, "(uuuu)", &new_time.tv_sec, &new_time.tv_nsec, - &req_time.tv_sec, &req_time.tv_nsec); + gint64 new_sec, new_nsec, req_sec, req_nsec; + g_variant_get(param->v, "(xxxx)", &new_sec, &new_nsec, + &req_sec, &req_nsec); + new_time.tv_sec = (time_t)new_sec; + new_time.tv_nsec = (long)new_nsec; + req_time.tv_sec = (time_t)req_sec; + req_time.tv_nsec = (long)new_nsec; + _send_alarm_set_time_with_propagation_delay_async(alarm_context, - new_time.tv_sec, new_time.tv_nsec, - req_time.tv_sec, req_time.tv_nsec, - param->result_cb, param->user_param); + new_time, req_time, param->result_cb, param->user_param); } else if (param->type == SET_SYSTIME) { - int new_time; - g_variant_get(param->v, "i", &new_time); - _send_alarm_set_time_async(alarm_context, new_time, + gint64 new_time; + g_variant_get(param->v, "x", &new_time); + _send_alarm_set_time_async(alarm_context, (time_t)new_time, param->result_cb, param->user_param); } @@ -385,7 +447,7 @@ static int __sub_init() alarm_context.connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); if (alarm_context.connection == NULL) { - ALARM_MGR_EXCEPTION_PRINT("g_bus_get_sync() is failed. error: %s", error->message); + LOGE("g_bus_get_sync() is failed. error: %s", error->message); g_error_free(error); pthread_mutex_unlock(&init_lock); return ERR_ALARM_SYSTEM_FAIL; @@ -394,26 +456,26 @@ static int __sub_init() ret = __alarm_context_init(); pthread_mutex_unlock(&init_lock); - return ALARMMGR_RESULT_SUCCESS; + return ret; } static int __compare_api_version(int *result, uid_t uid) { int ret = 0; pkgmgrinfo_pkginfo_h pkginfo = NULL; - char pkgid[512] = {0, }; + char pkgid[MAX_PKG_ID_LEN] = {0, }; char *pkg_version; if (aul_app_get_pkgid_bypid_for_uid(getpid(), pkgid, sizeof(pkgid), uid) != AUL_R_OK) { - ALARM_MGR_EXCEPTION_PRINT("aul_app_get_pkgid_bypid() is failed. PID %d may not be app.", getpid()); + LOGE("aul_app_get_pkgid_bypid() is failed. PID %d may not be app.", getpid()); } else { ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &pkginfo); if (ret != PMINFO_R_OK) { - ALARM_MGR_EXCEPTION_PRINT("Failed to get pkginfo\n"); + LOGE("Failed to get pkginfo\n"); } else { ret = pkgmgrinfo_pkginfo_get_api_version(pkginfo, &pkg_version); if (ret != PMINFO_R_OK) - ALARM_MGR_EXCEPTION_PRINT("Failed to check api version [%d]\n", ret); + LOGE("Failed to check api version [%d]\n", ret); *result = strverscmp(pkg_version, "2.4"); pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); @@ -422,6 +484,57 @@ static int __compare_api_version(int *result, uid_t uid) return ret; } +static void __adjust_current_milliseconds(alarm_info_t *alarm_info) +{ + struct timeval current_time; + struct tm start_tm; + time_t start; + + gettimeofday(¤t_time, NULL); + if (current_time.tv_usec > 500 * 1000) { + /* When the millisecond part of the current_time is bigger than 500ms, + * the duetime increases by extra 1sec. */ + + start_tm.tm_year = alarm_info->start.year - 1900; + start_tm.tm_mon = alarm_info->start.month - 1; + start_tm.tm_mday = alarm_info->start.day; + start_tm.tm_hour = alarm_info->start.hour; + start_tm.tm_min = alarm_info->start.min; + start_tm.tm_sec = alarm_info->start.sec; + start_tm.tm_isdst = -1; + + start = timegm(&start_tm); + + if (current_time.tv_sec == start) { + start += 1; + + localtime_r(&start, &start_tm); + alarm_info->start.year = start_tm.tm_year + 1900; + alarm_info->start.month = start_tm.tm_mon + 1; + alarm_info->start.day = start_tm.tm_mday; + alarm_info->start.hour = start_tm.tm_hour; + alarm_info->start.min = start_tm.tm_min; + alarm_info->start.sec = start_tm.tm_sec; + + LOGW("adjusted start(%d-%d-%d, %02d:%02d:%02d),", + alarm_info->start.day, alarm_info->start.month, alarm_info->start.year, + alarm_info->start.hour, alarm_info->start.min, alarm_info->start.sec); + } + } +} + +static void __check_appid(void) +{ + if (flag_appid_checked == 0) { + if (aul_app_get_appid_bypid(getpid(), g_appid, sizeof(g_appid)) != AUL_R_OK) { + LOGE("PID[%d] may not be app. Please call alarmmgr_init(caller name) in advance.", getpid()); + } else { + LOGD("Get appid only once. appid[%s]", g_appid); + flag_appid_checked = 1; + } + } +} + EXPORT_API int alarmmgr_init(const char *appid) { SECURE_LOGD("Enter"); @@ -434,11 +547,15 @@ EXPORT_API int alarmmgr_init(const char *appid) int j = 0; bool is_user = false; - if (appid == NULL) + if (appid == NULL) { + LOGE("alarm is null"); return ERR_ALARM_INVALID_PARAM; + } - if (strlen(appid) >= MAX_PKG_NAME_LEN) + if (strlen(appid) >= MAX_PKG_NAME_LEN) { + LOGE("length of appid is invalid"); return ERR_ALARM_INVALID_PARAM; + } if (b_initialized) { SECURE_LOGD("alarm was already initialized. app_service_name=%s", @@ -473,7 +590,7 @@ EXPORT_API int alarmmgr_init(const char *appid) introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL); if (introspection_data == NULL) { - ALARM_MGR_EXCEPTION_PRINT("g_dbus_node_info_new_for_xml() is failed."); + LOGE("g_dbus_node_info_new_for_xml() is failed."); goto error; } @@ -483,7 +600,7 @@ EXPORT_API int alarmmgr_init(const char *appid) introspection_data->interfaces[0], &interface_vtable, NULL, NULL, NULL); if (registration_id == 0) { - ALARM_MGR_EXCEPTION_PRINT("Registering the callback is failed."); + LOGE("Registering the callback is failed."); goto error; } @@ -492,7 +609,7 @@ EXPORT_API int alarmmgr_init(const char *appid) service_name_mod, G_BUS_NAME_OWNER_FLAGS_NONE, NULL, NULL, NULL, NULL); if (owner_id == 0) { - ALARM_MGR_EXCEPTION_PRINT("Acquiring the own name is failed. %s", service_name_mod); + LOGE("Acquiring the own name is failed. %s", service_name_mod); goto error; } @@ -577,7 +694,7 @@ EXPORT_API int alarmmgr_set_cb(alarm_cb_t handler, void *user_param) SECURE_LOGD("Enter"); if (handler == NULL) { - ALARM_MGR_EXCEPTION_PRINT("callback is NULL."); + LOGE("callback is NULL."); return ERR_ALARM_INVALID_PARAM; } alarm_context.alarm_handler = handler; @@ -591,8 +708,10 @@ EXPORT_API alarm_entry_t *alarmmgr_create_alarm(void) { alarm_info_t *alarm = (alarm_info_t *)malloc(sizeof(alarm_info_t)); - if (alarm == NULL) + if (alarm == NULL) { + LOGE("alarm is null"); return NULL; + } alarm->start.year = 0; alarm->start.month = 0; @@ -622,8 +741,10 @@ EXPORT_API alarm_entry_t *alarmmgr_create_alarm(void) EXPORT_API int alarmmgr_free_alarm(alarm_entry_t *alarm) { - if (alarm == NULL) + if (alarm == NULL) { + LOGE("alarm is null"); return ERR_ALARM_INVALID_PARAM; + } free(alarm); @@ -635,17 +756,19 @@ EXPORT_API int alarmmgr_set_time(alarm_entry_t *alarm, alarm_date_t time) alarm_info_t *alarm_info; int error_code; - if (alarm == NULL) + if (alarm == NULL) { + LOGE("alarm is null"); return ERR_ALARM_INVALID_PARAM; + } alarm_info = (alarm_info_t *)alarm; if (!__alarm_validate_date(&time, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("start date error\n"); + LOGE("start date error\n"); return error_code; } if (!__alarm_validate_time(&time, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("start time error\n"); + LOGE("start time error\n"); return error_code; } @@ -659,8 +782,10 @@ EXPORT_API int alarmmgr_get_time(const alarm_entry_t *alarm, { alarm_info_t *alarm_info = (alarm_info_t *)alarm; - if (alarm == NULL) + if (alarm == NULL) { + LOGE("alarm is null"); return ERR_ALARM_INVALID_PARAM; + } if (time != NULL) memcpy(time, &alarm_info->start, sizeof(alarm_date_t)); @@ -673,8 +798,10 @@ EXPORT_API int alarmmgr_set_repeat_mode(alarm_entry_t *alarm, { alarm_info_t *alarm_info = (alarm_info_t *)alarm; - if (repeat >= ALARM_REPEAT_MODE_MAX) + if (repeat >= ALARM_REPEAT_MODE_MAX) { + LOGE("repeat value is invalid"); return ERR_ALARM_INVALID_PARAM; + } alarm_info->mode.repeat = repeat; @@ -693,8 +820,10 @@ EXPORT_API int alarmmgr_get_repeat_mode(const alarm_entry_t *alarm, { alarm_info_t *alarm_info = (alarm_info_t *)alarm; - if (alarm == NULL) + if (alarm == NULL) { + LOGE("alarm is null"); return ERR_ALARM_INVALID_PARAM; + } if (repeat != NULL) *repeat = alarm_info->mode.repeat; @@ -708,8 +837,10 @@ EXPORT_API int alarmmgr_set_type(alarm_entry_t *alarm, int alarm_type) { alarm_info_t *alarm_info; - if (alarm == NULL) + if (alarm == NULL) { + LOGE("alarm is null"); return ERR_ALARM_INVALID_PARAM; + } alarm_info = (alarm_info_t *)alarm; alarm_info->alarm_type = alarm_type; @@ -722,8 +853,10 @@ EXPORT_API int alarmmgr_get_type(const alarm_entry_t *alarm, int *alarm_type) { alarm_info_t *alarm_info = (alarm_info_t *)alarm; - if (alarm == NULL) + if (alarm == NULL) { + LOGE("alarm is null"); return ERR_ALARM_INVALID_PARAM; + } if (alarm_type != NULL) *alarm_type = alarm_info->alarm_type; @@ -734,7 +867,7 @@ EXPORT_API int alarmmgr_get_type(const alarm_entry_t *alarm, int *alarm_type) static int __alarmmgr_init_appsvc(void) { if (b_initialized) { - ALARM_MGR_EXCEPTION_PRINT("alarm was already initialized."); + LOGW("alarm was already initialized."); return ALARMMGR_RESULT_SUCCESS; } @@ -748,7 +881,6 @@ static int __alarmmgr_init_appsvc(void) EXPORT_API void *alarmmgr_get_alarm_appsvc_info(alarm_id_t alarm_id, int *return_code) { - int ret = 0; ret = __sub_init(); @@ -759,9 +891,10 @@ EXPORT_API void *alarmmgr_get_alarm_appsvc_info(alarm_id_t alarm_id, int *return return NULL; } - ALARM_MGR_LOG_PRINT("[alarm-lib]:alarmmgr_get_alarm_appsvc_info() is called."); + LOGD("[alarm-lib]:alarmmgr_get_alarm_appsvc_info() is called."); if (alarm_id <= 0) { + LOGE("alarm_id is Invalid[%d]", alarm_id); if (return_code) *return_code = ERR_ALARM_INVALID_ID; @@ -779,10 +912,12 @@ EXPORT_API int alarmmgr_get_alarm_noti_info(alarm_id_t alarm_id, notification_h if (ret < 0) return ret; - ALARM_MGR_LOG_PRINT("[alarm-lib]:alarmmgr_get_alarm_appsvc_info() is called."); + LOGD("[alarm-lib]:alarmmgr_get_alarm_appsvc_info() is called."); - if (alarm_id <= 0) + if (alarm_id <= 0) { + LOGE("alarm_id is Invalid[%d]", alarm_id); return ERR_ALARM_INVALID_ID; + } *noti = _send_alarm_get_noti_info(alarm_context, alarm_id, &ret); @@ -796,7 +931,7 @@ EXPORT_API int alarmmgr_set_rtc_time(alarm_date_t *time) int error_code = 0; if (!time) { - ALARM_MGR_EXCEPTION_PRINT("Invalid parameter time\n"); + LOGE("Invalid parameter time\n"); return ERR_ALARM_INVALID_PARAM; } @@ -804,15 +939,15 @@ EXPORT_API int alarmmgr_set_rtc_time(alarm_date_t *time) if (ret < 0) return ret; - ALARM_MGR_LOG_PRINT("[alarm-lib]:alarmmgr_set_rtc_time() is called\n"); + LOGD("[alarm-lib]:alarmmgr_set_rtc_time() is called\n"); if (!__alarm_validate_date(time, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("RTC date error\n"); + LOGE("RTC date error\n"); return error_code; } if (!__alarm_validate_time(time, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("RTC time error\n"); + LOGE("RTC time error\n"); return error_code; } @@ -827,20 +962,26 @@ EXPORT_API int alarmmgr_set_rtc_time(alarm_date_t *time) EXPORT_API int alarmmgr_add_alarm_appsvc_with_localtime(alarm_entry_t *alarm, void *bundle_data, alarm_id_t *alarm_id) { - alarm_info_t *alarm_info = NULL; /* = (alarm_info_t*)alarm; */ + alarm_info_t *alarm_info = NULL; + alarm_mode_t *mode; const char *operation = NULL; int error_code = 0; const char *appid = NULL; bundle *b; - ALARM_MGR_LOG_PRINT("[alarm-lib]:alarm_create() is called\n"); + LOGD("[alarm-lib]:alarm_create() is called\n"); - if (alarm == NULL) + alarm_info = (alarm_info_t *)alarm; + if (alarm_info == NULL || alarm_id == NULL) { + LOGE("Invalid parameter\n"); return ERR_ALARM_INVALID_PARAM; + } + + __adjust_current_milliseconds(alarm_info); b = (bundle *)bundle_data; if (b == NULL) { - ALARM_MGR_EXCEPTION_PRINT("Invalid parameter bundle\n"); + LOGE("Invalid parameter bundle\n"); return ERR_ALARM_INVALID_PARAM; } @@ -849,48 +990,34 @@ EXPORT_API int alarmmgr_add_alarm_appsvc_with_localtime(alarm_entry_t *alarm, vo appsvc_set_operation(b, APPSVC_OPERATION_DEFAULT); if (__alarmmgr_init_appsvc() < 0) { - ALARM_MGR_EXCEPTION_PRINT("Unable to initialize dbus!!!\n"); + LOGE("Unable to initialize dbus!!!\n"); return ERR_ALARM_SYSTEM_FAIL; } - alarm_info = (alarm_info_t *)alarm; appid = appsvc_get_appid(b); - if ((appid == NULL && (alarm_info->alarm_type & ALARM_TYPE_NOLAUNCH)) || - (appid == NULL && operation && !strcmp(operation, APPSVC_OPERATION_DEFAULT))) { - ALARM_MGR_EXCEPTION_PRINT("Invalid parameter\n"); - return ERR_ALARM_INVALID_PARAM; + if (appid == NULL) { + if ((alarm_info->alarm_type & ALARM_TYPE_NOLAUNCH) || + (operation && !strcmp(operation, APPSVC_OPERATION_DEFAULT))) { + LOGE("appid is invalid"); + return ERR_ALARM_INVALID_PARAM; + } } - if (alarm_info == NULL || alarm_id == NULL) { - ALARM_MGR_EXCEPTION_PRINT("Invalid parameter\n"); - return ERR_ALARM_INVALID_PARAM; - } - alarm_mode_t *mode = &alarm_info->mode; + mode = &alarm_info->mode; - ALARM_MGR_EXCEPTION_PRINT("start(%d-%d-%d, %02d:%02d:%02d), end(%d-%d-%d), repeat(%d), interval(%d), type(%d)", + LOGW("start(%d-%d-%d, %02d:%02d:%02d), end(%d-%d-%d), repeat(%d), interval(%ld), type(%d)", alarm_info->start.day, alarm_info->start.month, alarm_info->start.year, alarm_info->start.hour, alarm_info->start.min, alarm_info->start.sec, alarm_info->end.year, alarm_info->end.month, alarm_info->end.day, - alarm_info->mode.repeat, (int)alarm_info->mode.u_interval.interval, alarm_info->alarm_type); + alarm_info->mode.repeat, alarm_info->mode.u_interval.interval, alarm_info->alarm_type); /* TODO: This should be changed to > ALARM_REPEAT_MODE_MAX ? */ if (mode->repeat >= ALARM_REPEAT_MODE_MAX) return ERR_ALARM_INVALID_PARAM; - if (!__alarm_validate_date(&alarm_info->start, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("start date error\n"); + error_code = __check_validation(alarm_info, __FUNCTION__); + if (error_code != ALARMMGR_RESULT_SUCCESS) return error_code; - } - - if (!__alarm_validate_time(&alarm_info->start, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("start time error\n"); - return error_code; - } - - if (!__alarm_validate_date(&alarm_info->end, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("end date error\n"); - return error_code; - } if (!_send_alarm_create_appsvc(alarm_context, alarm_info, alarm_id, b, &error_code)) return error_code; @@ -904,57 +1031,54 @@ EXPORT_API int alarmmgr_add_alarm_with_localtime(alarm_entry_t *alarm, { char dst_service_name[MAX_SERVICE_NAME_LEN] = { 0 }; char dst_service_name_mod[MAX_SERVICE_NAME_LEN] = { 0 }; - alarm_info_t *alarm_info; /* = (alarm_info_t*)alarm; */ + alarm_info_t *alarm_info = NULL; + alarm_mode_t *mode; int ret; + int error_code; int i = 0; int j = 0; - ALARM_MGR_LOG_PRINT("[alarm-lib]:alarm_create() is called\n"); + LOGD("[alarm-lib]:alarm_create() is called\n"); - if (alarm == NULL) + if (alarm == NULL) { + LOGE("alarm is null"); return ERR_ALARM_INVALID_PARAM; + } alarm_info = (alarm_info_t *) alarm; - if (alarm_info == NULL || alarm_id == NULL) + if (alarm_info == NULL || alarm_id == NULL) { + LOGE("Invalid parameter bundle\n"); return ERR_ALARM_INVALID_PARAM; + } - int error_code; - alarm_mode_t *mode = &alarm_info->mode; + __adjust_current_milliseconds(alarm_info); + + mode = &alarm_info->mode; ret = __sub_init(); if (ret < 0) return ret; - ALARM_MGR_LOG_PRINT("start(%d-%d-%d, %02d:%02d:%02d), end(%d-%d-%d), repeat(%d), interval(%d), type(%d)", + LOGD("start(%d-%d-%d, %02d:%02d:%02d), end(%d-%d-%d), repeat(%d), interval(%ld), type(%d)", alarm_info->start.day, alarm_info->start.month, alarm_info->start.year, alarm_info->start.hour, alarm_info->start.min, alarm_info->start.sec, alarm_info->end.year, alarm_info->end.month, alarm_info->end.day, - alarm_info->mode.repeat, (int)alarm_info->mode.u_interval.interval, alarm_info->alarm_type); + alarm_info->mode.repeat, alarm_info->mode.u_interval.interval, alarm_info->alarm_type); /* TODO: This should be changed to > ALARM_REPEAT_MODE_MAX ? */ - if (mode->repeat >= ALARM_REPEAT_MODE_MAX) + if (mode->repeat >= ALARM_REPEAT_MODE_MAX) { + LOGE("repeat is Invalid"); return ERR_ALARM_INVALID_PARAM; + } if (destination && strlen(destination) >= MAX_PKG_NAME_LEN) { - ALARM_MGR_EXCEPTION_PRINT("[alarm-lib]: destination name is too long!\n"); + LOGE("[alarm-lib]: destination name is too long!\n"); return ERR_ALARM_INVALID_PARAM; } - - if (!__alarm_validate_date(&alarm_info->start, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("start date error\n"); - return error_code; - } - - if (!__alarm_validate_time(&alarm_info->start, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("start time error\n"); + error_code = __check_validation(alarm_info, __FUNCTION__); + if (error_code != ALARMMGR_RESULT_SUCCESS) return error_code; - } - - if (!__alarm_validate_date(&alarm_info->end, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("end date error\n"); - return error_code; - } if (destination != NULL) { memset(dst_service_name, 0, strlen(destination) + strlen("ALARM.") + 2); @@ -983,49 +1107,38 @@ EXPORT_API int alarmmgr_add_alarm_with_localtime(alarm_entry_t *alarm, EXPORT_API int alarmmgr_add_alarm_noti_with_localtime(alarm_entry_t *alarm, notification_h noti, alarm_id_t *alarm_id) { - alarm_info_t *alarm_info = NULL; /* = (alarm_info_t*)alarm; */ + alarm_info_t *alarm_info = NULL; int error_code = 0; + alarm_info = (alarm_info_t *)alarm; + alarm_mode_t *mode; - if (alarm == NULL) + if (alarm_info == NULL || alarm_id == NULL) { + LOGE("Invalid parameter\n"); return ERR_ALARM_INVALID_PARAM; + } + + __adjust_current_milliseconds(alarm_info); if (__alarmmgr_init_appsvc() < 0) { - ALARM_MGR_EXCEPTION_PRINT("Unable to initialize dbus!!!\n"); + LOGE("Unable to initialize dbus!!!\n"); return ERR_ALARM_SYSTEM_FAIL; } - alarm_info = (alarm_info_t *)alarm; + mode = &alarm_info->mode; - if (alarm_info == NULL || alarm_id == NULL) { - ALARM_MGR_EXCEPTION_PRINT("Invalid parameter\n"); - return ERR_ALARM_INVALID_PARAM; - } - alarm_mode_t *mode = &alarm_info->mode; - - ALARM_MGR_EXCEPTION_PRINT("start(%d-%d-%d, %02d:%02d:%02d), end(%d-%d-%d), repeat(%d), interval(%d), type(%d)", + LOGW("start(%d-%d-%d, %02d:%02d:%02d), end(%d-%d-%d), repeat(%d), interval(%ld), type(%d)", alarm_info->start.day, alarm_info->start.month, alarm_info->start.year, alarm_info->start.hour, alarm_info->start.min, alarm_info->start.sec, alarm_info->end.year, alarm_info->end.month, alarm_info->end.day, - alarm_info->mode.repeat, (int)alarm_info->mode.u_interval.interval, alarm_info->alarm_type); + alarm_info->mode.repeat, alarm_info->mode.u_interval.interval, alarm_info->alarm_type); /* TODO: This should be changed to > ALARM_REPEAT_MODE_MAX ? */ if (mode->repeat >= ALARM_REPEAT_MODE_MAX) return ERR_ALARM_INVALID_PARAM; - if (!__alarm_validate_date(&alarm_info->start, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("start date error\n"); + error_code = __check_validation(alarm_info, __FUNCTION__); + if (error_code != ALARMMGR_RESULT_SUCCESS) return error_code; - } - - if (!__alarm_validate_time(&alarm_info->start, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("start time error\n"); - return error_code; - } - - if (!__alarm_validate_date(&alarm_info->end, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("end date error\n"); - return error_code; - } if (!_send_alarm_create_noti(alarm_context, alarm_info, alarm_id, noti, &error_code)) return error_code; @@ -1039,23 +1152,19 @@ EXPORT_API int alarmmgr_add_alarm_appsvc(int alarm_type, time_t trigger_at_time, { int error_code = 0; int result = 0; - struct timeval current_time; - struct tm duetime_tm; alarm_info_t alarm_info; const char *operation = NULL; const char *appid = NULL; bundle *b; - ALARM_MGR_LOG_PRINT("[alarm-lib]:alarm_create() is called\n"); + LOGD("[alarm-lib]:alarm_create() is called\n"); b = (bundle *)bundle_data; if (b == NULL) { - ALARM_MGR_EXCEPTION_PRINT("Invalid parameter bundle\n"); + LOGE("Invalid parameter bundle\n"); return ERR_ALARM_INVALID_PARAM; } - _initialize_alarm_info(&alarm_info); - operation = appsvc_get_operation(b); if (operation == NULL) appsvc_set_operation(b, APPSVC_OPERATION_DEFAULT); @@ -1064,76 +1173,48 @@ EXPORT_API int alarmmgr_add_alarm_appsvc(int alarm_type, time_t trigger_at_time, if ((appid == NULL && (alarm_type & ALARM_TYPE_NOLAUNCH)) || (appid == NULL && operation && !strcmp(operation, APPSVC_OPERATION_DEFAULT))) { - ALARM_MGR_EXCEPTION_PRINT("Invalid parameter\n"); + LOGE("Invalid parameter\n"); return ERR_ALARM_INVALID_PARAM; } if (__alarmmgr_init_appsvc() < 0) { - ALARM_MGR_EXCEPTION_PRINT("Unable to initialize dbus!!!\n"); + LOGE("Unable to initialize dbus!!!\n"); return ERR_ALARM_SYSTEM_FAIL; } - if (alarm_id == NULL) + if (alarm_id == NULL) { + LOGE("alarm_id is null"); return ERR_ALARM_INVALID_PARAM; + } - if (trigger_at_time < 0) + if (trigger_at_time < 0) { + LOGE("trigger_at_time is invalid[%ld]", trigger_at_time); return ERR_ALARM_INVALID_PARAM; - - alarm_info.alarm_type = alarm_type; - alarm_info.alarm_type |= ALARM_TYPE_RELATIVE; - - gettimeofday(¤t_time, NULL); - if (current_time.tv_usec > 500 * 1000) { - /* When the millisecond part of the current_time is bigger than 500ms, - * the duetime increases by extra 1sec. */ - current_time.tv_sec += (trigger_at_time + 1); - } else { - current_time.tv_sec += trigger_at_time; } - alarm_info.reserved_info = current_time.tv_sec; - - tzset(); /* Processes the TZ environment variable, and Set timezone, daylight, and tzname. */ - localtime_r(¤t_time.tv_sec, &duetime_tm); - - alarm_info.start.year = duetime_tm.tm_year + 1900; - alarm_info.start.month = duetime_tm.tm_mon + 1; - alarm_info.start.day = duetime_tm.tm_mday; - alarm_info.end.year = 0; - alarm_info.end.month = 0; - alarm_info.end.day = 0; + _initialize_alarm_info(&alarm_info, alarm_type, trigger_at_time, interval, + false); - alarm_info.start.hour = duetime_tm.tm_hour; - alarm_info.start.min = duetime_tm.tm_min; - alarm_info.start.sec = duetime_tm.tm_sec; + alarm_info.alarm_type |= ALARM_TYPE_RELATIVE; + LOGD("alarm_info.type : %d", alarm_info.alarm_type); if (__compare_api_version(&result, getuid()) < 0) return ERR_ALARM_SYSTEM_FAIL; - if (result < 0) { if (alarm_info.alarm_type & ALARM_TYPE_INEXACT) alarm_info.alarm_type ^= ALARM_TYPE_INEXACT; } - if ((alarm_type & ALARM_TYPE_INEXACT) && interval < MIN_INEXACT_INTERVAL) - interval = MIN_INEXACT_INTERVAL; - - if (interval <= 0) { - alarm_info.mode.repeat = ALARM_REPEAT_MODE_ONCE; - alarm_info.mode.u_interval.interval = 0; - } else { - alarm_info.mode.repeat = ALARM_REPEAT_MODE_REPEAT; - alarm_info.mode.u_interval.interval = interval; - } - - ALARM_MGR_LOG_PRINT("trigger_at_time(%ld), start(%d-%d-%d, %02d:%02d:%02d), repeat(%d), interval(%d), type(%d)", - trigger_at_time, alarm_info.start.day, alarm_info.start.month, alarm_info.start.year, - alarm_info.start.hour, alarm_info.start.min, alarm_info.start.sec, - alarm_info.mode.repeat, (int)alarm_info.mode.u_interval.interval, alarm_info.alarm_type); + if ((alarm_type & ALARM_TYPE_INEXACT) && + alarm_info.mode.u_interval.interval < MIN_INEXACT_INTERVAL) + alarm_info.mode.u_interval.interval = MIN_INEXACT_INTERVAL; if (!_send_alarm_create_appsvc(alarm_context, &alarm_info, alarm_id, b, &error_code)) return error_code; + + LOGD("alarm_id : %d", *alarm_id); + return ALARMMGR_RESULT_SUCCESS; } @@ -1142,66 +1223,32 @@ EXPORT_API int alarmmgr_add_alarm_noti(int alarm_type, time_t trigger_at_time, alarm_id_t *alarm_id) { int error_code = 0; - struct timeval current_time; - struct tm duetime_tm; alarm_info_t alarm_info; if (__alarmmgr_init_appsvc() < 0) { - ALARM_MGR_EXCEPTION_PRINT("Unable to initialize dbus!!!\n"); + LOGE("Unable to initialize dbus!!!\n"); return ERR_ALARM_SYSTEM_FAIL; } - if (alarm_id == NULL) + if (alarm_id == NULL) { + LOGE("alarm_id is null"); return ERR_ALARM_INVALID_PARAM; + } - if (trigger_at_time < 0) + if (trigger_at_time < 0) { + LOGE("trigger_at_time is invalid[%ld]", trigger_at_time); return ERR_ALARM_INVALID_PARAM; - - _initialize_alarm_info(&alarm_info); - - alarm_info.alarm_type = alarm_type; - alarm_info.alarm_type |= ALARM_TYPE_RELATIVE; - - gettimeofday(¤t_time, NULL); - if (current_time.tv_usec > 500 * 1000) { - /* When the millisecond part of the current_time is bigger than 500ms, - * the duetime increases by extra 1sec. */ - current_time.tv_sec += (trigger_at_time + 1); - } else { - current_time.tv_sec += trigger_at_time; } - alarm_info.reserved_info = current_time.tv_sec; - - tzset(); /* Processes the TZ environment variable, and Set timezone, daylight, and tzname. */ - localtime_r(¤t_time.tv_sec, &duetime_tm); - - alarm_info.start.year = duetime_tm.tm_year + 1900; - alarm_info.start.month = duetime_tm.tm_mon + 1; - alarm_info.start.day = duetime_tm.tm_mday; - - alarm_info.end.year = 0; - alarm_info.end.month = 0; - alarm_info.end.day = 0; - alarm_info.start.hour = duetime_tm.tm_hour; - alarm_info.start.min = duetime_tm.tm_min; - alarm_info.start.sec = duetime_tm.tm_sec; + _initialize_alarm_info(&alarm_info, alarm_type, trigger_at_time, interval, + false); - if ((alarm_info.alarm_type & ALARM_TYPE_INEXACT) && interval < MIN_INEXACT_INTERVAL) - interval = MIN_INEXACT_INTERVAL; - - if (interval <= 0) { - alarm_info.mode.repeat = ALARM_REPEAT_MODE_ONCE; - alarm_info.mode.u_interval.interval = 0; - } else { - alarm_info.mode.repeat = ALARM_REPEAT_MODE_REPEAT; - alarm_info.mode.u_interval.interval = interval; - } + alarm_info.alarm_type |= ALARM_TYPE_RELATIVE; + LOGD("alarm_info.type : %d", alarm_info.alarm_type); - ALARM_MGR_LOG_PRINT("trigger_at_time(%ld), start(%d-%d-%d, %02d:%02d:%02d), repeat(%d), interval(%d), type(%d)", - trigger_at_time, alarm_info.start.day, alarm_info.start.month, alarm_info.start.year, - alarm_info.start.hour, alarm_info.start.min, alarm_info.start.sec, - alarm_info.mode.repeat, (int)alarm_info.mode.u_interval.interval, alarm_info.alarm_type); + if ((alarm_info.alarm_type & ALARM_TYPE_INEXACT) && + alarm_info.mode.u_interval.interval < MIN_INEXACT_INTERVAL) + alarm_info.mode.u_interval.interval = MIN_INEXACT_INTERVAL; if (!_send_alarm_create_noti(alarm_context, &alarm_info, alarm_id, noti, &error_code)) return error_code; @@ -1219,72 +1266,33 @@ static int _alarmmgr_add_alarm(int alarm_type, int i = 0; int j = 0; int error_code; - struct timeval current_time; - struct tm duetime_tm; alarm_info_t alarm_info; int ret; - gettimeofday(¤t_time, NULL); - - _initialize_alarm_info(&alarm_info); - ret = __sub_init(); if (ret < 0) return ret; - if (alarm_id == NULL) + if (alarm_id == NULL) { + LOGE("[alarm-lib]: alarm_id is null"); return ERR_ALARM_INVALID_PARAM; + } if (trigger_at_time < 0) + LOGE("trigger_at_time is invalid[%ld]", trigger_at_time); return ERR_ALARM_INVALID_PARAM; if (destination && strlen(destination) >= MAX_PKG_NAME_LEN) { - ALARM_MGR_EXCEPTION_PRINT("[alarm-lib]: destination name is too long!\n"); + LOGE("[alarm-lib]: destination name is too long!\n"); return ERR_ALARM_INVALID_PARAM; } - alarm_info.alarm_type = alarm_type; - alarm_info.alarm_type |= ALARM_TYPE_RELATIVE; - - - if (current_time.tv_usec > 500 * 1000) { - /* When the millisecond part of the current_time is bigger than 500ms, - * the duetime increases by extra 1sec. */ - current_time.tv_sec += (trigger_at_time + 1); - } else { - current_time.tv_sec += trigger_at_time; - } - alarm_info.reserved_info = current_time.tv_sec; + _initialize_alarm_info(&alarm_info, alarm_type, trigger_at_time, interval, + precision); - tzset(); /* Processes the TZ environment variable, and Set timezone, daylight, and tzname. */ - localtime_r(¤t_time.tv_sec, &duetime_tm); - - alarm_info.start.year = duetime_tm.tm_year + 1900; - alarm_info.start.month = duetime_tm.tm_mon + 1; - alarm_info.start.day = duetime_tm.tm_mday; - - alarm_info.msec = precision ? (int)current_time.tv_usec / 1000 : 0; - - alarm_info.end.year = 0; - alarm_info.end.month = 0; - alarm_info.end.day = 0; - - alarm_info.start.hour = duetime_tm.tm_hour; - alarm_info.start.min = duetime_tm.tm_min; - alarm_info.start.sec = duetime_tm.tm_sec; - - if (interval <= 0) { - alarm_info.mode.repeat = ALARM_REPEAT_MODE_ONCE; - alarm_info.mode.u_interval.interval = 0; - } else { - alarm_info.mode.repeat = ALARM_REPEAT_MODE_REPEAT; - alarm_info.mode.u_interval.interval = interval; - } + alarm_info.alarm_type |= ALARM_TYPE_RELATIVE; - ALARM_MGR_LOG_PRINT("trigger_at_time(%ld), start(%d-%d-%d, %02d:%02d:%02d), repeat(%d), interval(%d), type(%d)", - trigger_at_time, alarm_info.start.day, alarm_info.start.month, alarm_info.start.year, - alarm_info.start.hour, alarm_info.start.min, alarm_info.start.sec, - alarm_info.mode.repeat, (int)alarm_info.mode.u_interval.interval, alarm_info.alarm_type); + LOGD("alarm_info.type : %d", alarm_info.alarm_type); if (destination != NULL) { memset(dst_service_name, 0, @@ -1340,77 +1348,33 @@ static int _alarmmgr_add_alarm_withcb(int alarm_type, time_t trigger_at_time, alarm_id_t *alarm_id, bool precision) { int error_code = 0; - struct timeval current_time; - struct tm duetime_tm; alarm_info_t alarm_info; int ret = 0; - gettimeofday(¤t_time, NULL); - - _initialize_alarm_info(&alarm_info); - - if (flag_appid_checked == 0) { - if (aul_app_get_appid_bypid(getpid(), g_appid, sizeof(g_appid)) != AUL_R_OK) - ALARM_MGR_EXCEPTION_PRINT("PID[%d] may not be app. Please call alarmmgr_init(caller name) in advance.", getpid()); - else - ALARM_MGR_LOG_PRINT("Get appid only once. appid[%s]", g_appid); - flag_appid_checked = 1; - } - + __check_appid(); ret = alarmmgr_init(g_appid); if (ret < 0) return ret; - ALARM_MGR_LOG_PRINT("[alarm-lib]:alarmmgr_add_alarm_withcb() is called"); + LOGD("[alarm-lib]:alarmmgr_add_alarm_withcb() is called"); - if (alarm_id == NULL) + if (alarm_id == NULL) { + LOGE("alarm_id is null "); return ERR_ALARM_INVALID_PARAM; + } - if (trigger_at_time < 0) + if (trigger_at_time < 0) { + LOGE("trigger_at_time is invalid[%ld]", trigger_at_time); return ERR_ALARM_INVALID_PARAM; - - alarm_info.alarm_type = alarm_type; - alarm_info.alarm_type |= ALARM_TYPE_RELATIVE; - alarm_info.alarm_type |= ALARM_TYPE_WITHCB; - - if (current_time.tv_usec > 500 * 1000) { - /* When the millisecond part of the current_time is bigger than 500ms, */ - /* the duetime increases by extra 1sec. */ - current_time.tv_sec += (trigger_at_time + 1); - } else { - current_time.tv_sec += trigger_at_time; } - alarm_info.reserved_info = current_time.tv_sec; - tzset(); /* Processes the TZ environment variable, and Set timezone, daylight, and tzname. */ - localtime_r(¤t_time.tv_sec, &duetime_tm); + _initialize_alarm_info(&alarm_info, alarm_type, trigger_at_time, interval, + precision); - alarm_info.start.year = duetime_tm.tm_year + 1900; - alarm_info.start.month = duetime_tm.tm_mon + 1; - alarm_info.start.day = duetime_tm.tm_mday; - - alarm_info.msec = precision ? (int)current_time.tv_usec / 1000 : 0; - - alarm_info.end.year = 0; - alarm_info.end.month = 0; - alarm_info.end.day = 0; - - alarm_info.start.hour = duetime_tm.tm_hour; - alarm_info.start.min = duetime_tm.tm_min; - alarm_info.start.sec = duetime_tm.tm_sec; - - if (interval <= 0) { - alarm_info.mode.repeat = ALARM_REPEAT_MODE_ONCE; - alarm_info.mode.u_interval.interval = 0; - } else { - alarm_info.mode.repeat = ALARM_REPEAT_MODE_REPEAT; - alarm_info.mode.u_interval.interval = interval; - } + alarm_info.alarm_type |= ALARM_TYPE_RELATIVE; + alarm_info.alarm_type |= ALARM_TYPE_WITHCB; - ALARM_MGR_LOG_PRINT("trigger_at_time(%ld), start(%d-%d-%d, %02d:%02d:%02d), repeat(%d), interval(%d), type(%d)", - trigger_at_time, alarm_info.start.day, alarm_info.start.month, alarm_info.start.year, - alarm_info.start.hour, alarm_info.start.min, alarm_info.start.sec, - alarm_info.mode.repeat, (int)alarm_info.mode.u_interval.interval, alarm_info.alarm_type); + LOGD("alarm_info.type : %d", alarm_info.alarm_type); if (!_send_alarm_create(alarm_context, &alarm_info, alarm_id, "null", "null", &error_code)) return error_code; @@ -1444,10 +1408,12 @@ EXPORT_API int alarmmgr_remove_alarm(alarm_id_t alarm_id) if (ret < 0) return ret; - ALARM_MGR_LOG_PRINT("[alarm-lib]:alarm_delete(%d) is called\n", alarm_id); + LOGD("[alarm-lib]:alarm_delete(%d) is called\n", alarm_id); - if (alarm_id <= 0) + if (alarm_id <= 0) { + LOGE("[alarm-lib]:alarm_id is invalid[%d]\n", alarm_id); return ERR_ALARM_INVALID_ID; + } if (!_send_alarm_delete(alarm_context, alarm_id, &error_code)) return error_code; @@ -1475,82 +1441,38 @@ EXPORT_API int alarmmgr_remove_all(void) EXPORT_API int alarmmgr_enum_alarm_ids(alarm_enum_fn_t fn, void *user_param) { SECURE_LOGD("Enter"); - GError *error = NULL; - GVariant *alarm_array = NULL; int return_code = 0; int maxnum_of_ids = 0; int num_of_ids = 0; - alarm_id_t alarm_id = -1; + alarm_id_t alarm_id; int ret = 0; GVariantIter *iter = NULL; - if (fn == NULL) + if (fn == NULL) { + LOGE("fn is null."); return ERR_ALARM_INVALID_PARAM; + } ret = __sub_init(); if (ret < 0) { - ALARM_MGR_EXCEPTION_PRINT("__sub_init() is failed."); - return ret; - } - - SECURE_LOGD("alarm_manager_call_alarm_get_number_of_ids_sync() is called"); - if (!alarm_manager_call_alarm_get_number_of_ids_sync( - (AlarmManager *)alarm_context.proxy, &maxnum_of_ids, &return_code, NULL, &error)) { - /* dbus error. error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT( - "alarm_manager_call_alarm_get_number_of_ids_sync() is failed by dbus. return_code[%d], err message[%s] err code[%d]", - return_code, error->message, error->code); - if (error->code == G_DBUS_ERROR_ACCESS_DENIED) - ret = ERR_ALARM_NO_PERMISSION; - else - ret = ERR_ALARM_SYSTEM_FAIL; - g_error_free(error); + LOGE("__sub_init() is failed."); return ret; } - if (return_code != ALARMMGR_RESULT_SUCCESS) { - ALARM_MGR_EXCEPTION_PRINT("alarm_manager_call_alarm_get_number_of_ids_sync() is failed. return_code[%d]", return_code); + if (!_send_alarm_get_number_of_ids(alarm_context, &maxnum_of_ids, &return_code)) return return_code; - } else { - ALARM_MGR_LOG_PRINT("maxnum_of_ids[%d]", maxnum_of_ids); - } - - SECURE_LOGD("alarm_manager_call_alarm_get_list_of_ids_sync() is called"); - if (!alarm_manager_call_alarm_get_list_of_ids_sync( - (AlarmManager *)alarm_context.proxy, maxnum_of_ids, &alarm_array, &num_of_ids, &return_code, NULL, &error)) { - /* dbus error. error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT( - "alarm_manager_call_alarm_get_list_of_ids_sync() failed by dbus. num_of_ids[%d], return_code[%d]. err message[%s] err code[%d]", num_of_ids, return_code, error->message, error->code); - if (error->code == G_DBUS_ERROR_ACCESS_DENIED) - ret = ERR_ALARM_NO_PERMISSION; - else - ret = ERR_ALARM_SYSTEM_FAIL; - g_error_free(error); - return ret; - } - if (return_code != ALARMMGR_RESULT_SUCCESS) - return return_code; + LOGD("maxnum_of_ids[%d]", maxnum_of_ids); - if (error != NULL) { - ALARM_MGR_EXCEPTION_PRINT("Alarm server is not ready dbus. error message %s.", error->message); - return ERR_ALARM_SYSTEM_FAIL; - } - - if (alarm_array == NULL) { - ALARM_MGR_EXCEPTION_PRINT("alarm server is not initilized."); - return ERR_ALARM_SYSTEM_FAIL; - } + if (!_send_alarm_get_list_of_ids(alarm_context, maxnum_of_ids, &iter, &num_of_ids, &return_code)) + return return_code; - g_variant_get(alarm_array, "ai", &iter); while (g_variant_iter_loop(iter, "i", &alarm_id)) { + LOGD("alarm_id (%d)", alarm_id); (*fn)(alarm_id, user_param); - ALARM_MGR_LOG_PRINT("alarm_id (%d)", alarm_id); } g_variant_iter_free(iter); - g_variant_unref(alarm_array); - SECURE_LOGD("Leave"); return ALARMMGR_RESULT_SUCCESS; } @@ -1564,67 +1486,14 @@ EXPORT_API int alarmmgr_get_info(alarm_id_t alarm_id, alarm_entry_t *alarm) if (ret < 0) return ret; - ALARM_MGR_LOG_PRINT("[alarm-lib]:alarm_get_info() is called\n"); + LOGD("[alarm-lib]:alarm_get_info() is called\n"); - if (alarm_id < 0 || alarm_info == NULL) + if (alarm_id < 0 || alarm_info == NULL) { + LOGE("[alarm-lib]:alarm_info is null or alar_id is invalid[%d].", alarm_id); return ERR_ALARM_INVALID_PARAM; - - if (!_send_alarm_get_info(alarm_context, alarm_id, alarm_info, &error_code)) - return error_code; - - return ALARMMGR_RESULT_SUCCESS; -} - -int alarmmgr_create(alarm_info_t *alarm_info, char *destination, - alarm_id_t *alarm_id) -{ - char dst_service_name[MAX_SERVICE_NAME_LEN] = { 0 }; - alarm_mode_t *mode = &alarm_info->mode; - int error_code; - - ALARM_MGR_LOG_PRINT("[alarm-lib]:alarm_create() is called\n"); - - if (alarm_info == NULL || alarm_id == NULL) - return ERR_ALARM_INVALID_PARAM; - - ALARM_MGR_LOG_PRINT("alarm_info->start.year(%d), " - "alarm_info->start.month(%d), alarm_info->start.day(%d)", - alarm_info->start.year, alarm_info->start.month, - alarm_info->start.day); - - /* TODO: This should be changed to > ALARM_REPEAT_MODE_MAX ? */ - if (mode->repeat >= ALARM_REPEAT_MODE_MAX) - return ERR_ALARM_INVALID_PARAM; - - if (!__alarm_validate_date(&alarm_info->start, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("start date error\n"); - return error_code; - } - - if (!__alarm_validate_time(&alarm_info->start, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("start time error\n"); - return error_code; - } - - if (!__alarm_validate_date(&alarm_info->end, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("end date error\n"); - return error_code; - } - - if (destination != NULL) { - memset(dst_service_name, 0, - strlen(destination) + strlen("ALARM.") + 2); - snprintf(dst_service_name, MAX_SERVICE_NAME_LEN, "ALARM.%s", - destination); - if (!_send_alarm_create(alarm_context, alarm_info, - alarm_id, dst_service_name, "null", - &error_code)) - return error_code; } - /*TODO: Currently this API is not exported. Hence not modifying*/ - if (!_send_alarm_create(alarm_context, alarm_info, alarm_id, - "null", "null", &error_code)) + if (!_send_alarm_get_info(alarm_context, alarm_id, alarm_info, &error_code)) return error_code; return ALARMMGR_RESULT_SUCCESS; @@ -1633,36 +1502,16 @@ int alarmmgr_create(alarm_info_t *alarm_info, char *destination, int alarmmgr_get_number_of_ids(int *num_of_ids) { int error_code; - ALARM_MGR_LOG_PRINT("[alarm-lib]: alarm_get_number_of_ids() is called."); - - if (num_of_ids == NULL) - return ERR_ALARM_INVALID_PARAM; - - ALARM_MGR_LOG_PRINT("call alarm_get_number_of_ids\n"); - if (!_send_alarm_get_number_of_ids(alarm_context, num_of_ids, &error_code)) - return error_code; - - return ALARMMGR_RESULT_SUCCESS; -} - -int alarmmgr_get_list_of_ids(int maxnum_of_ids, alarm_id_t *alarm_id, - int *num_of_ids) -{ - int error_code; - ALARM_MGR_LOG_PRINT("[alarm-lib]:alarm_get_list_of_ids() is called."); + LOGD("[alarm-lib]: alarm_get_number_of_ids() is called."); - if (maxnum_of_ids < 0 || alarm_id == NULL || num_of_ids == NULL) + if (num_of_ids == NULL) { + LOGE("[alarm-lib]:num_of_ids."); return ERR_ALARM_INVALID_PARAM; - - if (maxnum_of_ids == 0) { - *num_of_ids = 0; - return ALARMMGR_RESULT_SUCCESS; } - if (!_send_alarm_get_list_of_ids - (alarm_context, maxnum_of_ids, alarm_id, num_of_ids, &error_code)) { + LOGD("call alarm_get_number_of_ids\n"); + if (!_send_alarm_get_number_of_ids(alarm_context, num_of_ids, &error_code)) return error_code; - } return ALARMMGR_RESULT_SUCCESS; } @@ -1676,10 +1525,12 @@ EXPORT_API int alarmmgr_get_next_duetime(alarm_id_t alarm_id, time_t *duetime) if (ret < 0) return ret; - ALARM_MGR_LOG_PRINT("[alarm-lib]:alarmmgr_get_next_duetime() is called."); + LOGD("[alarm-lib]:alarmmgr_get_next_duetime() is called."); - if (duetime == NULL) + if (duetime == NULL) { + LOGE("[alarm-lib]:duetime is null."); return ERR_ALARM_INVALID_PARAM; + } if (!_send_alarm_get_next_duetime(alarm_context, alarm_id, duetime, &error_code)) return error_code; @@ -1690,15 +1541,17 @@ EXPORT_API int alarmmgr_get_next_duetime(alarm_id_t alarm_id, time_t *duetime) EXPORT_API int alarmmgr_get_all_info(char **db_path) { int error_code; - ALARM_MGR_LOG_PRINT("[alarm-lib]:alarmmgr_get_all_info() is called."); + LOGD("[alarm-lib]:alarmmgr_get_all_info() is called."); - if (db_path == NULL) + if (db_path == NULL) { + LOGE("[alarm-lib]:db_path is null."); return ERR_ALARM_INVALID_PARAM; + } if (!_send_alarm_get_all_info(alarm_context, db_path, &error_code)) return error_code; - ALARM_MGR_LOG_PRINT("[alarm-lib]: successfully save info in %s.", *db_path); + LOGD("[alarm-lib]: successfully save info in %s.", *db_path); return ALARMMGR_RESULT_SUCCESS; } @@ -1706,23 +1559,17 @@ EXPORT_API int alarmmgr_add_periodic_alarm_withcb(int interval, periodic_method_ alarm_cb_t handler, void *user_param, alarm_id_t *alarm_id) { int error_code = 0; - alarm_info_t alarm_info; int ret = 0; - if (flag_appid_checked == 0) { - if (aul_app_get_appid_bypid(getpid(), g_appid, sizeof(g_appid)) != AUL_R_OK) - ALARM_MGR_EXCEPTION_PRINT("PID[%d] may not be app. Please call alarmmgr_init(caller name) in advance.", getpid()); - else - ALARM_MGR_LOG_PRINT("Get appid only once. appid[%s]", g_appid); - flag_appid_checked = 1; - } - + __check_appid(); ret = alarmmgr_init(g_appid); if (ret < 0) return ret; - if (alarm_id == NULL) + if (alarm_id == NULL) { + LOGE("[alarm-lib]:alarm_id is null."); return ERR_ALARM_INVALID_PARAM; + } if (!_send_alarm_create_periodic(alarm_context, interval, 0, (int)method, alarm_id, @@ -1738,23 +1585,17 @@ EXPORT_API int alarmmgr_add_reference_periodic_alarm_withcb(int interval, alarm_cb_t handler, void *user_param, alarm_id_t *alarm_id) { int error_code = 0; - alarm_info_t alarm_info; int ret = 0; - if (flag_appid_checked == 0) { - if (aul_app_get_appid_bypid(getpid(), g_appid, sizeof(g_appid)) != AUL_R_OK) - ALARM_MGR_EXCEPTION_PRINT("PID[%d] may not be app. Please call alarmmgr_init(caller name) in advance.", getpid()); - else - ALARM_MGR_LOG_PRINT("Get appid only once. appid[%s]", g_appid); - flag_appid_checked = 1; - } - + __check_appid(); ret = alarmmgr_init(g_appid); if (ret < 0) return ret; - if (alarm_id == NULL) + if (alarm_id == NULL) { + LOGE("[alarm-lib]:alarm_id is null."); return ERR_ALARM_INVALID_PARAM; + } if (!_send_alarm_create_periodic(alarm_context, interval, 1, 0, alarm_id, &error_code)) @@ -1767,27 +1608,36 @@ EXPORT_API int alarmmgr_add_reference_periodic_alarm_withcb(int interval, EXPORT_API int alarmmgr_set_systime(int new_time) { + return alarmmgr_set_systime64((time_t)new_time); +} + +EXPORT_API int alarmmgr_set_systime64(time_t new_time) +{ int error_code; - ALARM_MGR_LOG_PRINT("[alarm-lib]:alarmmgr_set_systime(%d) is called.", new_time); + LOGD("[alarm-lib]:alarmmgr_set_systime(%ld) is called.", new_time); if (__sub_init() < 0) return ERR_ALARM_SYSTEM_FAIL; if (!_send_alarm_set_time(alarm_context, new_time, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("Failed to set time. error: %d", error_code); + LOGE("Failed to set time. error: %d", error_code); return error_code; } - ALARM_MGR_LOG_PRINT("[alarm-lib]: successfully set the time(%d) by pid(%d).", new_time, getpid()); + LOGD("[alarm-lib]: successfully set the time(%ld) by pid(%d).", new_time, getpid()); return ALARMMGR_RESULT_SUCCESS; } EXPORT_API int alarmmgr_set_systime_async(int new_time, alarm_set_time_cb_t result_cb, void *user_param) { - int error_code; + return alarmmgr_set_systime64_async((time_t)new_time, result_cb, user_param); +} + +EXPORT_API int alarmmgr_set_systime64_async(time_t new_time, alarm_set_time_cb_t result_cb, void *user_param) +{ struct alarm_async_param_t *param; - ALARM_MGR_LOG_PRINT("[alarm-lib]:alarmmgr_set_systime(%d) is called.", new_time); + LOGD("[alarm-lib]:alarmmgr_set_systime(%ld) is called.", new_time); if (sub_initialized) { if (!_send_alarm_set_time_async(alarm_context, new_time, @@ -1802,7 +1652,7 @@ EXPORT_API int alarmmgr_set_systime_async(int new_time, alarm_set_time_cb_t resu #endif param = g_try_new0(struct alarm_async_param_t, 1); if (param == NULL) { - ALARM_MGR_EXCEPTION_PRINT("Failed to alloc param"); + LOGE("Failed to alloc param"); return ERR_ALARM_SYSTEM_FAIL; } param->type = SET_SYSTIME; @@ -1818,33 +1668,31 @@ EXPORT_API int alarmmgr_set_systime_async(int new_time, alarm_set_time_cb_t resu EXPORT_API int alarmmgr_set_systime_with_propagation_delay(struct timespec new_time, struct timespec req_time) { int error_code; - ALARM_MGR_LOG_PRINT("[alarm-lib] New: %ld(sec) %09ld(nsec), Requested: %ld(sec) %09ld(nsec)", + LOGD("[alarm-lib] New: %ld(sec) %09ld(nsec), Requested: %ld(sec) %09ld(nsec)", new_time.tv_sec, new_time.tv_nsec, req_time.tv_sec, req_time.tv_nsec); if (__sub_init() < 0) return ERR_ALARM_SYSTEM_FAIL; - if (!_send_alarm_set_time_with_propagation_delay(alarm_context, new_time.tv_sec, new_time.tv_nsec, req_time.tv_sec, req_time.tv_nsec, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("Failed to set time with propagation delay. error: %d", error_code); + if (!_send_alarm_set_time_with_propagation_delay(alarm_context, new_time, req_time, &error_code)) { + LOGE("Failed to set time with propagation delay. error: %d", error_code); return error_code; } - ALARM_MGR_LOG_PRINT("[alarm-lib]: successfully set the time by pid(%d).", getpid()); + LOGD("[alarm-lib]: successfully set the time by pid(%d).", getpid()); return ALARMMGR_RESULT_SUCCESS; } EXPORT_API int alarmmgr_set_systime_with_propagation_delay_async(struct timespec new_time, struct timespec req_time, alarm_set_time_cb_t result_cb, void *user_param) { - int error_code; struct alarm_async_param_t *param; - ALARM_MGR_LOG_PRINT("[alarm-lib] New: %ld(sec) %09ld(nsec), Requested: %ld(sec) %09ld(nsec)", + LOGD("[alarm-lib] New: %ld(sec) %09ld(nsec), Requested: %ld(sec) %09ld(nsec)", new_time.tv_sec, new_time.tv_nsec, req_time.tv_sec, req_time.tv_nsec); if (sub_initialized) { if (!_send_alarm_set_time_with_propagation_delay_async(alarm_context, - new_time.tv_sec, new_time.tv_nsec, req_time.tv_sec, - req_time.tv_nsec, result_cb, user_param)) + new_time, req_time, result_cb, user_param)) return ERR_ALARM_SYSTEM_FAIL; } else { #if !(GLIB_CHECK_VERSION(2, 32, 0)) @@ -1855,12 +1703,13 @@ EXPORT_API int alarmmgr_set_systime_with_propagation_delay_async(struct timespec #endif param = g_try_new0(struct alarm_async_param_t, 1); if (param == NULL) { - ALARM_MGR_EXCEPTION_PRINT("Failed to alloc param"); + LOGE("Failed to alloc param"); return ERR_ALARM_SYSTEM_FAIL; } param->type = SET_SYSTIME_WITH_PROPAGATION_DELAY; - param->v = g_variant_new("(uuuu)", new_time.tv_sec, new_time.tv_nsec, - req_time.tv_sec, req_time.tv_nsec); + param->v = g_variant_new("(xxxx)", + (gint64)new_time.tv_sec, (gint64)new_time.tv_nsec, + (gint64)req_time.tv_sec, (gint64)req_time.tv_nsec); param->result_cb = result_cb; param->user_param = user_param; g_bus_get(G_BUS_TYPE_SYSTEM, NULL, __bus_get_for_async_api, param); @@ -1872,10 +1721,12 @@ EXPORT_API int alarmmgr_set_systime_with_propagation_delay_async(struct timespec EXPORT_API int alarmmgr_set_timezone(char *tzpath_str) { int error_code; - ALARM_MGR_LOG_PRINT("[alarm-lib]:alarmmgr_set_timezone() is called."); + LOGD("[alarm-lib]:alarmmgr_set_timezone() is called."); - if (tzpath_str == NULL) + if (tzpath_str == NULL) { + LOGE("[alarm-lib]:tzpath_str is NULL\n"); return ERR_ALARM_INVALID_PARAM; + } if (__sub_init() < 0) return ERR_ALARM_SYSTEM_FAIL; @@ -1883,7 +1734,7 @@ EXPORT_API int alarmmgr_set_timezone(char *tzpath_str) if (!_send_alarm_set_timezone(alarm_context, tzpath_str, &error_code)) return error_code; - ALARM_MGR_LOG_PRINT("[alarm-lib]: successfully set the timezone(%s) by pid(%d)", tzpath_str, getpid()); + LOGD("[alarm-lib]: successfully set the timezone(%s) by pid(%d)", tzpath_str, getpid()); return ALARMMGR_RESULT_SUCCESS; } @@ -1891,7 +1742,7 @@ EXPORT_API int alarmmgr_set_global(const alarm_id_t alarm_id, bool global) { int error_code; - ALARM_MGR_LOG_PRINT("[alarm-lib]:alarmmgr_set_global() is called."); + LOGD("[alarm-lib]:alarmmgr_set_global(%d) is called.", alarm_id); if (__sub_init() < 0) return ERR_ALARM_SYSTEM_FAIL; @@ -1911,8 +1762,10 @@ EXPORT_API int alarmmgr_get_global(const alarm_id_t alarm_id, if (__sub_init() < 0) return ERR_ALARM_SYSTEM_FAIL; - if (global == NULL) + if (global == NULL) { + LOGE("[alarm-lib]:global is NULL\n"); return ERR_ALARM_INVALID_PARAM; + } if (!_send_alarm_get_global(alarm_context, alarm_id, global, &error_code)) return error_code; @@ -1923,46 +1776,38 @@ EXPORT_API int alarmmgr_get_global(const alarm_id_t alarm_id, EXPORT_API int alarmmgr_update_alarm(alarm_id_t alarm_id, alarm_entry_t *alarm, int update_flag) { - alarm_info_t *alarm_info; /* = (alarm_info_t*)alarm; */ + alarm_info_t *alarm_info; int ret; - ALARM_MGR_LOG_PRINT("[alarm-lib]:alarmmgr_update_alarm() is called\n"); + LOGD("[alarm-lib]:alarmmgr_update_alarm() is called\n"); - if (alarm == NULL) + if (alarm == NULL) { + LOGE("[alarm-lib]:alarm is NULL\n"); return ERR_ALARM_INVALID_PARAM; + } alarm_info = (alarm_info_t *) alarm; - if (alarm_info == NULL || alarm_id <= 0) + if (alarm_info == NULL || alarm_id <= 0) { + LOGE("[alarm-lib]:alarm is NULL or invalid alarm_id[%d]\n", alarm_id); return ERR_ALARM_INVALID_PARAM; + } int error_code; - alarm_mode_t *mode = &alarm_info->mode; ret = __sub_init(); if (ret < 0) return ret; - ALARM_MGR_LOG_PRINT("start(%d-%d-%d, %02d:%02d:%02d), end(%d-%d-%d), repeat(%d), interval(%d), type(%d)", + LOGD("start(%d-%d-%d, %02d:%02d:%02d), end(%d-%d-%d), repeat(%d), interval(%ld), type(%d)", alarm_info->start.day, alarm_info->start.month, alarm_info->start.year, alarm_info->start.hour, alarm_info->start.min, alarm_info->start.sec, alarm_info->end.year, alarm_info->end.month, alarm_info->end.day, - alarm_info->mode.repeat, (int)alarm_info->mode.u_interval.interval, alarm_info->alarm_type); + alarm_info->mode.repeat, alarm_info->mode.u_interval.interval, alarm_info->alarm_type); if (update_flag == ALARM_UPDATE_FLAG_TIME) { - if (!__alarm_validate_date(&alarm_info->start, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("start date error\n"); + error_code = __check_validation(alarm_info, __FUNCTION__); + if (error_code != ALARMMGR_RESULT_SUCCESS) return error_code; - } - - if (!__alarm_validate_time(&alarm_info->start, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("start time error\n"); - return error_code; - } - - if (!__alarm_validate_date(&alarm_info->end, &error_code)) { - ALARM_MGR_EXCEPTION_PRINT("end date error\n"); - return error_code; - } } if (!_send_alarm_update(alarm_context, alarm_id, alarm_info, update_flag, &error_code)) diff --git a/alarm-service.pc.in b/lib/alarm-service.pc.in index e1736a5..aba063d 100644 --- a/alarm-service.pc.in +++ b/lib/alarm-service.pc.in @@ -1,11 +1,11 @@ prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=@CMAKE_INSTALL_PREFIX@ -libdir=@CMAKE_INSTALL_LIBDIR@ +libdir=@LIB_INSTALL_DIR@ includedir=@INCLUDE_INSTALL_DIR@ Name: alarm-service Description: alarm library -Version: @VERSION@ +Version: @FULLVER@ Requires: glib-2.0 gobject-2.0 dlog notification -Libs: -L${libdir} -lalarm +Libs: -L${libdir} -l@LIBRARY@ Cflags: -I${includedir} diff --git a/org.tizen.alarm.manager.service.in b/org.tizen.alarm.manager.service.in deleted file mode 100644 index 20da859..0000000 --- a/org.tizen.alarm.manager.service.in +++ /dev/null @@ -1,4 +0,0 @@ -[D-BUS Service] -Name=org.tizen.alarm.manager -Exec=/bin/false -SystemdService=alarm-server.service diff --git a/alarm-lib.manifest b/packaging/alarm-lib.manifest index 97e8c31..97e8c31 100644 --- a/alarm-lib.manifest +++ b/packaging/alarm-lib.manifest diff --git a/packaging/alarm-manager.conf b/packaging/alarm-manager.conf index e4d6a58..5d387a9 100644 --- a/packaging/alarm-manager.conf +++ b/packaging/alarm-manager.conf @@ -1,2 +1,2 @@ d /run/alarm_agent 0777 root users - -d /run/alarmmgr_log 0775 app_fw app_fw - +d /var/log/appfw/alarmmgr_log 0775 app_fw app_fw - diff --git a/packaging/alarm-manager.spec b/packaging/alarm-manager.spec index e2d7a9b..53229cb 100644 --- a/packaging/alarm-manager.spec +++ b/packaging/alarm-manager.spec @@ -10,9 +10,10 @@ Source2: alarm-session-agent.service Source3: alarm-session-agent.socket Source4: alarm-manager.conf Source5: 99-rtc.rules -Requires(post): /sbin/ldconfig -Requires(postun): /sbin/ldconfig - +Source6: alarm-session-agent@.service +Source7: alarm-session-agent@.socket +Source1001: alarm-server.manifest +Source1002: alarm-lib.manifest BuildRequires: cmake BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(dlog) @@ -37,6 +38,21 @@ BuildRequires: pkgconfig(cynara-client) BuildRequires: pkgconfig(cynara-session) BuildRequires: pkgconfig(cynara-creds-gdbus) +%if 0%{?gcov:1} +BuildRequires: lcov +BuildRequires: zip +%endif + +%define gtests 0 + +%if 0%{?gtests:1} +BuildRequires: pkgconfig(gmock) +%endif +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%define logdir /var/log/appfw/alarmmgr_log + %description Alarm Server and devel libraries @@ -93,31 +109,66 @@ Requires: libalarm = %{version}-%{release} %description -n alarm-config-service-restricted A configuration file package for restricting service applications +################################################# +# unittests +################################################# +%package unittests +Summary: GTest for alarm manager library +Group: Development/Libraries +Requires: %{name} + +%description unittests +GTest for alarm-manager library + + +################################################# +# gcov +################################################# +%if 0%{?gcov:1} +%package gcov +Summary: Alarm library (gcov) +Group: Application Framework/Testing + +%description gcov +Alarm library gcov objects +%endif + %prep %setup -q +cp %{SOURCE1001} ./ +cp %{SOURCE1002} ./ %build +%if 0%{?gcov:1} +export CFLAGS+=" -fprofile-arcs -ftest-coverage" +export CXXFLAGS+=" -fprofile-arcs -ftest-coverage" +export FFLAGS+=" -fprofile-arcs -ftest-coverage" +export LDFLAGS+=" -lgcov" +%endif + MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` -export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" -export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" -export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" %define appfw_feature_alarm_manager_module_log 1 %if 0%{?appfw_feature_alarm_manager_module_log} _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG=ON %endif %cmake . -DOBS=1 \ - -DFULLVER=%{version} \ - -DMAJORVER=${MAJORVER} \ + -DFULLVER=%{version} -DMAJORVER=${MAJORVER} \ + -DBIN_INSTALL_DIR:PATH=%{_bindir} \ -DTZ_SYS_ETC=%{TZ_SYS_ETC} \ -D_APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG:BOOL=${_APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG} \ - -DALARM_CONF_DIR=%{_datadir}/alarm-manager + -DALARM_CONF_DIR=%{_datadir}/alarm-manager \ + -DBUILD_GTESTS=%{?gtests:1}%{!?gtests:0} \ make %{?jobs:-j%jobs} +%if 0%{?gcov:1} +mkdir -p gcov-obj +find . -name '*.gcno' -exec cp '{}' gcov-obj ';' +%endif %install rm -rf %{buildroot} @@ -125,15 +176,34 @@ rm -rf %{buildroot} mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants mkdir -p %{buildroot}%{_unitdir_user}/sockets.target.wants +mkdir -p %{buildroot}%{_unitdir}/user-sockets@.target.wants install -m 0644 %SOURCE1 %{buildroot}%{_unitdir}/alarm-server.service install -m 0644 %SOURCE2 %{buildroot}%{_unitdir_user}/alarm-session-agent.service install -m 0644 %SOURCE3 %{buildroot}%{_unitdir_user}/alarm-session-agent.socket +install -m 0644 %SOURCE6 %{buildroot}%{_unitdir}/alarm-session-agent@.service +install -m 0644 %SOURCE7 %{buildroot}%{_unitdir}/alarm-session-agent@.socket ln -s ../alarm-server.service %{buildroot}%{_unitdir}/multi-user.target.wants/alarm-server.service ln -sf ../alarm-session-agent.socket %{buildroot}%{_unitdir_user}/sockets.target.wants/alarm-session-agent.socket +ln -sf ../alarm-session-agent@.socket %{buildroot}%{_unitdir}/user-sockets@.target.wants/alarm-session-agent@.socket mkdir -p %{buildroot}%{_tmpfilesdir} install -m 0644 %SOURCE4 %{buildroot}%{_tmpfilesdir}/alarm-manager.conf mkdir -p %{buildroot}%{_libdir}/udev/rules.d install -m 0644 %SOURCE5 %{buildroot}%{_libdir}/udev/rules.d +mkdir -p %{buildroot}%{logdir} + +%if 0%{?gcov:1} +mkdir -p %{buildroot}%{_datadir}/gcov/obj +install -m 0644 gcov-obj/* %{buildroot}%{_datadir}/gcov/obj +%endif + +%check +(cd unittest && LD_LIBRARY_PATH=../lib ctest -V) +%if 0%{?gcov:1} +lcov -c --ignore-errors graph --no-external -q -d . -o alarm-manager.info +genhtml alarm-manager.info -o alarm-manager.out +zip -r alarm-manager.zip alarm-manager.out +install -m 0644 alarm-manager.zip %{buildroot}%{_datadir}/gcov/ +%endif %post -p /sbin/ldconfig @@ -157,27 +227,28 @@ fi %files -n alarm-server %manifest alarm-server.manifest -%{_bindir}/* -%attr(0755,root,root) %{_bindir}/alarm-server -%attr(0755,root,root) %{_bindir}/alarm_session_agent +%{_bindir}/alarm* %attr(0644,root,root) %{_unitdir}/alarm-server.service %{_unitdir}/multi-user.target.wants/alarm-server.service %{_unitdir_user}/alarm-session-agent.service %{_unitdir_user}/alarm-session-agent.socket +%{_unitdir}/alarm-session-agent@.service +%{_unitdir}/alarm-session-agent@.socket %{_unitdir_user}/sockets.target.wants/alarm-session-agent.socket +%{_unitdir}/user-sockets@.target.wants/alarm-session-agent@.socket %attr(0644,root,root) %{_datadir}/dbus-1/system-services/org.tizen.alarm.manager.service -%license LICENSE %config %{_sysconfdir}/dbus-1/system.d/alarm-service.conf %{_tmpfilesdir}/alarm-manager.conf %{_libdir}/udev/rules.d/99-rtc.rules +%license LICENSE %if 0%{?appfw_feature_alarm_manager_module_log} %attr(0755,root,root) %{TZ_SYS_ETC}/dump.d/module.d/alarmmgr_log_dump.sh +%attr(0755,app_fw,app_fw) %{logdir} %endif %files -n libalarm %manifest alarm-lib.manifest -%attr(0644,root,root) %{_libdir}/libalarm.so.* -%{_libdir}/*.so.* +%{_libdir}/libalarm.so.* %license LICENSE %files -n libalarm-devel @@ -193,3 +264,16 @@ fi %files -n alarm-config-service-restricted %{_datadir}/alarm-manager/alarm-config-service-restricted + +#%if 0%{?gtests:1} +#%files unittests +#%{_bindir}/gtest* +#%endif + +################################################# +# gcov +################################################# +%if 0%{?gcov:1} +%files gcov +%{_datadir}/gcov/* +%endif diff --git a/alarm-server.manifest b/packaging/alarm-server.manifest index 97e8c31..97e8c31 100644 --- a/alarm-server.manifest +++ b/packaging/alarm-server.manifest diff --git a/packaging/alarm-session-agent@.service b/packaging/alarm-session-agent@.service new file mode 100755 index 0000000..a4eb6ac --- /dev/null +++ b/packaging/alarm-session-agent@.service @@ -0,0 +1,13 @@ +[Unit] +PartOf=userlogin@%i.target +Description=Start the alarm agent + +[Service] +User=%i +Environment=DBUS_SESSION_BUS_ADDRESS=kernel:path=/sys/fs/kdbus/%i-user/bus;unix:path=/run/user/%i/bus +Environment=XDG_RUNTIME_DIR=/run/user/%i +SmackProcessLabel=User +ExecStart=/usr/bin/alarm_session_agent + +[Install] +WantedBy=user-default@.target diff --git a/packaging/alarm-session-agent@.socket b/packaging/alarm-session-agent@.socket new file mode 100755 index 0000000..34f2bea --- /dev/null +++ b/packaging/alarm-session-agent@.socket @@ -0,0 +1,13 @@ +[Unit] +PartOf=userlogin@%i.target +DefaultDependencies=no +After=systemd-logind.service + +[Socket] +SocketUser=%i +ListenStream=/run/alarm_agent/%i +DirectoryMode=0777 +ExecStartPost=/usr/bin/chmod 0777 /run/alarm_agent/%i + +[Install] +WantedBy=user-sockets@.target diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt new file mode 100755 index 0000000..fd55d4b --- /dev/null +++ b/server/CMakeLists.txt @@ -0,0 +1,32 @@ +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/server) + +AUX_SOURCE_DIRECTORY(./ SRCS) + +PKG_CHECK_MODULES(svr_pkgs REQUIRED glib-2.0 dlog aul bundle appsvc pkgmgr-info pkgmgr vconf + gio-2.0 gio-unix-2.0 capi-system-device libtzplatform-config libsystemd-login + eventsystem notification capi-system-info sqlite3 cert-svc-vcore + cynara-session cynara-client cynara-creds-gdbus) + +FOREACH(flag ${svr_pkgs_CFLAGS_OTHER}) + IF(${flag} MATCHES "\\-D+") + ADD_DEFINITIONS(${flag}) + ENDIF(${flag} MATCHES "\\-D+") +ENDFOREACH(flag) + +INCLUDE_DIRECTORIES(${svr_pkgs_INCLUDE_DIRS}) +LINK_DIRECTORIES(${svr_pkgs_LIBRARY_DIRS}) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fpie") + +ADD_EXECUTABLE(${SERVER} ${SRCS}) + +TARGET_LINK_LIBRARIES(${SERVER} ${svr_pkgs_LIBRARIES} rt) +INSTALL(TARGETS ${SERVER} DESTINATION ${BIN_INSTALL_DIR}) + +CONFIGURE_FILE(alarm-service.conf.in alarm-service.conf @ONLY) +INSTALL(FILES alarm-service.conf DESTINATION ${SYSCONF_INSTALL_DIR}/dbus-1/system.d/) + +CONFIGURE_FILE(${DBUS_INTERFACE}.service.in ${DBUS_INTERFACE}.service @ONLY) +INSTALL(FILES ${DBUS_INTERFACE}.service DESTINATION ${SHARE_INSTALL_PREFIX}/dbus-1/system-services/) diff --git a/server/alarm-manager-db.c b/server/alarm-manager-db.c new file mode 100644 index 0000000..a6fa50e --- /dev/null +++ b/server/alarm-manager-db.c @@ -0,0 +1,578 @@ +/* + * Copyright (c) 2000 - 2019 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 <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <signal.h> +#include <string.h> +#include <sys/types.h> + +#include <sqlite3.h> +#include <glib.h> +#include <tzplatform_config.h> +#if !GLIB_CHECK_VERSION(2, 31, 0) +#include <glib/gmacros.h> +#endif + +#include "alarm-manager-db.h" + +#define ALARMMGR_DB_FILE tzplatform_mkpath(TZ_SYS_DB, ".alarmmgr.db") +#define QUERY_CREATE_TABLE_ALARMMGR "create table if not exists alarmmgr \ + (alarm_id integer primary key,\ + start integer,\ + end integer,\ + uid integer,\ + global integer,\ + is_disabled integer,\ + caller_pkgid text,\ + callee_pkgid text,\ + app_unique_name text,\ + app_service_name text,\ + app_service_name_mod text,\ + bundle text, \ + noti_len integer,\ + noti text, \ + year integer,\ + month integer,\ + day integer,\ + hour integer,\ + min integer,\ + sec integer,\ + msec integer,\ + day_of_week integer,\ + repeat integer,\ + alarm_type integer,\ + reserved_info integer,\ + dst_service_name text, \ + dst_service_name_mod text \ + )" + +extern GSList *g_disabled_alarm_list; +extern __alarm_server_context_t alarm_context; + +sqlite3 *alarmmgr_db; +static bool is_db_corrupted = false; + +static int __db_busyhandler(void *pData, int count) +{ + if (5 - count > 0) { + struct timespec time = { + .tv_sec = 0, + .tv_nsec = (count + 1) * 100 * 1000 * 1000 + }; + nanosleep(&time, NULL); + LOGD("alarmmgr_db: busy handler called. count: %d", count + 1); + return 1; + } else { + LOGD("alarmmgr_db: busy handler will return SQLITE_BUSY error"); + return 0; + } +} + +bool _save_alarms(__alarm_info_t *__alarm_info) +{ + char *error_message = NULL; + alarm_info_t *alarm_info = + (alarm_info_t *) &(__alarm_info->alarm_info); + alarm_date_t *start = &alarm_info->start; + alarm_mode_t *mode = &alarm_info->mode; + + char *query = sqlite3_mprintf("insert into alarmmgr( alarm_id, start,\ + end, uid, global, is_disabled, caller_pkgid, callee_pkgid, app_unique_name,\ + app_service_name, app_service_name_mod, bundle, noti_len, noti, year,\ + month, day, hour, min, sec, msec, day_of_week, repeat,\ + alarm_type, reserved_info, dst_service_name, dst_service_name_mod)\ + values (%d,%lld,%lld,%d,%d,0,%Q,%Q,%Q,%Q,%Q,%Q,%d,%Q,%d,%d,%d,%d,%d,%d,%d,%d,%d,\ + %d,%lld,%Q,%Q)",\ + __alarm_info->alarm_id, + (gint64)__alarm_info->start, + (gint64)__alarm_info->end, + __alarm_info->uid, + __alarm_info->global, + CHECK_NULL_STRING(__alarm_info->caller_pkgid), + CHECK_NULL_STRING(__alarm_info->callee_pkgid), + CHECK_NULL_STRING(__alarm_info->app_unique_name), + CHECK_NULL_STRING(__alarm_info->app_service_name), + CHECK_NULL_STRING(__alarm_info->app_service_name_mod), + CHECK_NULL_STRING(__alarm_info->bundle), + __alarm_info->noti ? strlen(__alarm_info->noti) : 0, + CHECK_NULL_STRING(__alarm_info->noti), + start->year, + start->month, + start->day, + start->hour, + start->min, + start->sec, + alarm_info->msec, + mode->u_interval.day_of_week, + mode->repeat, + alarm_info->alarm_type, + (gint64)alarm_info->reserved_info, + CHECK_NULL_STRING(__alarm_info->dst_service_name), + CHECK_NULL_STRING(__alarm_info->dst_service_name_mod)); + + if (SQLITE_OK != sqlite3_exec(alarmmgr_db, query, NULL, NULL, &error_message)) { + SECURE_LOGE("sqlite3_exec() is failed. query = %s, error message = %s", query, error_message); + sqlite3_free(error_message); + sqlite3_free(query); + return false; + } + + sqlite3_free(query); + return true; +} + +bool _update_alarms(__alarm_info_t *__alarm_info) +{ + char *error_message = NULL; + alarm_info_t *alarm_info = + (alarm_info_t *) &(__alarm_info->alarm_info); + alarm_date_t *start = &alarm_info->start; + alarm_mode_t *mode = &alarm_info->mode; + + char *query = sqlite3_mprintf("update alarmmgr set start=%lld, end=%lld,\ + uid=%d, global=%d, is_disabled=0, caller_pkgid=%Q, callee_pkgid=%Q, app_unique_name=%Q, app_service_name=%Q, app_service_name_mod=%Q,\ + bundle=%Q, noti_len=%d, noti=%Q, year=%d, month=%d, day=%d, hour=%d, min=%d, sec=%d, msec=%d,\ + day_of_week=%d, repeat=%d, alarm_type=%d,\ + reserved_info=%lld, dst_service_name=%Q, dst_service_name_mod=%Q\ + where alarm_id=%d",\ + (gint64)__alarm_info->start, + (gint64)__alarm_info->end, + __alarm_info->uid, + __alarm_info->global, + CHECK_NULL_STRING(__alarm_info->caller_pkgid), + CHECK_NULL_STRING(__alarm_info->callee_pkgid), + CHECK_NULL_STRING(__alarm_info->app_unique_name), + CHECK_NULL_STRING(__alarm_info->app_service_name), + CHECK_NULL_STRING(__alarm_info->app_service_name_mod), + CHECK_NULL_STRING(__alarm_info->bundle), + __alarm_info->noti ? strlen(__alarm_info->noti) : 0, + CHECK_NULL_STRING(__alarm_info->noti), + start->year, + start->month, + start->day, + start->hour, + start->min, + start->sec, + alarm_info->msec, + mode->u_interval.day_of_week, + mode->repeat, + alarm_info->alarm_type, + (gint64)alarm_info->reserved_info, + CHECK_NULL_STRING(__alarm_info->dst_service_name), + CHECK_NULL_STRING(__alarm_info->dst_service_name_mod), + __alarm_info->alarm_id); + + if (SQLITE_OK != sqlite3_exec(alarmmgr_db, query, NULL, NULL, &error_message)) { + SECURE_LOGE("sqlite3_exec() is failed. query = %s, error message = %s", query, error_message); + sqlite3_free(error_message); + sqlite3_free(query); + return false; + } + + sqlite3_free(query); + return true; +} + +bool _delete_alarms(alarm_id_t alarm_id) +{ + char *error_message = NULL; + char *query = sqlite3_mprintf("delete from alarmmgr where alarm_id=%d", alarm_id); + + if (SQLITE_OK != sqlite3_exec(alarmmgr_db, query, NULL, NULL, &error_message)) { + SECURE_LOGE("sqlite3_exec() is failed. query = %s, error message = %s", query, error_message); + sqlite3_free(error_message); + sqlite3_free(query); + return false; + } + + sqlite3_free(query); + return true; +} + +void _load_alarms_from_db() +{ + int i = 0; + int col_idx; + const char *query = "select * from alarmmgr"; + const char *null_str = "null"; + sqlite3_stmt *stmt = NULL; + const char *tail = NULL; + alarm_info_t *alarm_info = NULL; + __alarm_info_t *__alarm_info = NULL; + alarm_date_t *start = NULL; + alarm_mode_t *mode = NULL; + int is_disabled; + char caller_pkgid[MAX_PKG_ID_LEN] = {0,}; + char callee_pkgid[MAX_PKG_ID_LEN] = {0,}; + char app_unique_name[MAX_APP_ID_LEN] = {0,}; + char app_service_name[MAX_SERVICE_NAME_LEN] = {0,}; + char app_service_name_mod[MAX_SERVICE_NAME_LEN] = {0,}; + char dst_service_name[MAX_SERVICE_NAME_LEN] = {0,}; + char dst_service_name_mod[MAX_SERVICE_NAME_LEN] = {0,}; + char bundle[MAX_BUNDLE_NAME_LEN] = {0,}; + int noti_len; + char *noti; + gint64 start_64, end_64, reserved_info_64; + + if (SQLITE_OK != sqlite3_prepare(alarmmgr_db, query, strlen(query), &stmt, &tail)) { + LOGE("sqlite3_prepare() is failed."); + return; + } + + for (i = 0; SQLITE_ROW == sqlite3_step(stmt); i++) { + col_idx = 0; + __alarm_info = (__alarm_info_t *)calloc(1, sizeof(__alarm_info_t)); + + if (G_UNLIKELY(__alarm_info == NULL)) { + LOGE("Memory allocation failed."); + goto done; + } + alarm_info = (alarm_info_t *) &(__alarm_info->alarm_info); + start = &alarm_info->start; + mode = &alarm_info->mode; + + __alarm_info->alarm_id = sqlite3_column_int(stmt, col_idx++); + start_64 = sqlite3_column_int64(stmt, col_idx++); + __alarm_info->start = (time_t)start_64; + end_64 = sqlite3_column_int64(stmt, col_idx++); + __alarm_info->end = (time_t)end_64; + __alarm_info->uid = sqlite3_column_int(stmt, col_idx++); + __alarm_info->global = sqlite3_column_int(stmt, col_idx++); + is_disabled = sqlite3_column_int(stmt, col_idx++); + + strncpy(caller_pkgid, (const char *)sqlite3_column_text(stmt, col_idx++), + MAX_PKG_ID_LEN - 1); + strncpy(callee_pkgid, (const char *)sqlite3_column_text(stmt, col_idx++), + MAX_PKG_ID_LEN - 1); + strncpy(app_unique_name, (const char *)sqlite3_column_text(stmt, col_idx++), + MAX_APP_ID_LEN - 1); + strncpy(app_service_name, (const char *)sqlite3_column_text(stmt, col_idx++), + MAX_SERVICE_NAME_LEN - 1); + strncpy(app_service_name_mod, (const char *)sqlite3_column_text(stmt, col_idx++), + MAX_SERVICE_NAME_LEN - 1); + strncpy(bundle, (const char *)sqlite3_column_text(stmt, col_idx++), + MAX_BUNDLE_NAME_LEN - 1); + noti_len = sqlite3_column_int(stmt, col_idx++); + noti_len = noti_len ? noti_len : strlen(null_str); + noti = (char *)calloc(1, noti_len + 1); + strncpy(noti, (const char *)sqlite3_column_text(stmt, col_idx++), + noti_len); + start->year = sqlite3_column_int(stmt, col_idx++); + start->month = sqlite3_column_int(stmt, col_idx++); + start->day = sqlite3_column_int(stmt, col_idx++); + start->hour = sqlite3_column_int(stmt, col_idx++); + start->min = sqlite3_column_int(stmt, col_idx++); + start->sec = sqlite3_column_int(stmt, col_idx++); + alarm_info->msec = sqlite3_column_int(stmt, col_idx++); + mode->u_interval.day_of_week = sqlite3_column_int(stmt, col_idx++); + mode->repeat = (alarm_repeat_mode_t)sqlite3_column_int(stmt, col_idx++); + alarm_info->alarm_type = sqlite3_column_int(stmt, col_idx++); + reserved_info_64 = sqlite3_column_int64(stmt, col_idx++); + alarm_info->reserved_info = (time_t)reserved_info_64; + strncpy(dst_service_name, (const char *)sqlite3_column_text(stmt, col_idx++), + MAX_SERVICE_NAME_LEN - 1); + strncpy(dst_service_name_mod, (const char *)sqlite3_column_text(stmt, col_idx++), + MAX_SERVICE_NAME_LEN - 1); + + __alarm_info->caller_pkgid = STRDUP_WITH_NULLCMP(caller_pkgid); + __alarm_info->callee_pkgid = STRDUP_WITH_NULLCMP(callee_pkgid); + __alarm_info->app_unique_name = STRDUP_WITH_NULLCMP(app_unique_name); + __alarm_info->app_service_name = STRDUP_WITH_NULLCMP(app_service_name); + __alarm_info->app_service_name_mod = + STRDUP_WITH_NULLCMP(app_service_name_mod); + __alarm_info->dst_service_name = STRDUP_WITH_NULLCMP(dst_service_name); + __alarm_info->dst_service_name_mod = + STRDUP_WITH_NULLCMP(dst_service_name_mod); + __alarm_info->bundle = STRDUP_WITH_NULLCMP(bundle); + __alarm_info->noti = STRDUP_WITH_NULLCMP(noti); + free(noti); + + if (is_disabled) { + _alarm_set_next_duetime(__alarm_info); + g_disabled_alarm_list = g_slist_append(g_disabled_alarm_list, __alarm_info); + LOGW("Save alarm_id[%d] caller[%s] callee[%s]", __alarm_info->alarm_id, caller_pkgid, callee_pkgid); + } else { + _alarm_set_next_duetime(__alarm_info); + alarm_context.alarms = g_slist_append(alarm_context.alarms, __alarm_info); + } + } +done: + _alarm_schedule(); + if (sqlite3_finalize(stmt) != SQLITE_OK) + LOGE("sqlite3_finalize() is failed."); + + return; +} + +int _get_db_path_for_all_info(uid_t uid, char** db_path) +{ + sqlite3 *alarmmgr_tool_db; + char db_path_tmp[50] = {0,}; + const char *query_for_creating_table = "create table alarmmgr_tool \ + (alarm_id integer primary key,\ + duetime_epoch integer,\ + duetime text,\ + start_epoch integer,\ + end_epoch integer,\ + global integer,\ + caller_pkgid text,\ + callee_pkgid text,\ + app_unique_name text,\ + app_service_name text,\ + dst_service_name text,\ + day_of_week integer,\ + repeat integer,\ + alarm_type integer)"; + const char *query_for_deleting_table = "drop table alarmmgr_tool"; + time_t current_time = 0; + struct tm current_tm; + GSList *gs_iter = NULL; + __alarm_info_t *entry = NULL; + char *error_message = NULL; + int index = 0; + + /* Open a DB */ + time(¤t_time); + localtime_r(¤t_time, ¤t_tm); + snprintf(db_path_tmp, sizeof(db_path_tmp), "/tmp/alarmmgr_%d%d%d_%02d%02d%02d.db", + current_tm.tm_year + 1900, current_tm.tm_mon + 1, current_tm.tm_mday, current_tm.tm_hour, current_tm.tm_min, current_tm.tm_sec); + *db_path = strdup(db_path_tmp); + if (*db_path == NULL) { + LOGE("Out of memory"); + return ERR_ALARM_SYSTEM_FAIL; + } + + if (sqlite3_open(db_path_tmp, &alarmmgr_tool_db) != SQLITE_OK) { + LOGE("Failed to open [%s]", db_path_tmp); + return ERR_ALARM_SYSTEM_FAIL; + } + + /* Register busy handler */ + if (sqlite3_busy_handler(alarmmgr_tool_db, __db_busyhandler, NULL) != SQLITE_OK) { + LOGE("Failed to register the busy handler"); + sqlite3_close(alarmmgr_tool_db); + return ERR_ALARM_SYSTEM_FAIL; + } + + /* Drop a table */ + if (sqlite3_exec(alarmmgr_tool_db, query_for_deleting_table, NULL, NULL, &error_message) != SQLITE_OK) { + LOGE("Deleting the table is failed. error message = %s", error_message); + sqlite3_free(error_message); + } + + /* Create a table if it does not exist */ + if (sqlite3_exec(alarmmgr_tool_db, query_for_creating_table, NULL, NULL, &error_message) != SQLITE_OK) { + LOGE("Creating the table is failed. error message = %s", error_message); + sqlite3_free(error_message); + sqlite3_close(alarmmgr_tool_db); + return ERR_ALARM_SYSTEM_FAIL; + } + + /* Get information of all alarms and save those into the DB. */ + for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { + entry = (__alarm_info_t*)gs_iter->data; + if (uid >= REGULAR_UID_MIN && entry->uid != uid) + continue; + ++index; + SECURE_LOGD("#%d alarm id[%d] app_name[%s] duetime[%ld]", + index, entry->alarm_id, entry->app_unique_name, entry->start); + + alarm_info_t *alarm_info = (alarm_info_t *) &(entry->alarm_info); + alarm_mode_t *mode = &alarm_info->mode; + + char *query = sqlite3_mprintf("insert into alarmmgr_tool( alarm_id, duetime_epoch, duetime, start_epoch,\ + end_epoch, global, caller_pkgid, callee_pkgid, app_unique_name, app_service_name, dst_service_name, day_of_week, repeat, alarm_type)\ + values (%d,%d,%Q,%d,%d,%d,%Q,%Q,%Q,%Q,%Q,%d,%d,%d)", + entry->alarm_id, + (int)entry->due_time, + ctime(&(entry->due_time)), + (int)entry->start, + (int)entry->end, + (bool)entry->global, + CHECK_NULL_STRING(entry->caller_pkgid), + CHECK_NULL_STRING(entry->callee_pkgid), + CHECK_NULL_STRING(entry->app_unique_name), + CHECK_NULL_STRING(entry->app_service_name), + CHECK_NULL_STRING(entry->dst_service_name), + mode->u_interval.day_of_week, + mode->repeat, + entry->alarm_info.alarm_type); + + if (sqlite3_exec(alarmmgr_tool_db, query, NULL, NULL, &error_message) != SQLITE_OK) { + SECURE_LOGE("sqlite3_exec() is failed. error message = %s", error_message); + sqlite3_free(error_message); + } + + sqlite3_free(query); + } + + sqlite3_close(alarmmgr_tool_db); + return ALARMMGR_RESULT_SUCCESS; +} + +gboolean _update_relative_alarms(gpointer user_data) +{ + GSList *iter = NULL; + __alarm_info_t *entry = NULL; + char *error_message = NULL; + + if (sqlite3_exec(alarmmgr_db, "BEGIN EXCLUSIVE", NULL, NULL, &error_message) != SQLITE_OK) { + SECURE_LOGE("sqlite3_exec() is failed. error message = %s", error_message); + sqlite3_free(error_message); + return false; + } + + for (iter = alarm_context.alarms; iter != NULL; iter = g_slist_next(iter)) { + entry = (__alarm_info_t *)iter->data; + alarm_info_t *alarm_info = &(entry->alarm_info); + if (alarm_info->alarm_type & ALARM_TYPE_RELATIVE) + _update_alarms(entry); + } + + if (sqlite3_exec(alarmmgr_db, "COMMIT", NULL, NULL, &error_message) != SQLITE_OK) { + SECURE_LOGE("sqlite3_exec() is failed. error message = %s", error_message); + sqlite3_free(error_message); + return false; + } + + return false; +} + +bool _alarm_set_global_to_db(__alarm_info_t *alarm_info, bool global) +{ + + char *error_message = NULL; + char *query = sqlite3_mprintf("update alarmmgr set global=%d where alarm_id=%d", + alarm_info->global, alarm_info->alarm_id); + + if (SQLITE_OK != sqlite3_exec(alarmmgr_db, query, NULL, NULL, &error_message)) { + SECURE_LOGE("sqlite3_exec() is failed. query = %s, error message = %s", query, error_message); + sqlite3_free(query); + sqlite3_free(error_message); + return false; + } + + sqlite3_free(query); + return true; +} + +void _update_db_for_disabled_alarm(alarm_id_t alarm_id, bool disabled) +{ + char *error_message = NULL; + + LOGW("Update (%d) is_disabled to (%d)", alarm_id, disabled); + char *query = sqlite3_mprintf("update alarmmgr set is_disabled=%d where alarm_id=%d", disabled, alarm_id); + + if (SQLITE_OK != sqlite3_exec(alarmmgr_db, query, NULL, NULL, &error_message)) { + SECURE_LOGE("Failed to update the DB table. error message = %s", error_message); + sqlite3_free(error_message); + } + + sqlite3_free(query); + return; +} + +int __check_callback(void *pid, int argc, char **argv, char **notUsed2) +{ + if (strcmp(argv[0], "ok") != 0) { + LOGE("check integrity result : %s" , argv[0]); + is_db_corrupted = true; + return -1; + } else { + LOGD("check integrity result : %s" , argv[0]); + } + + return 0; +} + +bool _initialize_db() +{ + char *error_message = NULL; + int ret; + + /* Create or Open the DB file */ + ret = sqlite3_open(ALARMMGR_DB_FILE, &alarmmgr_db); + if (ret != SQLITE_OK) { + LOGE("Failed to open [%s]. error: %s", ALARMMGR_DB_FILE, sqlite3_errmsg(alarmmgr_db)); + if (ret == SQLITE_CORRUPT) + goto recover; + else + return false; + } + /* Register busy handler */ + ret = sqlite3_busy_handler(alarmmgr_db, __db_busyhandler, NULL); + if (ret != SQLITE_OK) { + LOGE("Failed to register the busy handler"); + if (ret == SQLITE_CORRUPT) { + goto recover; + } else { + sqlite3_close(alarmmgr_db); + return false; + } + } + /* Create alarmmgr table */ + ret = sqlite3_exec(alarmmgr_db, QUERY_CREATE_TABLE_ALARMMGR, NULL, NULL, &error_message); + if (ret != SQLITE_OK) { + LOGE("Don't execute query = %s, error message = %s", QUERY_CREATE_TABLE_ALARMMGR, error_message); + if (ret == SQLITE_CORRUPT || ret == SQLITE_NOTADB) { + goto recover; + } else { + sqlite3_close(alarmmgr_db); + sqlite3_free(error_message); + return false; + } + } + + /* Check integrity of DB */ + ret = sqlite3_exec(alarmmgr_db, "PRAGMA integrity_check", __check_callback, NULL, 0); + if (ret != SQLITE_OK || is_db_corrupted) { + LOGE("Loss alarm db's integrity"); + goto recover; + } + + return true; + +recover: + if (alarmmgr_db) + sqlite3_close(alarmmgr_db); + if (error_message) + sqlite3_free(error_message); + unlink(ALARMMGR_DB_FILE); + + ret = sqlite3_open(ALARMMGR_DB_FILE, &alarmmgr_db); + if (ret != SQLITE_OK) { + LOGE("[recover] Failed to open [%s]. error: %s", ALARMMGR_DB_FILE, sqlite3_errmsg(alarmmgr_db)); + return false; + } + + ret = sqlite3_busy_handler(alarmmgr_db, __db_busyhandler, NULL); + if (ret != SQLITE_OK) { + LOGE("[recover] Failed to register the busy handler"); + sqlite3_close(alarmmgr_db); + return false; + } + + ret = sqlite3_exec(alarmmgr_db, QUERY_CREATE_TABLE_ALARMMGR, NULL, NULL, &error_message); + if (ret != SQLITE_OK) { + LOGE("[recover] Don't execute query = %s, error message = %s", QUERY_CREATE_TABLE_ALARMMGR, error_message); + sqlite3_close(alarmmgr_db); + sqlite3_free(error_message); + return false; + } + + return true; +} diff --git a/server/alarm-manager-db.h b/server/alarm-manager-db.h new file mode 100644 index 0000000..59f6902 --- /dev/null +++ b/server/alarm-manager-db.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019 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. + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib.h> + +#include "alarm.h" +#include "alarm-internal.h" + +bool _alarm_set_global_to_db(__alarm_info_t *alarm_info, bool global); +bool _delete_alarms(alarm_id_t alarm_id); +int _get_db_path_for_all_info(uid_t uid, char** db_path); +bool _initialize_db(); +void _load_alarms_from_db(); +bool _save_alarms(__alarm_info_t *__alarm_info); +bool _update_alarms(__alarm_info_t *__alarm_info); +gboolean _update_relative_alarms(gpointer user_data); +void _update_db_for_disabled_alarm(alarm_id_t alarm_id, bool disabled_by_ups); + +#ifdef __cplusplus +} +#endif + diff --git a/server/alarm-manager-dbus.c b/server/alarm-manager-dbus.c new file mode 100644 index 0000000..9c16f3d --- /dev/null +++ b/server/alarm-manager-dbus.c @@ -0,0 +1,843 @@ +/* + * Copyright (c) 2019 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. + */ +#define _GNU_SOURCE +#include <stdlib.h> +#include <stdint.h> +#include <stdio.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/un.h> + +#include "alarm.h" +#include "alarm-internal.h" +#include "alarm-manager-dbus.h" +#include "alarm-manager-util.h" + +/* GDBus Declaration */ +#define ALARM_MGR_DBUS_PATH "/org/tizen/alarm/manager" +#define ALARM_MGR_DBUS_NAME "org.tizen.alarm.manager" + +extern __alarm_server_context_t alarm_context; +extern GSList *g_expired_alarm_list; + +struct watch_info_t { + int watch_id; + alarm_id_t alarm_id; +}; + +static GDBusNodeInfo *introspection_data; +static const gchar introspection_xml[] = +"<node name='/org/tizen/alarm/manager'>" +" <interface name='org.tizen.alarm.manager'>" +" <method name='alarm_create_periodic'>" +" <arg type='s' name='app_service_name' direction='in' />" +" <arg type='s' name='app_service_name_mod' direction='in' />" +" <arg type='i' name='interval' direction='in' />" +" <arg type='i' name='is_ref' direction='in' />" +" <arg type='i' name='method' direction='in' />" +" <arg type='i' name='alarm_id' direction='out' />" +" <arg type='i' name='return_code' direction='out' />" +" </method>" +" <method name='alarm_create'>" +" <arg type='s' name='app_service_name' direction='in' />" +" <arg type='s' name='app_service_name_mod' direction='in' />" +" <arg type='i' name='alarm_info_start_year' direction='in' />" +" <arg type='i' name='alarm_info_start_month' direction='in' />" +" <arg type='i' name='alarm_info_start_day' direction='in' />" +" <arg type='i' name='alarm_info_start_hour' direction='in' />" +" <arg type='i' name='alarm_info_start_min' direction='in' />" +" <arg type='i' name='alarm_info_start_sec' direction='in' />" +" <arg type='i' name='alarm_info_msec' direction='in' />" +" <arg type='i' name='alarm_info_end_year' direction='in' />" +" <arg type='i' name='alarm_info_end_month' direction='in' />" +" <arg type='i' name='alarm_info_end_day' direction='in' />" +" <arg type='i' name='alarm_info_mode_day_of_week' direction='in' />" +" <arg type='i' name='alarm_info_mode_repeat' direction='in' />" +" <arg type='i' name='alarm_info_alarm_type' direction='in' />" +" <arg type='x' name='alarm_info_reserved_info' direction='in' />" +" <arg type='s' name='alarm_info_reserved_service_name' direction='in' />" +" <arg type='s' name='alarm_info_reserved_service_name_mod' direction='in' />" +" <arg type='i' name='alarm_id' direction='out' />" +" <arg type='i' name='return_code' direction='out' />" +" </method>" +" <method name='alarm_create_appsvc'>" +" <arg type='i' name='alarm_info_start_year' direction='in' />" +" <arg type='i' name='alarm_info_start_month' direction='in' />" +" <arg type='i' name='alarm_info_start_day' direction='in' />" +" <arg type='i' name='alarm_info_start_hour' direction='in' />" +" <arg type='i' name='alarm_info_start_min' direction='in' />" +" <arg type='i' name='alarm_info_start_sec' direction='in' />" +" <arg type='i' name='alarm_info_end_year' direction='in' />" +" <arg type='i' name='alarm_info_end_month' direction='in' />" +" <arg type='i' name='alarm_info_end_day' direction='in' />" +" <arg type='i' name='alarm_info_mode_day_of_week' direction='in' />" +" <arg type='x' name='alarm_info_mode_interval' direction='in' />" +" <arg type='i' name='alarm_info_mode_repeat' direction='in' />" +" <arg type='i' name='alarm_info_alarm_type' direction='in' />" +" <arg type='x' name='alarm_info_reserved_info' direction='in' />" +" <arg type='s' name='alarm_info_bundle_data' direction='in' />" +" <arg type='i' name='alarm_id' direction='out' />" +" <arg type='i' name='return_code' direction='out' />" +" </method>" +" <method name='alarm_create_noti'>" +" <arg type='i' name='alarm_info_start_year' direction='in' />" +" <arg type='i' name='alarm_info_start_month' direction='in' />" +" <arg type='i' name='alarm_info_start_day' direction='in' />" +" <arg type='i' name='alarm_info_start_hour' direction='in' />" +" <arg type='i' name='alarm_info_start_min' direction='in' />" +" <arg type='i' name='alarm_info_start_sec' direction='in' />" +" <arg type='i' name='alarm_info_end_year' direction='in' />" +" <arg type='i' name='alarm_info_end_month' direction='in' />" +" <arg type='i' name='alarm_info_end_day' direction='in' />" +" <arg type='i' name='alarm_info_mode_day_of_week' direction='in' />" +" <arg type='x' name='alarm_info_mode_interval' direction='in' />" +" <arg type='i' name='alarm_info_mode_repeat' direction='in' />" +" <arg type='i' name='alarm_info_alarm_type' direction='in' />" +" <arg type='x' name='alarm_info_reserved_info' direction='in' />" +" <arg type='s' name='alarm_info_noti_data' direction='in' />" +" <arg type='i' name='alarm_id' direction='out' />" +" <arg type='i' name='return_code' direction='out' />" +" </method>" +" <method name='alarm_delete'>" +" <arg type='i' name='alarm_id' direction='in' />" +" <arg type='i' name='alarm_info_return_code' direction='out' />" +" </method>" +" <method name='alarm_delete_all'>" +" <arg type='i' name='alarm_info_return_code' direction='out' />" +" </method>" +" <method name='alarm_update'>" +" <arg type='i' name='alarm_id' direction='in' />" +" <arg type='i' name='alarm_info_start_year' direction='in' />" +" <arg type='i' name='alarm_info_start_month' direction='in' />" +" <arg type='i' name='alarm_info_start_day' direction='in' />" +" <arg type='i' name='alarm_info_start_hour' direction='in' />" +" <arg type='i' name='alarm_info_start_min' direction='in' />" +" <arg type='i' name='alarm_info_start_sec' direction='in' />" +" <arg type='i' name='alarm_info_end_year' direction='in' />" +" <arg type='i' name='alarm_info_end_month' direction='in' />" +" <arg type='i' name='alarm_info_end_day' direction='in' />" +" <arg type='x' name='alarm_info_mode_interval' direction='in' />" +" <arg type='i' name='alarm_info_mode_repeat' direction='in' />" +" <arg type='i' name='alarm_info_alarm_type' direction='in' />" +" <arg type='x' name='alarm_info_reserved_info' direction='in' />" +" <arg type='i' name='update_flag' direction='in' />" +" <arg type='i' name='return_code' direction='out' />" +" </method>" +" <method name='alarm_get_number_of_ids'>" +" <arg type='i' name='number_of_ids' direction='out' />" +" <arg type='i' name='return_code' direction='out' />" +" </method>" +" <method name='alarm_get_list_of_ids'>" +" <arg type='i' name='max_number_of_ids' direction='in' />" +" <arg type='ai' name='alarm_id' direction='out' />" +" <arg type='i' name='number_of_ids' direction='out' />" +" <arg type='i' name='return_code' direction='out' />" +" </method>" +" <method name='alarm_get_appsvc_info'>" +" <arg type='i' name='alarm_id' direction='in' />" +" <arg type='s' name='b_data' direction='out' />" +" <arg type='i' name='return_code' direction='out' />" +" </method>" +" <method name='alarm_get_noti_info'>" +" <arg type='i' name='alarm_id' direction='in' />" +" <arg type='s' name='noti_data' direction='out' />" +" <arg type='i' name='return_code' direction='out' />" +" </method>" +" <method name='alarm_get_info'>" +" <arg type='i' name='alarm_id' direction='in' />" +" <arg type='i' name='alarm_info_start_year' direction='out' />" +" <arg type='i' name='alarm_info_start_month' direction='out' />" +" <arg type='i' name='alarm_info_start_day' direction='out' />" +" <arg type='i' name='alarm_info_start_hour' direction='out' />" +" <arg type='i' name='alarm_info_start_min' direction='out' />" +" <arg type='i' name='alarm_info_start_sec' direction='out' />" +" <arg type='i' name='alarm_info_end_year' direction='out' />" +" <arg type='i' name='alarm_info_end_month' direction='out' />" +" <arg type='i' name='alarm_info_end_day' direction='out' />" +" <arg type='i' name='alarm_info_mode_day_of_week' direction='out' />" +" <arg type='i' name='alarm_info_mode_repeat' direction='out' />" +" <arg type='i' name='alarm_info_alarm_type' direction='out' />" +" <arg type='x' name='alarm_info_reserved_info' direction='out' />" +" <arg type='i' name='return_code' direction='out' />" +" </method>" +" <method name='alarm_set_rtc_time'>" +" <arg type='i' name='alarm_info_year' direction='in' />" +" <arg type='i' name='alarm_info_month' direction='in' />" +" <arg type='i' name='alarm_info_day' direction='in' />" +" <arg type='i' name='alarm_info_hour' direction='in' />" +" <arg type='i' name='alarm_info_min' direction='in' />" +" <arg type='i' name='alarm_info_sec' direction='in' />" +" <arg type='i' name='return_code' direction='out' />" +" </method>" +" <method name='alarm_get_next_duetime'>" +" <arg type='i' name='alarm_id' direction='in' />" +" <arg type='x' name='duetime' direction='out' />" +" <arg type='i' name='return_code' direction='out' />" +" </method>" +" <method name='alarm_get_all_info'>" +" <arg type='s' name='db_path' direction='out' />" +" <arg type='i' name='return_code' direction='out' />" +" </method>" +" <method name='alarm_set_time'>" +" <arg type='x' name='time' direction='in' />" +" <arg type='i' name='return_code' direction='out' />" +" </method>" +" <method name='alarm_set_time_with_propagation_delay'>" +" <arg type='x' name='new_sec' direction='in' />" +" <arg type='x' name='new_nsec' direction='in' />" +" <arg type='x' name='req_sec' direction='in' />" +" <arg type='x' name='req_nsec' direction='in' />" +" <arg type='i' name='return_code' direction='out' />" +" </method>" +" <method name='alarm_set_timezone'>" +" <arg type='s' name='tzpath_str' direction='in' />" +" <arg type='i' name='return_code' direction='out' />" +" </method>" +" <method name='alarm_set_global'>" +" <arg type='i' name='alarm_id' direction='in' />" +" <arg type='b' name='global' direction='in' />" +" <arg type='i' name='return_code' direction='out' />" +" </method>" +" <method name='alarm_get_global'>" +" <arg type='i' name='alarm_id' direction='in' />" +" <arg type='b' name='global' direction='out' />" +" <arg type='i' name='return_code' direction='out' />" +" </method>" +" <signal name='alarm_expired'>" +" <arg type='i' name='alarm_id' />" +" <arg type='s' name='app_service_name' />" +" </signal>" +" </interface>" +"</node>"; + +static gboolean __send_noti_to_session_bus(char *service_name, + alarm_id_t alarm_id, int msec, uid_t uid) +{ + int fd; + int ret; + int len; + struct sockaddr_un saddr; + uint8_t *data; + GVariant *gv; + uint8_t *gv_data; + + fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); + if (fd < 0) + return FALSE; + + saddr.sun_family = AF_UNIX; + snprintf(saddr.sun_path, sizeof(saddr.sun_path), + "/run/alarm_agent/%d", uid); + + ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)); + if (ret < 0) { + LOGE("connect failed - (errno %d)", errno); + close(fd); + return FALSE; + } + + gv = g_variant_new("(iis)", alarm_id, msec, service_name); + if (!gv) { + close(fd); + return FALSE; + } + + len = g_variant_get_size(gv); + + gv_data = NULL; + if (len > 0) + gv_data = (uint8_t *)malloc(len); + + if (!gv_data) { + g_variant_unref(gv); + close(fd); + return FALSE; + } + + g_variant_store(gv, gv_data); + g_variant_unref(gv); + + data = (uint8_t *)malloc(len + 4); + if (!data) { + close(fd); + free(gv_data); + return FALSE; + } + + memcpy(data, &len, 4); + memcpy(data + 4, gv_data, len); + free(gv_data); + + if (send(fd, data, len + 4, 0) == -1) { + LOGE("sendto() failed (errno %d)", errno); + free(data); + close(fd); + return FALSE; + } + + free(data); + close(fd); + return TRUE; +} + +static void __on_name_appeared(GDBusConnection *connection, + const gchar *name, + const gchar *name_owner, + gpointer user_data) +{ + SECURE_LOGW("alarm sender name appeared : %s %s", name, name_owner); + + struct watch_info_t *watch_info = (struct watch_info_t *)user_data; + GSList *gs_iter; + __alarm_info_t *entry; + alarm_id_t alarm_id = watch_info->alarm_id; + + g_bus_unwatch_name(watch_info->watch_id); + free(watch_info); + + for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { + entry = gs_iter->data; + if (alarm_id == entry->alarm_id) { + entry->zombie_mode = false; + + _alarm_disable_timer(alarm_context); + _clear_scheduled_alarm_list(); + _alarm_schedule(); + _rtc_set(); + + return; + } + } +} + +static void __alarm_send_noti_to_application_reply( + GObject *source_object, GAsyncResult *res, gpointer user_data) { + + GVariant *message; + GDBusConnection *conn; + GError *error = NULL; + alarm_id_t *reply_alarm_id = (alarm_id_t *)user_data; + char *service_name = NULL; + char *app_unique_name = NULL; + struct watch_info_t *watch_info; + char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; + + GSList *gs_iter; + __alarm_info_t *entry; + bool is_existed = false; + + conn = G_DBUS_CONNECTION(source_object); + message = g_dbus_connection_call_finish(conn, res, &error); + + if (error != NULL && error->code == G_DBUS_ERROR_SERVICE_UNKNOWN) { + for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter) ) { + entry = gs_iter->data; + + if (*reply_alarm_id == entry->alarm_id) { + is_existed = true; + + app_unique_name = entry->app_unique_name; + + if (entry->dst_service_name == NULL) + service_name = entry->app_service_name_mod; + else + service_name = entry->dst_service_name_mod; + + break; + } + } + + + LOGW("failed to send alarm expired noti [%d: %s] [id : %d, %s -> %s]", + error->code, error->message, *reply_alarm_id, + app_unique_name, service_name); + + snprintf(log_message, sizeof(log_message), + "failed to send alarm expired noti [%d: %s] [id : %d, %s -> %s]", + error->code, error->message, *reply_alarm_id, app_unique_name, service_name); + _save_module_log("EXPIRED_FAIL", log_message); + + g_error_free(error); + + if (is_existed) { + entry->zombie_mode = true; + watch_info = (struct watch_info_t *)calloc(1, sizeof(struct watch_info_t)); + watch_info->alarm_id = entry->alarm_id; + watch_info->watch_id = g_bus_watch_name_on_connection( + alarm_context.connection, + service_name, + G_BUS_NAME_WATCHER_FLAGS_NONE, + __on_name_appeared, + NULL, + watch_info, + NULL); + + alarm_context.c_due_time = -1; + _alarm_disable_timer(alarm_context); + _clear_scheduled_alarm_list(); + _alarm_schedule(); + _rtc_set(); + } + } else { + g_variant_unref(message); + } + + free(reply_alarm_id); + +} + +void _alarm_send_noti_to_application_by_dbus(const char *app_service_name, + alarm_id_t alarm_id, int msec, uid_t uid) +{ + char service_name[MAX_SERVICE_NAME_LEN] = {0,}; + gboolean ret; + alarm_id_t *reply_alarm_id; + + if (app_service_name == NULL || strlen(app_service_name) == 0) { + LOGE("This alarm destination is invalid."); + return; + } + + if (_can_skip_expired_cb(alarm_id)) + return; + + strncpy(service_name, app_service_name, sizeof(service_name) - 1); + SECURE_LOGI("[send expired_alarm(alarm_id=%d) to app_service_name(%s)]", + alarm_id, service_name); + + if (uid >= REGULAR_UID_MIN) { + ret = __send_noti_to_session_bus(service_name, alarm_id, msec, uid); + if (ret != TRUE) + LOGE("failed to send alarm expired noti for %d, %s", + alarm_id, service_name); + } else { + reply_alarm_id = (alarm_id_t *)calloc(1, sizeof(alarm_id_t)); + *reply_alarm_id = alarm_id; + g_dbus_connection_call(alarm_context.connection, + service_name, + "/org/tizen/alarm/client", + "org.tizen.alarm.client", + "alarm_expired", + g_variant_new("(iis)", alarm_id, msec, service_name), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + __alarm_send_noti_to_application_reply, + reply_alarm_id); + } +} + +static uid_t __get_caller_uid(const char *name) +{ + guint uid; + GVariant *ret; + GError *error = NULL; + + ret = g_dbus_connection_call_sync( + alarm_context.connection, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "GetConnectionUnixUser", + g_variant_new("(s)", name), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (!ret) { + LOGE("failed to get caller uid"); + if (error) { + LOGE("dbus error message : %s", error->message); + g_error_free(error); + } + return -1; + } + g_variant_get(ret, "(u)", &uid); + g_variant_unref(ret); + + return uid; +} + +static pid_t __get_caller_pid(const char *name) +{ + guint pid; + GVariant *ret; + GError *error = NULL; + + ret = g_dbus_connection_call_sync(alarm_context.connection, + "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus", + "GetConnectionUnixProcessID", + g_variant_new("(s)", name), + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + &error); + if (!ret) { + LOGE("failed to get caller pid"); + if (error) { + LOGE("dbus error message : %s", error->message); + g_error_free(error); + } + return -1; + } + g_variant_get(ret, "(u)", &pid); + g_variant_unref(ret); + + return pid; +} + +void _display_lock_state(char *state, char *flag, unsigned int timeout) +{ + GDBusMessage *msg = NULL; + GDBusMessage *reply = NULL; + GVariant *body = NULL; + int val = -1; + + LOGD("Lock the display not to enter LCD OFF"); + + msg = g_dbus_message_new_method_call( + DEVICED_BUS_NAME, + DEVICED_PATH_DISPLAY, + DEVICED_INTERFACE_DISPLAY, + DEVICED_LOCK_STATE); + if (!msg) { + LOGE("g_dbus_message_new_method_call() is failed. (%s:%s-%s)", + DEVICED_BUS_NAME, DEVICED_INTERFACE_DISPLAY, DEVICED_LOCK_STATE); + return; + } + + g_dbus_message_set_body( + msg, g_variant_new("(sssi)", state, flag, "NULL", timeout)); + + reply = g_dbus_connection_send_message_with_reply_sync( + alarm_context.connection, + msg, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + DEVICED_DBUS_REPLY_TIMEOUT, NULL, NULL, NULL); + if (!reply) { + LOGE("No reply.\ + g_dbus_connection_send_message_with_reply_sync() is failed."); + } else { + body = g_dbus_message_get_body(reply); + if (!body) { + LOGE("g_dbus_message_get_body() is failed."); + } else { + g_variant_get(body, "(i)", &val); + if (val != 0) { + LOGE("Failed to lock display"); + } else { + LOGD("Lock LCD OFF is successfully done"); + } + } + } + + g_dbus_connection_flush_sync(alarm_context.connection, NULL, NULL); + g_object_unref(msg); + if (reply) + g_object_unref(reply); +} + +void _display_unlock_state(char *state, char *flag) +{ + GDBusMessage *msg = NULL; + GDBusMessage *reply = NULL; + GVariant *body = NULL; + int val = -1; + + LOGD("Unlock the display from LCD OFF"); + + msg = g_dbus_message_new_method_call( + DEVICED_BUS_NAME, + DEVICED_PATH_DISPLAY, + DEVICED_INTERFACE_DISPLAY, + DEVICED_UNLOCK_STATE); + if (!msg) { + LOGE("g_dbus_message_new_method_call() is failed. (%s:%s-%s)", + DEVICED_BUS_NAME, DEVICED_INTERFACE_DISPLAY, DEVICED_UNLOCK_STATE); + return; + } + + g_dbus_message_set_body(msg, g_variant_new("(ss)", state, flag)); + + reply = g_dbus_connection_send_message_with_reply_sync( + alarm_context.connection, + msg, + G_DBUS_SEND_MESSAGE_FLAGS_NONE, + DEVICED_DBUS_REPLY_TIMEOUT, NULL, NULL, NULL); + if (!reply) { + LOGE("No reply.\ + g_dbus_connection_send_message_with_reply_sync() is failed."); + } else { + body = g_dbus_message_get_body(reply); + if (!body) { + LOGE("g_dbus_message_get_body() is failed."); + } else { + g_variant_get(body, "(i)", &val); + if (val != 0) { + LOGE("Failed to unlock display"); + } else { + LOGD("Unlock LCD OFF is successfully done"); + } + } + } + + g_dbus_connection_flush_sync(alarm_context.connection, NULL, NULL); + g_object_unref(msg); + if (reply) + g_object_unref(reply); +} + +static void handle_method_call(GDBusConnection *connection, + const gchar *sender, const gchar *object_path, + const gchar *interface_name, const gchar *method_name, + GVariant *parameters, GDBusMethodInvocation *invoc, + gpointer user_data) +{ + int ret; + int num_of_alarm; + int alarm_id; + const char *name = g_dbus_method_invocation_get_sender(invoc); + uid_t uid = __get_caller_uid(name); + pid_t pid = __get_caller_pid(name); + + if (g_strcmp0(method_name, "alarm_create_periodic") == 0) { + ret = alarm_manager_alarm_create_periodic(parameters, uid, pid, &alarm_id); + g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, ret)); + } else if (g_strcmp0(method_name, "alarm_create") == 0) { + ret = alarm_manager_alarm_create(parameters, uid, pid, &alarm_id); + g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, ret)); + } else if (g_strcmp0(method_name, "alarm_create_appsvc") == 0) { + ret = alarm_manager_alarm_create_appsvc(parameters, uid, pid, &alarm_id); + g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, ret)); + } else if (g_strcmp0(method_name, "alarm_create_noti") == 0) { + const char *notification_priv = "http://tizen.org/privilege/notification"; + ret = _cynara_check(invoc, notification_priv, pid); + if (ret == ALARMMGR_RESULT_SUCCESS) { + ret = alarm_manager_alarm_create_noti(parameters, uid, pid, &alarm_id); + } + g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", alarm_id, ret)); + } else if (g_strcmp0(method_name, "alarm_delete") == 0) { + ret = alarm_manager_alarm_delete(parameters, uid, pid); + g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ret)); + } else if (g_strcmp0(method_name, "alarm_delete_all") == 0) { + ret = alarm_manager_alarm_delete_all(parameters, uid, pid); + g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ret)); + } else if (g_strcmp0(method_name, "alarm_update") == 0) { + ret = alarm_manager_alarm_update(parameters, uid, pid); + g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ret)); + } else if (g_strcmp0(method_name, "alarm_get_number_of_ids") == 0) { + ret = alarm_manager_alarm_get_number_of_ids(uid, pid, &num_of_alarm); + g_dbus_method_invocation_return_value(invoc, g_variant_new("(ii)", num_of_alarm, ret)); + } else if (g_strcmp0(method_name, "alarm_get_list_of_ids") == 0) { + GVariant *arr = NULL; + + ret = alarm_manager_alarm_get_list_of_ids(parameters, uid, pid, &arr, &num_of_alarm); + g_dbus_method_invocation_return_value(invoc, g_variant_new("(@aiii)", arr, num_of_alarm, ret)); + } else if (g_strcmp0(method_name, "alarm_get_appsvc_info") == 0) { + gchar *b_data = NULL; + + ret = alarm_manager_alarm_get_appsvc_info(parameters, uid, &b_data); + g_dbus_method_invocation_return_value(invoc, g_variant_new("(si)", b_data, ret)); + if (b_data) + free(b_data); + } else if (g_strcmp0(method_name, "alarm_get_noti_info") == 0) { + gchar *noti_data = NULL; + + ret = alarm_manager_alarm_get_noti_info(parameters, uid, ¬i_data); + g_dbus_method_invocation_return_value(invoc, g_variant_new("(si)", noti_data, ret)); + + if (noti_data) + free(noti_data); + } else if (g_strcmp0(method_name, "alarm_get_info") == 0) { + alarm_info_t alarm_info = { 0, }; + + ret = alarm_manager_alarm_get_info(parameters, uid, &alarm_info); + + g_dbus_method_invocation_return_value( + invoc, g_variant_new("(iiiiiiiiiiiixi)", + alarm_info.start.year, alarm_info.start.month, + alarm_info.start.day, alarm_info.start.hour, + alarm_info.start.min, alarm_info.start.sec, + alarm_info.end.year, alarm_info.end.month, + alarm_info.end.day, alarm_info.mode.u_interval.day_of_week, + alarm_info.mode.repeat, alarm_info.alarm_type, + (gint64)alarm_info.reserved_info, ret)); + } else if (g_strcmp0(method_name, "alarm_get_next_duetime") == 0) { + time_t duetime; + ret = alarm_manager_alarm_get_next_duetime(parameters, uid, &duetime); + + g_dbus_method_invocation_return_value(invoc, g_variant_new("(xi)", (gint64)duetime, ret)); + } else if (g_strcmp0(method_name, "alarm_get_all_info") == 0) { + char *db_path = NULL; + + ret = alarm_manager_alarm_get_all_info(uid, &db_path); + g_dbus_method_invocation_return_value(invoc, g_variant_new("(si)", db_path, ret)); + + if (db_path) + free(db_path); + } else if (g_strcmp0(method_name, "alarm_set_rtc_time") == 0) { + _display_lock_state(DEVICED_LCD_OFF, DEVICED_STAY_CUR_STATE, 0); + ret = alarm_manager_alarm_set_rtc_time(parameters); + g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ret)); + _display_unlock_state(DEVICED_LCD_OFF, DEVICED_SLEEP_MARGIN); + } else if (g_strcmp0(method_name, "alarm_set_time") == 0) { + _display_lock_state(DEVICED_LCD_OFF, DEVICED_STAY_CUR_STATE, 0); + ret = alarm_manager_alarm_set_time(parameters, pid); + g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ret)); + _display_unlock_state(DEVICED_LCD_OFF, DEVICED_SLEEP_MARGIN); + } else if (g_strcmp0(method_name, "alarm_set_time_with_propagation_delay") == 0) { + _display_lock_state(DEVICED_LCD_OFF, DEVICED_STAY_CUR_STATE, 0); + ret = alarm_manager_alarm_set_time_with_propagation_delay(parameters, pid); + g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ret)); + _display_unlock_state(DEVICED_LCD_OFF, DEVICED_SLEEP_MARGIN); + } else if (g_strcmp0(method_name, "alarm_set_timezone") == 0) { + _display_lock_state(DEVICED_LCD_OFF, DEVICED_STAY_CUR_STATE, 0); + ret = alarm_manager_alarm_set_timezone(parameters); + g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ret)); + _display_unlock_state(DEVICED_LCD_OFF, DEVICED_SLEEP_MARGIN); + } else if (g_strcmp0(method_name, "alarm_set_global") == 0) { + ret = alarm_manager_alarm_set_global(parameters, uid); + g_dbus_method_invocation_return_value(invoc, g_variant_new("(i)", ret)); + } else if (g_strcmp0(method_name, "alarm_get_global") == 0) { + gboolean global; + + ret = alarm_manager_alarm_get_global(parameters, &global); + g_dbus_method_invocation_return_value(invoc, g_variant_new("(bi)", global, ret)); + } +} + +static const GDBusInterfaceVTable interface_vtable = { + handle_method_call, + NULL, + NULL +}; + +static void __on_bus_name_acquired(GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + LOGD("bus acquired(%s)", name); + + guint reg_id = 0; + GError *error = NULL; + + reg_id = g_dbus_connection_register_object(connection, + ALARM_MGR_DBUS_PATH, + introspection_data->interfaces[0], + &interface_vtable, + NULL, NULL, &error); + if (reg_id == 0) { + LOGE("g_dbus_connection_register_object error(%s)", error->message); + g_error_free(error); + } +} + +static void __on_bus_name_owner_changed(GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + GSList *entry = NULL; + __expired_alarm_t *expire_info = NULL; + char *service_name = NULL; + + /* On expiry, the killed app can be launched by aul. Then, the owner of the bus name which was registered by the app is changed. + * In this case, "NameOwnerChange" signal is broadcasted. */ + if (signal_name && strcmp(signal_name, "NameOwnerChanged") == 0) { + g_variant_get(parameters, "(&sss)", &service_name, NULL, NULL); + + for (entry = g_expired_alarm_list; entry; entry = entry->next) { + if (entry->data) { + expire_info = (__expired_alarm_t *) entry->data; + SECURE_LOGD("expired service(%s), owner changed service(%s)", + expire_info->service_name, service_name); + + if (strcmp(expire_info->service_name, service_name) == 0) { + SECURE_LOGE("expired service name(%s) alarm_id (%d)", + expire_info->service_name, expire_info->alarm_id); + _alarm_send_noti_to_application_by_dbus( + expire_info->service_name, + expire_info->alarm_id, + 0, + expire_info->uid); + g_expired_alarm_list = + g_slist_remove(g_expired_alarm_list, entry->data); + g_free(expire_info); + } + } + } + } +} + +bool _initialize_dbus(void) +{ + GDBusConnection *connection = NULL; + GError *error = NULL; + guint subsc_id; + guint owner_id; + LOGD("__initialize_dbus Enter"); + + connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error); + if (connection == NULL) { + LOGE("g_bus_get_sync() is failed"); + if (error) { + LOGE("dbus error message : %s", error->message); + g_error_free(error); + } + return false; + } + + subsc_id = g_dbus_connection_signal_subscribe(connection, + "org.freedesktop.DBus", "org.freedesktop.DBus", + "NameOwnerChanged", "/org/freedesktop/DBus", NULL, + G_DBUS_SIGNAL_FLAGS_NONE, __on_bus_name_owner_changed, NULL, NULL); + if (subsc_id == 0) { + LOGE("Subscribing to signal for invoking callback is failed."); + g_object_unref(connection); + return false; + } + + introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, &error); + if (!introspection_data) { + LOGE("g_dbus_node_info_new_for_xml error(%s)", error->message); + g_object_unref(connection); + g_error_free(error); + return false; + } + + owner_id = g_bus_own_name_on_connection(connection, + ALARM_MGR_DBUS_NAME, G_BUS_NAME_OWNER_FLAGS_NONE, + __on_bus_name_acquired, NULL, NULL, NULL); + + if (owner_id == 0) { + LOGE("Acquiring the own name is failed."); + g_dbus_node_info_unref(introspection_data); + g_object_unref(connection); + return false; + } + + alarm_context.connection = connection; + + return true; +} diff --git a/server/alarm-manager-dbus.h b/server/alarm-manager-dbus.h new file mode 100644 index 0000000..85f23b8 --- /dev/null +++ b/server/alarm-manager-dbus.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2019 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. + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib.h> +#include <gio/gio.h> + +/* display lock and unlock */ +#define DEVICED_BUS_NAME "org.tizen.system.deviced" +#define DEVICED_PATH_DISPLAY "/Org/Tizen/System/DeviceD/Display" +#define DEVICED_INTERFACE_DISPLAY "org.tizen.system.deviced.display" +#define DEVICED_LOCK_STATE "lockstate" +#define DEVICED_UNLOCK_STATE "unlockstate" +#define DEVICED_DBUS_REPLY_TIMEOUT (120*1000) +#define DEVICED_LCD_OFF "lcdoff" +#define DEVICED_STAY_CUR_STATE "staycurstate" +#define DEVICED_SLEEP_MARGIN "sleepmargin" + +bool _initialize_dbus(void); + +void _alarm_send_noti_to_application_by_dbus(const char *app_service_name, + alarm_id_t alarm_id, int msec, uid_t uid); + +void _display_lock_state(char *state, char *flag, unsigned int timeout); +void _display_unlock_state(char *state, char *flag); + +#ifdef __cplusplus +} +#endif + diff --git a/server/alarm-manager-main.c b/server/alarm-manager-main.c new file mode 100644 index 0000000..7e11e8c --- /dev/null +++ b/server/alarm-manager-main.c @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2019 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 <stdlib.h> +#include <glib.h> + +#include "alarm-internal.h" + + +int main() +{ + GMainLoop *mainloop = NULL; + + LOGD("Enter main loop\n"); + +#ifdef TIZEN_TEST_GCOV + setenv("GCOV_PREFIX", "/tmp/daemon", 1); +#endif + + mainloop = g_main_loop_new(NULL, FALSE); + + _alarm_initialize(); + + g_main_loop_run(mainloop); + + return 0; +} diff --git a/alarm-manager-schedule.c b/server/alarm-manager-schedule.c index 6750a58..68b9180 100644 --- a/alarm-manager-schedule.c +++ b/server/alarm-manager-schedule.c @@ -1,10 +1,5 @@ /* - * alarm-manager - * - * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. - * - * Contact: Venkatesha Sarpangala <sarpangala.v@samsung.com>, Jayoun Lee <airjany@samsung.com>, - * Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com> + * Copyright (c) 2000 - 2017 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. @@ -17,9 +12,7 @@ * 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<time.h> @@ -31,8 +24,9 @@ #include"alarm.h" #include"alarm-internal.h" -#define WAKEUP_ALARM_APP_ID "org.tizen.alarm.ALARM" /*alarm ui - application's alarm's dbus_service name instead of 21 value */ +#include"alarm-manager-db.h" +#include"alarm-manager-util.h" + #define DST_TIME_DIFF 1 extern __alarm_server_context_t alarm_context; @@ -45,78 +39,32 @@ static time_t __alarm_next_duetime_annually(__alarm_info_t *__alarm_info); static time_t __alarm_next_duetime_monthly(__alarm_info_t *__alarm_info); static time_t __alarm_next_duetime_weekly(__alarm_info_t *__alarm_info); static bool __find_next_alarm_to_be_scheduled(time_t *min_due_time); -bool _alarm_schedule(void); -bool _clear_scheduled_alarm_list() +void _clear_scheduled_alarm_list() { g_slist_free_full(g_scheduled_alarm_list, free); g_scheduled_alarm_list = NULL; - - return true; -} - -bool _init_scheduled_alarm_list() -{ - _clear_scheduled_alarm_list(); - - return true; } -bool _add_to_scheduled_alarm_list(__alarm_info_t *__alarm_info) +void _add_to_scheduled_alarm_list(__alarm_info_t *__alarm_info) { - /* - * 20080328. Sewook Park(sewook7.park@samsung.com) - * When multiple alarms are expired at same time, dbus rpc call for alarm - * ui should be invoked first.(Ui conflicting manager cannot manage the - * different kinds of alarm popups(wake up alarm/org alarm) correctly, - * when they are displayed at same time)So when arranging the schedule - * alarm list, wake up alarm element is located ahead. - */ - - bool prior = false; - gint count = 0; - GSList *iter = NULL; __scheduled_alarm_t *alarm = NULL; - __scheduled_alarm_t *entry = NULL; - alarm = g_malloc(sizeof(__scheduled_alarm_t)); - if (alarm == NULL) - return false; + alarm = (__scheduled_alarm_t *)g_malloc(sizeof(__scheduled_alarm_t)); + if (alarm == NULL) { + LOGE("Out of memory"); + return; + } alarm->used = true; alarm->alarm_id = __alarm_info->alarm_id; alarm->uid = __alarm_info->uid; - alarm->pid = __alarm_info->pid; alarm->__alarm_info = __alarm_info; - SECURE_LOGD("%s :alarm->uid =%d, alarm->pid =%d, app_service_name=%s\n", - __FUNCTION__, alarm->uid, alarm->pid, - alarm->__alarm_info->app_service_name); - - if (alarm->__alarm_info->app_service_name && - strcmp(WAKEUP_ALARM_APP_ID, alarm->__alarm_info->app_service_name)) { - g_scheduled_alarm_list = g_slist_append(g_scheduled_alarm_list, alarm); - } else { - for (iter = g_scheduled_alarm_list; iter != NULL; iter = g_slist_next(iter)) { - count++; - entry = iter->data; - if (entry->__alarm_info->app_service_name && - strcmp(WAKEUP_ALARM_APP_ID, entry->__alarm_info->app_service_name)) { - prior = true; - break; - } - } - - if (!prior) { - g_scheduled_alarm_list = g_slist_append(g_scheduled_alarm_list, alarm); - ALARM_MGR_LOG_PRINT("appended : prior is %d\tcount is %d\n", prior, count); - } else { - g_scheduled_alarm_list = g_slist_insert(g_scheduled_alarm_list, alarm, count - 1); - ALARM_MGR_LOG_PRINT("appended : prior is %d\tcount is %d\n", prior, count); - } - } + SECURE_LOGD("%s :alarm->uid =%d, app_service_name=%s\n", + __FUNCTION__, alarm->uid, alarm->__alarm_info->app_service_name); - return true; + g_scheduled_alarm_list = g_slist_append(g_scheduled_alarm_list, alarm); } bool _remove_from_scheduled_alarm_list(uid_t uid, alarm_id_t alarm_id) @@ -126,7 +74,7 @@ bool _remove_from_scheduled_alarm_list(uid_t uid, alarm_id_t alarm_id) __scheduled_alarm_t *alarm = NULL; for (iter = g_scheduled_alarm_list; iter != NULL; iter = g_slist_next(iter)) { - alarm = iter->data; + alarm = (__scheduled_alarm_t *)iter->data; if (alarm->uid == uid && alarm->alarm_id == alarm_id) { g_scheduled_alarm_list = g_slist_remove(g_scheduled_alarm_list, iter->data); free(alarm); @@ -151,7 +99,7 @@ static time_t __alarm_next_duetime_once(__alarm_info_t *__alarm_info) int current_dst = 0; if ((__alarm_info->alarm_info.alarm_type & ALARM_TYPE_RELATIVE) && __alarm_info->start != 0) { - ALARM_MGR_EXCEPTION_PRINT("Final due_time = %ld, %s", + LOGE("Final due_time = %ld, %s", __alarm_info->start, ctime(&__alarm_info->start)); return __alarm_info->start; } @@ -174,7 +122,7 @@ static time_t __alarm_next_duetime_once(__alarm_info_t *__alarm_info) due_time = mktime(&duetime_tm); if (!(due_time > current_time)) due_time = due_time + 60 * 60 * 24; - } else /*specific date*/ { + } else { duetime_tm.tm_year = start->year - 1900; duetime_tm.tm_mon = start->month - 1; duetime_tm.tm_mday = start->day; @@ -182,30 +130,30 @@ static time_t __alarm_next_duetime_once(__alarm_info_t *__alarm_info) } if (due_time <= current_time) { - ALARM_MGR_EXCEPTION_PRINT("duetime is less than or equal to current time. current_dst = %d", current_dst); - duetime_tm.tm_isdst = 0; /* DST off */ + LOGW("duetime is less than or equal to current time. current_dst = %d", current_dst); + duetime_tm.tm_isdst = 0; due_time_tmp = mktime(&duetime_tm); localtime_r(&due_time_tmp, &tmp_tm); - ALARM_MGR_LOG_PRINT("%d:%d:%d. duetime = %ld", tmp_tm.tm_hour, tmp_tm.tm_min, tmp_tm.tm_sec, due_time); + LOGD("%d:%d:%d. duetime = %ld", tmp_tm.tm_hour, tmp_tm.tm_min, tmp_tm.tm_sec, due_time); if (tmp_tm.tm_hour == start->hour && tmp_tm.tm_min == start->min && tmp_tm.tm_sec == start->sec) { due_time = due_time_tmp; - ALARM_MGR_EXCEPTION_PRINT("due_time = %ld", due_time); + LOGW("due_time = %ld", due_time); } } else { localtime_r(&due_time, &tmp_tm); - ALARM_MGR_LOG_PRINT("%d:%d:%d. current_dst = %d, duetime_dst = %d", tmp_tm.tm_hour, tmp_tm.tm_min, tmp_tm.tm_sec, current_dst, tmp_tm.tm_isdst); + LOGD("%d:%d:%d. current_dst = %d, duetime_dst = %d", tmp_tm.tm_hour, tmp_tm.tm_min, tmp_tm.tm_sec, current_dst, tmp_tm.tm_isdst); if (current_dst == 1 && tmp_tm.tm_isdst == 1 && tmp_tm.tm_hour == start->hour + 1) { /* When the calculated duetime is forwarded 1hour due to DST, Adds 23hours. */ due_time += 60 * 60 * 23; localtime_r(&due_time, &duetime_tm); - ALARM_MGR_EXCEPTION_PRINT("due_time = %ld", due_time); + LOGW("due_time = %ld", due_time); } } - ALARM_MGR_EXCEPTION_PRINT("Final due_time = %ld, %s", due_time, ctime(&due_time)); + LOGW("Final due_time = %ld, %s", due_time, ctime(&due_time)); return due_time; } @@ -219,7 +167,6 @@ static time_t __alarm_next_duetime_repeat(__alarm_info_t *__alarm_info) alarm_date_t *start = &alarm_info->start; time(¤t_time); - /*localtime_r(¤t_time, &duetime_tm); */ duetime_tm.tm_hour = start->hour; duetime_tm.tm_min = start->min; @@ -244,7 +191,7 @@ static time_t __alarm_next_duetime_repeat(__alarm_info_t *__alarm_info) while (__alarm_info->start > due_time || current_time > due_time || ((!is_time_changed) && (current_time == due_time))) { if (due_time + alarm_info->mode.u_interval.interval < due_time) { - ALARM_MGR_LOG_PRINT("time_t OVERFLOW!! duetime = %ld", due_time); + LOGD("time_t OVERFLOW!! duetime = %ld", due_time); due_time = -1; break; } @@ -291,7 +238,7 @@ static time_t __alarm_next_duetime_annually(__alarm_info_t *__alarm_info) duetime_tm.tm_year += 1; due_time = mktime(&duetime_tm); if (due_time < 0) { - ALARM_MGR_LOG_PRINT("time_t OVERFLOW!! duetime = %ld", due_time); + LOGD("time_t OVERFLOW!! duetime = %ld", due_time); break; } } @@ -332,7 +279,7 @@ static time_t __alarm_next_duetime_monthly(__alarm_info_t *__alarm_info) } due_time = mktime(&duetime_tm); if (due_time < 0) { - ALARM_MGR_LOG_PRINT("time_t OVERFLOW!! duetime = %ld", due_time); + LOGD("time_t OVERFLOW!! duetime = %ld", due_time); break; } } @@ -376,10 +323,10 @@ static time_t __alarm_next_duetime_weekly(__alarm_info_t *__alarm_info) due_time = mktime(&duetime_tm); localtime_r(&due_time, &tmp_tm); - ALARM_MGR_LOG_PRINT("%d:%d:%d. duetime = %ld, isdst = %d", tmp_tm.tm_hour, tmp_tm.tm_min, tmp_tm.tm_sec, due_time, tmp_tm.tm_isdst); + LOGD("%d:%d:%d. duetime = %ld, isdst = %d", tmp_tm.tm_hour, tmp_tm.tm_min, tmp_tm.tm_sec, due_time, tmp_tm.tm_isdst); if (due_time <= current_time) { - ALARM_MGR_EXCEPTION_PRINT("duetime is less than or equal to current time. current_dst = %d", current_dst); + LOGW("duetime is less than or equal to current time. current_dst = %d", current_dst); duetime_tm.tm_isdst = 0; due_time = mktime(&duetime_tm); @@ -409,8 +356,7 @@ static time_t __alarm_next_duetime_weekly(__alarm_info_t *__alarm_info) wday = before_tm.tm_wday; - /* CQ defect(72810) : only one time alarm function is not working - under all recurrence_disabled. */ + /* Only one time alarm function with recurrence_disabled. */ if (due_time > current_time && mode->u_interval.day_of_week == 0) return due_time; @@ -430,7 +376,7 @@ static time_t __alarm_next_duetime_weekly(__alarm_info_t *__alarm_info) day = 0; } - ALARM_MGR_LOG_PRINT("interval : %d\n", interval); + LOGD("interval : %d\n", interval); due_time += 60 * 60 * 24 * interval; } @@ -444,11 +390,11 @@ static time_t __alarm_next_duetime_weekly(__alarm_info_t *__alarm_info) else if (before_tm.tm_isdst == 0 && after_tm.tm_isdst == 1) due_time -= 60 * 60; /* Subtract an hour */ - ALARM_MGR_LOG_PRINT("Final due_time = %ld", due_time); + LOGD("Final due_time = %ld", due_time); return due_time; } -time_t _alarm_next_duetime(__alarm_info_t *__alarm_info) +void _alarm_set_next_duetime(__alarm_info_t *__alarm_info) { int is_dst = 0; time_t current_time = 0; @@ -464,7 +410,7 @@ time_t _alarm_next_duetime(__alarm_info_t *__alarm_info) if (cur_tm && cur_tm->tm_isdst > 0) is_dst = 1; - ALARM_MGR_LOG_PRINT("mode->repeat is %d\n", mode->repeat); + LOGD("mode->repeat is %d\n", mode->repeat); if (mode->repeat == ALARM_REPEAT_MODE_ONCE) { due_time = __alarm_next_duetime_once(__alarm_info); @@ -477,34 +423,34 @@ time_t _alarm_next_duetime(__alarm_info_t *__alarm_info) } else if (mode->repeat == ALARM_REPEAT_MODE_WEEKLY) { due_time = __alarm_next_duetime_weekly(__alarm_info); } else { - ALARM_MGR_EXCEPTION_PRINT("repeat mode(%d) is wrong\n", + LOGE("repeat mode(%d) is wrong\n", mode->repeat); - return 0; + __alarm_info->due_time = due_time; + return; } if (mode->repeat != ALARM_REPEAT_MODE_WEEKLY && mode->repeat != ALARM_REPEAT_MODE_ONCE) { due_tm = localtime_r(&due_time, &tm); if (is_dst == 0 && due_tm && due_tm->tm_isdst == 1) { - ALARM_MGR_LOG_PRINT("DST alarm found, enable\n"); + LOGD("DST alarm found, enable\n"); due_tm->tm_hour = due_tm->tm_hour - DST_TIME_DIFF; } else if (is_dst == 1 && due_tm && due_tm->tm_isdst == 0) { - ALARM_MGR_LOG_PRINT("DST alarm found. disable\n"); + LOGD("DST alarm found. disable\n"); due_tm->tm_hour = due_tm->tm_hour + DST_TIME_DIFF; } if (due_tm) due_time = mktime(due_tm); } - ALARM_MGR_LOG_PRINT("alarm_id: %d, next duetime: %ld", __alarm_info->alarm_id, due_time); + LOGD("alarm_id: %d, next duetime: %ld", __alarm_info->alarm_id, due_time); if (__alarm_info->end != 0 && __alarm_info->end < due_time) { - ALARM_MGR_LOG_PRINT("due time > end time"); + LOGD("due time > end time"); __alarm_info->due_time = 0; - return 0; + return; } - __alarm_info->due_time = due_time; - return due_time; + __alarm_info->due_time = due_time; } static bool __find_next_alarm_to_be_scheduled(time_t *min_due_time) @@ -519,55 +465,79 @@ static bool __find_next_alarm_to_be_scheduled(time_t *min_due_time) for (iter = alarm_context.alarms; iter != NULL; iter = g_slist_next(iter)) { - entry = iter->data; + entry = (__alarm_info_t *)iter->data; due_time = entry->due_time; double interval = 0; - SECURE_LOGD("alarm[%d] with duetime(%ld) at current(%ld) pid: (%d)\n", - entry->alarm_id, due_time, current_time, entry->pid); + SECURE_LOGD("alarm[%d] with duetime(%ld) at current(%ld) - (%s) z:%d", + entry->alarm_id, due_time, current_time, + entry->app_unique_name, (int)entry->zombie_mode); + if (due_time == 0) /*0 means this alarm has been disabled*/ { continue; } interval = difftime(due_time, current_time); - if (interval < 0) /*2008.08.06 when the alarm expires, it may makes an error.*/ { - ALARM_MGR_EXCEPTION_PRINT("The duetime of alarm(%d) is OVER.", entry->alarm_id); - continue; + if (interval < 0) /*When the alarm expires, it may makes an error.*/ { + LOGW("The duetime of alarm(%d) is OVER.(z:%d)", + entry->alarm_id, entry->zombie_mode); + + _alarm_set_next_duetime(entry); + if (entry->due_time < current_time) { + const char *dst = entry->callee_pkgid ? entry->callee_pkgid : entry->dst_service_name; + LOGW("The alarm(%d) is removed [unique_name : %s, dst : %s", + entry->alarm_id, entry->app_unique_name, dst); + + if (!(entry->alarm_info.alarm_type & ALARM_TYPE_VOLATILE)) + _delete_alarms(entry->alarm_id); + + _save_alarm_info_log("AUTO_DELETE", entry); + + alarm_context.alarms = g_slist_remove(alarm_context.alarms, iter->data); + _release_alarm_info_t(entry); + continue; + } else { + due_time = entry->due_time; + } + } + if (entry->zombie_mode) + continue; + interval = difftime(due_time, min_time); if ((interval < 0) || min_time == -1) min_time = due_time; } + if (min_time == -1) { + LOGE("[alarm-server][schedule]: There is no alarm to be scheduled."); + return false; + } + *min_due_time = min_time; return true; } -bool _alarm_schedule() +void _alarm_schedule() { time_t due_time = 0; time_t min_time = 0; GSList *iter = NULL; __alarm_info_t *entry = NULL; - __find_next_alarm_to_be_scheduled(&min_time); - - if (min_time == -1) { - ALARM_MGR_EXCEPTION_PRINT("[alarm-server][schedule]: There is no alarm to be scheduled."); - } else { + if (__find_next_alarm_to_be_scheduled(&min_time)) { for (iter = alarm_context.alarms; iter != NULL; iter = g_slist_next(iter)) { - entry = iter->data; + entry = (__alarm_info_t *)iter->data; due_time = entry->due_time; - if (due_time == min_time) + if (due_time == min_time && entry->zombie_mode == false) _add_to_scheduled_alarm_list(entry); } - _alarm_set_timer(&alarm_context, alarm_context.timer, min_time); - } - return true; + _alarm_set_timer(alarm_context.timer, min_time); + } } diff --git a/server/alarm-manager-timer.c b/server/alarm-manager-timer.c new file mode 100644 index 0000000..fd20049 --- /dev/null +++ b/server/alarm-manager-timer.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2000 - 2019 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 <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <signal.h> +#include <string.h> +#include <sys/types.h> +#include <errno.h> +#include <stdint.h> +#include <sys/timerfd.h> +#include <glib.h> + +#include "alarm.h" +#include "alarm-internal.h" +#include "alarm-manager-dbus.h" + +extern __alarm_server_context_t alarm_context; + +bool g_dummy_timer_is_set = false; + +static gboolean __alarm_handler_idle(gpointer user_data) +{ + GPollFD *gpollfd = (GPollFD *) user_data; + uint64_t exp; + time_t current_time; + +#ifdef TIZEN_TEST_GCOV + void __gcov_flush(void); + __gcov_flush(); +#endif + + if (gpollfd == NULL) { + LOGE("gpollfd is NULL"); + return false; + } + + if (read(gpollfd->fd, &exp, sizeof(uint64_t)) < 0) { + LOGE("Reading the fd is failed."); + return false; + } + + _display_lock_state(DEVICED_LCD_OFF, DEVICED_STAY_CUR_STATE, 0); + + if (g_dummy_timer_is_set == true) { + LOGD("dummy alarm timer has expired."); + } else { + LOGD("__alarm_handler_idle"); + _alarm_expired(); + } + + _alarm_schedule(); + + /* + * Previous alarm can be expired late as tolerance of RTC. + * In this case, Expire alarms forcibly if real duetime is same to current time. + */ + time(¤t_time); + if (alarm_context.c_due_time == current_time) { + LOGD("Expire alarms forcibly when duetime is same to current time(%ld).", current_time); + _alarm_expired(); + _alarm_schedule(); + } + + _rtc_set(); + + _display_unlock_state(DEVICED_LCD_OFF, DEVICED_SLEEP_MARGIN); + + return false; +} + + +static void __timer_glib_finalize(GSource *src) +{ + GSList *fd_list; + GPollFD *tmp; + + fd_list = src->poll_fds; + do { + tmp = (GPollFD *) fd_list->data; + g_free(tmp); + + fd_list = fd_list->next; + } while (fd_list); + + return; +} + +static gboolean __timer_glib_check(GSource *src) +{ + GSList *fd_list; + GPollFD *tmp; + + fd_list = src->poll_fds; + do { + tmp = (GPollFD *) fd_list->data; + if (tmp->revents & (G_IO_IN | G_IO_PRI)) + return TRUE; + + fd_list = fd_list->next; + } while (fd_list); + + return FALSE; +} + +static gboolean __timer_glib_dispatch(GSource *src, GSourceFunc callback, + gpointer data) +{ + callback(data); + return TRUE; +} + +static gboolean __timer_glib_prepare(GSource *src, gint *timeout) +{ + return FALSE; +} + +GSourceFuncs funcs = { + .prepare = __timer_glib_prepare, + .check = __timer_glib_check, + .dispatch = __timer_glib_dispatch, + .finalize = __timer_glib_finalize +}; + +int _initialize_timer() +{ + int fd; + GSource *src; + GPollFD *gpollfd; + int ret; + + fd = timerfd_create(CLOCK_REALTIME, 0); + if (fd == -1) { + LOGE("timerfd_create() is failed.\n"); + return -1; + } + src = g_source_new(&funcs, sizeof(GSource)); + + gpollfd = (GPollFD *) g_malloc(sizeof(GPollFD)); + if (gpollfd == NULL) { + LOGE("Out of memory\n"); + return -1; + } + gpollfd->events = G_IO_IN; + gpollfd->fd = fd; + + g_source_add_poll(src, gpollfd); + g_source_set_callback(src, (GSourceFunc) __alarm_handler_idle, + (gpointer) gpollfd, NULL); + g_source_set_priority(src, G_PRIORITY_HIGH); + + ret = g_source_attach(src, NULL); + if (ret == 0) { + LOGE("g_source_attach() is failed.\n"); + return -1; + } + + g_source_unref(src); + + return fd; +} + +void _alarm_disable_timer() +{ + struct itimerspec time_spec; + + time_spec.it_value.tv_sec = 0; + time_spec.it_value.tv_nsec = 0; + time_spec.it_interval.tv_sec = time_spec.it_interval.tv_nsec = 0; + + if (timerfd_settime(alarm_context.timer, 0, &time_spec, NULL) < 0) + LOGE("timerfd_settime has failed : errno(%d).", errno); +} + +void _alarm_set_timer(int timer, time_t due_time) +{ + struct itimerspec time_spec; + time_t current_time; + double interval; + char due_time_r[100] = { 0 }; + struct tm ts_ret; + + time(¤t_time); + + interval = difftime(due_time, current_time); + LOGD("[alarm-server][timer]: remain time from current is %f , due_time is %ld.", interval, due_time); + + /*set timer as absolute time */ + /*we create dummy timer when the interval is longer than one day. */ + /*the timer will be expired in half day. */ + + localtime_r(&due_time, &ts_ret); + + if (interval > 60 * 60 * 24) { + interval = 60 * 60 * 12; + g_dummy_timer_is_set = true; + strftime(due_time_r, 30, "%c", &ts_ret); + LOGD("create dummy alarm timer(%d), due_time(%s)", timer, due_time_r); + } else { + g_dummy_timer_is_set = false; + } + + time_spec.it_value.tv_sec = due_time; + time_spec.it_value.tv_nsec = 0; + time_spec.it_interval.tv_sec = time_spec.it_interval.tv_nsec = 0; + + if (interval > 0 && timerfd_settime(timer, TFD_TIMER_ABSTIME, &time_spec, NULL) != 0) { + LOGE("set timer has failed : timer(%d), due_time(%ld) , errno(%d).", timer, due_time, errno); + } + + /* we set c_due_time to due_time due to allow newly created alarm can + be schedlued when its interval is less than the current alarm */ + alarm_context.c_due_time = due_time; +} diff --git a/server/alarm-manager-util.c b/server/alarm-manager-util.c new file mode 100644 index 0000000..55a078a --- /dev/null +++ b/server/alarm-manager-util.c @@ -0,0 +1,535 @@ +/* + * Copyright (c) 2019 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. + */ + +#define _GNU_SOURCE +#include <fcntl.h> +#include <system_info.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> + +#include <aul.h> +#include <cert-svc/ccert.h> +#include <cert-svc/cinstance.h> +#include <cynara-session.h> +#include <cynara-client.h> +#include <cynara-creds-gdbus.h> +#include <tzplatform_config.h> + +#include "alarm-manager-util.h" + +#define ALARMMGR_LOG_BUFFER_SIZE 10000 +#define ALARMMGR_LOG_BUFFER_STRING_SIZE 400 +#define ALARMMGR_LOG_DIR_PATH "/var/log/appfw/alarmmgr_log/" +#define ALARMMGR_LOG_FILE_PATH "/var/log/appfw/alarmmgr_log/alarmmgr.log" +static int log_index = 0; +static int log_fd = 0; + +static int __bg_category_func(const char *name, void *user_data) +{ + bg_category_cb_info_t *info = (bg_category_cb_info_t *)user_data; + LOGD("appid[%s], bg name = %s", info->appid, name); + if (name && strncmp("enable", name, strlen(name)) && + strncmp("disable", name, strlen(name))) { + info->has_bg = true; + return -1; + } + + return 0; +} + +profile_t _get_profile() +{ + static profile_t saved = PROFILE_UNKNOWN; + char *profileName; + int r; + + if (__builtin_expect(saved != PROFILE_UNKNOWN, 1)) + return saved; + + r = system_info_get_platform_string("http://tizen.org/feature/profile", + &profileName); + if (r != SYSTEM_INFO_ERROR_NONE) { + LOGD("Failed to get profile info. error(%d)", r); + return saved; + } + + switch (*profileName) { + case 'm': + case 'M': + saved = PROFILE_MOBILE; + break; + case 'w': + case 'W': + saved = PROFILE_WEARABLE; + break; + case 't': + case 'T': + saved = PROFILE_TV; + break; + case 'i': + case 'I': + saved = PROFILE_IVI; + break; + default: // common or unknown ==> ALL ARE COMMON. + saved = PROFILE_COMMON; + } + free(profileName); + + return saved; +} + +int _pkg_is_global(const char *callee_pkgid, uid_t uid) +{ + int retval; + int return_code = ERR_ALARM_SYSTEM_FAIL; + pkgmgrinfo_pkginfo_h handle; + + retval = pkgmgrinfo_pkginfo_get_usr_pkginfo(callee_pkgid, uid, &handle); + if (retval != PMINFO_R_OK) { + LOGE("Failed to get pkginfo\n"); + return_code = ERR_ALARM_INVALID_ID; + } else { + bool is_global = 0; + retval = pkgmgrinfo_pkginfo_is_global(handle, &is_global); + if (retval == PMINFO_R_OK && is_global) + return_code = ALARMMGR_RESULT_SUCCESS; + else if (retval == PMINFO_R_OK && !is_global) + return_code = ERR_ALARM_NOT_PERMITTED_APP; + + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + } + + return return_code; +} + +int _cynara_check(GDBusMethodInvocation *invocation, const char *privilege, + pid_t pid) +{ + int ret = 0; + char *user = NULL; + char *client = NULL; + char *client_session = NULL; + cynara *p_cynara = NULL; + const char *sender_unique_name; + GDBusConnection *connection; + + connection = g_dbus_method_invocation_get_connection(invocation); + sender_unique_name = g_dbus_method_invocation_get_sender(invocation); + + ret = cynara_initialize(&p_cynara, NULL); + if (ret != CYNARA_API_SUCCESS) { + LOGE("cynara_initialize() failed : %d", ret); + ret = ERR_ALARM_SYSTEM_FAIL; + goto cynara_out; + } + + ret = cynara_creds_gdbus_get_user(connection, sender_unique_name, + USER_METHOD_DEFAULT, &user); + if (ret != CYNARA_API_SUCCESS) { + LOGE("cynara_creds_gdbus_get_user() failed : %d", ret); + ret = ERR_ALARM_SYSTEM_FAIL; + goto cynara_out; + } + + ret = cynara_creds_gdbus_get_client(connection, sender_unique_name, + CLIENT_METHOD_DEFAULT, &client); + if (ret != CYNARA_API_SUCCESS) { + LOGE("cynara_creds_gdbus_get_client() failed : %d", ret); + ret = ERR_ALARM_SYSTEM_FAIL; + goto cynara_out; + } + + LOGD("user :%s , client :%s ,unique_name : %s, pid() : %d", + user, client, sender_unique_name, pid); + + client_session = cynara_session_from_pid(pid); + if (!client_session) { + LOGE("cynara_session_from_pid() failed : %d", ret); + ret = ERR_ALARM_SYSTEM_FAIL; + goto cynara_out; + } + + ret = cynara_check(p_cynara, client, client_session, user, + privilege); + if (ret == CYNARA_API_ACCESS_ALLOWED) { + LOGD("CYNARA_ACCESS_ALLOWED"); + ret = ALARMMGR_RESULT_SUCCESS; + } + else { + LOGD("CYNARA_NOT_ALLOWED [%d]", ret); + ret = ERR_ALARM_NOT_PERMITTED_APP; + } + +cynara_out: + if (client_session) + g_free(client_session); + if (client) + g_free(client); + if (user) + g_free(user); + if (p_cynara) + cynara_finish(p_cynara); + + return ret; +} + +int _get_pid_from_appid(const char *app_id, uid_t uid) +{ + int pid; + pid = aul_app_get_pid_for_uid(app_id, uid); + if (pid < 0) { + LOGE("aul_app_get_pid_for_uid() is failed. appid %s may not be app. uid : [%d]", app_id, uid); + return 0; + } + + LOGD("app_id:%s [pid:%d]", app_id, pid); + return pid; +} + +char *_get_pkgid_by_appid(const char *app_id, uid_t uid) +{ + pkgmgrinfo_pkginfo_h handle; + char *pkgid = NULL; + char *temp; + + if (pkgmgrinfo_appinfo_get_usr_appinfo(app_id, uid, &handle) == PMINFO_R_OK) { + if (pkgmgrinfo_appinfo_get_pkgid(handle, &temp) == PMINFO_R_OK) { + if (temp) + pkgid = strdup(temp); + } + pkgmgrinfo_appinfo_destroy_appinfo(handle); + } + + return pkgid; +} + +int _is_ui_app(const char *appid, uid_t uid) +{ + int ret = 0; + int found = 0; + char *component = NULL; + pkgmgrinfo_appinfo_h appinfo_h = NULL; + + if (appid == NULL) + return 0; + + ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &appinfo_h); + if (ret < 0) + return 0; + + ret = pkgmgrinfo_appinfo_get_component_type(appinfo_h, &component); + if (ret == 0 && component != NULL && strncmp(component, "uiapp", 5) == 0) + found = 1; + + if (appinfo_h) + pkgmgrinfo_appinfo_destroy_appinfo(appinfo_h); + + return found; +} + +bool _is_app(const char *appid, uid_t uid) +{ + pkgmgrinfo_appinfo_h appinfo_h = NULL; + int ret; + + ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &appinfo_h); + if (ret != PMINFO_R_OK) + return false; + + if (appinfo_h) + pkgmgrinfo_appinfo_destroy_appinfo(appinfo_h); + + return true; +} + +int _compare_api_version(int *result, int pid, uid_t uid) +{ + int ret = 0; + pkgmgrinfo_pkginfo_h pkginfo = NULL; + char pkgid[MAX_PKG_ID_LEN] = {0, }; + char *pkg_version; + + if (aul_app_get_pkgid_bypid_for_uid(pid, pkgid, sizeof(pkgid), uid) != AUL_R_OK) { + LOGE("aul_app_get_pkgid_bypid() is failed. PID %d may not be app.", getpid()); + } else { + ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &pkginfo); + if (ret != PMINFO_R_OK) { + LOGE("Failed to get pkginfo\n"); + } else { + ret = pkgmgrinfo_pkginfo_get_api_version(pkginfo, &pkg_version); + if (ret != PMINFO_R_OK) + LOGE("Failed to check api version [%d]\n", ret); + *result = strverscmp(pkg_version, "2.4"); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); + } + } + return ret; +} + +bool _permit_by_config(pkgmgrinfo_appinfo_h handle, uid_t uid) +{ + if (access(tzplatform_mkpath(TZ_SYS_RO_SHARE, + "alarm-manager/alarm-config-service-restricted"), F_OK) == 0) { + LOGD("This profile restrict alarms for service applications\n"); + return false; + } + + if (access(tzplatform_mkpath(TZ_SYS_RO_SHARE, + "alarm-manager/alarm-config-platform-service-permitted"), F_OK) == 0) { + LOGD("This profile permit alarm for service applications which has platform cert\n"); + char *pkgid; + int r; + const char *cert_value; + pkgmgrinfo_certinfo_h certinfo; + CertSvcInstance instance; + CertSvcCertificate certificate; + CertSvcVisibility visibility = CERTSVC_VISIBILITY_PUBLIC; + + r = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid); + if (r != PMINFO_R_OK) { + LOGE("Failed to get certinfo pkgid"); + return false; + } + + r = pkgmgrinfo_pkginfo_create_certinfo(&certinfo); + if (r != PMINFO_R_OK) { + LOGE("Failed to create certinfo"); + return false; + } + + r = pkgmgrinfo_pkginfo_load_certinfo(pkgid, certinfo, uid); + if (r != PMINFO_R_OK) { + LOGE("Failed to load certinfo"); + pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); + return false; + } + + r = pkgmgrinfo_pkginfo_get_cert_value(certinfo, + PMINFO_DISTRIBUTOR_ROOT_CERT, &cert_value); + if (r != PMINFO_R_OK || cert_value == NULL) { + LOGE("Failed to get cert value"); + pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); + return false; + } + + r = certsvc_instance_new(&instance); + if (r != CERTSVC_SUCCESS) { + LOGE("certsvc_instance_new() is failed."); + pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); + return false; + } + + r = certsvc_certificate_new_from_memory(instance, + (const unsigned char *)cert_value, + strlen(cert_value), + CERTSVC_FORM_DER_BASE64, + &certificate); + if (r != CERTSVC_SUCCESS) { + LOGE("certsvc_certificate_new_from_memory() is failed."); + pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); + certsvc_instance_free(instance); + return false; + } + + r = certsvc_certificate_get_visibility(certificate, &visibility); + if (r != CERTSVC_SUCCESS) + LOGE("certsvc_certificate_get_visibility() is failed."); + + pkgmgrinfo_pkginfo_destroy_certinfo(certinfo); + certsvc_instance_free(instance); + certsvc_certificate_free(certificate); + + LOGW("visibility is %d", visibility); + if (visibility & CERTSVC_VISIBILITY_PLATFORM) { + return true; + } + } + + if (access(tzplatform_mkpath(TZ_SYS_RO_SHARE, + "alarm-manager/alarm-config-all-service-permitted"), F_OK) == 0) { + LOGD("This profile permit alarms for all service applications\n"); + return true; + } + + return false; +} + +bool _is_permitted(const char *app_id, int alarm_type, uid_t uid) +{ + pkgmgrinfo_appinfo_h handle = NULL; + int ret; + bool _return = false; + + if (app_id == NULL) { + LOGE("app_id is NULL. Only expicit launch is permitted\n"); + return false; + } + + ret = pkgmgrinfo_appinfo_get_usr_appinfo(app_id, uid, &handle); + if (ret != PMINFO_R_OK) { + LOGE("Failed to get appinfo [%s]\n", app_id); + } else { + char *app_type = NULL; + ret = pkgmgrinfo_appinfo_get_component_type(handle, &app_type); + if (app_type && strcmp("uiapp", app_type) == 0) { + if (alarm_type & ALARM_TYPE_EXACT_SERVICE_APP) { + LOGE("[%s] is ui application.\ + But alarm_type is ALARM_TYPE_EXACT_SERVICE_APP.\ + soit is not allowed", app_id); + _return = false; + goto out; + } + LOGD("[%s] is ui application. It is allowed", app_id); + _return = true; + goto out; + } else if (app_type && strcmp("svcapp", app_type) == 0) { + LOGD("[%s] is service application.", app_id); + + if (_permit_by_config(handle, uid)) { + LOGD("service applications are allowed"); + _return = true; + goto out; + } + + bg_category_cb_info_t info = { + .appid = app_id, + .has_bg = false + }; + + if (alarm_type & ALARM_TYPE_INEXACT || alarm_type & ALARM_TYPE_EXACT_SERVICE_APP) { + ret = pkgmgrinfo_appinfo_foreach_background_category(handle, __bg_category_func, &info); + if (ret == PMINFO_R_OK && info.has_bg) { + LOGD("[%s] has background categories. It is allowed", app_id); + _return = true; + goto out; + } else { + LOGE("Failed to foreach background category. [%s] is not allowed", app_id); + } + } + } + } + +out: + if (handle) + pkgmgrinfo_appinfo_destroy_appinfo(handle); + + return _return; +} + +void _initialize_module_log(void) +{ +#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG + char buf[1024]; + + if (access(ALARMMGR_LOG_DIR_PATH, F_OK)) { + LOGE("Not exist(%s)", ALARMMGR_LOG_DIR_PATH); + + if (mkdir(ALARMMGR_LOG_DIR_PATH, (S_IRUSR | S_IWUSR | S_IXUSR | + S_IRGRP | S_IWGRP | S_IXGRP))) { + LOGE("Failed to create directory(%s). errno(%d)", + ALARMMGR_LOG_DIR_PATH, errno); + return; + } + } + + log_fd = open(ALARMMGR_LOG_FILE_PATH, O_CREAT | O_WRONLY, 0644); + if (log_fd == -1) { + LOGE("Opening the file for alarmmgr log is failed. err: %s", strerror_r(errno, buf, sizeof(buf))); + return; + } + + int offset = lseek(log_fd, 0, SEEK_END); + if (offset != 0) { + log_index = (int)(offset / ALARMMGR_LOG_BUFFER_STRING_SIZE); + if (log_index >= ALARMMGR_LOG_BUFFER_SIZE) { + log_index = 0; + lseek(log_fd, 0, SEEK_SET); + } + } +#endif /* _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG */ + return; +} + +void _save_module_log(const char *tag, const char *message) +{ +#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG + char buffer[ALARMMGR_LOG_BUFFER_STRING_SIZE] = {0,}; + time_t now; + char buf[1024]; + char *time_str; + + if (log_fd == -1) { + LOGE("The file is not ready."); + return; + } + + if (log_index != 0) + lseek(log_fd, 0, SEEK_CUR); + else + lseek(log_fd, 0, SEEK_SET); + + time(&now); + time_str = ctime(&now); + if (time_str) + time_str[strlen(time_str) - 1] = '\0'; /* to avoid new line */ + + snprintf(buffer, ALARMMGR_LOG_BUFFER_STRING_SIZE, "[%-6d]%s\t%s\t : %ld %s\n", log_index, tag, message, now, time_str); + + SECURE_LOGW("%s", buffer); + int ret = write(log_fd, buffer, strlen(buffer)); + if (ret < 0) { + LOGE("Writing the alarmmgr log is failed. err: %s", strerror_r(errno, buf, sizeof(buf))); + return; + } + + if (++log_index >= ALARMMGR_LOG_BUFFER_SIZE) + log_index = 0; +#endif /* _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG */ + return; +} + +void _save_alarm_info_log(const char *tag, __alarm_info_t *info) +{ +#ifdef _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG + char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; + char *due_time_str = ctime(&(info->due_time)); + if (due_time_str) + due_time_str[strlen(due_time_str) - 1] = '\0'; /* to avoid new line */ + + char *timebuf = strdup(ctime(&info->due_time)); + if (timebuf) + timebuf[strlen(timebuf) - 1] = '\0'; /* to avoid new line */ + + snprintf(log_message, sizeof(log_message), + "alarmID: %d, uid: %d, caller : %s -> callee : %s, " + "dst_name %s, dst_mod %s, " + "type 0x%x, mode %d, " + "interval:%ld, duetime: %ld %s", + info->alarm_id, info->uid, info->app_unique_name, info->callee_pkgid, + info->dst_service_name, info->dst_service_name_mod, + info->alarm_info.alarm_type, info->alarm_info.mode.repeat, + info->alarm_info.mode.u_interval.interval, info->due_time, timebuf); + + if (timebuf) + free(timebuf); + + _save_module_log(tag, log_message); +#endif /* _APPFW_FEATURE_ALARM_MANAGER_MODULE_LOG */ + return; +} + diff --git a/server/alarm-manager-util.h b/server/alarm-manager-util.h new file mode 100644 index 0000000..1ff1f8e --- /dev/null +++ b/server/alarm-manager-util.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019 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. + */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib.h> +#include <pkgmgr-info.h> +#include <sys/un.h> +#include <sys/types.h> +#include <stdbool.h> + +#include "alarm-internal.h" + +#define ALARMMGR_LOG_TAG_SIZE 20 +#define ALARMMGR_LOG_MESSAGE_SIZE 330 + +profile_t _get_profile(); +int _cynara_check(GDBusMethodInvocation *invocation, const char* privilege, + pid_t pid); +char* _get_pkgid_by_appid(const char* app_id, uid_t uid); +int _pkg_is_global(const char* callee_pkgid, uid_t uid); +int _is_ui_app(const char *appid, uid_t uid); +bool _is_app(const char *appid, uid_t uid); +int _compare_api_version(int *result, int pid, uid_t uid); +bool _permit_by_config(pkgmgrinfo_appinfo_h handle, uid_t uid); +bool _is_permitted(const char *app_id, int alarm_type, uid_t uid); +int _get_pid_from_appid(const char *app_id, uid_t uid); + +void _initialize_module_log(void); +void _save_module_log(const char *tag, const char *messgae); +void _save_alarm_info_log(const char *tag, __alarm_info_t *info); + +#ifdef __cplusplus +} +#endif + diff --git a/server/alarm-manager.c b/server/alarm-manager.c new file mode 100755 index 0000000..4ce7e5f --- /dev/null +++ b/server/alarm-manager.c @@ -0,0 +1,3138 @@ +/* + * Copyright (c) 2000 - 2019 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. + */ +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <signal.h> +#include <sys/un.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <unistd.h> +#include <errno.h> +#include <linux/rtc.h> +#include <sys/ioctl.h> +#include <fcntl.h> + +#include <tzplatform_config.h> +#include <aul.h> +#include <aul_svc.h> +#include <bundle.h> +#include <bundle_internal.h> +#include <vconf.h> +#include <vconf-keys.h> +#include <package-manager.h> +#include <device/display.h> +#include <systemd/sd-login.h> +#include <eventsystem.h> +#include <notification.h> +#include <notification_ipc.h> +#include <notification_internal.h> + +#include "alarm.h" +#include "alarm-internal.h" +#include "alarm-manager-db.h" +#include "alarm-manager-util.h" +#include "alarm-manager-dbus.h" + +#if !GLIB_CHECK_VERSION(2, 31, 0) +#include <glib/gmacros.h> +#endif + +#define BILLION 1000000000 /* for calculating nano seconds */ + +/* link path for timezone info */ +#define TIMEZONE_INFO_LINK_PATH tzplatform_mkpath(TZ_SYS_ETC, "localtime") + +#ifndef RTC_WKALM_BOOT_SET +#define RTC_WKALM_BOOT_SET _IOW('p', 0x80, struct rtc_wkalrm) +#endif + +#define _APPFW_FEATURE_WAKEUP_USING_RTC (_get_profile() != PROFILE_TV) + + +static const char default_rtc[] = "/dev/rtc"; +static int gfd = -1; + +__alarm_server_context_t alarm_context; + +extern bool g_dummy_timer_is_set; + +GSList *g_scheduled_alarm_list; +GSList *g_expired_alarm_list; +GSList *g_disabled_alarm_list; +GHashTable *caller_appid_cache_table; + +bool is_time_changed = false; /* for calculating next duetime */ +static time_t periodic_alarm_standard_time = 0; + +struct running_info_t { + char *appid; + bool is_running; +}; + +typedef struct { + int pid; + bool is_app; + char *unique_name; +} appid_cache_t; + +static long __get_proper_interval(long interval, int alarm_type); +static void __alarm_add_to_list(__alarm_info_t *__alarm_info); +static void __alarm_generate_alarm_id(__alarm_info_t *__alarm_info, alarm_id_t *alarm_id); +static __alarm_info_t *__alarm_update_in_list(uid_t uid, alarm_id_t alarm_id, + alarm_info_t *alarm_info, int update_flag, int *error_code); +static bool __alarm_remove_from_list(uid_t uid, alarm_id_t alarm_id, + int *error_code); +static void __alarm_set_start_and_end_time(alarm_info_t *alarm_info, + __alarm_info_t *__alarm_info); +static void __alarm_update_due_time_of_all_items_in_list(time_t new_time,double diff_time); +static bool __alarm_create(alarm_info_t *alarm_info, alarm_id_t *alarm_id, uid_t uid, + int pid, periodic_method_e method, long requested_interval, int is_ref, + char *app_service_name, char *app_service_name_mod, + const char *dst_service_name, const char *dst_service_name_mod, + int *error_code); +static bool __alarm_create_appsvc(alarm_info_t *alarm_info, alarm_id_t *alarm_id, + long requested_interval, uid_t uid, int pid, char *bundle_data, int *error_code); + +static bool __alarm_delete(uid_t uid, alarm_id_t alarm_id, int *error_code); +static bool __alarm_update(uid_t uid, alarm_id_t alarm_id, + alarm_info_t *alarm_info, int update_flag, int *error_code); +static void __on_system_time_external_changed(keynode_t *node, void *data); +static void __initialize_alarm_list(); +static void __initialize_scheduled_alarm_list(); +static void __initialize_noti(); +static gboolean __alarm_expired_directly(gpointer user_data); + +void _release_alarm_info_t(__alarm_info_t *entry); +static notification_h __get_notification(guchar *data, int datalen); + +static bool __get_caller_unique_name(int pid, char *unique_name, int size, bool *is_app, uid_t uid) +{ + char caller_appid[MAX_APP_ID_LEN] = {0,}; + + if (unique_name == NULL) { + LOGE("unique_name should not be NULL."); + return false; + } + + if (aul_app_get_appid_bypid_for_uid(pid, caller_appid, + sizeof(caller_appid), uid) == AUL_R_OK) { + /* When a caller is an application, the unique name is appID. */ + if (is_app) + *is_app = true; + strncpy(unique_name, caller_appid, size - 1); + } else { + /* Otherwise, the unique name is /proc/pid/cmdline. */ + char proc_file[MAX_APP_ID_LEN] = {0,}; + char process_name[MAX_APP_ID_LEN] = {0,}; + int fd = 0; + int i = 0; + + if (is_app) + *is_app = false; + + snprintf(proc_file, MAX_APP_ID_LEN, "/proc/%d/cmdline", pid); + + fd = open(proc_file, O_RDONLY); + if (fd < 0) { + SECURE_LOGE("Caution!! pid(%d) seems to be killed.", + pid); + return false; + } else { + if (read(fd, process_name, sizeof(process_name) - 1) <= 0) { + LOGE("Unable to get the process name."); + close(fd); + return false; + } + close(fd); + + while (process_name[i] != '\0') { + if (process_name[i] == ' ') { + process_name[i] = '\0'; + break; + } + ++i; + } + strncpy(unique_name, process_name, size - 1); + } + } + + return true; +} + +gboolean __hash_table_remove_cb(gpointer key, gpointer value, gpointer user_data) +{ + char *target_name = (char *)user_data; + appid_cache_t *data = (appid_cache_t *)value; + if (target_name && data && strcmp(target_name, data->unique_name) == 0) { + LOGD("Remove cached data of [%s]", target_name); + return true; + } + + return false; +} + +static bool __get_cached_unique_name(int pid, char *unique_name, int size, bool *is_app, uid_t uid) +{ + appid_cache_t *data; + bool ret; + bool _is_app; + + data = (appid_cache_t *)g_hash_table_lookup(caller_appid_cache_table, GINT_TO_POINTER(pid)); + if (data) { + snprintf(unique_name, MAX_APP_ID_LEN, "%s", data->unique_name); + if (is_app) + *is_app = data->is_app; + LOGD("Get cached unique_name: %s, pid:%d", unique_name, pid); + return true; + } + + LOGD("There is no cached unique_name for pid(%d)", pid); + + ret = __get_caller_unique_name(pid, unique_name, size, &_is_app, uid); + if (ret) { + g_hash_table_foreach_remove(caller_appid_cache_table, __hash_table_remove_cb, (gpointer)unique_name); + data = (appid_cache_t *)calloc(1, sizeof(appid_cache_t)); + if (data) { + data->unique_name = strdup(unique_name); + data->is_app = _is_app; + data->pid = pid; + g_hash_table_insert(caller_appid_cache_table, GINT_TO_POINTER(data->pid), (gpointer)data); + } + + if (is_app) + *is_app = _is_app; + + SECURE_LOGD("unique_name= %s", unique_name); + } + + return ret; +} + +void __hashtable_foreach_cb(gpointer key, gpointer value, gpointer user_data) +{ + appid_cache_t *data = (appid_cache_t *)value; + if (data) + LOGD("# %s(%d) - %d", data->unique_name, data->pid, data->is_app); +} + +void __free_cached_value(gpointer data) +{ + appid_cache_t *value = (appid_cache_t *)data; + + if (value) { + if (value->unique_name) + free(value->unique_name); + free(value); + } +} + +void _rtc_set() +{ + if (_APPFW_FEATURE_WAKEUP_USING_RTC) { + const char *rtc = default_rtc; + struct tm due_tm; + char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; +#ifdef _SIMUL /* RTC does not work in simulator. */ + LOGE("because it is simulator's mode, we don't set RTC."); + return; +#endif + + if (gfd < 0) { + gfd = open(rtc, O_RDWR); + if (gfd < 0) { + LOGE("RTC open failed."); + return; + } + } + + /* Read the RTC time/date */ + int retval = 0; + char buf[1024]; + char *timebuf = ctime(&alarm_context.c_due_time); + if (timebuf) { + timebuf[strlen(timebuf) - 1] = '\0'; /* to avoid new line */ + snprintf(log_message, sizeof(log_message), "wakeup time: %d, %s", (int)alarm_context.c_due_time, timebuf); + } + + LOGD("alarm_context.c_due_time is %d.", (int)alarm_context.c_due_time); + + if (alarm_context.c_due_time != -1) { + struct rtc_wkalrm rtc_wkalarm = { 0, }; + rtc_wkalarm.enabled = 0; + rtc_wkalarm.time.tm_year = 1900; + rtc_wkalarm.time.tm_mon = 0; + rtc_wkalarm.time.tm_mday = 1; + rtc_wkalarm.time.tm_hour = 0; + rtc_wkalarm.time.tm_min = 0; + rtc_wkalarm.time.tm_sec = 0; + + retval = ioctl(gfd, RTC_WKALM_SET, &rtc_wkalarm); + if (retval == -1) { + if (errno == ENOTTY) + LOGE("Alarm IRQs is not supported."); + + LOGE("RTC_WKALM_SET disabled ioctl is failed. errno = %s", strerror_r(errno, buf, sizeof(buf))); + _save_module_log("FAIL: SET RTC", log_message); + return; + } + LOGD("[alarm-server]RTC_WKALM_SET disabled ioctl is successfully done."); + + time_t due_time = alarm_context.c_due_time; + gmtime_r(&due_time, &due_tm); + + LOGD("Setted RTC Alarm date/time is %d-%d-%d, %02d:%02d:%02d (UTC).", + due_tm.tm_mday, due_tm.tm_mon + 1, due_tm.tm_year + 1900, + due_tm.tm_hour, due_tm.tm_min, due_tm.tm_sec); + + rtc_wkalarm.enabled = 1; + rtc_wkalarm.time.tm_year = due_tm.tm_year; + rtc_wkalarm.time.tm_mon = due_tm.tm_mon; + rtc_wkalarm.time.tm_mday = due_tm.tm_mday; + rtc_wkalarm.time.tm_hour = due_tm.tm_hour; + rtc_wkalarm.time.tm_min = due_tm.tm_min; + rtc_wkalarm.time.tm_sec = due_tm.tm_sec; + retval = ioctl(gfd, RTC_WKALM_SET, &rtc_wkalarm); + if (retval == -1) { + if (errno == ENOTTY) + LOGE("Alarm IRQs is not supported."); + + LOGE("RTC ALARM_SET ioctl is failed. errno = %s", strerror_r(errno, buf, sizeof(buf))); + _save_module_log("FAIL: SET RTC", log_message); + return; + } + LOGD("[alarm-server]RTC ALARM_SET ioctl is successfully done."); + _save_module_log("SET RTC", log_message); + } else { + LOGE("[alarm-server]alarm_context.c_due_time is" + "less than 10 sec. RTC alarm does not need to be set"); + } + } else { + LOGD("[alarm-server] RTC does not work."); + } + return; +} + +static bool __set_time(time_t _time) +{ + int ret = 0; + struct timeval tv; + struct tm tm, *gmtime_res; + + tv.tv_sec = _time; + tv.tv_usec = 0; + + gmtime_res = gmtime_r(&(tv.tv_sec), &tm); + if (!gmtime_res) { + LOGE("gmtime_r is failed. [%d]", errno); + return false; + } + + ret = settimeofday(&tv, NULL); + if (ret < 0) { + LOGE("settimeofday is failed.[%d]", errno); + return false; + } + + if (_APPFW_FEATURE_WAKEUP_USING_RTC) { + const char *rtc0 = default_rtc; + struct rtc_time _rtc_time; + char buf[1024]; + char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,}; + char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; + char *timebuf = ctime(&_time); + if (timebuf) { + timebuf[strlen(timebuf) - 1] = '\0'; /* to avoid new line */ + snprintf(log_message, sizeof(log_message), "RTC & OS =%ld, %s", + _time, timebuf); + } + + if (gfd < 0) { + gfd = open(rtc0, O_RDWR); + if (gfd < 0) { + LOGE("Opening the /dev/rtc is failed."); + return false; + } + } + + memset(&_rtc_time, 0, sizeof(_rtc_time)); + _rtc_time.tm_sec = tm.tm_sec; + _rtc_time.tm_min = tm.tm_min; + _rtc_time.tm_hour = tm.tm_hour; + _rtc_time.tm_mday = tm.tm_mday; + _rtc_time.tm_mon = tm.tm_mon; + _rtc_time.tm_year = tm.tm_year; + _rtc_time.tm_wday = tm.tm_wday; + _rtc_time.tm_yday = tm.tm_yday; + _rtc_time.tm_isdst = tm.tm_isdst; + + ret = ioctl(gfd, RTC_SET_TIME, &_rtc_time); + if (ret == -1) { + LOGE("ALARM_SET_RTC ioctl is failed. errno = %s", strerror_r(errno, buf, sizeof(buf))); + strncpy(log_tag, "FAIL: SET RTC", sizeof(log_tag) - 1); + _save_module_log(log_tag, log_message); + } else { + LOGD("ALARM_SET_RTC ioctl is succeed. [%d]", (int)_time); + strncpy(log_tag, "SET RTC START", sizeof(log_tag) - 1); + _save_module_log(log_tag, log_message); + return true; + } + } else { + LOGD("[alarm-server] RTC does not work."); + return true; + } + + return false; +} + +bool __alarm_clean_list() +{ + __alarm_info_t *entry = NULL; + GSList *iter = NULL; + + for (iter = alarm_context.alarms; iter != NULL; + iter = g_slist_next(iter)) { + entry = (__alarm_info_t *)iter->data; + _release_alarm_info_t(entry); + } + + g_slist_free(alarm_context.alarms); + alarm_context.alarms = NULL; + + return true; +} + +static void __alarm_generate_alarm_id(__alarm_info_t *__alarm_info, alarm_id_t *alarm_id) +{ + bool unique_id = false; + __alarm_info_t *entry = NULL; + GSList *iter = NULL; + + __alarm_info->alarm_id = g_random_int_range(0, INT_MAX) + 1; + LOGD("__alarm_info->alarm_id is %d", __alarm_info->alarm_id); + + while (unique_id == false) { + unique_id = true; + + for (iter = alarm_context.alarms; iter != NULL; + iter = g_slist_next(iter)) { + entry = (__alarm_info_t *)iter->data; + if (entry->alarm_id == __alarm_info->alarm_id) { + __alarm_info->alarm_id++; + unique_id = false; + } + } + } + + *alarm_id = __alarm_info->alarm_id; + + return; +} + +static void __alarm_add_to_list(__alarm_info_t *__alarm_info) +{ + alarm_info_t *alarm_info = &__alarm_info->alarm_info; + __alarm_info_t *entry = NULL; + GSList *iter = NULL; + + LOGD("[alarm-server]: Before add alarm_id(%d)", __alarm_info->alarm_id); + + alarm_context.alarms = g_slist_append(alarm_context.alarms, __alarm_info); + LOGD("[alarm-server]: After add alarm_id(%d)", __alarm_info->alarm_id); + + /* alarm list */ + for (iter = alarm_context.alarms; iter != NULL; iter = g_slist_next(iter)) { + entry = (__alarm_info_t *)iter->data; + LOGD("[alarm-server]: alarm_id(%d).", entry->alarm_id); + } + + if (!(alarm_info->alarm_type & ALARM_TYPE_VOLATILE)) { + if (!_save_alarms(__alarm_info)) + LOGE("Saving alarm_id(%d) in DB is failed.", __alarm_info->alarm_id); + } +} + +static bool __check_bundle_for_update(const gchar *b_data, uid_t uid) +{ + const char *callee_appid; + bundle *b; + bool ret = false; + + if (b_data == NULL) + return true; + + b = bundle_decode((bundle_raw *)b_data, strlen(b_data)); + if (b == NULL) + return false; + + callee_appid = appsvc_get_appid(b); + if (callee_appid == NULL) { + bundle_free(b); + return false; + } + + if (_is_ui_app(callee_appid, uid)) + ret = true; + + bundle_free(b); + return ret; +} + +static __alarm_info_t *__alarm_update_in_list(uid_t uid, alarm_id_t alarm_id, + alarm_info_t *alarm_info, int update_flag, int *error_code) +{ + bool found = false; + GSList *iter = NULL; + __alarm_info_t *entry = NULL; + alarm_info_t *_alarm_info = NULL; + time_t current_time; + + for (iter = alarm_context.alarms; iter != NULL; + iter = g_slist_next(iter)) { + entry = (__alarm_info_t *)iter->data; + if (entry->uid == uid && + entry->alarm_id == alarm_id) { + found = true; + _alarm_info = &entry->alarm_info; + + if (update_flag == ALARM_UPDATE_FLAG_TIME || + ALARM_UPDATE_FLAG_WEEK) { + if (!__check_bundle_for_update(entry->bundle, + entry->uid)) { + *error_code = ERR_ALARM_NOT_PERMITTED_APP; + return NULL; + } + } + + if (update_flag == ALARM_UPDATE_FLAG_TIME) { + __alarm_set_start_and_end_time(alarm_info, entry); + memcpy(_alarm_info, alarm_info, sizeof(alarm_info_t)); + + if (_alarm_info->mode.repeat == ALARM_REPEAT_MODE_ONCE) { + time(¤t_time); + _alarm_info->reserved_info = current_time; + } + } else if (update_flag == ALARM_UPDATE_FLAG_PERIOD) { + _alarm_info->alarm_type |= ALARM_TYPE_INEXACT; + _alarm_info->alarm_type |= ALARM_TYPE_PERIOD; + _alarm_info->mode.repeat = ALARM_REPEAT_MODE_REPEAT; + _alarm_info->mode.u_interval.interval = + __get_proper_interval(alarm_info->mode.u_interval.interval, + _alarm_info->alarm_type); + } else if (update_flag == ALARM_UPDATE_FLAG_WEEK) { + _alarm_info->alarm_type &= ~ALARM_TYPE_INEXACT; + _alarm_info->mode = alarm_info->mode; + } else if (update_flag == ALARM_UPDATE_FLAG_CLEAR_PERIOD) { + if (_alarm_info->mode.repeat == ALARM_REPEAT_MODE_REPEAT) { + _alarm_info->mode.repeat = ALARM_REPEAT_MODE_ONCE; + _alarm_info->mode.u_interval.interval = 0; + } + } else if (update_flag == ALARM_UPDATE_FLAG_CLEAR_WEEK_FLAG) { + if (_alarm_info->mode.repeat == ALARM_REPEAT_MODE_WEEKLY) { + _alarm_info->mode.repeat = ALARM_REPEAT_MODE_ONCE; + _alarm_info->mode.u_interval.interval = 0; + } + } + break; + } + } + + if (!found) { + if (error_code) + *error_code = ERR_ALARM_INVALID_ID; + return NULL; + } + + if (!(alarm_info->alarm_type & ALARM_TYPE_VOLATILE)) { + if (!_update_alarms(entry)) + LOGE("Updating alarm_id(%d) in DB is failed.", alarm_id); + } + + return entry; +} + +static bool __alarm_remove_from_list(uid_t uid, alarm_id_t alarm_id, + int *error_code) +{ + bool found = false; + + alarm_info_t *alarm_info = NULL; + + GSList *iter = NULL; + __alarm_info_t *entry = NULL; + + /*list alarms */ + LOGD("[alarm-server]: before del : alarm id(%d)", alarm_id); + + for (iter = alarm_context.alarms; iter != NULL; iter = g_slist_next(iter)) { + entry = (__alarm_info_t *)iter->data; + if (entry->uid == uid && entry->alarm_id == alarm_id) { + alarm_info = &entry->alarm_info; + + LOGD("[alarm-server]:Remove alarm id(%d)", entry->alarm_id); + + if (!(alarm_info->alarm_type & ALARM_TYPE_VOLATILE)) { + if (!_delete_alarms(alarm_id)) + break; + } + + alarm_context.alarms = g_slist_remove(alarm_context.alarms, iter->data); + _release_alarm_info_t(entry); + found = true; + break; + } + } + + LOGD("[alarm-server]: after del\n"); + + if (!found) { + if (error_code) + *error_code = ERR_ALARM_INVALID_ID; + return false; + } + + return true; +} + +static void __alarm_set_start_and_end_time(alarm_info_t *alarm_info, + __alarm_info_t *__alarm_info) +{ + alarm_date_t *start = &alarm_info->start; + alarm_date_t *end = &alarm_info->end; + + struct tm alarm_tm = { 0, }; + + if (start->year != 0) { + if ((alarm_info->alarm_type & ALARM_TYPE_RELATIVE) && alarm_info->reserved_info != 0) { + __alarm_info->start = alarm_info->reserved_info; + } else { + alarm_tm.tm_year = start->year - 1900; + alarm_tm.tm_mon = start->month - 1; + alarm_tm.tm_mday = start->day; + + alarm_tm.tm_hour = start->hour; + alarm_tm.tm_min = start->min; + alarm_tm.tm_sec = start->sec; + alarm_tm.tm_isdst = -1; + + __alarm_info->start = mktime(&alarm_tm); + } + } else { + __alarm_info->start = 0; + } + + if (end->year != 0) { + alarm_tm.tm_year = end->year - 1900; + alarm_tm.tm_mon = end->month - 1; + alarm_tm.tm_mday = end->day; + + alarm_tm.tm_hour = end->hour; + alarm_tm.tm_min = end->min; + alarm_tm.tm_sec = end->sec; + + __alarm_info->end = mktime(&alarm_tm); + } else { + __alarm_info->end = 0; + } +} + +static void __alarm_update_due_time_of_all_items_in_list(time_t new_time, double diff_time) +{ + time_t current_time; + time_t min_time = -1; + time_t due_time = 0; + GSList *iter = NULL; + __alarm_info_t *entry = NULL; + struct tm *p_time = NULL; + struct tm due_time_result; + bool is_rtc_reset = false; + is_time_changed = true; + + if (periodic_alarm_standard_time != 0) + periodic_alarm_standard_time += diff_time; + + tzset(); + for (iter = alarm_context.alarms; iter != NULL; iter = g_slist_next(iter)) { + entry = (__alarm_info_t *)iter->data; + alarm_info_t *alarm_info = &(entry->alarm_info); + if (alarm_info->alarm_type & ALARM_TYPE_RELATIVE) { + /* case of RTC reset */ + if (entry->alarm_info.mode.repeat == ALARM_REPEAT_MODE_ONCE) { + if ((entry->due_time + diff_time - new_time) > + (entry->due_time - entry->alarm_info.reserved_info)) { + LOGE("[ RTC reset]: new time %s %ld, diff %f, id %d duetime %s %ld %ld", + ctime(&new_time), new_time, diff_time, entry->alarm_id, + ctime(&entry->due_time), entry->due_time, + entry->alarm_info.reserved_info); + continue; + } + + entry->due_time += diff_time; + entry->alarm_info.reserved_info = new_time; + + } else { + entry->due_time += diff_time; + is_rtc_reset = false; + if ((entry->due_time - new_time) > alarm_info->mode.u_interval.interval) { + is_rtc_reset = true; + entry->due_time = new_time + + ((entry->due_time - new_time) % alarm_info->mode.u_interval.interval); + LOGE("[ RTC reset]: new time %s %ld, diff %f, id %d duetime %s %ld %ld", + ctime(&new_time), new_time, diff_time, entry->alarm_id, + ctime(&entry->due_time), entry->due_time, + alarm_info->mode.u_interval.interval); + } + } + + alarm_date_t *start = &alarm_info->start; /**< start time of the alarm */ + alarm_date_t *end = &alarm_info->end; /**< end time of the alarm */ + + p_time = localtime_r(&entry->due_time, &due_time_result); + if (p_time != NULL) { + start->year = p_time->tm_year + 1900; + start->month = p_time->tm_mon + 1; + start->day = p_time->tm_mday; + start->hour = p_time->tm_hour; + start->min = p_time->tm_min; + start->sec = p_time->tm_sec; + } + if (entry->start != 0) + entry->start = entry->due_time; + + if (entry->end != 0 && is_rtc_reset == false) { + entry->end += diff_time; + p_time = localtime_r(&entry->end, &due_time_result); + if (p_time != NULL) { + end->year = p_time->tm_year + 1900; + end->month = p_time->tm_mon + 1; + end->day = p_time->tm_mday; + end->hour = p_time->tm_hour; + end->min = p_time->tm_min; + end->sec = p_time->tm_sec; + } + } + } + _alarm_set_next_duetime(entry); + } + + time(¤t_time); + + for (iter = alarm_context.alarms; iter != NULL; iter = g_slist_next(iter)) { + entry = (__alarm_info_t *)iter->data; + due_time = entry->due_time; + + double interval = 0; + + LOGD("alarm[%d] with duetime(%ld) at current(%ld)", entry->alarm_id, due_time, current_time); + if (due_time == 0) { /* 0 means this alarm has been disabled */ + continue; + } + + interval = difftime(due_time, current_time); + + if (interval < 0) { + LOGW("The duetime of alarm(%d) is OVER.", entry->alarm_id); + + _alarm_set_next_duetime(entry); + if (entry->due_time < current_time) { + const char *dst = entry->callee_pkgid ? entry->callee_pkgid : entry->dst_service_name; + LOGW("The alarm(%d) is removed [unique_name : %s, dst : %s", + entry->alarm_id, entry->app_unique_name, dst); + + if (!(entry->alarm_info.alarm_type & ALARM_TYPE_VOLATILE)) + _delete_alarms(entry->alarm_id); + + _save_alarm_info_log("AUTO_DELETE", entry); + + alarm_context.alarms = g_slist_remove(alarm_context.alarms, iter->data); + _release_alarm_info_t(entry); + continue; + } else { + due_time = entry->due_time; + } + + } + + interval = difftime(due_time, min_time); + + if ((interval < 0) || min_time == -1) + min_time = due_time; + } + + is_time_changed = false; + alarm_context.c_due_time = min_time; + + g_idle_add(_update_relative_alarms, NULL); +} + +static void __set_caller_info(bundle *b, uid_t uid, + const char *appid, const char *pkgid) +{ + char buf[12]; + + snprintf(buf, sizeof(buf), "%u", uid); + bundle_del(b, AUL_K_ORG_CALLER_UID); + bundle_add(b, AUL_K_ORG_CALLER_UID, buf); + + bundle_del(b, AUL_K_ORG_CALLER_APPID); + bundle_add(b, AUL_K_ORG_CALLER_APPID, appid); + + if (pkgid) { + bundle_del(b, AUL_K_ORG_CALLER_PKGID); + bundle_add(b, AUL_K_ORG_CALLER_PKGID, pkgid); + } +} + +static bool __alarm_add_and_set(__alarm_info_t *alarm_info, pid_t pid) +{ + time_t current_time; + struct tm ts_ret; + char due_time_r[100] = { 0 }; + + time(¤t_time); + + SECURE_LOGW("[alarm-server]:pid=%d, app_unique_name=%s, \ + app_service_name=%s,dst_service_name=%s, c_due_time=%ld", + pid, alarm_info->app_unique_name, + alarm_info->app_service_name, + alarm_info->dst_service_name, + alarm_context.c_due_time); + + if (alarm_info->alarm_info.mode.repeat == ALARM_REPEAT_MODE_ONCE) + alarm_info->alarm_info.reserved_info = current_time; + + if (alarm_context.c_due_time < current_time) { + LOGW("Caution!! alarm_context.c_due_time (%ld) is less than current time(%ld)", + alarm_context.c_due_time, current_time); + alarm_context.c_due_time = -1; + } + + _alarm_set_next_duetime(alarm_info); + + if (alarm_info->due_time == 0) { + LOGW("[alarm-server]:Create a new alarm: due_time is 0. [alarm(%d):repeat_type(%d)]", + alarm_info->alarm_id, alarm_info->alarm_info.mode.repeat); + + if (alarm_info->alarm_info.mode.repeat == ALARM_REPEAT_MODE_ONCE) + return false; + + __alarm_add_to_list(alarm_info); + return true; + } else if (current_time == alarm_info->due_time) { + LOGW("[alarm-server]:Create alarm: current_time(%ld) is same as due_time(%ld) [alarm(%d):repeat_type(%d)]", + current_time, alarm_info->due_time, alarm_info->alarm_id, alarm_info->alarm_info.mode.repeat); + + __alarm_add_to_list(alarm_info); + _clear_scheduled_alarm_list(); + _add_to_scheduled_alarm_list(alarm_info); + alarm_context.c_due_time = alarm_info->due_time; + + time_t *_dt = malloc(sizeof(time_t)); + if (_dt) { + *_dt = alarm_info->due_time; + } else { + LOGE("Out of memory"); + return false; + } + + g_idle_add(__alarm_expired_directly, (gpointer)_dt); + + return true; + } else if (difftime(alarm_info->due_time, current_time) < 0) { + LOGW("[alarm-server]: Expired Due Time. \ + [Due time=%ld, Current Time=%ld]!!!Do not add to schedule list. \ + [alarm(%d):repeat_type(%d)]", + alarm_info->due_time, current_time, alarm_info->alarm_id, alarm_info->alarm_info.mode.repeat); + + if (alarm_info->alarm_info.mode.repeat == ALARM_REPEAT_MODE_ONCE) + return false; + + __alarm_add_to_list(alarm_info); + return true; + } else { + localtime_r(&(alarm_info->due_time), &ts_ret); + strftime(due_time_r, 30, "%c", &ts_ret); + SECURE_LOGD("[alarm-server]:Create a new alarm: alarm(%d) due_time(%s)", + alarm_info->alarm_id, due_time_r); + + __alarm_add_to_list(alarm_info); + } + + LOGD("[alarm-server]:alarm_context.c_due_time(%ld), due_time(%ld)", + alarm_context.c_due_time, alarm_info->due_time); + + if (alarm_context.c_due_time == -1 || alarm_info->due_time < alarm_context.c_due_time) { + _clear_scheduled_alarm_list(); + _add_to_scheduled_alarm_list(alarm_info); + _alarm_set_timer(alarm_context.timer, alarm_info->due_time); + alarm_context.c_due_time = alarm_info->due_time; + _rtc_set(); + } else if (alarm_info->due_time == alarm_context.c_due_time) { + _add_to_scheduled_alarm_list(alarm_info); + } + + return true; +} + +static bool __alarm_create_appsvc(alarm_info_t *alarm_info, alarm_id_t *alarm_id, + long requested_interval, uid_t uid, int pid, char *bundle_data, int *error_code) +{ + char app_name[MAX_APP_ID_LEN] = { 0 }; + bundle *b; + const char *callee_appid = NULL; + bundle_raw *b_data = NULL; + int datalen = 0; + bool caller_is_app = false; + + __alarm_info_t *__alarm_info = NULL; + + __alarm_info = (__alarm_info_t *)calloc(1, sizeof(__alarm_info_t)); + if (__alarm_info == NULL) { + SECURE_LOGE("Caution!! app_pid=%d, calloc failed. it seems to be OOM.", pid); + *error_code = ERR_ALARM_SYSTEM_FAIL; + return false; + } + + __alarm_info->uid = uid; + __alarm_info->alarm_id = -1; + __alarm_info->requested_interval = requested_interval; + __alarm_info->global = false; + + if (__get_cached_unique_name(pid, app_name, sizeof(app_name), &caller_is_app, uid) == false) { + *error_code = ERR_ALARM_SYSTEM_FAIL; + _release_alarm_info_t(__alarm_info); + return false; + } + __alarm_info->app_unique_name = strdup(app_name); + + /* caller */ + if (caller_is_app) + __alarm_info->caller_pkgid = _get_pkgid_by_appid(app_name, uid); + + /* callee */ + b = bundle_decode((bundle_raw *)bundle_data, strlen(bundle_data)); + callee_appid = appsvc_get_appid(b); + __alarm_info->callee_pkgid = _get_pkgid_by_appid(callee_appid, uid); + + if (b && caller_is_app) { + __set_caller_info(b, uid, app_name, __alarm_info->caller_pkgid); + bundle_del(b, AUL_K_REQUEST_TYPE); + bundle_add(b, AUL_K_REQUEST_TYPE, "indirect-request"); + } + + SECURE_LOGD("caller_pkgid = %s, callee_pkgid = %s", + __alarm_info->caller_pkgid, __alarm_info->callee_pkgid); + + bundle_encode(b, &b_data, &datalen); + if (b_data) + __alarm_info->bundle = strdup((const gchar *)b_data); + + bundle_free(b); + if (b_data) { + free(b_data); + b_data = NULL; + } + + __alarm_set_start_and_end_time(alarm_info, __alarm_info); + memcpy(&(__alarm_info->alarm_info), alarm_info, sizeof(alarm_info_t)); + __alarm_generate_alarm_id(__alarm_info, alarm_id); + + if (__alarm_add_and_set(__alarm_info, pid) == false) { + *error_code = ERR_ALARM_INVALID_TIME; + _release_alarm_info_t(__alarm_info); + return false; + } + + _save_alarm_info_log("CREATE SVC", __alarm_info); + + return true; +} + +static bool __alarm_create(alarm_info_t *alarm_info, alarm_id_t *alarm_id, uid_t uid, + int pid, periodic_method_e method, long requested_interval, int is_ref, + char *app_service_name, char *app_service_name_mod, + const char *dst_service_name, const char *dst_service_name_mod, + int *error_code) +{ + char unique_name[MAX_APP_ID_LEN] = { 0 }; + bool caller_is_app = false; + + __alarm_info_t *__alarm_info = NULL; + + __alarm_info = (__alarm_info_t *)calloc(1, sizeof(__alarm_info_t)); + if (__alarm_info == NULL) { + SECURE_LOGE("Caution!! app_pid=%d, calloc " + "failed. it seems to be OOM\n", pid); + *error_code = ERR_ALARM_SYSTEM_FAIL; + return false; + } + __alarm_info->uid = uid; + __alarm_info->alarm_id = -1; + __alarm_info->method = method; + __alarm_info->requested_interval = requested_interval; + __alarm_info->is_ref = is_ref; + __alarm_info->global = false; + + if (__get_cached_unique_name(pid, unique_name, sizeof(unique_name), + &caller_is_app, uid) == false) { + *error_code = ERR_ALARM_SYSTEM_FAIL; + _release_alarm_info_t(__alarm_info); + return false; + } + + /* Get caller_appid to get caller's package id. There is no callee. */ + if (caller_is_app) + __alarm_info->caller_pkgid = _get_pkgid_by_appid(unique_name, uid); + + SECURE_LOGD("caller_pkgid = %s, callee_pkgid = null", __alarm_info->caller_pkgid); + + __alarm_info->app_unique_name = strdup(unique_name); + if (app_service_name) + __alarm_info->app_service_name = strdup(app_service_name); + if (app_service_name_mod) + __alarm_info->app_service_name_mod = strdup(app_service_name_mod); + if (dst_service_name) + __alarm_info->dst_service_name = strdup(dst_service_name); + if (dst_service_name_mod) + __alarm_info->dst_service_name_mod = strdup(dst_service_name_mod); + + __alarm_set_start_and_end_time(alarm_info, __alarm_info); + memcpy(&(__alarm_info->alarm_info), alarm_info, sizeof(alarm_info_t)); + __alarm_generate_alarm_id(__alarm_info, alarm_id); + + if (__alarm_add_and_set(__alarm_info, pid) == false) { + *error_code = ERR_ALARM_INVALID_TIME; + _release_alarm_info_t(__alarm_info); + return false; + } + + _save_alarm_info_log("CREATE", __alarm_info); + + return true; +} + +static char *__create_new_noti_data(char *noti_data, pid_t pid, uid_t uid) +{ + GVariant *noti_gv; + guchar *decoded_data; + int decoded_datalen; + notification_h noti = NULL; + char *new_noti_data = NULL; + guchar* data = NULL; + int datalen; + + decoded_data = g_base64_decode(noti_data, (gsize *)&decoded_datalen); + if (decoded_data == NULL) + return NULL; + + noti = __get_notification(decoded_data, decoded_datalen); + if (noti == NULL) + goto end; + + notification_set_indirect_request(noti, pid, uid); + + noti_gv = notification_ipc_make_gvariant_from_noti(noti, false); + if (noti_gv == NULL) + goto end; + + datalen = g_variant_get_size(noti_gv); + if (datalen < 0) + goto end; + + data = (guchar *)malloc(datalen); + if (data == NULL) + goto end; + + g_variant_store(noti_gv, data); + new_noti_data = g_base64_encode(data, datalen); + +end: + if (data) + free(data); + if (noti) + notification_free(noti); + if (decoded_data) + g_free(decoded_data); + + return new_noti_data; +} + +static bool __alarm_create_noti(alarm_info_t *alarm_info, alarm_id_t *alarm_id, + long requested_interval, uid_t uid, int pid, char *noti_data, int *error_code) +{ + char app_name[MAX_APP_ID_LEN] = { 0 }; + bool caller_is_app = false; + char *new_noti_data = NULL; + + __alarm_info_t *__alarm_info = NULL; + + __alarm_info = (__alarm_info_t *)calloc(1, sizeof(__alarm_info_t)); + if (__alarm_info == NULL) { + SECURE_LOGE("Caution!! app_pid=%d, calloc " + "failed. it seems to be OOM\n", pid); + *error_code = ERR_ALARM_SYSTEM_FAIL; + return false; + } + __alarm_info->uid = uid; + __alarm_info->alarm_id = -1; + __alarm_info->requested_interval = requested_interval; + __alarm_info->global = false; + + if (__get_cached_unique_name(pid, app_name, sizeof(app_name), &caller_is_app, uid) == false) { + *error_code = ERR_ALARM_SYSTEM_FAIL; + _release_alarm_info_t(__alarm_info); + return false; + } + __alarm_info->app_unique_name = strdup(app_name); + + if (caller_is_app) { + __alarm_info->caller_pkgid = _get_pkgid_by_appid(app_name, uid); + } + + SECURE_LOGD("caller_pkgid = %s, callee_pkgid = null", + __alarm_info->caller_pkgid); + + if (noti_data) { + if (caller_is_app) { + new_noti_data = __create_new_noti_data(noti_data, pid, + uid); + } + + if (new_noti_data) + __alarm_info->noti = new_noti_data; + else + __alarm_info->noti = strdup(noti_data); + } + + __alarm_set_start_and_end_time(alarm_info, __alarm_info); + memcpy(&(__alarm_info->alarm_info), alarm_info, sizeof(alarm_info_t)); + __alarm_generate_alarm_id(__alarm_info, alarm_id); + + if (__alarm_add_and_set(__alarm_info, pid) == false) { + *error_code = ERR_ALARM_INVALID_TIME; + _release_alarm_info_t(__alarm_info); + return false; + } + + _save_alarm_info_log("CREATE NOTI", __alarm_info); + + return true; +} + +static bool __alarm_update(uid_t uid, alarm_id_t alarm_id, + alarm_info_t *alarm_info, int update_flag, int *error_code) +{ + time_t current_time; + char due_time_r[100] = { 0 }; + __alarm_info_t *__alarm_info = NULL; + bool result = false; + struct tm ts_ret; + + time(¤t_time); + + if (alarm_context.c_due_time < current_time) { + LOGE("Caution!! alarm_context.c_due_time " + "(%ld) is less than current time(%ld)", alarm_context.c_due_time, current_time); + alarm_context.c_due_time = -1; + } + + __alarm_info = __alarm_update_in_list(uid, alarm_id, alarm_info, + update_flag, error_code); + if (!__alarm_info) { + LOGE("[alarm-server]: requested alarm_id " + "(%d) does not exist. so this value is invalid id.", alarm_id); + return false; + } + + if (__alarm_info->alarm_info.mode.repeat == ALARM_REPEAT_MODE_ONCE) + __alarm_info->alarm_info.reserved_info = current_time; + + _alarm_set_next_duetime(__alarm_info); + + _save_alarm_info_log("UPDATE", __alarm_info); + + result = _remove_from_scheduled_alarm_list(uid, alarm_id); + if (result == true && g_slist_length(g_scheduled_alarm_list) == 0) { + /*there is no scheduled alarm */ + _alarm_disable_timer(); + _alarm_schedule(); + + LOGD("[alarm-server]:Update alarm: alarm(%d).", alarm_id); + + _rtc_set(); + + if (__alarm_info->due_time == 0) + LOGE("[alarm-server]:Update alarm: due_time is 0."); + + return true; + } + + if (__alarm_info->due_time == 0) { + LOGE("[alarm-server]:Update alarm: " + "due_time is 0, alarm(%d)\n", alarm_id); + return true; + } else if (current_time == __alarm_info->due_time) { + LOGE("[alarm-server]:Update alarm: " + "current_time(%ld) is same as due_time(%ld)", current_time, + __alarm_info->due_time); + return true; + } else if (difftime(__alarm_info->due_time, current_time) < 0) { + LOGE("[alarm-server]: Expired Due Time.[Due time=%ld,\ + Current Time=%ld]!!!Do not add to schedule list\n", + __alarm_info->due_time, current_time); + return true; + } else { + localtime_r(&(__alarm_info->due_time), &ts_ret); + strftime(due_time_r, 30, "%c", &ts_ret); + SECURE_LOGD("[alarm-server]:Update alarm: alarm(%d) " + "due_time(%s)\n", alarm_id, due_time_r); + } + + LOGD("[alarm-server]:alarm_context.c_due_time(%ld), due_time(%ld)", + alarm_context.c_due_time, __alarm_info->due_time); + + if (alarm_context.c_due_time == -1 || __alarm_info->due_time < alarm_context.c_due_time) { + _clear_scheduled_alarm_list(); + _add_to_scheduled_alarm_list(__alarm_info); + _alarm_set_timer(alarm_context.timer, __alarm_info->due_time); + LOGD("[alarm-server1]:alarm_context.c_due_time " + "(%ld), due_time(%ld)", alarm_context.c_due_time, __alarm_info->due_time); + } else if (__alarm_info->due_time == alarm_context.c_due_time) { + _add_to_scheduled_alarm_list(__alarm_info); + LOGD("[alarm-server2]:alarm_context.c_due_time " + "(%ld), due_time(%ld)", alarm_context.c_due_time, __alarm_info->due_time); + } + + _rtc_set(); + + return true; +} + + +static bool __alarm_delete(uid_t uid, alarm_id_t alarm_id, int *error_code) +{ + bool result = false; + + SECURE_LOGD("[alarm-server]:delete alarm: alarm(%d) uid(%d)\n", alarm_id, uid); + result = _remove_from_scheduled_alarm_list(uid, alarm_id); + + if (!__alarm_remove_from_list(uid, alarm_id, error_code)) { + + SECURE_LOGE("[alarm-server]:delete alarm: " + "alarm(%d) uid(%d) has failed with error_code(%d)\n", + alarm_id, uid, *error_code); + return false; + } + + if (result == true && g_slist_length(g_scheduled_alarm_list) == 0) { + _alarm_disable_timer(); + _alarm_schedule(); + _rtc_set(); + } + + return true; +} + +bool _can_skip_expired_cb(alarm_id_t alarm_id) +{ + GSList *gs_iter = NULL; + __alarm_info_t *entry = NULL; + alarm_info_t *alarm = NULL; + + for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { + entry = (__alarm_info_t *)gs_iter->data; + if (entry->alarm_id == alarm_id) { + alarm = &(entry->alarm_info); + time_t ts = 0; + struct tm ts_tm; + int dur = entry->requested_interval; + int from, to; + + if (dur == 0 || !(alarm->alarm_type & ALARM_TYPE_PERIOD) || entry->method == CUT_OFF) + return false; + + ts_tm.tm_hour = alarm->start.hour; + ts_tm.tm_min = alarm->start.min; + ts_tm.tm_sec = alarm->start.sec; + + ts_tm.tm_year = alarm->start.year - 1900; + ts_tm.tm_mon = alarm->start.month - 1; + ts_tm.tm_mday = alarm->start.day; + ts_tm.tm_isdst = -1; + + ts = mktime(&ts_tm); + + from = (ts / dur) * dur; + to = from + dur; + + if (ts >= from && ts < to && from > ts - alarm->mode.u_interval.interval) + return false; + + return true; + } + } + + return false; +} + +static int __find_login_user(uid_t *uid) +{ + uid_t *uids; + int ret, i; + char *state; + + ret = sd_get_uids(&uids); + if (ret <= 0) + return -1; + + for (i = 0; i < ret; i++) { + if (sd_uid_get_state(uids[i], &state) < 0) { + free(uids); + return -1; + } else { + if (!strncmp(state, "online", 6)) { + *uid = uids[i]; + free(uids); + free(state); + return 0; + } + } + } + + free(uids); + free(state); + return -1; +} + +static notification_h __get_notification(guchar *data, int datalen) +{ + int ret; + GVariant *noti_gv = NULL; + GVariant *body = NULL; + notification_h noti; + + if (data == NULL || datalen <= 0) + return NULL; + + noti_gv = g_variant_new_from_data(G_VARIANT_TYPE("(v)"), + data, datalen, TRUE, NULL, NULL); + + if (noti_gv == NULL) + return NULL; + + g_variant_get(noti_gv, "(v)", &body); + + if (body == NULL) { + g_variant_unref(noti_gv); + return NULL; + } + + noti = notification_create(NOTIFICATION_TYPE_NOTI); + if (noti == NULL) { + g_variant_unref(body); + g_variant_unref(noti_gv); + return NULL; + } + + ret = notification_ipc_make_noti_from_gvariant(noti, body); + + if (ret != NOTIFICATION_ERROR_NONE) { + g_variant_unref(body); + g_variant_unref(noti_gv); + notification_free(noti); + return NULL; + } + + g_variant_unref(body); + g_variant_unref(noti_gv); + + return noti; +} + +static void __expire_notification(__alarm_info_t *alarm_info) +{ + int ret; + int datalen; + notification_h noti; + guchar *noti_data; + int expire_mode = ALARM_EXPIRE_MODE_NORMAL; + + noti_data = g_base64_decode(alarm_info->noti, + (gsize *)&datalen); + if (!noti_data) { + LOGE("Failed to decode noti data"); + return; + } + + noti = __get_notification(noti_data, datalen); + if (noti == NULL) { + LOGE("Failed to get notification"); + g_free(noti_data); + return; + } + + if (vconf_get_int(VCONFKEY_ALARM_EXPIRE_MODE, &expire_mode) != 0) + LOGE("Failed to get value of VCONFKEY_ALARM_EXPIRE_MODE"); + + LOGD("Value of alarm_expire_mode [%d]", expire_mode); + + if (expire_mode == ALARM_EXPIRE_MODE_NORMAL) + device_display_change_state(DISPLAY_STATE_NORMAL); + + ret = notification_post_for_uid(noti, alarm_info->uid); + if (ret != NOTIFICATION_ERROR_NONE) + LOGE("Failed to post notification"); + + notification_free(noti); + g_free(noti_data); +} + +static void __expire_app_control(__alarm_info_t *alarm_info) +{ + char alarm_id_val[32]; + bundle *b = NULL; + char *appid = NULL; + int b_len = 0; + int app_pid = 0; + int ret; + int result = 0; + int expire_mode = ALARM_EXPIRE_MODE_NORMAL; + uid_t target_uid; + + b_len = strlen(alarm_info->bundle); + b = bundle_decode((bundle_raw *)(alarm_info->bundle), b_len); + if (b == NULL) { + LOGE("Error!!!..Unable to decode the bundle!!\n"); + return; + } + + snprintf(alarm_id_val, sizeof(alarm_id_val), "%d", alarm_info->alarm_id); + + if (bundle_add_str(b, "http://tizen.org/appcontrol/data/alarm_id", alarm_id_val)) { + LOGE("Unable to add alarm id to the bundle\n"); + bundle_free(b); + return; + } + + app_pid = _get_pid_from_appid(alarm_info->app_unique_name, + alarm_info->uid); + SECURE_LOGW("alarm_expired : from [uid : %d, pid : %d, pkgid : %s, " + "unique_name : %s]", alarm_info->uid, app_pid, + alarm_info->caller_pkgid, alarm_info->app_unique_name); + + if (_compare_api_version(&result, app_pid, alarm_info->uid) < 0) { + LOGE("Unable to check api version\n"); + result = -1; + } + + if (result < 0) { + /* before 2.4 */ + if (aul_svc_run_service_async_for_uid(b, 0, NULL, NULL, alarm_info->uid) < 0) + LOGE("Unable to run app svc\n"); + else + LOGD("Successfuly run app svc\n"); + } else { + /* since 2.4 */ + appid = (char *)appsvc_get_appid(b); + if ((alarm_info->alarm_info.alarm_type & ALARM_TYPE_NOLAUNCH) && !aul_app_is_running(appid)) { + LOGE("This alarm is ignored\n"); + } else if (!(alarm_info->alarm_info.alarm_type & ALARM_TYPE_INEXACT) || + !_can_skip_expired_cb(alarm_info->alarm_id)) { + if (alarm_info->global) { + if (__find_login_user(&target_uid) < 0) { + LOGE("Fail to get login user\n"); + ret = -1; + } else { + ret = aul_svc_run_service_async_for_uid(b, 0, NULL, NULL, target_uid); + } + } else { + ret = aul_svc_run_service_async_for_uid(b, 0, NULL, NULL, alarm_info->uid); + } + + if (ret < 0) { + LOGE("Unable to launch app [%s] \n", appid); + } else { + if (vconf_get_int(VCONFKEY_ALARM_EXPIRE_MODE, &expire_mode) != 0) + LOGE("Failed to get value of VCONFKEY_ALARM_EXPIRE_MODE"); + + LOGD("Successfuly ran app svc (expire_mode : %d)", expire_mode); + + if (_is_ui_app(appid, alarm_info->uid) && + expire_mode == ALARM_EXPIRE_MODE_NORMAL) + device_display_change_state(DISPLAY_STATE_NORMAL); + } + } + } + + bundle_free(b); +} + +static int __app_info_iter(const aul_app_info *info, void *data) +{ + struct running_info_t *app_info = (struct running_info_t *)data; + + if (strcmp(app_info->appid, info->appid) == 0) + app_info->is_running = true; + + return 0; +} + +static void __expire_dbus_activation(__alarm_info_t *alarm_info) +{ + const char *destination_app_service_name = NULL; + char appid[MAX_SERVICE_NAME_LEN] = { 0, }; + struct running_info_t app_info; + bundle *kb; + uid_t target_uid; + bool is_app = false; + + if (alarm_info->dst_service_name == NULL) { + SECURE_LOGD("[alarm-server]:destination is null, so we send expired alarm to %s.", + alarm_info->app_service_name); + destination_app_service_name = alarm_info->app_service_name_mod; + } else { + SECURE_LOGD("[alarm-server]:destination :%s", + alarm_info->dst_service_name); + destination_app_service_name = alarm_info->dst_service_name_mod; + } + + /* + * we should consider a situation that + * destination_app_service_name is owner_name like (:xxxx) and + * application's pid which registered this alarm was killed.In that case, + * we don't need to send the expire event because the process was killed. + * this causes needless message to be sent. + */ + + if (alarm_info->dst_service_name == NULL) { + if (alarm_info->app_service_name != NULL && strlen(alarm_info->app_service_name) > 6) + strncpy(appid, alarm_info->app_service_name + 6, sizeof(appid) - 1); + } else { + if (strlen(alarm_info->dst_service_name) > 6) + strncpy(appid, alarm_info->dst_service_name + 6, sizeof(appid) - 1); + } + + if (alarm_info->uid >= REGULAR_UID_MIN) { + is_app = _is_app(appid, alarm_info->uid); + } + LOGD("appid : %s app?(%d)", appid, is_app); + + /* Case #3-1. The process was killed && App type + * This app is launched and owner of DBus connection is changed. and then, expiration noti is sent by DBus. */ + app_info.is_running = false; + if (is_app) { + app_info.appid = appid; + aul_app_get_all_running_app_info_for_uid(__app_info_iter, + &app_info, alarm_info->uid); + + SECURE_LOGD("[alarm-server]: destination_app_id :%s", appid); + } + + if (is_app && !app_info.is_running) { + __expired_alarm_t *expire_info; + char alarm_id_str[32] = { 0, }; + + if (alarm_info->alarm_info.alarm_type & ALARM_TYPE_WITHCB) { + __alarm_remove_from_list(alarm_info->uid, alarm_info->alarm_id, NULL); + LOGW("[alarm-server]:This alarm_type is WITHCB"); + return; + } + + expire_info = (__expired_alarm_t *)malloc(sizeof(__expired_alarm_t)); + if (G_UNLIKELY(NULL == expire_info)) { + LOGE("[alarm-server]:Malloc failed!Can't notify alarm expiry info\n"); + return; + } + memset(expire_info, '\0', sizeof(__expired_alarm_t)); + strncpy(expire_info->service_name, destination_app_service_name, MAX_SERVICE_NAME_LEN-1); + expire_info->alarm_id = alarm_info->alarm_id; + expire_info->uid = alarm_info->uid; + g_expired_alarm_list = g_slist_append(g_expired_alarm_list, expire_info); + + snprintf(alarm_id_str, 31, "%d", alarm_info->alarm_id); + + SECURE_LOGD("before aul_launch appid(%s) alarm_id_str(%s)", appid, alarm_id_str); + + kb = bundle_create(); + bundle_add_str(kb, "__ALARM_MGR_ID", alarm_id_str); + + if (alarm_info->global) { + if (__find_login_user(&target_uid) < 0) + LOGE("Fail to get login user\n"); + else + aul_launch_app_for_uid(appid, kb, target_uid); /* on_bus_name_owner_changed will be called. */ + } else { + aul_launch_app_for_uid(appid, kb, alarm_info->uid); /* on_bus_name_owner_changed will be called. */ + } + + bundle_free(kb); + } else { + /* Case #3-2. The process is alive or was killed && non-app type(daemon) + * Expiration noti is sent by DBus. it makes the process alive. (dbus auto activation) */ + LOGD("before alarm_send_noti_to_application"); + + _alarm_send_noti_to_application_by_dbus(destination_app_service_name, + alarm_info->alarm_id, alarm_info->alarm_info.msec, alarm_info->uid); /* dbus auto activation */ + LOGD("after _alarm_send_noti_to_application_by_dbus"); + } + + return 0; +} + +void _alarm_expired() +{ + __alarm_info_t *__alarm_info = NULL; + GSList *iter = NULL; + __scheduled_alarm_t *alarm = NULL; + + LOGD("[alarm-server]: Enter"); + + time_t current_time; + double interval; + + time(¤t_time); + + interval = difftime(alarm_context.c_due_time, current_time); + LOGD("[alarm-server]: c_due_time(%ld), current_time(%ld), interval(%f)", + alarm_context.c_due_time, current_time, interval); + + if (alarm_context.c_due_time > current_time + 1) { + LOGE("[alarm-server]: False Alarm. due time is (%ld) seconds future", + alarm_context.c_due_time - current_time); + goto done; + } + /* 10 seconds is maximum permitted delay from timer expire to this function */ + if (alarm_context.c_due_time + 10 < current_time) { + LOGE("[alarm-server]: False Alarm. due time is (%ld) seconds past.", + current_time - alarm_context.c_due_time); + goto done; + } + + for (iter = g_scheduled_alarm_list; iter != NULL; iter = g_slist_next(iter)) { + alarm = (__scheduled_alarm_t *)iter->data; + __alarm_info = alarm->__alarm_info; + + /* Case #1. The process is an application launched by app_control. + * It registered an alarm using launch-based APIs like alarm_schedule_xxx, alarmmgr_xxx_appsvc. */ + if (__alarm_info->bundle != NULL) { + __expire_app_control(__alarm_info); + } else if (__alarm_info->noti != NULL) { + /* Case #2. The process is an application launched by notification. */ + __expire_notification(__alarm_info); + } else { + /* Case #3. Expiration noti is sent by DBus. + * 3-1. The process was killed && App type + * 3-2. The process is alive or was killed && non-app type(daemon) */ + __expire_dbus_activation(__alarm_info); + } + + LOGD("alarm_id[%d] is expired.", __alarm_info->alarm_id); + + _save_alarm_info_log("EXPIRED", __alarm_info); + + if (__alarm_info->alarm_info.mode.repeat == ALARM_REPEAT_MODE_ONCE) { + __alarm_remove_from_list(__alarm_info->uid, __alarm_info->alarm_id, NULL); + } else { + _alarm_set_next_duetime(__alarm_info); + _save_alarm_info_log("DUETIME", __alarm_info); + } + } + +done: + _clear_scheduled_alarm_list(); + alarm_context.c_due_time = -1; + + LOGD("[alarm-server]: Leave"); +} + + +static void __on_system_time_external_changed(keynode_t *node, void *data) +{ + double diff_time = 0.0; + time_t cur_time = 0; + + _alarm_disable_timer(); + + if (node) { + diff_time = vconf_keynode_get_dbl(node); + } else { + if (vconf_get_dbl(VCONFKEY_SYSTEM_TIMECHANGE_EXTERNAL, &diff_time) != 0) { + LOGE("Failed to get value of VCONFKEY_SYSTEM_TIMECHANGE_EXTERNAL."); + return; + } + } + + tzset(); + time(&cur_time); + + LOGD("diff_time is %f, New time is %s\n", diff_time, ctime(&cur_time)); + + LOGD("[alarm-server] System time has been changed externally\n"); + LOGD("1.alarm_context.c_due_time is %ld\n", + alarm_context.c_due_time); + + if (!__set_time(cur_time)) { /* Change both OS time and RTC */ + LOGE("Failed to change both OS time and RTC"); + _clear_scheduled_alarm_list(); + _alarm_schedule(); + _rtc_set(); + return; + } + + vconf_set_int(VCONFKEY_SYSTEM_TIME_CHANGED, (int)diff_time); + bundle *b = NULL; + b = bundle_create(); + bundle_add_str(b, EVT_KEY_TIME_CHANGED, EVT_VAL_TIME_CHANGED_TRUE); + eventsystem_send_system_event(SYS_EVENT_TIME_CHANGED, b); + bundle_free(b); + + __alarm_update_due_time_of_all_items_in_list(cur_time, diff_time); + + LOGD("2.alarm_context.c_due_time is %ld\n", + alarm_context.c_due_time); + _clear_scheduled_alarm_list(); + _alarm_schedule(); + _rtc_set(); + + _save_module_log("SET RTC END", "requested by vconf"); + + return; +} + +static int __on_app_enable_cb(uid_t target_uid, int req_id, + const char *pkg_type, const char *pkgid, const char *appid, + const char *key, const char *val, const void *pmsg, void *data) +{ + SECURE_LOGD("appid:%s, key:%s, val:%s, req_id: %d", appid, key, val, req_id); + + GSList *gs_iter = NULL; + __alarm_info_t *entry = NULL; + bool is_restored = false; + + if (key && strncmp(key, "end", 3) == 0 && val && strncmp(val, "ok", 2) == 0) { + SECURE_LOGD("Enable appid(%s)", appid); + for (gs_iter = g_disabled_alarm_list; gs_iter != NULL; ) { + entry = (__alarm_info_t *)gs_iter->data; + + gs_iter = g_slist_next(gs_iter); + if (strncmp(appid, entry->app_unique_name, strlen(appid)) == 0) { + _alarm_set_next_duetime(entry); + SECURE_LOGD("Restore alarm_id(%d) duetime(%d) appid(%s)", + entry->alarm_id, (int)(entry->due_time), appid); + alarm_context.alarms = g_slist_append(alarm_context.alarms, entry); + g_disabled_alarm_list = g_slist_remove(g_disabled_alarm_list, entry); + + if (!(entry->alarm_info.alarm_type & ALARM_TYPE_VOLATILE)) + _update_db_for_disabled_alarm(entry->alarm_id, false); + is_restored = true; + } + } + + if (is_restored) { + _alarm_disable_timer(); + _clear_scheduled_alarm_list(); + _alarm_schedule(); + _rtc_set(); + } + } + + return 0; +} + +static int __on_app_disable_cb(uid_t target_uid, int req_id, + const char *pkg_type, const char *pkgid, const char *appid, + const char *key, const char *val, const void *pmsg, void *data) +{ + SECURE_LOGD("appid:%s, key:%s, val:%s, req_id: %d", appid, key, val, req_id); + + GSList *gs_iter = NULL; + __alarm_info_t *entry = NULL; + bool is_disabled = false; + + if (key && strncmp(key, "end", 3) == 0 && val && strncmp(val, "ok", 2) == 0) { + SECURE_LOGD("Disable appid(%s)", appid); + for (gs_iter = alarm_context.alarms; gs_iter != NULL; ) { + entry = (__alarm_info_t *)gs_iter->data; + + gs_iter = g_slist_next(gs_iter); + if (strncmp(appid, entry->app_unique_name, strlen(appid)) == 0) { + if (!(entry->alarm_info.alarm_type & ALARM_TYPE_VOLATILE)) + _update_db_for_disabled_alarm(entry->alarm_id, true); + g_disabled_alarm_list = g_slist_append(g_disabled_alarm_list, entry); + alarm_context.alarms = g_slist_remove(alarm_context.alarms, entry); + is_disabled = true; + } + } + + if (is_disabled) { + _alarm_disable_timer(alarm_context); + _clear_scheduled_alarm_list(); + _alarm_schedule(); + _rtc_set(); + } + } + + return 0; +} + +static int __on_app_uninstalled(uid_t target_uid, int req_id, const char *pkg_type, + const char *pkgid, const char *key, const char *val, + const void *pmsg, void *user_data) +{ + GSList *gs_iter = NULL; + __alarm_info_t *entry = NULL; + alarm_info_t *alarm_info = NULL; + bool is_deleted = false; + + SECURE_LOGD("pkg_type(%s), pkgid(%s), key(%s), value(%s)", pkg_type, pkgid, key, val); + + if (strncmp(key, "end", 3) == 0 && strncmp(val, "ok", 2) == 0) { + for (gs_iter = alarm_context.alarms; gs_iter != NULL;) { + entry = (__alarm_info_t *)gs_iter->data; + + const char *caller_pkgid = entry->caller_pkgid; + const char *callee_pkgid = entry->callee_pkgid; + int pid = _get_pid_from_appid(entry->app_unique_name, entry->uid); + + gs_iter = g_slist_next(gs_iter); + if ((caller_pkgid && strncmp(pkgid, caller_pkgid, strlen(pkgid)) == 0) || + (callee_pkgid && strncmp(pkgid, callee_pkgid, strlen(pkgid)) == 0)) { + if (_remove_from_scheduled_alarm_list(entry->uid, entry->alarm_id)) + is_deleted = true; + + alarm_info = &entry->alarm_info; + if (!(alarm_info->alarm_type & ALARM_TYPE_VOLATILE)) { + if (!_delete_alarms(entry->alarm_id)) + SECURE_LOGE("_delete_alarms() is failed. pkgid[%s], alarm_id[%d]", pkgid, entry->alarm_id); + } + + if (g_hash_table_remove(caller_appid_cache_table, GINT_TO_POINTER(pid)) == true) + LOGD("Remove cachd data of pid[%d]", pid); + + SECURE_LOGD("Remove pkgid[%s], alarm_id[%d]", pkgid, entry->alarm_id); + alarm_context.alarms = g_slist_remove(alarm_context.alarms, entry); + _release_alarm_info_t(entry); + + } + } + + if (is_deleted && (g_slist_length(g_scheduled_alarm_list) == 0)) { + _alarm_disable_timer(); + _alarm_schedule(); + _rtc_set(); + } + } + + return ALARMMGR_RESULT_SUCCESS; +} + +static long __get_proper_interval(long interval, int alarm_type) +{ + GSList *gs_iter = NULL; + __alarm_info_t *entry = NULL; + long maxInterval = 60; + + for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { + entry = (__alarm_info_t *)gs_iter->data; + if (entry->alarm_info.alarm_type & ALARM_TYPE_PERIOD) { + if (entry->alarm_info.mode.u_interval.interval <= interval && + entry->alarm_info.mode.u_interval.interval > maxInterval) + maxInterval = entry->alarm_info.mode.u_interval.interval; + } + } + + while ((maxInterval * 2 <= interval && maxInterval < LONG_MAX / 2) || + (alarm_type & ALARM_TYPE_INEXACT && maxInterval < MIN_INEXACT_INTERVAL)) + maxInterval *= 2; + + return maxInterval; +} + +static gboolean __alarm_expired_directly(gpointer user_data) +{ + if (g_scheduled_alarm_list == NULL || g_scheduled_alarm_list->data == NULL) + return false; + + time_t *time_sec = (time_t *)user_data; + __scheduled_alarm_t *alarm = (__scheduled_alarm_t *)g_scheduled_alarm_list->data; + __alarm_info_t *alarm_info = alarm->__alarm_info; + + /* Expire alarms with duetime equal to newtime by force */ + if (alarm_info->due_time == *time_sec) { + _display_lock_state(DEVICED_LCD_OFF, DEVICED_STAY_CUR_STATE, 0); + + if (g_dummy_timer_is_set == true) { + LOGD("dummy alarm timer has expired."); + } else { + LOGD("due_time=%ld is expired.", alarm_info->due_time); + _alarm_expired(); + } + + _alarm_schedule(); + _rtc_set(); + + _display_unlock_state(DEVICED_LCD_OFF, DEVICED_SLEEP_MARGIN); + } + + if (time_sec) + free(time_sec); + + return false; +} + +void __reschedule_alarms_with_newtime(time_t cur_time, time_t new_time, double diff_time) +{ + char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; + + time_t *_new_time; + vconf_set_int(VCONFKEY_SYSTEM_TIME_CHANGED, (int)diff_time); + bundle *b = NULL; + b = bundle_create(); + bundle_add_str(b, EVT_KEY_TIME_CHANGED, EVT_VAL_TIME_CHANGED_TRUE); + eventsystem_send_system_event(SYS_EVENT_TIME_CHANGED, b); + bundle_free(b); + + __alarm_update_due_time_of_all_items_in_list(new_time, diff_time); /* Rescheduling alarms with ALARM_TYPE_RELATIVE */ + LOGD("Next duetime is %ld", alarm_context.c_due_time); + + _clear_scheduled_alarm_list(); + _alarm_schedule(); + _rtc_set(); + + char *timebuf = ctime((const time_t *)&new_time); + if (timebuf) { + timebuf[strlen(timebuf) - 1] = '\0'; /* to avoid newline */ + snprintf(log_message, sizeof(log_message), "Current: %ld, New: %ld, %s, diff: %f", cur_time, new_time, timebuf, diff_time); + } + + _save_module_log("CHANGE TIME", log_message); + + _new_time = malloc(sizeof(time_t)); + if (_new_time) { + *_new_time = new_time; + } else { + LOGE("Out of memory"); + return; + } + + g_idle_add(__alarm_expired_directly, (gpointer)_new_time); /* Expire alarms with duetime equal to newtime directly */ + return; +} + +static int __check_modifiable(uid_t uid, pid_t pid, int alarm_id) +{ + bool caller_is_app = false; + char app_name[MAX_APP_ID_LEN] = { 0 }; + GSList *gs_iter = NULL; + __alarm_info_t *entry = NULL; + char *caller_pkgid = NULL; + + if (__get_cached_unique_name(pid, app_name, sizeof(app_name), + &caller_is_app, uid) == false) + return ERR_ALARM_SYSTEM_FAIL; + + if (!caller_is_app) { + LOGD("Daemon process is possible to modify alarms[%s]", + app_name); + return ALARMMGR_RESULT_SUCCESS; + } else { + caller_pkgid = _get_pkgid_by_appid(app_name, uid); + if (!caller_pkgid) { + LOGE("Failed to get appinfo %s", app_name); + return ERR_ALARM_SYSTEM_FAIL; + } + } + + for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { + entry = (__alarm_info_t *)gs_iter->data; + if (entry->uid == uid && entry->alarm_id == alarm_id && + strcmp(caller_pkgid, entry->caller_pkgid) == 0) { + LOGD("Found alarm of app (uid:%d, pid:%d, caller_pkgid:%s) ", uid, pid, caller_pkgid); + + if (caller_pkgid) + free(caller_pkgid); + return ALARMMGR_RESULT_SUCCESS; + } + } + + LOGW("[%s] is not permitted to modify alarm_id[%d]", app_name, alarm_id); + if (caller_pkgid) + free(caller_pkgid); + + return ERR_ALARM_NOT_PERMITTED_APP; +} + +int alarm_manager_alarm_set_rtc_time(GVariant *parameters) +{ + if (_APPFW_FEATURE_WAKEUP_USING_RTC) { + const char *rtc = default_rtc; + struct rtc_wkalrm rtc_wkalarm; + int retval = 0; + struct tm tm, *alarm_tm = NULL; + char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,}; + char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; + /*extract day of the week, day in the year & daylight saving time from system*/ + time_t current_time; + char buf[1024]; + int year, mon, day, hour, min, sec; + int return_code = ALARMMGR_RESULT_SUCCESS; + + g_variant_get(parameters, "(iiiiii)", &year, &mon, &day, &hour, &min, &sec); + + current_time = time(NULL); + alarm_tm = gmtime_r(¤t_time, &tm); + if (alarm_tm == NULL) { + LOGE("alarm_tm is NULL"); + return ERR_ALARM_SYSTEM_FAIL; + } + + alarm_tm->tm_year = year; + alarm_tm->tm_mon = mon; + alarm_tm->tm_mday = day; + alarm_tm->tm_hour = hour; + alarm_tm->tm_min = min; + alarm_tm->tm_sec = sec; + + /*convert to calendar time representation*/ + time_t rtc_time = mktime(alarm_tm); + + if (gfd < 0) { + gfd = open(rtc, O_RDWR); + if (gfd < 0) { + LOGE("RTC open failed."); + return ERR_ALARM_SYSTEM_FAIL; + } + } + + rtc_wkalarm.enabled = 1; + rtc_wkalarm.time.tm_year = year; + rtc_wkalarm.time.tm_mon = mon; + rtc_wkalarm.time.tm_mday = day; + rtc_wkalarm.time.tm_hour = hour; + rtc_wkalarm.time.tm_min = min; + rtc_wkalarm.time.tm_sec = sec; + + retval = ioctl(gfd, RTC_WKALM_SET, &rtc_wkalarm); + if (retval == -1) { + if (errno == ENOTTY) + LOGE("Alarm IRQs is not supported."); + + LOGE("RTC ALARM_SET ioctl is failed. errno = %s", strerror_r(errno, buf, sizeof(buf))); + return_code = ERR_ALARM_SYSTEM_FAIL; + strncpy(log_tag, "FAIL: SET RTC", sizeof(log_tag) - 1); + } else { + LOGD("[alarm-server]RTC alarm is setted"); + strncpy(log_tag, "SET RTC", sizeof(log_tag) - 1); + } + + snprintf(log_message, sizeof(log_message), "wakeup rtc time: %ld, %s", rtc_time, ctime(&rtc_time)); + _save_module_log(log_tag, log_message); + return return_code; + } else { + LOGW("[alarm-server] RTC does not work."); + return ERR_ALARM_SYSTEM_FAIL; + } +} + +static int accrue_msec = 0; /* To check a millisecond part of current time at changing the system time(sec) */ + +int alarm_manager_alarm_set_time(GVariant* parameters, pid_t pid) +{ + double diff_time = 0.0; + struct timeval cur_time = {0,}; + gint64 time_sec; + time_t new_time; + char sender_id[MAX_APP_ID_LEN]; + char log_message[ALARMMGR_LOG_MESSAGE_SIZE]; + + g_variant_get(parameters, "(x)", &time_sec); + + new_time = (time_t)time_sec; + + _alarm_disable_timer(); /* Disable the timer to reschedule the alarm before the time is changed. */ + + tzset(); + gettimeofday(&cur_time, NULL); + + accrue_msec += (cur_time.tv_usec / 1000); /* Accrue the millisecond to compensate the time */ + if (accrue_msec > 500) { + diff_time = difftime(new_time, cur_time.tv_sec) - 1; + accrue_msec -= 1000; + } else { + diff_time = difftime(new_time, cur_time.tv_sec); + } + + if (!__set_time(new_time)) { /* Change both OS time and RTC */ + LOGE("Failed to change both OS time and RTC"); + _clear_scheduled_alarm_list(); + _alarm_schedule(); + _rtc_set(); + return ERR_ALARM_SYSTEM_FAIL; + } + + LOGD("[TIMESTAMP]Current time(%ld), New time(%ld)(%s), diff_time(%f)", + cur_time.tv_sec, new_time, ctime((const time_t *)&new_time), diff_time); + + __reschedule_alarms_with_newtime(cur_time.tv_sec, new_time, diff_time); + + __get_cached_unique_name(pid, sender_id, MAX_APP_ID_LEN, NULL, 5001); + snprintf(log_message, sizeof(log_message), "requested by %s (pid %d)", sender_id, pid); + _save_module_log("SET TIME END", log_message); + + return ALARMMGR_RESULT_SUCCESS;; +} + +int alarm_manager_alarm_set_time_with_propagation_delay(GVariant* parameters, pid_t pid) +{ + double diff_time = 0.0; + struct timespec cur_time = {0,}; + struct timespec delay = {0,}; + struct timespec sleep_time = {0,}; + time_t real_newtime = 0; + accrue_msec = 0; /* reset accrued msec */ + time_t new_sec, req_sec; + long new_nsec, req_nsec; + gint64 tmp_new_sec, tmp_req_sec, tmp_new_nsec, tmp_req_nsec; + char sender_id[MAX_APP_ID_LEN]; + char log_message[ALARMMGR_LOG_MESSAGE_SIZE]; + + g_variant_get(parameters, "(xxxx)", &tmp_new_sec, &tmp_new_nsec, &tmp_req_sec, &tmp_req_nsec); + new_sec = (time_t)tmp_new_sec; + new_nsec = (long)tmp_new_nsec; + req_sec = (time_t)tmp_req_sec; + req_nsec = (long)tmp_req_nsec; + + _alarm_disable_timer(); /* Disable the timer to reschedule the alarm before the time is changed. */ + + tzset(); + clock_gettime(CLOCK_REALTIME, &cur_time); + + /* Check validation of requested time */ + if (req_sec > cur_time.tv_sec || (req_sec == cur_time.tv_sec && req_nsec > cur_time.tv_nsec)) { + LOGE("The requeted time(%ld.%09ld) must be equal to or less than current time(%ld.%09ld).", + req_sec, req_nsec, cur_time.tv_sec, cur_time.tv_nsec); + return ERR_ALARM_INVALID_PARAM; + } + + /* Compensate propagation delay */ + if (req_nsec > cur_time.tv_nsec) { + delay.tv_sec = cur_time.tv_sec - 1 - req_sec; + delay.tv_nsec = cur_time.tv_nsec + BILLION - req_nsec; + } else { + delay.tv_sec = cur_time.tv_sec - req_sec; + delay.tv_nsec = cur_time.tv_nsec - req_nsec; + } + + if (new_nsec + delay.tv_nsec >= BILLION) { + real_newtime = new_sec + delay.tv_sec + 2; + sleep_time.tv_nsec = BILLION - ((delay.tv_nsec + new_nsec) - BILLION); + } else { + real_newtime = new_sec + delay.tv_sec + 1; + sleep_time.tv_nsec = BILLION - (delay.tv_nsec + new_nsec); + } + + nanosleep(&sleep_time, NULL); /* Wait until 0 nsec to match both OS time and RTC(sec) */ + + if (!__set_time(real_newtime)) { /* Change both OS time and RTC */ + LOGE("Failed to change both OS time and RTC"); + _clear_scheduled_alarm_list(); + _alarm_schedule(); + _rtc_set(); + return ERR_ALARM_SYSTEM_FAIL; + } + + diff_time = difftime(real_newtime, cur_time.tv_sec); + LOGD("[TIMESTAMP]Current time(%ld.%09ld), New time(%ld.%09ld), Real Newtime(%ld), diff_time(%f)", + cur_time.tv_sec, cur_time.tv_nsec, new_sec, new_nsec, real_newtime, diff_time); + LOGD("Requested(%ld.%09ld) Delay(%ld.%09ld) Sleep(%09ld)", req_sec, req_nsec, delay.tv_sec, delay.tv_nsec, sleep_time.tv_nsec); + __reschedule_alarms_with_newtime(cur_time.tv_sec, real_newtime, diff_time); + + __get_cached_unique_name(pid, sender_id, MAX_APP_ID_LEN, NULL, 5001); + snprintf(log_message, sizeof(log_message), "requested by %s (pid %d)", sender_id, pid); + _save_module_log("SET TIME PROPAGATION END", log_message); + + return ALARMMGR_RESULT_SUCCESS; +} + +int alarm_manager_alarm_set_timezone(GVariant* parameters) +{ + int retval = 0; + int return_code = ALARMMGR_RESULT_SUCCESS; + struct stat statbuf; + bundle *b = NULL; + char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,}; + char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; + char *tzpath_str; + time_t cur_time; + + g_variant_get(parameters, "(&s)", &tzpath_str); + + LOGD("[TIMESTAMP]Set the timezone to %s.", tzpath_str); + + if (lstat(tzpath_str, &statbuf) == -1 && errno == ENOENT) { + LOGE("Invalid tzpath, %s", tzpath_str); + return_code = ERR_ALARM_INVALID_PARAM; + goto done; + } + + retval = lstat(TIMEZONE_INFO_LINK_PATH, &statbuf); + if (retval == 0 || (retval == -1 && errno != ENOENT)) { + /* unlink the current link */ + if (unlink(TIMEZONE_INFO_LINK_PATH) < 0) { + LOGE("unlink() is failed."); + return_code = ERR_ALARM_SYSTEM_FAIL; + goto done; + } + } + + /* create a new symlink when the /opt/etc/localtime is empty. */ + if (symlink(tzpath_str, TIMEZONE_INFO_LINK_PATH) < 0) { + LOGE("Failed to create an symlink of %s.", tzpath_str); + return_code = ERR_ALARM_SYSTEM_FAIL; + goto done; + } + + tzset(); + + /* Rescheduling alarms */ + _alarm_disable_timer(); + time(&cur_time); + __alarm_update_due_time_of_all_items_in_list(cur_time, 0); + LOGD("next expiring due_time is %ld", alarm_context.c_due_time); + + _clear_scheduled_alarm_list(); + _alarm_schedule(); + _rtc_set(); + + vconf_set_int(VCONFKEY_SYSTEM_TIME_CHANGED, 0); + b = bundle_create(); + bundle_add_str(b, EVT_KEY_TIME_CHANGED, EVT_VAL_TIME_CHANGED_TRUE); + eventsystem_send_system_event(SYS_EVENT_TIME_CHANGED, b); + bundle_free(b); + + b = bundle_create(); + bundle_add_str(b, EVT_KEY_TIME_ZONE, tzpath_str); + eventsystem_send_system_event(SYS_EVENT_TIME_ZONE, b); + bundle_free(b); + +done: + if (return_code == ALARMMGR_RESULT_SUCCESS) + strncpy(log_tag, "SET TIMEZONE", sizeof(log_tag) - 1); + else + strncpy(log_tag, "FAIL: SET TIMEZONE", sizeof(log_tag) - 1); + + snprintf(log_message, sizeof(log_message), "Set the timezone to %s.", tzpath_str); + _save_module_log(log_tag, log_message); + + return return_code; +} + +int alarm_manager_alarm_create_appsvc(GVariant *parameters, uid_t uid, pid_t pid, int *alarm_id) +{ + alarm_info_t alarm_info; + int return_code = ALARMMGR_RESULT_SUCCESS; + int _alarm_id = 0; + char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,}; + char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; + int result; + bundle *b; + const char *callee_appid; + int start_year, start_month, start_day, start_hour, start_min, start_sec; + int end_year, end_month, end_day; + int mode_day_of_week, mode_repeat, alarm_type; + time_t mode_interval, reserved_info; + gint64 tmp_mode_interval, tmp_reserved_info; + char *bundle_data; + + *alarm_id = _alarm_id; + if (uid < 0 || pid < 0) + return ERR_ALARM_SYSTEM_FAIL; + + g_variant_get(parameters, "(iiiiiiiiiixiix&s)", + &start_year, &start_month, &start_day, &start_hour, &start_min, + &start_sec, &end_year, &end_month, &end_day, &mode_day_of_week, + &tmp_mode_interval, &mode_repeat, &alarm_type, &tmp_reserved_info, &bundle_data); + + mode_interval = (time_t)tmp_mode_interval; + reserved_info = (time_t)tmp_reserved_info; + + b = bundle_decode((bundle_raw *)bundle_data, strlen(bundle_data)); + if (b == NULL) { + int ret_bundle = get_last_result(); + LOGE("Failed to decode bundle_data[Error:%d]\n", ret_bundle); + return ERR_ALARM_SYSTEM_FAIL; + } else { + callee_appid = appsvc_get_appid(b); + + if (_compare_api_version(&result, pid, uid) < 0) { + LOGE("Unable to check api version\n"); + bundle_free(b); + return ERR_ALARM_SYSTEM_FAIL; + } + + if (result < 0) { + if (alarm_type & ALARM_TYPE_INEXACT) + alarm_type ^= ALARM_TYPE_INEXACT; + } else { /* Since 2.4 */ + if (!_is_permitted(callee_appid, alarm_type, uid)) { + LOGE("[%s] is not permitted \n", callee_appid); + bundle_free(b); + return ERR_ALARM_NOT_PERMITTED_APP; + } + } + + bundle_free(b); + } + + alarm_info.start.year = start_year; + alarm_info.start.month = start_month; + alarm_info.start.day = start_day; + alarm_info.start.hour = start_hour; + alarm_info.start.min = start_min; + alarm_info.start.sec = start_sec; + + alarm_info.end.year = end_year; + alarm_info.end.month = end_month; + alarm_info.end.day = end_day; + + alarm_info.mode.u_interval.day_of_week = mode_day_of_week; + alarm_info.mode.repeat = (alarm_repeat_mode_t)mode_repeat; + + alarm_info.alarm_type = alarm_type; + alarm_info.reserved_info = reserved_info; + + if ((alarm_info.alarm_type & ALARM_TYPE_INEXACT)) { + alarm_info.alarm_type |= ALARM_TYPE_PERIOD; + alarm_info.mode.u_interval.interval = + __get_proper_interval(mode_interval, alarm_info.alarm_type); + } else if (mode_interval <= 0) { + alarm_info.mode.u_interval.interval = 0; + } + + if (!__alarm_create_appsvc(&alarm_info, &_alarm_id, mode_interval, uid, pid, bundle_data, &return_code)) { + LOGE("Unable to create alarm! return_code[%d]", return_code); + strncpy(log_tag, "FAIL: CREATE SVC", sizeof(log_tag) - 1); + snprintf(log_message, sizeof(log_message), + "alarmID: %d, uid: %d, pid: %d, duetime: %d-%d-%d %02d:%02d:%02d", + _alarm_id, uid, pid, start_year, start_month, start_day, start_hour, start_min, start_sec); + _save_module_log(log_tag, log_message); + return_code = ERR_ALARM_SYSTEM_FAIL; + } else { + *alarm_id = _alarm_id; + return_code = ALARMMGR_RESULT_SUCCESS; + } + + return return_code; +} + +int alarm_manager_alarm_create_noti(GVariant *parameters, uid_t uid, pid_t pid, + int *alarm_id) +{ + alarm_info_t alarm_info; + int return_code = ALARMMGR_RESULT_SUCCESS; + int _alarm_id = 0; + char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,}; + char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; + int start_year, start_month, start_day, start_hour, start_min, start_sec; + int end_year, end_month, end_day; + int mode_day_of_week, mode_repeat, alarm_type; + time_t mode_interval, reserved_info; + gint64 tmp_mode_interval, tmp_reserved_info; + char *noti_data; + + *alarm_id = _alarm_id; + if (uid < 0 || pid < 0) + return ERR_ALARM_SYSTEM_FAIL; + + g_variant_get(parameters, "(iiiiiiiiiixiix&s)", + &start_year, &start_month, &start_day, &start_hour, &start_min, + &start_sec, &end_year, &end_month, &end_day, &mode_day_of_week, + &tmp_mode_interval, &mode_repeat, &alarm_type, &tmp_reserved_info, ¬i_data); + + mode_interval = (time_t)tmp_mode_interval; + reserved_info = (time_t)tmp_reserved_info; + + alarm_info.start.year = start_year; + alarm_info.start.month = start_month; + alarm_info.start.day = start_day; + alarm_info.start.hour = start_hour; + alarm_info.start.min = start_min; + alarm_info.start.sec = start_sec; + + alarm_info.end.year = end_year; + alarm_info.end.month = end_month; + alarm_info.end.day = end_day; + + alarm_info.mode.u_interval.day_of_week = mode_day_of_week; + alarm_info.mode.repeat = (alarm_repeat_mode_t)mode_repeat; + + alarm_info.alarm_type = alarm_type; + alarm_info.reserved_info = reserved_info; + + if ((alarm_info.alarm_type & ALARM_TYPE_INEXACT)) { + alarm_info.alarm_type |= ALARM_TYPE_PERIOD; + alarm_info.mode.u_interval.interval = + __get_proper_interval(mode_interval, alarm_info.alarm_type); + } else if (mode_interval <= 0) { + alarm_info.mode.u_interval.interval = 0; + } + + if (!__alarm_create_noti(&alarm_info, &_alarm_id, mode_interval, uid, pid, noti_data, &return_code)) { + LOGE("Unable to create alarm! return_code[%d]", return_code); + strncpy(log_tag, "FAIL: CREATE NOTI", sizeof(log_tag) - 1); + snprintf(log_message, sizeof(log_message), "alarmID: %d, uid: %d, pid: %d, duetime: %d-%d-%d %02d:%02d:%02d", + _alarm_id, uid, pid, start_year, start_month, start_day, start_hour, start_min, start_sec); + _save_module_log(log_tag, log_message); + return_code = ERR_ALARM_SYSTEM_FAIL; + } else { + return_code = ALARMMGR_RESULT_SUCCESS; + *alarm_id = _alarm_id; + } + + return return_code; +} + +int alarm_manager_alarm_create(GVariant *parameters, uid_t uid, pid_t pid, int *alarm_id) +{ + alarm_info_t alarm_info; + int return_code = ALARMMGR_RESULT_SUCCESS; + int _alarm_id = 0; + char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,}; + char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; + char *_reserved_service_name = NULL; + char *_reserved_service_name_mod = NULL; + + char *app_service_name = NULL; + char *app_service_name_mod = NULL; + int start_year, start_month, start_day, start_hour, start_min, start_sec; + int msec, end_year, end_month, end_day; + int mode_day_of_week, mode_repeat, alarm_type; + gint64 tmp_reserved_info; + time_t reserved_info; + char *reserved_service_name = NULL; + char *reserved_service_name_mod = NULL; + + *alarm_id = _alarm_id; + if (uid < 0 || pid < 0) + return ERR_ALARM_SYSTEM_FAIL; + + g_variant_get(parameters, "(&s&siiiiiiiiiiiiix&s&s)", + &app_service_name, &app_service_name_mod, + &start_year, &start_month, &start_day, &start_hour, &start_min, + &start_sec, &msec, &end_year, &end_month, &end_day, + &mode_day_of_week, &mode_repeat, &alarm_type, &tmp_reserved_info, + &reserved_service_name, &reserved_service_name_mod); + + reserved_info = (time_t)tmp_reserved_info; + + alarm_info.start.year = start_year; + alarm_info.start.month = start_month; + alarm_info.start.day = start_day; + alarm_info.start.hour = start_hour; + alarm_info.start.min = start_min; + alarm_info.start.sec = start_sec; + + alarm_info.msec = msec; + + alarm_info.end.year = end_year; + alarm_info.end.month = end_month; + alarm_info.end.day = end_day; + + alarm_info.mode.u_interval.day_of_week = mode_day_of_week; + alarm_info.mode.repeat = (alarm_repeat_mode_t)mode_repeat; + + alarm_info.alarm_type = alarm_type; + alarm_info.reserved_info = reserved_info; + + if (strcmp(reserved_service_name, "null") == 0) + _reserved_service_name = NULL; + if (strcmp(reserved_service_name_mod, "null") == 0) + _reserved_service_name_mod = NULL; + + if (!__alarm_create(&alarm_info, &_alarm_id, uid, pid, QUANTUMIZE, 0, 0, app_service_name, app_service_name_mod, + _reserved_service_name, _reserved_service_name_mod, &return_code)) { + LOGE("Unable to create alarm! return_code[%d]", return_code); + strncpy(log_tag, "FAIL: CREATE", sizeof(log_tag) - 1); + snprintf(log_message, sizeof(log_message), "alarmID: %d, uid: %d, pid: %d, duetime: %d-%d-%d %02d:%02d:%02d", + _alarm_id, uid, pid, start_year, start_month, start_day, start_hour, start_min, start_sec); + _save_module_log(log_tag, log_message); + return_code = ERR_ALARM_SYSTEM_FAIL; + } else { + return_code = ALARMMGR_RESULT_SUCCESS; + *alarm_id = _alarm_id; + } + + return return_code; +} + +time_t _get_periodic_alarm_standard_time(void) +{ + /* To avoid start time of all devices are same. */ + if (periodic_alarm_standard_time == 0) + periodic_alarm_standard_time = g_random_int_range(0, BILLION) + 1; + + LOGD("periodic_standard_time : [%ld]", periodic_alarm_standard_time); + return periodic_alarm_standard_time; +} + +int alarm_manager_alarm_create_periodic(GVariant *parameters, uid_t uid, + pid_t pid, int *alarm_id) +{ + alarm_info_t alarm_info; + int return_code = ALARMMGR_RESULT_SUCCESS; + int _alarm_id = 0; + char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,}; + char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; + char *app_service_name = NULL; + char *app_service_name_mod = NULL; + int interval, is_ref, method; + + *alarm_id = _alarm_id; + if (uid < 0 || pid < 0) + return ERR_ALARM_SYSTEM_FAIL; + + g_variant_get(parameters, "(&s&siii)", &app_service_name, + &app_service_name_mod, &interval, &is_ref, &method); + + struct tm standard_tm; + time_t standard_time = _get_periodic_alarm_standard_time(); + localtime_r(&standard_time, &standard_tm); + + alarm_info.reserved_info = standard_time; + + alarm_info.start.year = standard_tm.tm_year + 1900; + alarm_info.start.month = standard_tm.tm_mon + 1; + alarm_info.start.day = standard_tm.tm_mday; + alarm_info.start.hour = standard_tm.tm_hour; + alarm_info.start.min = standard_tm.tm_min; + alarm_info.start.sec = standard_tm.tm_sec; + + alarm_info.msec = 0; + + alarm_info.end.year = 0; + alarm_info.end.month = 0; + alarm_info.end.day = 0; + + alarm_info.alarm_type = ALARM_TYPE_VOLATILE; + alarm_info.alarm_type |= ALARM_TYPE_RELATIVE; + alarm_info.alarm_type |= ALARM_TYPE_WITHCB; + alarm_info.alarm_type |= ALARM_TYPE_PERIOD; + + if (interval <= 0) { + alarm_info.mode.repeat = ALARM_REPEAT_MODE_ONCE; + alarm_info.mode.u_interval.interval = 0; + } else { + alarm_info.mode.repeat = ALARM_REPEAT_MODE_REPEAT; + if (is_ref) + alarm_info.mode.u_interval.interval = interval * 60; + else + alarm_info.mode.u_interval.interval = __get_proper_interval(interval * 60, alarm_info.alarm_type); + } + + if (!__alarm_create(&alarm_info, &_alarm_id, uid, pid, (periodic_method_e)method, interval * 60, is_ref, + app_service_name, app_service_name_mod, + NULL, NULL, &return_code)) { + LOGE("Unable to create alarm! return_code[%d]", return_code); + strncpy(log_tag, "FAIL: CREATE PERIODIC", sizeof(log_tag) - 1); + snprintf(log_message, sizeof(log_message), "alarmID: %d, uid: %d, pid: %d, duetime: %d-%d-%d %02d:%02d:%02d", + _alarm_id, uid, pid, alarm_info.start.year, alarm_info.start.month, + alarm_info.start.day, alarm_info.start.hour, + alarm_info.start.min, alarm_info.start.sec); + _save_module_log(log_tag, log_message); + return_code = ERR_ALARM_SYSTEM_FAIL; + } else { + return_code = ALARMMGR_RESULT_SUCCESS; + *alarm_id = _alarm_id; + } + + return return_code; +} + +int alarm_manager_alarm_delete(GVariant *parameters, uid_t uid, pid_t pid) +{ + int return_code = ALARMMGR_RESULT_SUCCESS; + char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,}; + char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; + int alarm_id; + + if (uid < 0 || pid < 0) + return ERR_ALARM_SYSTEM_FAIL; + + g_variant_get(parameters, "(i)", &alarm_id); + + return_code = __check_modifiable(uid, pid, alarm_id); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return return_code; + + if (!__alarm_delete(uid, alarm_id, &return_code)) { + LOGE("Unable to delete the alarm! alarm_id[%d], return_code[%d]", alarm_id, return_code); + strncpy(log_tag, "FAIL: DELETE", sizeof(log_tag) - 1); + return_code = ERR_ALARM_SYSTEM_FAIL; + } else { + LOGD("alarm_id[%d] is removed.", alarm_id); + strncpy(log_tag, "DELETE", sizeof(log_tag) - 1); + return_code = ALARMMGR_RESULT_SUCCESS; + } + + snprintf(log_message, sizeof(log_message), "alarmID: %d, uid: %d, pid: %d", alarm_id, uid, pid); + _save_module_log(log_tag, log_message); + + return return_code; +} + +int alarm_manager_alarm_delete_all(GVariant *parameters, uid_t uid, pid_t pid) +{ + GSList *gs_iter = NULL; + char app_name[MAX_APP_ID_LEN] = { 0 }; + alarm_info_t *alarm_info = NULL; + __alarm_info_t *entry = NULL; + bool is_deleted = false; + char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; + + if (uid < 0 || pid < 0) + return ERR_ALARM_SYSTEM_FAIL; + + if (__get_cached_unique_name(pid, app_name, sizeof(app_name), NULL, uid) == false) { + snprintf(log_message, sizeof(log_message), "pid: %d. Can not get the unique_name.", pid); + _save_module_log("FAIL: DELETE ALL", log_message); + return ERR_ALARM_SYSTEM_FAIL; + } + + SECURE_LOGD("Called by process (pid:%d, unique_name=%s)", pid, app_name); + + for (gs_iter = alarm_context.alarms; gs_iter != NULL;) { + bool is_found = false; + entry = (__alarm_info_t*)gs_iter->data; + const char *tmp_appname = entry->app_unique_name; + SECURE_LOGD("Try to remove app_name[%s], alarm_id[%d]\n", tmp_appname, entry->alarm_id); + if (tmp_appname && strncmp(app_name, tmp_appname, strlen(tmp_appname)) == 0) { + if (_remove_from_scheduled_alarm_list(uid, entry->alarm_id)) + is_deleted = true; + + alarm_info = &entry->alarm_info; + if (!(alarm_info->alarm_type & ALARM_TYPE_VOLATILE)) { + if (!_delete_alarms(entry->alarm_id)) + SECURE_LOGE("_delete_alarms() is failed. pid[%d], alarm_id[%d]", pid, entry->alarm_id); + } + is_found = true; + } + + gs_iter = g_slist_next(gs_iter); + + if (is_found) { + LOGD("alarm_id[%d] is removed.", entry->alarm_id); + SECURE_LOGD("Removing is done. app_name[%s], alarm_id [%d]\n", tmp_appname, entry->alarm_id); + alarm_context.alarms = g_slist_remove(alarm_context.alarms, entry); + _release_alarm_info_t(entry); + } + } + + if (is_deleted && (g_slist_length(g_scheduled_alarm_list) == 0)) { + _alarm_disable_timer(); + _alarm_schedule(); + } + + snprintf(log_message, sizeof(log_message), "uid: %d, pid: %d, unique_name: %s", uid, pid, app_name); + _save_module_log("DELETE ALL", log_message); + + _rtc_set(); + return ALARMMGR_RESULT_SUCCESS; +} + +int alarm_manager_alarm_update(GVariant *parameters, uid_t uid, pid_t pid) +{ + int return_code = ALARMMGR_RESULT_SUCCESS; + alarm_info_t alarm_info; + char log_tag[ALARMMGR_LOG_TAG_SIZE] = {0,}; + char log_message[ALARMMGR_LOG_MESSAGE_SIZE] = {0,}; + int alarm_id; + int start_year, start_month, start_day, start_hour, start_min, start_sec; + int end_year, end_month, end_day; + int mode_repeat, alarm_type, update_flag; + time_t mode_interval, reserved_info; + gint64 tmp_mode_interval, tmp_reserved_info; + + if (uid < 0 || pid < 0) + return ERR_ALARM_SYSTEM_FAIL; + + g_variant_get(parameters, "(iiiiiiiiiixiixi)", + &alarm_id, &start_year, &start_month, &start_day, &start_hour, + &start_min, &start_sec, &end_year, &end_month, &end_day, + &tmp_mode_interval, &mode_repeat, &alarm_type, &tmp_reserved_info, + &update_flag); + + mode_interval = (time_t)tmp_mode_interval; + reserved_info = (time_t)tmp_reserved_info; + + return_code = __check_modifiable(uid, pid, alarm_id); + if (return_code != ALARMMGR_RESULT_SUCCESS) + return return_code; + + alarm_info.start.year = start_year; + alarm_info.start.month = start_month; + alarm_info.start.day = start_day; + alarm_info.start.hour = start_hour; + alarm_info.start.min = start_min; + alarm_info.start.sec = start_sec; + + alarm_info.end.year = end_year; + alarm_info.end.month = end_month; + alarm_info.end.day = end_day; + + alarm_info.mode.u_interval.interval = mode_interval; + alarm_info.mode.repeat = (alarm_repeat_mode_t)mode_repeat; + + alarm_info.alarm_type = alarm_type; + alarm_info.reserved_info = reserved_info; + + if (!__alarm_update(uid, alarm_id, &alarm_info, + update_flag, &return_code)) { + LOGE("Unable to update the alarm! alarm_id[%d], return_code[%d]", alarm_id, return_code); + strncpy(log_tag, "FAIL: UPDATE", sizeof(log_tag) - 1); + snprintf(log_message, sizeof(log_message), "alarmID: %d, uid: %d, pid: %d, duetime: %d-%d-%d %02d:%02d:%02d", + alarm_id, uid, pid, start_year, start_month, start_day, start_hour, start_min, start_sec); + _save_module_log(log_tag, log_message); + } + + return return_code; +} + +int alarm_manager_alarm_get_number_of_ids(uid_t uid, pid_t pid, int *num_of_ids) +{ + GSList *gs_iter = NULL; + char app_name[MAX_APP_ID_LEN] = { 0 }; + __alarm_info_t *entry = NULL; + int _num_of_ids = 0; + + *num_of_ids = _num_of_ids; + if (uid < 0 || pid < 0) + return ERR_ALARM_SYSTEM_FAIL; + + if (__get_cached_unique_name(pid, app_name, sizeof(app_name), NULL, uid) == false) + return ERR_ALARM_SYSTEM_FAIL; + + SECURE_LOGD("Called by process (uid:%d, pid:%d, unique_name:%s)", uid, pid, app_name); + + for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { + entry = (__alarm_info_t*)gs_iter->data; + SECURE_LOGD("app_name=%s, app_unique_name=%s", app_name, entry->app_unique_name); + if (entry->uid == uid && + strncmp(app_name, entry->app_unique_name, strlen(app_name)) == 0) { + (_num_of_ids)++; + SECURE_LOGD("inc number of alarms of app (uid:%d, pid:%d, unique_name:%s) is %d.", uid, pid, app_name, _num_of_ids); + } + } + + SECURE_LOGD("number of alarms of the process (uid:%d, pid:%d, unique_name:%s) is %d.", uid, pid, app_name, _num_of_ids); + *num_of_ids = _num_of_ids; + return ALARMMGR_RESULT_SUCCESS; +} + +int alarm_manager_alarm_get_list_of_ids(GVariant *parameters, uid_t uid, + pid_t pid, GVariant **alarm_array, int *num_of_alarm) +{ + GSList *gs_iter = NULL; + char app_name[MAX_APP_ID_LEN] = { 0 }; + __alarm_info_t *entry = NULL; + int index = 0; + int max_number_of_ids; + GVariantBuilder *builder = NULL; + + *alarm_array = g_variant_new("ai", NULL); + + if (uid < 0 || pid < 0) + return ERR_ALARM_SYSTEM_FAIL; + + g_variant_get(parameters, "(i)", &max_number_of_ids); + + if (max_number_of_ids <= 0) { + SECURE_LOGE("called for uid(%d) pid(%d), but max_number_of_ids(%d) is less than 0.", uid, pid, max_number_of_ids); + *num_of_alarm = 0; + return ALARMMGR_RESULT_SUCCESS; + } + + if (__get_cached_unique_name(pid, app_name, sizeof(app_name), NULL, uid) == false) + return ERR_ALARM_SYSTEM_FAIL; + + SECURE_LOGD("Called by process (uid: %d, pid:%d, unique_name=%s).", uid, pid, app_name); + builder = g_variant_builder_new(G_VARIANT_TYPE("ai")); + + for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { + entry = (__alarm_info_t*)gs_iter->data; + if (entry->uid == uid && + strncmp(app_name, (entry->app_unique_name), strlen(app_name)) == 0) { + g_variant_builder_add(builder, "i", entry->alarm_id); + index++; + SECURE_LOGE("called for alarmid(%d), but max_number_of_ids(%d) index %d.", entry->alarm_id, max_number_of_ids, index); + } + } + + *alarm_array = g_variant_new("ai", builder); + *num_of_alarm = index; + + g_variant_builder_unref(builder); + SECURE_LOGE("Called by uid (%d), pid (%d), but max_number_of_ids(%d).", uid, pid, index); + + return ALARMMGR_RESULT_SUCCESS; +} + +int alarm_manager_alarm_get_appsvc_info(GVariant *parameters, uid_t uid, gchar **b_data) +{ + bool found = false; + GSList *gs_iter = NULL; + __alarm_info_t *entry = NULL; + int return_code = ALARMMGR_RESULT_SUCCESS; + int alarm_id; + + if (uid < 0) + return ERR_ALARM_SYSTEM_FAIL; + + g_variant_get(parameters, "(i)", &alarm_id); + + SECURE_LOGD("called for uid(%d), alarm_id(%d)\n", uid, alarm_id); + + for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { + entry = (__alarm_info_t*)gs_iter->data; + if (entry->uid == uid && entry->alarm_id == alarm_id) { + found = true; + *b_data = g_strdup(entry->bundle); + break; + } + } + + if (found) { + if (*b_data == NULL) { + LOGE("The alarm(%d) is an regular alarm, not svc alarm.", alarm_id); + return_code = ERR_ALARM_INVALID_TYPE; + } + } else { + LOGE("The alarm(%d) is not found.", alarm_id); + return_code = ERR_ALARM_INVALID_ID; + } + + return return_code; +} + +int alarm_manager_alarm_get_noti_info(GVariant *parameters, uid_t uid, gchar **noti_data) +{ + bool found = false; + GSList *gs_iter = NULL; + __alarm_info_t *entry = NULL; + int return_code = ALARMMGR_RESULT_SUCCESS; + int alarm_id; + + if (uid < 0) + return ERR_ALARM_SYSTEM_FAIL; + + g_variant_get(parameters, "(i)", &alarm_id); + + SECURE_LOGD("called for uid(%d), alarm_id(%d)\n", uid, alarm_id); + + for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { + entry = (__alarm_info_t*)gs_iter->data; + if (entry->uid == uid && entry->alarm_id == alarm_id) { + found = true; + *noti_data = strdup(entry->noti); + break; + } + } + + if (found) { + if (*noti_data == NULL) { + LOGE("The alarm(%d) is an regular alarm, not svc alarm.", alarm_id); + return_code = ERR_ALARM_INVALID_TYPE; + } + } else { + LOGE("The alarm(%d) is not found.", alarm_id); + return_code = ERR_ALARM_INVALID_ID; + } + + return return_code; +} + +int alarm_manager_alarm_get_info(GVariant *parameters, uid_t uid, alarm_info_t *alarm_info) +{ + GSList *gs_iter = NULL; + __alarm_info_t *entry = NULL; + alarm_info_t *_alarm_info = NULL; + int alarm_id; + + if (uid < 0) + return ERR_ALARM_SYSTEM_FAIL; + + g_variant_get(parameters, "(i)", &alarm_id); + + SECURE_LOGD("called for uid(%d), alarm_id(%d)\n", uid, alarm_id); + for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { + entry = (__alarm_info_t*)gs_iter->data; + if (entry->uid == uid && entry->alarm_id == alarm_id) { + _alarm_info = &(entry->alarm_info); + break; + } + } + + if (_alarm_info == NULL) { + LOGE("The alarm(%d) is not found.", alarm_id); + return ERR_ALARM_INVALID_ID; + } else { + LOGD("The alarm(%d) is found.", alarm_id); + alarm_info->start.year = _alarm_info->start.year; + alarm_info->start.month = _alarm_info->start.month; + alarm_info->start.day = _alarm_info->start.day; + alarm_info->start.hour = _alarm_info->start.hour; + alarm_info->start.min = _alarm_info->start.min; + alarm_info->start.sec = _alarm_info->start.sec; + alarm_info->end.year = _alarm_info->end.year; + alarm_info->end.month = _alarm_info->end.month; + alarm_info->end.day = _alarm_info->end.day; + alarm_info->mode.u_interval.day_of_week = + _alarm_info->mode.u_interval.day_of_week; + alarm_info->mode.repeat = _alarm_info->mode.repeat; + alarm_info->alarm_type = _alarm_info->alarm_type; + alarm_info->reserved_info = _alarm_info->reserved_info; + } + + return ALARMMGR_RESULT_SUCCESS; +} + +int alarm_manager_alarm_get_next_duetime(GVariant *parameters, uid_t uid, time_t *duetime) +{ + GSList *gs_iter = NULL; + __alarm_info_t *entry = NULL; + __alarm_info_t *find_item = NULL; + int alarm_id; + + if (uid < 0) + return ERR_ALARM_SYSTEM_FAIL; + + g_variant_get(parameters, "(i)", &alarm_id); + + SECURE_LOGD("called for alarm_id(%d)\n", alarm_id); + for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { + entry = (__alarm_info_t*)gs_iter->data; + if (entry->uid == uid && entry->alarm_id == alarm_id) { + find_item = entry; + break; + } + } + + if (find_item == NULL) { + LOGE("The alarm(%d) is not found.", alarm_id); + return ERR_ALARM_INVALID_ID; + } + + _alarm_set_next_duetime(find_item); + LOGD("Next duetime : %s", ctime(&(find_item->due_time))); + + *duetime = find_item->due_time; + return ALARMMGR_RESULT_SUCCESS; +} + +int alarm_manager_alarm_get_all_info(uid_t uid, char **db_path) +{ + if (uid < 0) + return ERR_ALARM_SYSTEM_FAIL; + + return _get_db_path_for_all_info(uid, &(*db_path)); +} + +int alarm_manager_alarm_set_global(GVariant *parameters, uid_t uid) +{ + GSList *gs_iter = NULL; + __alarm_info_t *entry = NULL; + alarm_info_t *alarm_info = NULL; + int retval = 0; + int return_code = ALARMMGR_RESULT_SUCCESS; + char *callee_pkgid; + int alarm_id; + gboolean global; + + if (uid < 0) + return ERR_ALARM_SYSTEM_FAIL; + + g_variant_get(parameters, "(ib)", &alarm_id, &global); + + SECURE_LOGD("called for uid(%d), alarm_id(%d)\n", uid, alarm_id); + for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { + entry = (__alarm_info_t*)gs_iter->data; + if (entry->uid == uid && entry->alarm_id == alarm_id) { + alarm_info = &(entry->alarm_info); + break; + } + } + + if (alarm_info == NULL) { + LOGE("The alarm(%d) is not found.", alarm_id); + return ERR_ALARM_INVALID_ID; + } else { + LOGD("The alarm(%d) is found.", alarm_id); + + if (entry->callee_pkgid == NULL) + callee_pkgid = entry->app_service_name + 6; + else + callee_pkgid = entry->callee_pkgid; + + LOGD("The alarm pkgid : %s.", callee_pkgid); + + retval = _pkg_is_global(callee_pkgid, uid); + if (retval == ALARMMGR_RESULT_SUCCESS) { + entry->global = (bool)global; + if (!_alarm_set_global_to_db(entry, (bool)global)) + return_code = ERR_ALARM_SYSTEM_FAIL; + } else { + LOGE("Get pkginfo error [%d]", retval); + return_code = retval; + } + } + + return return_code; +} + +int alarm_manager_alarm_get_global(GVariant *parameters, gboolean *global) +{ + GSList *gs_iter = NULL; + __alarm_info_t *entry = NULL; + __alarm_info_t *find_item = NULL; + int alarm_id; + + g_variant_get(parameters, "(i)", &alarm_id); + + *global = false; + SECURE_LOGD("called for alarm_id(%d)\n", alarm_id); + for (gs_iter = alarm_context.alarms; gs_iter != NULL; gs_iter = g_slist_next(gs_iter)) { + entry = (__alarm_info_t*)gs_iter->data; + if (entry->alarm_id == alarm_id) { + find_item = entry; + break; + } + } + + if (find_item == NULL) { + LOGE("The alarm(%d) is not found.", alarm_id); + return ERR_ALARM_INVALID_ID; + } + + *global = (gboolean)find_item->global; + LOGD("Is global : %d", *global); + + return ALARMMGR_RESULT_SUCCESS; +} + +static void __initialize_alarm_list() +{ + alarm_context.alarms = NULL; + alarm_context.c_due_time = -1; + + _load_alarms_from_db(); + + _rtc_set(); /*Set RTC1 Alarm with alarm due time for alarm-manager initialization*/ +} + +static void __initialize_scheduled_alarm_list() +{ + _clear_scheduled_alarm_list(); +} + +static void __initialize_noti() +{ + /* VCONFKEY_SYSTEM_TIMECHANGE_EXTERNAL is set by OSP app-service. */ + if (vconf_notify_key_changed + (VCONFKEY_SYSTEM_TIMECHANGE_EXTERNAL, __on_system_time_external_changed, NULL) < 0) { + LOGD("Failed to add callback for time external changing event."); + } + + /* If the caller or callee app is uninstalled, all registered alarms will be canceled. */ + pkgmgr_client *pc = pkgmgr_client_new(PC_LISTENING); + pkgmgr_client_set_status_type(pc, PKGMGR_CLIENT_STATUS_UNINSTALL); + pkgmgr_client_listen_status(pc, __on_app_uninstalled, NULL); + + pkgmgr_client_set_status_type(pc, PKGMGR_CLIENT_STATUS_ENABLE_APP); + pkgmgr_client_listen_app_status(pc, __on_app_enable_cb, NULL); + + pkgmgr_client_set_status_type(pc, PKGMGR_CLIENT_STATUS_DISABLE_APP); + pkgmgr_client_listen_app_status(pc, __on_app_disable_cb, NULL); +} + +void _alarm_initialize() +{ +#if !(GLIB_CHECK_VERSION(2, 36, 0)) + g_type_init(); +#endif + + //For debug + int expire_mode = ALARM_EXPIRE_MODE_NORMAL; + vconf_get_int(VCONFKEY_ALARM_EXPIRE_MODE, &expire_mode); + LOGD("alarm_expire_mode : %d", expire_mode); + + alarm_context.timer = _initialize_timer(); + if (alarm_context.timer == -1) { + LOGE("because _initialize_timer failed, " + "alarm-server cannot be runned.\n"); + exit(1); + } + + if (_initialize_dbus() == false) { + /* because dbus's initialize + * failed, we cannot continue any more. */ + LOGE("because _initialize_dbus failed, " + "alarm-server cannot be runned.\n"); + exit(1); + } + + _initialize_module_log(); /* for module log */ + + __initialize_scheduled_alarm_list(); + if (_initialize_db() == false) { + LOGE("_initialize_db failed, " + "alarm cannot be stored to database.\n"); + } + __initialize_alarm_list(); + __initialize_noti(); + + if (!caller_appid_cache_table) { + caller_appid_cache_table = g_hash_table_new_full(g_direct_hash, + g_direct_equal, NULL, __free_cached_value); + } +} + +void _release_alarm_info_t(__alarm_info_t *entry) +{ + if (!entry) + return; + + if (entry->caller_pkgid) + free(entry->caller_pkgid); + if (entry->callee_pkgid) + free(entry->callee_pkgid); + if (entry->app_unique_name) + free(entry->app_unique_name); + if (entry->app_service_name) + free(entry->app_service_name); + if (entry->app_service_name_mod) + free(entry->app_service_name_mod); + if (entry->dst_service_name) + free(entry->dst_service_name); + + if (entry->dst_service_name_mod) + free(entry->dst_service_name_mod); + if (entry->bundle) + free(entry->bundle); + if (entry->noti) + free(entry->noti); + + free(entry); +} diff --git a/alarm-service.conf.in b/server/alarm-service.conf.in index 7ffdafd..7ffdafd 100644..100755 --- a/alarm-service.conf.in +++ b/server/alarm-service.conf.in diff --git a/server/org.tizen.alarm.manager.service.in b/server/org.tizen.alarm.manager.service.in new file mode 100644 index 0000000..18f0364 --- /dev/null +++ b/server/org.tizen.alarm.manager.service.in @@ -0,0 +1,4 @@ +[D-BUS Service] +Name=@DBUS_INTERFACE@ +Exec=/bin/false +SystemdService=@SERVER@.service diff --git a/session-agent/CMakeLists.txt b/session-agent/CMakeLists.txt new file mode 100644 index 0000000..a6417af --- /dev/null +++ b/session-agent/CMakeLists.txt @@ -0,0 +1,20 @@ +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + +SET(AGENT "alarm_session_agent") + +SET(SRC agent.c) + +PKG_CHECK_MODULES(agent_pkgs REQUIRED gio-2.0 glib-2.0 dlog bundle libsystemd-daemon) +FOREACH(flag ${agent_pkgs_CFLAGS_OTHER}) + IF(${flag} MATCHES "\\-D+") + ADD_DEFINITIONS(${flag}) + ENDIF(${flag} MATCHES "\\-D+") +ENDFOREACH(flag) +INCLUDE_DIRECTORIES(${agent_pkgs_INCLUDE_DIRS}) +LINK_DIRECTORIES(${agent_pkgs_LIBRARY_DIRS}) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fpie") + +ADD_EXECUTABLE(${AGENT} ${SRC}) +TARGET_LINK_LIBRARIES(${AGENT} ${agent_pkgs_LIBRARIES} dl) +INSTALL(TARGETS ${AGENT} DESTINATION ${BIN_INSTALL_DIR}) diff --git a/alarm-session-agent/agent.c b/session-agent/agent.c index f353c48..370c397 100755 --- a/alarm-session-agent/agent.c +++ b/session-agent/agent.c @@ -1,13 +1,11 @@ /* - * alarm session agent + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * - * Copyright (C) 2016 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); + * 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 + * 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, @@ -15,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include <stdio.h> #include <stdlib.h> #include <stdbool.h> diff --git a/alarm-session-agent/agent.h b/session-agent/agent.h index c15d35e..babd7e3 100644 --- a/alarm-session-agent/agent.h +++ b/session-agent/agent.h @@ -1,13 +1,11 @@ /* - * alarm session agent + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * - * Copyright (C) 2016 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the License); + * 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 + * 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, @@ -15,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #pragma once #define _GNU_SOURCE diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index c28727d..0000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,50 +0,0 @@ -SET(this_target alarm) - -INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) - -SET(LIB_PKGS glib-2.0 gobject-2.0 dlog bundle appsvc gio-2.0 gio-unix-2.0 libtzplatform-config notification) - -INCLUDE(FindPkgConfig) -pkg_check_modules(lib_pkgs REQUIRED ${LIB_PKGS}) - -FOREACH(flag ${lib_pkgs_CFLAGS}) - SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") -ENDFOREACH(flag) - -AUX_SOURCE_DIRECTORY(./ LIB_SRCS) - -ADD_CUSTOM_COMMAND( - WORKING_DIRECTORY - OUTPUT alarm-mgr-stub.c - COMMAND gdbus-codegen --interface-prefix org.tizen. - --generate-c-code alarm-mgr-stub - ../alarm_mgr.xml - COMMENT "Generating Server GDBus .c/.h") - -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -Wno-unused -fvisibility=hidden") - -ADD_LIBRARY(${this_target} SHARED ${LIB_SRCS} alarm-mgr-stub.c) - -SET_TARGET_PROPERTIES(${this_target} PROPERTIES COMPILE_FLAGS "${EXTRA_CFLAGS}") -SET_TARGET_PROPERTIES(${this_target} PROPERTIES LINK_FLAGS "-Wl,--as-needed -Wl,--hash-style=both") -SET_TARGET_PROPERTIES(${this_target} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${EXECUTABLE_OUTPUT_PATH}") - -SET_TARGET_PROPERTIES(${this_target} - PROPERTIES - VERSION ${FULLVER} - SOVERSION ${MAJORVER} - CLEAN_DIRECT_OUTPUT 1 -) - -TARGET_LINK_LIBRARIES(${this_target} ${lib_pkgs_LDFLAGS}) - -# pkgconfig file -CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/alarm-service.pc.in ${CMAKE_SOURCE_DIR}/alarm-service.pc @ONLY) -INSTALL(FILES ${CMAKE_SOURCE_DIR}/alarm-service.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) -INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION include/ - FILES_MATCHING - PATTERN "*-internal.h" EXCLUDE - PATTERN "*.h" - ) -INSTALL(TARGETS ${this_target} DESTINATION ${CMAKE_INSTALL_LIBDIR}) - diff --git a/src/alarm-lib-stub.c b/src/alarm-lib-stub.c deleted file mode 100644 index ef9ff21..0000000 --- a/src/alarm-lib-stub.c +++ /dev/null @@ -1,984 +0,0 @@ -/* - * Copyright (c) 2000 - 2016 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 <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <sys/types.h> -#include <string.h> -#include <glib.h> -#include <notification.h> -#include <notification_ipc.h> -#include "alarm.h" -#include "alarm-internal.h" -#include "alarm-mgr-stub.h" - -#define ALARM_SERVICE_NAME "appframework.alarm" -#define ALARM_OBJECT_PATH "/appframework/alarm" -#define ALARM_INTERFACE_NAME "appframework.alarm" - -bool _send_alarm_create(alarm_context_t context, alarm_info_t *alarm_info, - alarm_id_t *alarm_id, const char *dst_service_name, - const char *dst_service_name_mod, int *error_code); -bool _send_alarm_create_appsvc(alarm_context_t context, alarm_info_t *alarm_info, - alarm_id_t *alarm_id, bundle *b, int *error_code); -bool _send_alarm_delete(alarm_context_t context, alarm_id_t alarm_id, - int *error_code); -bool _send_alarm_get_list_of_ids(alarm_context_t context, int maxnum_of_ids, - alarm_id_t *alarm_id, int *num_of_ids, int *error_code); -bool _send_alarm_get_number_of_ids(alarm_context_t context, int *num_of_ids, - int *error_code); -bool _send_alarm_get_info(alarm_context_t context, alarm_id_t alarm_id, - alarm_info_t *alarm_info, int *error_code); - -bool _send_alarm_create_noti(alarm_context_t context, alarm_info_t *alarm_info, - alarm_id_t *alarm_id, notification_h noti, int *error_code) -{ - gboolean ret; - GError *error = NULL; - int return_code = 0; - GVariant *noti_gv = NULL; - char *noti_data; - guchar *data; - int datalen = 0; - - noti_gv = notification_ipc_make_gvariant_from_noti(noti, true); - if (!noti_gv) { - if (error_code) - *error_code = ERR_ALARM_SYSTEM_FAIL; - return false; - } - - datalen = g_variant_get_size(noti_gv); - if (datalen < 0) - return false; - - data = malloc(datalen); - if (!data) - return false; - - g_variant_store(noti_gv, data); - noti_data = g_base64_encode((guchar *)data, datalen); - - ret = alarm_manager_call_alarm_create_noti_sync((AlarmManager *)context.proxy, - alarm_info->start.year, - alarm_info->start.month, - alarm_info->start.day, - alarm_info->start.hour, - alarm_info->start.min, - alarm_info->start.sec, - alarm_info->end.year, - alarm_info->end.month, - alarm_info->end.day, - alarm_info->mode.u_interval.day_of_week, - alarm_info->mode.u_interval.interval, - alarm_info->mode.repeat, - alarm_info->alarm_type, - alarm_info->reserved_info, - (char *)noti_data, - alarm_id, &return_code, - NULL, &error); - - if (noti_data) - free(noti_data); - if (data) - free(data); - g_variant_unref(noti_gv); - - if (ret != TRUE) { - /* g_dbus_proxy_call_sync error */ - /* error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT( - "alarm_manager_call_alarm_create_noti_sync()failed. alarm_id[%d], return_code[%d].", - *(int *)alarm_id, return_code); - if (error_code) { - if (error && error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - if (error) { - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - g_error_free(error); - } - return false; - } - - if (return_code != 0) { - if (error_code) - *error_code = return_code; - return false; - } - - return true; -} - -bool _send_alarm_create_appsvc(alarm_context_t context, alarm_info_t *alarm_info, - alarm_id_t *alarm_id, bundle *b, - int *error_code) -{ - gboolean ret; - GError *error = NULL; - int return_code = 0; - bundle_raw *b_data = NULL; - int datalen = 0; - - if (bundle_encode(b, &b_data, &datalen)) { - ALARM_MGR_EXCEPTION_PRINT("Unable to encode the bundle data\n"); - if (error_code) - *error_code = ERR_ALARM_SYSTEM_FAIL; - return false; - } - - ret = alarm_manager_call_alarm_create_appsvc_sync((AlarmManager *)context.proxy, - alarm_info->start.year, - alarm_info->start.month, - alarm_info->start.day, - alarm_info->start.hour, - alarm_info->start.min, - alarm_info->start.sec, - alarm_info->end.year, - alarm_info->end.month, - alarm_info->end.day, - alarm_info->mode.u_interval.day_of_week, - alarm_info->mode.u_interval.interval, - alarm_info->mode.repeat, - alarm_info->alarm_type, - alarm_info->reserved_info, - (char *)b_data, - alarm_id, &return_code, - NULL, &error); - if (b_data) { - free(b_data); - b_data = NULL; - } - - if (ret != TRUE) { - /* g_dbus_proxy_call_sync error */ - /* error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT( - "alarm_manager_call_alarm_create_appsvc_sync()failed. alarm_id[%d], return_code[%d].", - *(int *)alarm_id, return_code); - if (error_code) { - if (error && error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - if (error) { - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - g_error_free(error); - } - return false; - } - - if (return_code != 0) { - if (error_code) - *error_code = return_code; - return false; - } - - return true; -} - -bool _send_alarm_create(alarm_context_t context, alarm_info_t *alarm_info, - alarm_id_t *alarm_id, const char *dst_service_name, const char *dst_service_name_mod, - int *error_code) -{ - GError *error = NULL; - int return_code = 0; - - /*TODO: Dbus bus name validation is must & will be added to avoid alarm-server crash*/ - if (context.app_service_name == NULL - && strlen(dst_service_name) == 4 - && strncmp(dst_service_name, "null", 4) == 0) { - ALARM_MGR_EXCEPTION_PRINT("Invalid arg. Provide valid destination or call alarmmgr_init()\n"); - if (error_code) - *error_code = ERR_ALARM_INVALID_PARAM; - return false; - } - - if (!alarm_manager_call_alarm_create_sync((AlarmManager *)context.proxy, - context.app_service_name, - context.app_service_name_mod, - alarm_info->start.year, - alarm_info->start.month, - alarm_info->start.day, - alarm_info->start.hour, - alarm_info->start.min, - alarm_info->start.sec, - alarm_info->msec, - alarm_info->end.year, - alarm_info->end.month, - alarm_info->end.day, - alarm_info->mode.u_interval.day_of_week, - alarm_info->mode.repeat, - alarm_info->alarm_type, - alarm_info->reserved_info, - dst_service_name, dst_service_name_mod, - alarm_id, &return_code, - NULL, &error)) { - /* g_dbus_proxy_call_sync error error */ - /* error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT( - "alarm_manager_call_alarm_create_sync()failed. alarm_id[%d], return_code[%d]", - *(int *)alarm_id, return_code); - if (error_code) { - if (error && error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - if (error) { - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - g_error_free(error); - } - return false; - } - - if (return_code != 0) { - if (error_code) - *error_code = return_code; - return false; - } - - return true; -} - -bool _send_alarm_create_periodic(alarm_context_t context, int interval, int is_ref, - int method, alarm_id_t *alarm_id, int *error_code) -{ - GError *error = NULL; - int return_code = 0; - - if (context.app_service_name == NULL) { - ALARM_MGR_EXCEPTION_PRINT("Invalid arg. Provide valid destination or call alarmmgr_init()\n"); - if (error_code) - *error_code = ERR_ALARM_INVALID_PARAM; - return false; - } - - if (!alarm_manager_call_alarm_create_periodic_sync((AlarmManager *)context.proxy, - context.app_service_name, - context.app_service_name_mod, - interval, is_ref, method, - alarm_id, &return_code, NULL, &error)) { - ALARM_MGR_EXCEPTION_PRINT("alarm_manager_call_alarm_create_periodic_sync()failed. alarm_id[%d], return_code[%d]", - *(int *)alarm_id, return_code); - if (error_code) { - if (error && error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - if (error) { - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - g_error_free(error); - } - return false; - } - - if (return_code != 0) { - if (error_code) - *error_code = return_code; - return false; - } - - return true; -} - -bundle *_send_alarm_get_appsvc_info(alarm_context_t context, alarm_id_t alarm_id, int *error_code) -{ - GError *error = NULL; - int return_code = 0; - bundle *b = NULL; - gchar *b_data = NULL; - - if (!alarm_manager_call_alarm_get_appsvc_info_sync - ((AlarmManager *)context.proxy, alarm_id, &b_data, &return_code, NULL, &error)) { - /* g_dbus_proxy_call_sync error */ - /*error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT("alarm_manager_call_alarm_get_appsvc_info_sync() failed. alarm_id[%d], return_code[%d].", - (int)alarm_id, return_code); - if (error_code) { - if (error && error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - if (error) { - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - g_error_free(error); - } - - if (b_data) - g_free(b_data); - - return NULL; - } - - if (return_code != 0) { - if (error_code) - *error_code = return_code; - } else { - b = bundle_decode((bundle_raw *)b_data, strlen(b_data)); - } - - if (b_data) - g_free(b_data); - - return b; -} - -notification_h _send_alarm_get_noti_info(alarm_context_t context, alarm_id_t alarm_id, int *error_code) -{ - GError *error = NULL; - int return_code = 0; - int datalen; - GVariant *noti_gv = NULL; - GVariant *body = NULL; - notification_h noti = NULL; - gchar *noti_data = NULL; - guchar *data; - - if (!alarm_manager_call_alarm_get_noti_info_sync - ((AlarmManager *)context.proxy, alarm_id, ¬i_data, &return_code, NULL, &error)) { - /* g_dbus_proxy_call_sync error */ - /*error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT("alarm_manager_call_alarm_get_appsvc_info_sync() failed. alarm_id[%d], return_code[%d].", - (int)alarm_id, return_code); - if (error_code) { - if (error && error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - if (error) { - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - g_error_free(error); - } - - if (noti_data) - g_free(noti_data); - - return NULL; - } - - if (return_code != 0) { - if (error_code) - *error_code = return_code; - } else { - data = g_base64_decode(noti_data, (gsize *)&datalen); - - noti_gv = g_variant_new_from_data(G_VARIANT_TYPE("(v)"), - data, datalen, - TRUE, NULL, NULL); - - g_variant_get(noti_gv, "(v)", &body); - - noti = notification_create(NOTIFICATION_TYPE_NOTI); - notification_ipc_make_noti_from_gvariant(noti, body); - - g_free(data); - g_variant_unref(noti_gv); - } - - if (noti_data) - g_free(noti_data); - - return noti; -} - -bool _send_alarm_set_rtc_time(alarm_context_t context, alarm_date_t *time, int *error_code) -{ - - GError *error = NULL; - int return_code = 0; - - if (!alarm_manager_call_alarm_set_rtc_time_sync - ((AlarmManager *)context.proxy, time->year, time->month, time->day, - time->hour, time->min, time->sec, &return_code, NULL, &error)) { - /* g_dbus_proxy_call_sync error */ - /*error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT("alarm_manager_call_alarm_set_rtc_time() failed. return_code[%d]", return_code); - if (error_code) { - if (error && error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - if (error) { - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - g_error_free(error); - } - - return false; - } - - if (return_code != 0) { - if (error_code) - *error_code = return_code; - return false; - } - - return true; -} - -bool _send_alarm_delete(alarm_context_t context, alarm_id_t alarm_id, int *error_code) -{ - GError *error = NULL; - int return_code = 0; - - if (!alarm_manager_call_alarm_delete_sync - ((AlarmManager *)context.proxy, alarm_id, &return_code, NULL, &error)) { - /* g_dbus_proxy_call_sync error */ - /*error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT("alarm_manager_call_alarm_delete_sync() failed. alarm_id[%d], return_code[%d]", - (int)alarm_id, return_code); - if (error_code) { - if (error && error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - if (error) { - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - g_error_free(error); - } - - return false; - } - - if (return_code != 0) { - if (error_code) - *error_code = return_code; - return false; - } - - return true; -} - -bool _send_alarm_delete_all(alarm_context_t context, int *error_code) -{ - GError *error = NULL; - int return_code = 0; - - if (!alarm_manager_call_alarm_delete_all_sync - ((AlarmManager *)context.proxy, &return_code, NULL, &error)) { - /* g_dbus_proxy_call_sync error */ - /*error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT("alarm_manager_call_alarm_delete_all_sync() failed. return_code[%d]", return_code); - if (error_code) { - if (error && error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - if (error) { - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - g_error_free(error); - } - - return false; - } - - if (return_code != 0) { - if (error_code) - *error_code = return_code; - return false; - } - - return true; -} - -bool _send_alarm_get_list_of_ids(alarm_context_t context, int maxnum_of_ids, - alarm_id_t *alarm_id, int *num_of_ids, - int *error_code) -{ - GError *error = NULL; - GVariant *alarm_array = NULL; - int return_code = 0; - - if (!alarm_manager_call_alarm_get_list_of_ids_sync((AlarmManager *)context.proxy, - maxnum_of_ids, &alarm_array, - num_of_ids, &return_code, NULL, &error)) { - /* g_dbus_proxy_call_sync error */ - /*error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT( - "alarm_manager_call_alarm_get_list_of_ids_sync() failed by dbus. alarm_id[%d], return_code[%d]\n", - *(int *)alarm_id, return_code); - if (error_code) { - if (error && error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - if (error) { - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - g_error_free(error); - } - - return false; - } - - if (return_code != 0) { - if (error_code) - *error_code = return_code; - return false; - } else { - GVariantIter *iter = NULL; - gint i = 0; - g_variant_get(alarm_array, "ai", &iter); - while (g_variant_iter_loop(iter, "i", &alarm_id[i])) { - ALARM_MGR_LOG_PRINT("alarm_id (%d)", alarm_id[i]); - i++; - } - g_variant_iter_free(iter); - *num_of_ids = i; - g_variant_unref(alarm_array); - } - - return true; -} - -bool _send_alarm_get_number_of_ids(alarm_context_t context, int *num_of_ids, - int *error_code) -{ - GError *error = NULL; - gint return_code = 0; - - if (!alarm_manager_call_alarm_get_number_of_ids_sync((AlarmManager *)context.proxy, num_of_ids, &return_code, NULL, &error)) { - /* g_dbus_proxy_call_sync error */ - /* error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT( - "alarm_manager_call_alarm_get_number_of_ids_sync() failed by dbus. return_code[%d]", - return_code); - - if (error_code) { - if (error && error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - if (error) { - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - g_error_free(error); - } - return false; - } - - if (return_code != 0) { - if (error_code) - *error_code = return_code; - return false; - } - - return true; -} - -bool _send_alarm_get_info(alarm_context_t context, alarm_id_t alarm_id, - alarm_info_t *alarm_info, int *error_code) -{ - GError *error = NULL; - int return_code = 0; - - if (!alarm_manager_call_alarm_get_info_sync((AlarmManager *)context.proxy, - alarm_id, &alarm_info->start.year, - &alarm_info->start.month, &alarm_info->start.day, - &alarm_info->start.hour, &alarm_info->start.min, - &alarm_info->start.sec, &alarm_info->end.year, - &alarm_info->end.month, &alarm_info->end.day, - &alarm_info->mode.u_interval.day_of_week, - (gint *)&alarm_info->mode.repeat, - &alarm_info->alarm_type, &alarm_info->reserved_info, &return_code, NULL, &error)) { - /* g_dbus_proxy_call_sync error */ - /* error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT( - "alarm_manager_call_alarm_get_info_sync() failed by dbus. alarm_id[%d], return_code[%d]\n", - (int)alarm_id, return_code); - if (error_code) { - if (error && error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - if (error) { - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - g_error_free(error); - } - return false; - } - - if (return_code != 0) { - if (error_code) - *error_code = return_code; - return false; - } - - return true; -} - -bool _send_alarm_get_next_duetime(alarm_context_t context, - alarm_id_t alarm_id, time_t* duetime, - int *error_code) -{ - GError *error = NULL; - int return_code = 0; - - if (!alarm_manager_call_alarm_get_next_duetime_sync((AlarmManager *)context.proxy, - alarm_id, (gint *)duetime, &return_code, NULL, &error)) { - /*g_dbus_proxy_call_sync error */ - /*error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT( - "alarm_manager_call_alarm_get_next_duetime_sync() failed by dbus. alarm_id[%d], return_code[%d]\n", - (int)alarm_id, return_code); - if (error_code) { - if (error && error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - if (error) { - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - g_error_free(error); - } - return false; - } - - if (return_code != 0) { - if (error_code) - *error_code = return_code; - return false; - } - - return true; -} - -bool _send_alarm_get_all_info(alarm_context_t context, char **db_path, int *error_code) -{ - GError *error = NULL; - int return_code = 0; - - if (!alarm_manager_call_alarm_get_all_info_sync((AlarmManager *)context.proxy, db_path, &return_code, NULL, &error)) { - /*g_dbus_proxy_call_sync error */ - /*error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT("alarm_manager_call_alarm_get_all_info_sync() failed by dbus. return_code[%d]", return_code); - if (error_code) { - if (error && error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - if (error) { - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - g_error_free(error); - } - return false; - } - - if (return_code != ALARMMGR_RESULT_SUCCESS) { - if (error_code) - *error_code = return_code; - return false; - } - - return true; -} - -bool _send_alarm_set_time(alarm_context_t context, int new_time, int *error_code) -{ - GError *error = NULL; - int return_code = 0; - - if (!alarm_manager_call_alarm_set_time_sync((AlarmManager *)context.proxy, new_time, &return_code, NULL, &error)) { - /*g_dbus_proxy_call_sync error */ - /*error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT("alarm_manager_call_alarm_set_time_sync() failed by dbus. return_code[%d]", return_code); - if (error) { - ALARM_MGR_EXCEPTION_PRINT("dbus error message: %s", error->message); - g_error_free(error); - } - if (error_code) - *error_code = ERR_ALARM_SYSTEM_FAIL; - return false; - } - - if (return_code != ALARMMGR_RESULT_SUCCESS) { - if (error_code) - *error_code = return_code; - return false; - } - - return true; -} - -static void _alarm_set_time_cb(GObject *source_object, GAsyncResult *res, - gpointer user_data) -{ - int return_code = 0; - GError *error = NULL; - alarm_set_time_data_t *func_data = (alarm_set_time_data_t *)user_data; - - if (!alarm_manager_call_alarm_set_time_finish((AlarmManager *)func_data->proxy, - (gint *)&return_code, - res, &error)) { - if (error) { - ALARM_MGR_EXCEPTION_PRINT("dbus error message: %s", error->message); - g_error_free(error); - } - return_code = ERR_ALARM_SYSTEM_FAIL; - } - - if (func_data->callback != NULL) - func_data->callback(return_code, func_data->user_data); - - g_free(func_data); -} - -bool _send_alarm_set_time_async(alarm_context_t context, int new_time, alarm_set_time_cb_t result_cb, void *user_data) -{ - alarm_set_time_data_t *func_data; - - func_data = g_try_new0(alarm_set_time_data_t, 1); - - if (func_data == NULL) - return false; - - func_data->callback = result_cb; - func_data->user_data = user_data; - func_data->proxy = context.proxy; - - alarm_manager_call_alarm_set_time((AlarmManager *)context.proxy, new_time, - NULL, _alarm_set_time_cb, func_data); - - return true; -} - -bool _send_alarm_set_time_with_propagation_delay(alarm_context_t context, unsigned int new_sec, unsigned int new_nsec, unsigned int req_sec, unsigned int req_nsec, int *error_code) -{ - GError *error = NULL; - int return_code = 0; - - if (!alarm_manager_call_alarm_set_time_with_propagation_delay_sync((AlarmManager *)context.proxy, new_sec, new_nsec, req_sec, req_nsec, &return_code, NULL, &error)) { - /*g_dbus_proxy_call_sync error */ - /*error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT("alarm_manager_call_alarm_set_time_with_propagation_delay_sync() failed by dbus. return_code[%d]", return_code); - if (error_code) { - if (error && error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - if (error) { - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - g_error_free(error); - } - return false; - } - - if (return_code != ALARMMGR_RESULT_SUCCESS) { - if (error_code) - *error_code = return_code; - return false; - } - - return true; -} - -static void _alarm_set_time_with_delay_cb(GObject *source_object, GAsyncResult *res, - gpointer user_data) -{ - int return_code = 0; - GError *error = NULL; - alarm_set_time_data_t *func_data = (alarm_set_time_data_t *)user_data; - - if (!alarm_manager_call_alarm_set_time_with_propagation_delay_finish((AlarmManager *)func_data->proxy, - (gint *)&return_code, - res, &error)) { - if (error) { - ALARM_MGR_EXCEPTION_PRINT("dbus error message: %s", error->message); - g_error_free(error); - } - return_code = ERR_ALARM_SYSTEM_FAIL; - } - - if (func_data->callback != NULL) - func_data->callback(return_code, func_data->user_data); - - g_free(func_data); -} - -bool _send_alarm_set_time_with_propagation_delay_async(alarm_context_t context, unsigned int new_sec, unsigned int new_nsec, unsigned int req_sec, unsigned int req_nsec, alarm_set_time_cb_t result_cb, void *user_data) -{ - alarm_set_time_data_t *func_data; - - func_data = g_try_new0(alarm_set_time_data_t, 1); - - if (func_data == NULL) - return false; - - func_data->callback = result_cb; - func_data->user_data = user_data; - func_data->proxy = context.proxy; - - alarm_manager_call_alarm_set_time_with_propagation_delay((AlarmManager *)context.proxy, - new_sec, new_nsec, req_sec, req_nsec, - NULL, _alarm_set_time_with_delay_cb, func_data); - - return true; -} - -bool _send_alarm_set_timezone(alarm_context_t context, char *tzpath_str, int *error_code) -{ - GError *error = NULL; - int return_code = 0; - - if (!alarm_manager_call_alarm_set_timezone_sync((AlarmManager *)context.proxy, tzpath_str, &return_code, NULL, &error)) { - /*g_dbus_proxy_call_sync error */ - /*error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT("alarm_manager_call_alarm_set_timezone_sync() failed by dbus. return_code[%d]", return_code); - if (error_code) { - if (error && error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - if (error) { - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - g_error_free(error); - } - return false; - } - - if (return_code != ALARMMGR_RESULT_SUCCESS) { - if (error_code) - *error_code = return_code; - return false; - } - - return true; -} - -bool _send_alarm_set_global(alarm_context_t context, const alarm_id_t alarm_id, bool global, int *error_code) -{ - GError *error = NULL; - int return_code = 0; - - if (!alarm_manager_call_alarm_set_global_sync((AlarmManager *)context.proxy, alarm_id, global, &return_code, NULL, &error)) { - /*g_dbus_proxy_call_sync error */ - /*error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT("alarm_manager_call_alarm_set_global_sync() failed by dbus. return_code[%d]", return_code); - if (error_code) { - if (error && error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - if (error) { - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - g_error_free(error); - } - return false; - } - - if (return_code != ALARMMGR_RESULT_SUCCESS) { - if (error_code) - *error_code = return_code; - return false; - } - - return true; -} - -bool _send_alarm_get_global(alarm_context_t context, const alarm_id_t alarm_id, bool *global, int *error_code) -{ - GError *error = NULL; - int return_code = 0; - gboolean _global; - - if (!alarm_manager_call_alarm_get_global_sync((AlarmManager *)context.proxy, alarm_id, &_global, &return_code, NULL, &error)) { - /*g_dbus_proxy_call_sync error */ - /*error_code should be set */ - ALARM_MGR_EXCEPTION_PRINT("alarm_manager_call_alarm_get_global_sync() failed by dbus. return_code[%d]", return_code); - if (error_code) { - if (error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - if (error) { - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - g_error_free(error); - } - return false; - } - - if (return_code != ALARMMGR_RESULT_SUCCESS) { - if (error_code) - *error_code = return_code; - return false; - } - - *global = (bool)_global; - return true; -} - -bool _send_alarm_update(alarm_context_t context, alarm_id_t alarm_id, - alarm_info_t *alarm_info, int update_flag, int *error_code) -{ - GError *error = NULL; - int return_code = 0; - - if (!alarm_manager_call_alarm_update_sync((AlarmManager *)context.proxy, - alarm_id, - alarm_info->start.year, - alarm_info->start.month, - alarm_info->start.day, - alarm_info->start.hour, - alarm_info->start.min, - alarm_info->start.sec, - alarm_info->end.year, - alarm_info->end.month, - alarm_info->end.day, - alarm_info->mode.u_interval.interval, - alarm_info->mode.repeat, - alarm_info->alarm_type, - alarm_info->reserved_info, - update_flag, - &return_code, - NULL, &error)) { - ALARM_MGR_EXCEPTION_PRINT( - "alarm_manager_call_alarm_update_sync()failed. alarm_id[%d], return_code[%d]", - (int)alarm_id, return_code); - ALARM_MGR_EXCEPTION_PRINT("error->message is %s(%d)", error->message, error->code); - if (error_code) { - if (error->code == G_DBUS_ERROR_ACCESS_DENIED) - *error_code = ERR_ALARM_NO_PERMISSION; - else - *error_code = ERR_ALARM_SYSTEM_FAIL; - } - g_error_free(error); - return false; - } - - if (return_code != 0) { - if (error_code) - *error_code = return_code; - return false; - } - - return true; -} diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt index a83ec80..3a0431d 100644 --- a/tool/CMakeLists.txt +++ b/tool/CMakeLists.txt @@ -1,15 +1,20 @@ -# Test executable -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${TEST_CFLAGS} -fpie") +LINK_DIRECTORIES(${CMAKE_BINARY_DIR}) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fpie") + +PKG_CHECK_MODULES(tool_pkgs REQUIRED dlog glib-2.0 notification) +INCLUDE_DIRECTORIES(${tool_pkgs_INCLUDE_DIRS}) +LINK_DIRECTORIES(${tool_pkgs_LIBRARY_DIRS}) add_executable(alarmmgr_get_all_info alarmmgr_get_all_info.c) -target_link_libraries(alarmmgr_get_all_info alarm ${pkgs_LDFLAGS} "-pie") -INSTALL(TARGETS alarmmgr_get_all_info DESTINATION bin) +target_link_libraries(alarmmgr_get_all_info ${LIBRARY} ${tool_pkgs_LIBRARIES}) +INSTALL(TARGETS alarmmgr_get_all_info DESTINATION ${BIN_INSTALL_DIR}) add_executable(alarmmgr_add_reference_periodic_alarm_withcb alarmmgr_add_reference_periodic_alarm_withcb.c) -target_link_libraries(alarmmgr_add_reference_periodic_alarm_withcb alarm ${pkgs_LDFLAGS} "-pie") -INSTALL(TARGETS alarmmgr_add_reference_periodic_alarm_withcb DESTINATION bin) +target_link_libraries(alarmmgr_add_reference_periodic_alarm_withcb ${LIBRARY} ${tool_pkgs_LIBRARIES}) +INSTALL(TARGETS alarmmgr_add_reference_periodic_alarm_withcb DESTINATION ${BIN_INSTALL_DIR}) add_executable(alarmmgr_add_periodic_alarm_withcb alarmmgr_add_periodic_alarm_withcb.c) -target_link_libraries(alarmmgr_add_periodic_alarm_withcb alarm ${pkgs_LDFLAGS} "-pie") -INSTALL(TARGETS alarmmgr_add_periodic_alarm_withcb DESTINATION bin) - +target_link_libraries(alarmmgr_add_periodic_alarm_withcb ${LIBRARY} ${tool_pkgs_LIBRARIES}) +INSTALL(TARGETS alarmmgr_add_periodic_alarm_withcb DESTINATION ${BIN_INSTALL_DIR}) diff --git a/tool/alarmmgr_add_periodic_alarm_withcb.c b/tool/alarmmgr_add_periodic_alarm_withcb.c index 1c7195a..f4240d0 100644 --- a/tool/alarmmgr_add_periodic_alarm_withcb.c +++ b/tool/alarmmgr_add_periodic_alarm_withcb.c @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2015 - 2019 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<stdio.h> #include<stdlib.h> #include<glib.h> diff --git a/tool/alarmmgr_add_reference_periodic_alarm_withcb.c b/tool/alarmmgr_add_reference_periodic_alarm_withcb.c index b8c1a23..c66f788 100644 --- a/tool/alarmmgr_add_reference_periodic_alarm_withcb.c +++ b/tool/alarmmgr_add_reference_periodic_alarm_withcb.c @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2015 - 2019 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<stdio.h> #include<stdlib.h> #include<glib.h> diff --git a/tool/alarmmgr_get_all_info.c b/tool/alarmmgr_get_all_info.c index 40106de..be79431 100644 --- a/tool/alarmmgr_get_all_info.c +++ b/tool/alarmmgr_get_all_info.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 - 2016 Samsung Electronics Co., Ltd. All rights reserved. + * Copyright (c) 2014 - 2019 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #include<dlog.h> #include<stdio.h> #include<stdlib.h> diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt new file mode 100755 index 0000000..8e7cad9 --- /dev/null +++ b/unittest/CMakeLists.txt @@ -0,0 +1,31 @@ +LINK_DIRECTORIES(${CMAKE_BINARY_DIR}) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/common) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/server) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/mock) + +ENABLE_TESTING() + +SET(GTEST_TEST "gtest-alarmmgr") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fpie") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpie") + +FILE(GLOB GTEST_TEST_SRCS *.cpp) + +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/ GTEST_TEST_SRCS) +AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR}/mock GTEST_TEST_SRCS) + +PKG_CHECK_MODULES(gtest_pkgs REQUIRED glib-2.0 gmock) +INCLUDE_DIRECTORIES(${gtest_pkgs_INCLUDE_DIRS}) +LINK_DIRECTORIES(${gtest_pkgs_LIBRARY_DIRS}) + +INCLUDE_DIRECTORIES(${svr_pkgs_INCLUDE_DIRS}) +LINK_DIRECTORIES(${svr_pkgs_LIBRARY_DIRS}) + +ADD_EXECUTABLE(${GTEST_TEST} ${GTEST_TEST_SRCS}) +TARGET_LINK_LIBRARIES(${GTEST_TEST} ${gtest_pkgs_LIBRARIES} ${LIBRARY} ${svr_pkgs_LIBRARIES} alarm rt) + +ADD_TEST(${GTEST_TEST} ${GTEST_TEST}) + +INSTALL(TARGETS ${GTEST_TEST} DESTINATION ${BIN_INSTALL_DIR}) diff --git a/unittest/alarmlib_unittest.cpp b/unittest/alarmlib_unittest.cpp new file mode 100755 index 0000000..c06890d --- /dev/null +++ b/unittest/alarmlib_unittest.cpp @@ -0,0 +1,766 @@ +/* + * Copyright (c) 2019 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 <gmock/gmock.h> +#include <gtest/gtest.h> +#include <unistd.h> +#include <stdio.h> + +#include <appsvc.h> + +#include "unittest.h" +#include "alarm.h" +#include "mock/gio_fake.h" +#include "mock/alarm_dbus.h" +#include "mock/aul_fake.h" +#include "mock/notification_fake.h" + +void __g_dbus_node_info_unref_fake(GDBusNodeInfo *info) +{ + free(info->interfaces); + free(info); + info = NULL; + return; +} + +GDBusConnection* __g_bus_get_sync_fake(GBusType type, + GCancellable *cancellable, GError **error) +{ + GDBusConnection *con = (GDBusConnection*)g_object_new(G_TYPE_OBJECT, NULL); + + return con; +} + +GDBusProxy* __g_dbus_proxy_new_sync_fake(GDBusConnection *con, + GDBusProxyFlags flag, GDBusInterfaceInfo *info, const gchar *name, + const gchar *path, const gchar *interface, GCancellable *cancellable, + GError **error) +{ + GDBusProxy *proxy = (GDBusProxy*)g_object_new(G_TYPE_OBJECT, NULL); + + return proxy; +} + +GDBusNodeInfo* __g_dbus_node_info_new_for_xml_fake(const gchar *xml, GError **error) +{ + GDBusNodeInfo *info = (GDBusNodeInfo*)malloc(sizeof(GDBusNodeInfo)); + + info->ref_count = 10; + info->path = NULL; + info->interfaces = (GDBusInterfaceInfo**)malloc(sizeof(GDBusInterfaceInfo)); + info->nodes = NULL; + info->annotations = NULL; + + return info; +} + +guint __g_dbus_connection_register_object_fake(GDBusConnection *con, + const gchar *path, GDBusInterfaceInfo *info, + const GDBusInterfaceVTable *table, gpointer user_data, + GDestroyNotify user_data_free_func, GError **error) +{ + return 1; +} + +guint __g_bus_own_name_on_connection_fake(GDBusConnection *con, const gchar *name, + GBusNameOwnerFlags flag, GBusNameAcquiredCallback acquired_cb, + GBusNameLostCallback lost_cb, gpointer user_data, + GDestroyNotify user_data_free_func) +{ + return 1; +} + +gboolean __alarm_manager_call_alarm_get_info_sync_fake(AlarmManager *alarm, + gint alarm_id, gint *start_year, gint *start_month, gint *start_day, gint *start_hour, + gint *start_min, gint *start_sec, gint *end_year, gint *end_month, gint *end_day, + gint *mode_day_of_week, gint *mode_repeat, gint *alarm_type, + gint *reserved_info, gint *return_code, GCancellable *cancel, GError **error) +{ + return true; +} + +//gboolean __alarm_manager_call_alarm_create_sync_fake(AlarmManager *alarm, +// const gchar *arg_app_service_name, const gchar *arg_app_service_name_mod, +// gint start_year, gint start_month, +// gint start_day, gint start_hour, gint start_min, gint start_sec, +// gint msec, gint end_year, gint end_month, gint end_day, +// gint mode_day_of_week, gint mode_repeat, gint alarm_type, +// gint reserved_info, const gchar *arg_alarm_info_reserved_service_name, +// const gchar *arg_alarm_info_reserved_service_name_mod, gint *alarm_id, +// gint *return_code, GCancellable *cancel, GError **error) +//{ +// return true; +//} + +gboolean __alarm_manager_call_alarm_create_appsvc_sync_fake(AlarmManager *alarm, + gint start_year, gint start_month, gint start_day, gint start_hour, + gint start_min, gint start_sec, gint end_year, gint end_month, gint end_day, + gint mode_day_of_week, gint mode_ginterval, gint mode_repeat, gint alarm_type, + gint reserved_info, const char *bundle, gint *alarm_id, gint *return_code, + GCancellable *cancel, GError **error) +{ + return true; +} + +gboolean __alarm_manager_call_alarm_create_noti_sync_fake(AlarmManager *alarm, + gint start_year, gint start_month, gint start_day, gint start_hour, + gint start_min, gint start_sec, gint end_year, gint end_month, gint end_day, + gint mode_day_of_week, gint mode_ginterval, gint mode_repeat, gint alarm_type, + gint reserved_info, const char *bundle, gint *alarm_id, gint *return_code, + GCancellable *cancel, GError **error) +{ + return true; +} + +gboolean __alarm_manager_call_alarm_get_appsvc_info_sync_fake(AlarmManager *alarm, + gint alarm_id, gchar **b, gint *return_code, GCancellable *cancel, + GError **error) +{ + int datalen; + bundle_raw *raw = NULL; + bundle *bundle = bundle_create(); + bundle_add_str(bundle, "key", "val"); + + bundle_encode(bundle, &raw, &datalen); + + *b = (gchar *)raw; + *return_code = 0; + + bundle_free(bundle); + + return true; +} + +gboolean __alarm_manager_call_alarm_get_noti_info_sync_fake(AlarmManager *alarm, + gint alarm_id, gchar **b, gint *return_code, GCancellable *cancel, + GError **error) +{ + GVariant *noti_gv = NULL; + char *noti_data; + guchar *data; + int datalen = 0; + int noti_ret; + notification_h noti; + + noti = notification_create(NOTIFICATION_TYPE_NOTI); + if (!noti) + return false; + + noti_ret = notification_set_text(noti, NOTIFICATION_TEXT_TYPE_TITLE, + "Test Title", "TITLE", NOTIFICATION_VARIABLE_TYPE_NONE); + if (noti_ret != NOTIFICATION_ERROR_NONE) + return false; + + noti_gv = notification_ipc_make_gvariant_from_noti(noti, true); + if (!noti_gv) + return false; + + datalen = g_variant_get_size(noti_gv); + if (datalen < 0) + return false; + + data = (guchar *)malloc(datalen); + if (!data) + return false; + + g_variant_store(noti_gv, data); + noti_data = g_base64_encode((guchar *)data, datalen); + + *b = noti_data; + + return true; +} + +gboolean __alarm_manager_call_alarm_set_rtc_time_sync_fake(AlarmManager *alarm, + gint year, gint month, gint day, gint hour, gint min, gint sec, gint *return_code, GCancellable *cancel, GError **error) +{ + return true; +} + +gboolean __alarm_manager_call_alarm_delete_sync_fake(AlarmManager *alarm, + gint alarm_id, gint *return_code, GCancellable *cancel, + GError **error) +{ + return true; +} + +gboolean __alarm_manager_call_alarm_delete_all_sync_fake(AlarmManager *alarm, + gint *return_code, GCancellable *cancel, GError **error) +{ + return true; +} + +gboolean __alarm_manager_call_alarm_get_number_of_ids_sync_fake(AlarmManager *alarm, + gint *num, gint *return_code, GCancellable *cancel, GError **error) +{ + return true; +} + +gboolean __alarm_manager_call_alarm_get_list_of_ids_sync_fake(AlarmManager *alarm, + gint id, GVariant **alarm_array, gint *num_of_ids, gint *return_code, + GCancellable *cancel, GError **error) +{ + int test[2] = {1, 1}; + GVariantBuilder *builder; + + builder = g_variant_builder_new(G_VARIANT_TYPE("ai")); + g_variant_builder_add (builder, "i", test[0]); + g_variant_builder_add (builder, "i", test[1]); + + *alarm_array = g_variant_new("ai", builder); + + return true; +} + +gboolean __alarm_manager_call_alarm_get_next_duetime_sync_fake(AlarmManager *alarm, + gint alarm_id, gint *duetime, gint *return_code, GCancellable *cancel, + GError **error) +{ + return true; +} + +gboolean __alarm_manager_call_alarm_create_periodic_sync_fake(AlarmManager *alarm, + const gchar* service_name, const gchar *service_name_mod, gint interval, + gint is_ref, gint method, gint *alarm_id, gint *return_code, + GCancellable *cancel, GError **error) +{ + return true; +} + +gboolean __alarm_manager_call_alarm_set_time_sync_fake(AlarmManager *alarm, + gint new_time, gint *return_code, GCancellable *cancel, GError **error) +{ + return true; +} + +void __alarm_manager_call_alarm_set_time_fake(AlarmManager *alarm, + gint new_time, GCancellable *cancel, GAsyncReadyCallback cb, gpointer user_data) +{ + return; +} + +gboolean __alarm_manager_call_alarm_set_timezone_sync_fake(AlarmManager *alarm, + const gchar* tzpath, gint *return_code, GCancellable *cancel, GError **error) +{ + return true; +} + +gboolean __alarm_manager_call_alarm_set_time_with_propagation_delay_sync_fake(AlarmManager *alarm, + guint new_sec, guint new_nsec, guint req_sec, guint req_nsec, + gint *return_code, GCancellable *cancel, GError **error) +{ + return true; +} + +void __alarm_manager_call_alarm_set_time_with_propagation_delay_fake(AlarmManager *alarm, + guint new_sec, guint new_nsec, guint req_sec, guint req_nsec, + GCancellable *cancel, GAsyncReadyCallback, gpointer user_data) +{ + return; +} + +gboolean __alarm_manager_call_alarm_update_sync_fake(AlarmManager *alarm, + gint id, gint start_year, gint start_month, gint start_day, gint start_hour, + gint start_min, gint start_sec, gint end_year, gint end_month, gint end_day, + gint mode_ginterval, gint mode_repeat, gint alarm_type, gint reserved_info, + gint update_flag, gint *return_code, GCancellable *cancel, GError **error) +{ + return true; +} + +gboolean __alarm_manager_call_alarm_set_global_sync_fake(AlarmManager *alarm, + gint id, gboolean global, gint *return_code, GCancellable *cancel, GError **error) +{ + return true; +} + +gboolean __alarm_manager_call_alarm_get_global_sync_fake(AlarmManager *alarm, + gint id, gboolean *global, gint *return_code, GCancellable *cancel, GError **error) +{ + return true; +} + +int __aul_app_get_appid_bypid_fake(int pid, char *appid, int length) +{ + sprintf(appid, "%s", "test"); + + return 0; +} + +GVariant* __notification_ipc_make_gvariant_from_noti_fake(notification_h, + bool translate) +{ + GVariant *noti_gv = NULL; + + noti_gv = g_variant_new_string("test"); + + return noti_gv; +} + +class AlarmLibTest : public ::testing::Test { + protected: + void SetUp() override { + alarm = alarmmgr_create_alarm(); + + g_bus_get_sync_fake.custom_fake = __g_bus_get_sync_fake; + g_dbus_proxy_new_sync_fake.custom_fake = __g_dbus_proxy_new_sync_fake; + g_dbus_node_info_unref_fake.custom_fake = __g_dbus_node_info_unref_fake; + + } + + void TearDown() override { + alarmmgr_free_alarm(alarm); + } + + alarm_entry_t *alarm; +}; + +TEST_F(AlarmLibTest, alarmmgr_init_p) +{ + int ret; + char testapp[256] = "org.tizen.alarmmgrtestapp"; + + g_dbus_node_info_new_for_xml_fake.custom_fake = __g_dbus_node_info_new_for_xml_fake; + g_dbus_connection_register_object_fake.custom_fake = __g_dbus_connection_register_object_fake; + g_bus_own_name_on_connection_fake.custom_fake = __g_bus_own_name_on_connection_fake; + + ret = alarmmgr_init(testapp); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +TEST_F(AlarmLibTest, alarmmgr_set_get_time_p) +{ + int ret; + alarm_date_t date; + alarm_date_t get_date; + + date.year = 2020; + date.month = 1; + date.day = 1; + date.hour = 1; + date.min = 1; + date.sec = 1; + + ret = alarmmgr_set_time(alarm, date); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); + + ret = alarmmgr_get_time(alarm, &get_date); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); + + EXPECT_EQ(date.year, get_date.year); +} + +TEST_F(AlarmLibTest, alarmmgr_set_get_repeat_mode_p) +{ + int ret; + alarm_repeat_mode_t get_mode; + int interval; + + ret = alarmmgr_set_repeat_mode(alarm, ALARM_REPEAT_MODE_REPEAT, 1000); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); + + ret = alarmmgr_get_repeat_mode(alarm, &get_mode, &interval); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); + + EXPECT_EQ(ALARM_REPEAT_MODE_REPEAT, get_mode); +} + +TEST_F(AlarmLibTest, alarmmgr_set_get_type_p) +{ + int ret; + int get_type; + + ret = alarmmgr_set_type(alarm, ALARM_TYPE_VOLATILE); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); + + ret = alarmmgr_get_type(alarm, &get_type); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); + + EXPECT_EQ(ALARM_TYPE_VOLATILE, get_type); +} + +TEST_F(AlarmLibTest, alarmmgr_add_alarm_appsvc_p) +{ + int ret; + alarm_id_t alarm_id; + + bundle *b; + + alarm_manager_call_alarm_create_appsvc_sync_fake.custom_fake = __alarm_manager_call_alarm_create_appsvc_sync_fake; + + b = bundle_create(); + ASSERT_NE(b, nullptr); + + ret = appsvc_set_pkgname(b,"org.tizen.calendar"); + EXPECT_EQ(0, ret); + + ret = appsvc_set_operation(b, APPSVC_OPERATION_DEFAULT); + EXPECT_EQ(0, ret); + + ret = alarmmgr_add_alarm_appsvc(ALARM_TYPE_DEFAULT, 100, 0, (void *)b, + &alarm_id); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); + + bundle_free(b); +} + +TEST_F(AlarmLibTest, alarmmgr_get_alarm_appsvc_p) +{ + int ret; + alarm_id_t alarm_id = 10; + + bundle *get_b; + + alarm_manager_call_alarm_get_appsvc_info_sync_fake.custom_fake = __alarm_manager_call_alarm_get_appsvc_info_sync_fake; + + get_b = (bundle *)alarmmgr_get_alarm_appsvc_info(alarm_id, &ret); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); + + bundle_free(get_b); +} + + +TEST_F(AlarmLibTest, alarmmgr_add_alarm_noti_p) +{ + int ret; + alarm_id_t alarm_id; + notification_h noti = nullptr; + + alarm_manager_call_alarm_create_noti_sync_fake.custom_fake = __alarm_manager_call_alarm_create_noti_sync_fake; + notification_ipc_make_gvariant_from_noti_fake.custom_fake = __notification_ipc_make_gvariant_from_noti_fake; + + ret = alarmmgr_add_alarm_noti(ALARM_TYPE_DEFAULT, 100, 0, noti, + &alarm_id); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + + +TEST_F(AlarmLibTest, alarmmgr_get_alarm_noti_p) +{ + int ret; + notification_h get_noti; + + alarm_manager_call_alarm_get_noti_info_sync_fake.custom_fake = __alarm_manager_call_alarm_get_noti_info_sync_fake; + + ret = alarmmgr_get_alarm_noti_info(1, &get_noti); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +TEST_F(AlarmLibTest, alarmmgr_set_rtc_time_p) +{ + int ret; + alarm_date_t date = {2020, 4, 5, 10, 10, 0}; + + alarm_manager_call_alarm_set_rtc_time_sync_fake.custom_fake = __alarm_manager_call_alarm_set_rtc_time_sync_fake; + + ret = alarmmgr_set_rtc_time(&date); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +TEST_F(AlarmLibTest, alarmmgr_add_alarm_appsvc_with_localtime_p) +{ + int ret; + alarm_id_t alarm_id; + + bundle *b; + + alarm_date_t test_time; + + alarm_manager_call_alarm_create_appsvc_sync_fake.custom_fake = __alarm_manager_call_alarm_create_appsvc_sync_fake; + + b = bundle_create(); + ASSERT_NE(b, nullptr); + + ret = appsvc_set_pkgname(b,"org.tizen.calendar"); + EXPECT_EQ(0, ret); + + ret = appsvc_set_operation(b, APPSVC_OPERATION_DEFAULT); + EXPECT_EQ(0, ret); + + test_time.year = 2022; + test_time.month = 1; + test_time.day = 1; + + test_time.hour = 1; + test_time.min = 1; + test_time.sec = 5; + + ret = alarmmgr_set_time(alarm,test_time); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); + + ret = alarmmgr_set_type(alarm, ALARM_TYPE_DEFAULT); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); + + ret = alarmmgr_add_alarm_appsvc_with_localtime(alarm, (void *)b, + &alarm_id); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); + + bundle_free(b); +} + +TEST_F(AlarmLibTest, alarmmgr_get_info_p) +{ + int ret; + alarm_entry_t get_alarm; + + alarm_manager_call_alarm_get_info_sync_fake.custom_fake = __alarm_manager_call_alarm_get_info_sync_fake; + + ret = alarmmgr_get_info(1, &get_alarm); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +TEST_F(AlarmLibTest, alarmmgr_add_alarm_noti_with_localtime_p) +{ + int ret; + alarm_id_t alarm_id; + notification_h noti = nullptr; + + alarm_manager_call_alarm_create_noti_sync_fake.custom_fake = __alarm_manager_call_alarm_create_noti_sync_fake; + + ret = alarmmgr_add_alarm_noti_with_localtime(alarm, noti, &alarm_id); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +//TODO +/* +TEST_F(AlarmLibTest, alarmmgr_add_alarm_p) +{ + int ret; + alarm_id_t alarm_id; + alarm_entry_t get_alarm; + + alarm_manager_call_alarm_create_sync_fake.custom_fake = __alarm_manager_call_alarm_create_sync_fake; + + ret = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, 100, 1000, "gtest-alarmmgr", + &alarm_id); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +TEST_F(AlarmLibTest, alarmmgr_add_alarm_precision_p) +{ + int ret; + alarm_id_t alarm_id; + alarm_entry_t get_alarm; + + ret = alarmmgr_add_alarm_precision(ALARM_TYPE_VOLATILE, 100, 1000, + "gtest-alarmmgr", &alarm_id); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +TEST(AlarmLibTest, alarmmgr_add_get_alarm_withcb_p) +{ +} + +TEST(AlarmLibTest, alarmmgr_add_get_alarm_withcb_precision_p) +{ + } +*/ + +TEST_F(AlarmLibTest, alarmmgr_remove_alarm_p) +{ + int ret; + alarm_manager_call_alarm_delete_sync_fake.custom_fake = __alarm_manager_call_alarm_delete_sync_fake; + + ret = alarmmgr_remove_alarm(1); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +TEST_F(AlarmLibTest, alarmmgr_remove_all_p) +{ + int ret; + + alarm_manager_call_alarm_delete_all_sync_fake.custom_fake = __alarm_manager_call_alarm_delete_all_sync_fake; + + ret = alarmmgr_remove_all(); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +int enum_fn(alarm_id_t alarm_id, void *user_param) +{ + return 0; +} + +TEST_F(AlarmLibTest, alarmmgr_enum_alarm_ids_p) +{ + int ret; + + alarm_manager_call_alarm_get_number_of_ids_sync_fake.custom_fake = __alarm_manager_call_alarm_get_number_of_ids_sync_fake; + + alarm_manager_call_alarm_get_list_of_ids_sync_fake.custom_fake = __alarm_manager_call_alarm_get_list_of_ids_sync_fake; + + ret = alarmmgr_enum_alarm_ids(enum_fn, nullptr); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +TEST_F(AlarmLibTest, alarmmgr_get_next_duetime_p) +{ + int ret; + time_t next_time; + + alarm_manager_call_alarm_get_next_duetime_sync_fake.custom_fake = __alarm_manager_call_alarm_get_next_duetime_sync_fake; + + ret = alarmmgr_get_next_duetime(1, &next_time); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +int handler(alarm_id_t alarm_id, void *user_param) +{ + return 0; +} + +TEST_F(AlarmLibTest, alarmmgr_add_periodic_alarm_withcb_p) +{ + int ret; + alarm_id_t alarm_id; + + aul_app_get_appid_bypid_fake.custom_fake = __aul_app_get_appid_bypid_fake; + alarm_manager_call_alarm_create_periodic_sync_fake.custom_fake = __alarm_manager_call_alarm_create_periodic_sync_fake; + + ret = alarmmgr_add_periodic_alarm_withcb(1000, CUT_OFF, handler, NULL, + &alarm_id); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +TEST_F(AlarmLibTest, alarmmgr_add_reference_periodic_alarm_withcb_p) +{ + int ret; + alarm_id_t alarm_id; + + aul_app_get_appid_bypid_fake.custom_fake = __aul_app_get_appid_bypid_fake; + alarm_manager_call_alarm_create_periodic_sync_fake.custom_fake = __alarm_manager_call_alarm_create_periodic_sync_fake; + + ret = alarmmgr_add_reference_periodic_alarm_withcb(1000, handler, NULL, + &alarm_id); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +TEST_F(AlarmLibTest, alarmmgr_set_systime_p) +{ + int ret; + time_t current_time; + + time(¤t_time); + + alarm_manager_call_alarm_set_time_sync_fake.custom_fake = __alarm_manager_call_alarm_set_time_sync_fake; + + ret = alarmmgr_set_systime(current_time); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +TEST_F(AlarmLibTest, alarmmgr_set_systime_with_propagation_delay_p) +{ + int ret; + struct timespec newtime; + struct timespec reqtime; + + clock_gettime(CLOCK_REALTIME, &newtime); + clock_gettime(CLOCK_REALTIME, &reqtime); + + alarm_manager_call_alarm_set_time_with_propagation_delay_sync_fake.custom_fake = __alarm_manager_call_alarm_set_time_with_propagation_delay_sync_fake; + + ret = alarmmgr_set_systime_with_propagation_delay(newtime, reqtime); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +int set_time_cb(int result, void *user_param) +{ + return 0; +} + +TEST_F(AlarmLibTest, alarmmgr_set_systime_async_p) +{ + int ret; + time_t current_time; + + alarm_manager_call_alarm_set_time_fake.custom_fake = __alarm_manager_call_alarm_set_time_fake; + + time(¤t_time); + + ret = alarmmgr_set_systime_async(current_time, set_time_cb, NULL); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +TEST_F(AlarmLibTest, alarmmgr_set_systime_with_propagation_delay_async_p) +{ + int ret; + struct timespec newtime; + struct timespec reqtime; + + alarm_manager_call_alarm_set_time_with_propagation_delay_fake.custom_fake = __alarm_manager_call_alarm_set_time_with_propagation_delay_fake; + + clock_gettime(CLOCK_REALTIME, &newtime); + clock_gettime(CLOCK_REALTIME, &reqtime); + + newtime.tv_sec += 100; + reqtime.tv_sec += 100; + + ret = alarmmgr_set_systime_with_propagation_delay_async(newtime, + reqtime, set_time_cb, NULL); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +TEST_F(AlarmLibTest, alarmmgr_set_timezone_p) +{ + int ret; + char zone[] = "/usr/share/zoneinfo/Asia/Seoul"; + + alarm_manager_call_alarm_set_timezone_sync_fake.custom_fake = __alarm_manager_call_alarm_set_timezone_sync_fake; + + ret = alarmmgr_set_timezone(zone); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +TEST_F(AlarmLibTest, alarmmgr_set_globla_p) +{ + int ret; + + alarm_manager_call_alarm_set_global_sync_fake.custom_fake = __alarm_manager_call_alarm_set_global_sync_fake; + + ret = alarmmgr_set_global(1, true); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +TEST_F(AlarmLibTest, alarmmgr_get_globla_p) +{ + int ret; + bool global; + + alarm_manager_call_alarm_get_global_sync_fake.custom_fake = __alarm_manager_call_alarm_get_global_sync_fake; + + ret = alarmmgr_get_global(1, &global); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} + +TEST_F(AlarmLibTest, alarmmgr_update_alarm_p) +{ + int ret; + alarm_date_t test_time; + + alarm_manager_call_alarm_update_sync_fake.custom_fake = __alarm_manager_call_alarm_update_sync_fake; + + test_time.year = 2022; + test_time.month = 1; + test_time.day = 1; + + test_time.hour = 1; + test_time.min = 1; + test_time.sec = 5; + + ret = alarmmgr_set_time(alarm, test_time); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); + + ret = alarmmgr_update_alarm(1, alarm, ALARM_UPDATE_FLAG_TIME); + EXPECT_EQ(ALARMMGR_RESULT_SUCCESS, ret); +} diff --git a/unittest/mock/alarm_dbus.h b/unittest/mock/alarm_dbus.h new file mode 100755 index 0000000..b9c43d1 --- /dev/null +++ b/unittest/mock/alarm_dbus.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2019 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. + */ + +#ifndef MOCK_ALARM_DBUS_H_ +#define MOCK_ALARM_DBUS_H_ + +#include <glib.h> + +#include "mock.h" + +DECLARE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_get_info_sync, + AlarmManager*, gint, gint*, gint*, gint*, gint*, gint*, gint*, gint*, + gint*, gint*, gint*, gint*, gint*, gint*, gint*, GCancellable*, GError**); + +DECLARE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_create_appsvc_sync, + AlarmManager*, gint, gint, gint, gint, gint, gint, gint, gint, gint, gint, + gint, gint, gint, gint, const char*, gint*, gint*, GCancellable*, GError**); + +DECLARE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_get_appsvc_info_sync, + AlarmManager*, gint, gchar**, gint*, GCancellable*, GError**); + +DECLARE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_create_noti_sync, + AlarmManager*, gint, gint, gint, gint, gint, gint, gint, gint, gint, gint, gint, + gint, gint, gint, const char*, gint*, gint*, GCancellable*, GError**); + +DECLARE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_get_noti_info_sync, + AlarmManager*, gint, gchar**, gint*, GCancellable*, GError**); + +DECLARE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_set_rtc_time_sync, + AlarmManager*, gint, gint, gint, gint, gint, gint, gint*, GCancellable*, + GError**); + +DECLARE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_delete_sync, + AlarmManager*, gint, gint*, GCancellable*, GError**); + +DECLARE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_delete_all_sync, + AlarmManager*, gint*, GCancellable*, GError**); + +DECLARE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_get_number_of_ids_sync, + AlarmManager*, gint*, gint*, GCancellable*, GError**); + +DECLARE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_get_list_of_ids_sync, + AlarmManager*, gint, GVariant**, gint*, gint*, GCancellable*, GError**); + +DECLARE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_get_next_duetime_sync, + AlarmManager*, gint, gint*, gint*, GCancellable*, GError**); + +DECLARE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_create_periodic_sync, + AlarmManager*, const gchar*, const gchar*, gint, gint, gint, gint*, + gint*, GCancellable*, GError**); + +DECLARE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_set_time_sync, + AlarmManager*, gint, gint*, GCancellable*, GError**); + +DECLARE_FAKE_VOID_FUNC(alarm_manager_call_alarm_set_time, AlarmManager*, gint, + GCancellable*, GAsyncReadyCallback, gpointer); + +DECLARE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_set_timezone_sync, + AlarmManager*, const char*, gint*, GCancellable*, GError**); + +DECLARE_FAKE_VALUE_FUNC(gboolean, + alarm_manager_call_alarm_set_time_with_propagation_delay_sync, + AlarmManager*, guint, guint, guint, guint, gint*, GCancellable*, + GError**); + +DECLARE_FAKE_VOID_FUNC(alarm_manager_call_alarm_set_time_with_propagation_delay, + AlarmManager*, guint, guint, guint, guint, GCancellable*, + GAsyncReadyCallback, gpointer); + +DECLARE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_update_sync, + AlarmManager*, gint, gint, gint, gint, gint, gint, gint, gint, gint, + gint, gint, gint, gint, gint, gint, gint*, GCancellable*, GError**); + +DECLARE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_set_global_sync, + AlarmManager*, gint, gboolean, gint*, GCancellable*, GError**); + +DECLARE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_get_global_sync, + AlarmManager*, gint, gboolean*, gint*, GCancellable*, GError**); + +#endif //MOCK_ALARM_DBUS_H_ diff --git a/unittest/mock/aul_fake.h b/unittest/mock/aul_fake.h new file mode 100644 index 0000000..9eff529 --- /dev/null +++ b/unittest/mock/aul_fake.h @@ -0,0 +1,26 @@ +/*
+ * Copyright (c) 2019 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.
+ */
+
+#ifndef MOCK_AUL_H_
+#define MOCK_AUL_H_
+
+#include <aul.h>
+
+#include "mock.h"
+
+DECLARE_FAKE_VALUE_FUNC(int, aul_app_get_appid_bypid, int, char*, int);
+
+#endif //MOCK_AUL_H_
diff --git a/unittest/mock/cynara_fake.h b/unittest/mock/cynara_fake.h new file mode 100644 index 0000000..309f07b --- /dev/null +++ b/unittest/mock/cynara_fake.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019 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. + */ + +#ifndef MOCK_CYNARA_H_ +#define MOCK_CYNARA_H_ + +#include <cynara-session.h> +#include <cynara-client.h> +#include <cynara-creds-gdbus.h> + +#include "mock.h" + +DECLARE_FAKE_VALUE_FUNC(int, cynara_initialize, cynara**, + const cynara_configuration*); +DECLARE_FAKE_VALUE_FUNC(int, cynara_creds_gdbus_get_user, GDBusConnection*, + const gchar*, enum cynara_user_creds, gchar **); +DECLARE_FAKE_VALUE_FUNC(int, cynara_creds_gdbus_get_client, GDBusConnection*, + const gchar*, enum cynara_client_creds, gchar **); +DECLARE_FAKE_VALUE_FUNC(char*, cynara_session_from_pid, pid_t); +DECLARE_FAKE_VALUE_FUNC(int, cynara_check, cynara*, const char*, const char*, + const char*, const char*); + + +#endif //MOCK_CYNARA_H_ diff --git a/unittest/mock/fff.h b/unittest/mock/fff.h new file mode 100644 index 0000000..6289a58 --- /dev/null +++ b/unittest/mock/fff.h @@ -0,0 +1,6493 @@ +/* +LICENSE + +The MIT License (MIT) + +Copyright (c) 2010 Michael Long + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ +#ifndef FAKE_FUNCTIONS +#define FAKE_FUNCTIONS + +#include <stdarg.h> +#include <string.h> /* For memset and memcpy */ + +#define FFF_MAX_ARGS (20u) +#ifndef FFF_ARG_HISTORY_LEN + #define FFF_ARG_HISTORY_LEN (50u) +#endif +#ifndef FFF_CALL_HISTORY_LEN + #define FFF_CALL_HISTORY_LEN (50u) +#endif +/* -- INTERNAL HELPER MACROS -- */ +#define SET_RETURN_SEQ(FUNCNAME, ARRAY_POINTER, ARRAY_LEN) \ + FUNCNAME##_fake.return_val_seq = ARRAY_POINTER; \ + FUNCNAME##_fake.return_val_seq_len = ARRAY_LEN; +#define SET_CUSTOM_FAKE_SEQ(FUNCNAME, ARRAY_POINTER, ARRAY_LEN) \ + FUNCNAME##_fake.custom_fake_seq = ARRAY_POINTER; \ + FUNCNAME##_fake.custom_fake_seq_len = ARRAY_LEN; + +/* Defining a function to reset a fake function */ +#define RESET_FAKE(FUNCNAME) { \ + FUNCNAME##_reset(); \ +} \ + + +#define DECLARE_ARG(type, n, FUNCNAME) \ + type arg##n##_val; \ + type arg##n##_history[FFF_ARG_HISTORY_LEN]; + +#define DECLARE_ALL_FUNC_COMMON \ + unsigned int call_count; \ + unsigned int arg_history_len; \ + unsigned int arg_histories_dropped; \ + +#define DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + RETURN_TYPE return_val_history[FFF_ARG_HISTORY_LEN]; + +#define SAVE_ARG(FUNCNAME, n) \ + memcpy((void*)&FUNCNAME##_fake.arg##n##_val, (void*)&arg##n, sizeof(arg##n)); + +#define ROOM_FOR_MORE_HISTORY(FUNCNAME) \ + FUNCNAME##_fake.call_count < FFF_ARG_HISTORY_LEN + +#define SAVE_RET_HISTORY(FUNCNAME, RETVAL) \ + if ((FUNCNAME##_fake.call_count - 1) < FFF_ARG_HISTORY_LEN) \ + memcpy((void *)&FUNCNAME##_fake.return_val_history[FUNCNAME##_fake.call_count - 1], (const void *) &RETVAL, sizeof(RETVAL)); \ + +#define SAVE_ARG_HISTORY(FUNCNAME, ARGN) \ + memcpy((void*)&FUNCNAME##_fake.arg##ARGN##_history[FUNCNAME##_fake.call_count], (void*)&arg##ARGN, sizeof(arg##ARGN)); + +#define HISTORY_DROPPED(FUNCNAME) \ + FUNCNAME##_fake.arg_histories_dropped++ + +#define DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + RETURN_TYPE return_val; \ + int return_val_seq_len; \ + int return_val_seq_idx; \ + RETURN_TYPE * return_val_seq; \ + +#define DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + int custom_fake_seq_len; \ + int custom_fake_seq_idx; \ + +#define INCREMENT_CALL_COUNT(FUNCNAME) \ + FUNCNAME##_fake.call_count++ + +#define RETURN_FAKE_RESULT(FUNCNAME) \ + if (FUNCNAME##_fake.return_val_seq_len){ /* then its a sequence */ \ + if(FUNCNAME##_fake.return_val_seq_idx < FUNCNAME##_fake.return_val_seq_len) { \ + SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_idx]) \ + return FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_idx++]; \ + } \ + SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_len-1]) \ + return FUNCNAME##_fake.return_val_seq[FUNCNAME##_fake.return_val_seq_len-1]; /* return last element */ \ + } \ + SAVE_RET_HISTORY(FUNCNAME, FUNCNAME##_fake.return_val) \ + return FUNCNAME##_fake.return_val; \ + +#ifdef __cplusplus + #define FFF_EXTERN_C extern "C"{ + #define FFF_END_EXTERN_C } +#else /* ansi c */ + #define FFF_EXTERN_C + #define FFF_END_EXTERN_C +#endif /* cpp/ansi c */ + +#define DEFINE_RESET_FUNCTION(FUNCNAME) \ + void FUNCNAME##_reset(void){ \ + memset(&FUNCNAME##_fake, 0, sizeof(FUNCNAME##_fake)); \ + FUNCNAME##_fake.arg_history_len = FFF_ARG_HISTORY_LEN; \ + } +/* -- END INTERNAL HELPER MACROS -- */ + +typedef void (*fff_function_t)(void); +typedef struct { + fff_function_t call_history[FFF_CALL_HISTORY_LEN]; + unsigned int call_history_idx; +} fff_globals_t; + +FFF_EXTERN_C +extern fff_globals_t fff; +FFF_END_EXTERN_C + +#define DEFINE_FFF_GLOBALS \ + FFF_EXTERN_C \ + fff_globals_t fff; \ + FFF_END_EXTERN_C + +#define FFF_RESET_HISTORY() \ + fff.call_history_idx = 0; \ + memset(fff.call_history, 0, sizeof(fff.call_history)); + +#define REGISTER_CALL(function) \ + if(fff.call_history_idx < FFF_CALL_HISTORY_LEN) \ + fff.call_history[fff.call_history_idx++] = (fff_function_t)function; + +#define DECLARE_FAKE_VOID_FUNC0(FUNCNAME) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(void); \ + void(**custom_fake_seq)(void); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(void); \ + +#define DEFINE_FAKE_VOID_FUNC0(FUNCNAME) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(void){ \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC0(FUNCNAME) \ + DECLARE_FAKE_VOID_FUNC0(FUNCNAME) \ + DEFINE_FAKE_VOID_FUNC0(FUNCNAME) \ + + +#define DECLARE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0); \ + void(**custom_fake_seq)(ARG0_TYPE arg0); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0); \ + +#define DEFINE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0){ \ + SAVE_ARG(FUNCNAME, 0); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + DECLARE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + DEFINE_FAKE_VOID_FUNC1(FUNCNAME, ARG0_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + +#define DEFINE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + DECLARE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + DEFINE_FAKE_VOID_FUNC2(FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + +#define DEFINE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + DECLARE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + DEFINE_FAKE_VOID_FUNC3(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + +#define DEFINE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + DECLARE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + DEFINE_FAKE_VOID_FUNC4(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + +#define DEFINE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + DECLARE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + DEFINE_FAKE_VOID_FUNC5(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + +#define DEFINE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + DECLARE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + DEFINE_FAKE_VOID_FUNC6(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + +#define DEFINE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + DECLARE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + DEFINE_FAKE_VOID_FUNC7(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + +#define DEFINE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + DECLARE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + DEFINE_FAKE_VOID_FUNC8(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + +#define DEFINE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + DECLARE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + DEFINE_FAKE_VOID_FUNC9(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + +#define DEFINE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + DECLARE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + DEFINE_FAKE_VOID_FUNC10(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + +#define DEFINE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + DECLARE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + DEFINE_FAKE_VOID_FUNC11(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + +#define DEFINE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + DECLARE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + DEFINE_FAKE_VOID_FUNC12(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + +#define DEFINE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + DECLARE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + DEFINE_FAKE_VOID_FUNC13(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + +#define DEFINE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + DECLARE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + DEFINE_FAKE_VOID_FUNC14(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + +#define DEFINE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + DECLARE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + DEFINE_FAKE_VOID_FUNC15(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + +#define DEFINE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + DECLARE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + DEFINE_FAKE_VOID_FUNC16(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + +#define DEFINE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + DECLARE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + DEFINE_FAKE_VOID_FUNC17(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + +#define DEFINE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + DECLARE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + DEFINE_FAKE_VOID_FUNC18(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + +#define DEFINE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + DECLARE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + DEFINE_FAKE_VOID_FUNC19(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ARG(ARG19_TYPE, 19, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + +#define DEFINE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + SAVE_ARG(FUNCNAME, 19); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + SAVE_ARG_HISTORY(FUNCNAME, 19); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + } \ + else{ \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + DECLARE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + DEFINE_FAKE_VOID_FUNC20(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(void); \ + RETURN_TYPE(**custom_fake_seq)(void); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(void); \ + +#define DEFINE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(void){ \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + DECLARE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + DEFINE_FAKE_VALUE_FUNC0(RETURN_TYPE, FUNCNAME) \ + + +#define DECLARE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0); \ + +#define DEFINE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0){ \ + SAVE_ARG(FUNCNAME, 0); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + DECLARE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + DEFINE_FAKE_VALUE_FUNC1(RETURN_TYPE, FUNCNAME, ARG0_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1); \ + +#define DEFINE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + DECLARE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + DEFINE_FAKE_VALUE_FUNC2(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2); \ + +#define DEFINE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + DECLARE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + DEFINE_FAKE_VALUE_FUNC3(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3); \ + +#define DEFINE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + DECLARE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + DEFINE_FAKE_VALUE_FUNC4(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4); \ + +#define DEFINE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + DECLARE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + DEFINE_FAKE_VALUE_FUNC5(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5); \ + +#define DEFINE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + DECLARE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + DEFINE_FAKE_VALUE_FUNC6(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6); \ + +#define DEFINE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + DECLARE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + DEFINE_FAKE_VALUE_FUNC7(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7); \ + +#define DEFINE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + DECLARE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + DEFINE_FAKE_VALUE_FUNC8(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8); \ + +#define DEFINE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + DECLARE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + DEFINE_FAKE_VALUE_FUNC9(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9); \ + +#define DEFINE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + DECLARE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + DEFINE_FAKE_VALUE_FUNC10(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10); \ + +#define DEFINE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + DECLARE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + DEFINE_FAKE_VALUE_FUNC11(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11); \ + +#define DEFINE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + DECLARE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + DEFINE_FAKE_VALUE_FUNC12(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12); \ + +#define DEFINE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + DECLARE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + DEFINE_FAKE_VALUE_FUNC13(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13); \ + +#define DEFINE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + DECLARE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + DEFINE_FAKE_VALUE_FUNC14(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14); \ + +#define DEFINE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + DECLARE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + DEFINE_FAKE_VALUE_FUNC15(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15); \ + +#define DEFINE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + DECLARE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + DEFINE_FAKE_VALUE_FUNC16(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16); \ + +#define DEFINE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + DECLARE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + DEFINE_FAKE_VALUE_FUNC17(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17); \ + +#define DEFINE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + DECLARE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + DEFINE_FAKE_VALUE_FUNC18(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18); \ + +#define DEFINE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + DECLARE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + DEFINE_FAKE_VALUE_FUNC19(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE) \ + + +#define DECLARE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ARG(ARG19_TYPE, 19, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19); \ + +#define DEFINE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ARG19_TYPE arg19){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + SAVE_ARG(FUNCNAME, 19); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + SAVE_ARG_HISTORY(FUNCNAME, 19); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + else{ \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + } \ + } \ + if (FUNCNAME##_fake.custom_fake) return FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, arg19); \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + DECLARE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + DEFINE_FAKE_VALUE_FUNC20(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ARG19_TYPE) \ + + +#define DECLARE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ...); \ + +#define DEFINE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg0); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg0); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg0); \ + FUNCNAME##_fake.custom_fake(arg0, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC2_VARARG(FUNCNAME, ARG0_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...); \ + +#define DEFINE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg1); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg1); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg1); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC3_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...); \ + +#define DEFINE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg2); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg2); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg2); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC4_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...); \ + +#define DEFINE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg3); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg3); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg3); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC5_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...); \ + +#define DEFINE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg4); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg4); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg4); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC6_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...); \ + +#define DEFINE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg5); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg5); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg5); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC7_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...); \ + +#define DEFINE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg6); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg6); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg6); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC8_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...); \ + +#define DEFINE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg7); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg7); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg7); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC9_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...); \ + +#define DEFINE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg8); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg8); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg8); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC10_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...); \ + +#define DEFINE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg9); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg9); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg9); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC11_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...); \ + +#define DEFINE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg10); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg10); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg10); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC12_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...); \ + +#define DEFINE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg11); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg11); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg11); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC13_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...); \ + +#define DEFINE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg12); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg12); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg12); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC14_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...); \ + +#define DEFINE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg13); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg13); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg13); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC15_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...); \ + +#define DEFINE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg14); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg14); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg14); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC16_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...); \ + +#define DEFINE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg15); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg15); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg15); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC17_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...); \ + +#define DEFINE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg16); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg16); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg16); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC18_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...); \ + +#define DEFINE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg17); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg17); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg17); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC19_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + + +#define DECLARE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + void(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, va_list ap); \ + void(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...); \ + +#define DEFINE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg18); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + va_end(ap); \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg18); \ + FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + va_end(ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + va_list ap; \ + va_start(ap, arg18); \ + FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + va_end(ap); \ + } \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + DECLARE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + DEFINE_FAKE_VOID_FUNC20_VARARG(FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg0); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg0); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg0); \ + ret = FUNCNAME##_fake.custom_fake(arg0, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC2_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg1); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg1); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg1); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC3_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg2); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg2); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg2); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC4_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg3); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg3); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg3); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC5_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg4); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg4); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg4); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC6_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg5); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg5); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg5); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC7_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg6); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg6); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg6); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC8_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg7); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg7); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg7); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC9_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg8); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg8); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg8); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC10_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg9); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg9); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg9); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC11_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg10); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg10); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg10); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC12_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg11); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg11); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg11); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC13_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg12); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg12); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg12); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC14_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg13); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg13); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg13); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC15_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg14); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg14); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg14); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC16_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg15); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg15); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg15); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC17_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg16); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg16); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg16); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC18_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg17); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg17); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg17); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC19_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ...) \ + + +#define DECLARE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + typedef struct FUNCNAME##_Fake { \ + DECLARE_ARG(ARG0_TYPE, 0, FUNCNAME) \ + DECLARE_ARG(ARG1_TYPE, 1, FUNCNAME) \ + DECLARE_ARG(ARG2_TYPE, 2, FUNCNAME) \ + DECLARE_ARG(ARG3_TYPE, 3, FUNCNAME) \ + DECLARE_ARG(ARG4_TYPE, 4, FUNCNAME) \ + DECLARE_ARG(ARG5_TYPE, 5, FUNCNAME) \ + DECLARE_ARG(ARG6_TYPE, 6, FUNCNAME) \ + DECLARE_ARG(ARG7_TYPE, 7, FUNCNAME) \ + DECLARE_ARG(ARG8_TYPE, 8, FUNCNAME) \ + DECLARE_ARG(ARG9_TYPE, 9, FUNCNAME) \ + DECLARE_ARG(ARG10_TYPE, 10, FUNCNAME) \ + DECLARE_ARG(ARG11_TYPE, 11, FUNCNAME) \ + DECLARE_ARG(ARG12_TYPE, 12, FUNCNAME) \ + DECLARE_ARG(ARG13_TYPE, 13, FUNCNAME) \ + DECLARE_ARG(ARG14_TYPE, 14, FUNCNAME) \ + DECLARE_ARG(ARG15_TYPE, 15, FUNCNAME) \ + DECLARE_ARG(ARG16_TYPE, 16, FUNCNAME) \ + DECLARE_ARG(ARG17_TYPE, 17, FUNCNAME) \ + DECLARE_ARG(ARG18_TYPE, 18, FUNCNAME) \ + DECLARE_ALL_FUNC_COMMON \ + DECLARE_VALUE_FUNCTION_VARIABLES(RETURN_TYPE) \ + DECLARE_RETURN_VALUE_HISTORY(RETURN_TYPE) \ + DECLARE_CUSTOM_FAKE_SEQ_VARIABLES \ + RETURN_TYPE(*custom_fake)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, va_list ap); \ + RETURN_TYPE(**custom_fake_seq)(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, va_list ap); \ + } FUNCNAME##_Fake; \ + extern FUNCNAME##_Fake FUNCNAME##_fake; \ + void FUNCNAME##_reset(void); \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...); \ + +#define DEFINE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + FUNCNAME##_Fake FUNCNAME##_fake; \ + RETURN_TYPE FUNCNAME(ARG0_TYPE arg0, ARG1_TYPE arg1, ARG2_TYPE arg2, ARG3_TYPE arg3, ARG4_TYPE arg4, ARG5_TYPE arg5, ARG6_TYPE arg6, ARG7_TYPE arg7, ARG8_TYPE arg8, ARG9_TYPE arg9, ARG10_TYPE arg10, ARG11_TYPE arg11, ARG12_TYPE arg12, ARG13_TYPE arg13, ARG14_TYPE arg14, ARG15_TYPE arg15, ARG16_TYPE arg16, ARG17_TYPE arg17, ARG18_TYPE arg18, ...){ \ + SAVE_ARG(FUNCNAME, 0); \ + SAVE_ARG(FUNCNAME, 1); \ + SAVE_ARG(FUNCNAME, 2); \ + SAVE_ARG(FUNCNAME, 3); \ + SAVE_ARG(FUNCNAME, 4); \ + SAVE_ARG(FUNCNAME, 5); \ + SAVE_ARG(FUNCNAME, 6); \ + SAVE_ARG(FUNCNAME, 7); \ + SAVE_ARG(FUNCNAME, 8); \ + SAVE_ARG(FUNCNAME, 9); \ + SAVE_ARG(FUNCNAME, 10); \ + SAVE_ARG(FUNCNAME, 11); \ + SAVE_ARG(FUNCNAME, 12); \ + SAVE_ARG(FUNCNAME, 13); \ + SAVE_ARG(FUNCNAME, 14); \ + SAVE_ARG(FUNCNAME, 15); \ + SAVE_ARG(FUNCNAME, 16); \ + SAVE_ARG(FUNCNAME, 17); \ + SAVE_ARG(FUNCNAME, 18); \ + if(ROOM_FOR_MORE_HISTORY(FUNCNAME)){ \ + SAVE_ARG_HISTORY(FUNCNAME, 0); \ + SAVE_ARG_HISTORY(FUNCNAME, 1); \ + SAVE_ARG_HISTORY(FUNCNAME, 2); \ + SAVE_ARG_HISTORY(FUNCNAME, 3); \ + SAVE_ARG_HISTORY(FUNCNAME, 4); \ + SAVE_ARG_HISTORY(FUNCNAME, 5); \ + SAVE_ARG_HISTORY(FUNCNAME, 6); \ + SAVE_ARG_HISTORY(FUNCNAME, 7); \ + SAVE_ARG_HISTORY(FUNCNAME, 8); \ + SAVE_ARG_HISTORY(FUNCNAME, 9); \ + SAVE_ARG_HISTORY(FUNCNAME, 10); \ + SAVE_ARG_HISTORY(FUNCNAME, 11); \ + SAVE_ARG_HISTORY(FUNCNAME, 12); \ + SAVE_ARG_HISTORY(FUNCNAME, 13); \ + SAVE_ARG_HISTORY(FUNCNAME, 14); \ + SAVE_ARG_HISTORY(FUNCNAME, 15); \ + SAVE_ARG_HISTORY(FUNCNAME, 16); \ + SAVE_ARG_HISTORY(FUNCNAME, 17); \ + SAVE_ARG_HISTORY(FUNCNAME, 18); \ + } \ + else{ \ + HISTORY_DROPPED(FUNCNAME); \ + } \ + INCREMENT_CALL_COUNT(FUNCNAME); \ + REGISTER_CALL(FUNCNAME); \ + if (FUNCNAME##_fake.custom_fake_seq_len){ /* a sequence of custom fakes */ \ + if (FUNCNAME##_fake.custom_fake_seq_idx < FUNCNAME##_fake.custom_fake_seq_len){ \ + va_list ap; \ + va_start(ap, arg18); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_idx++](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + } \ + else{ \ + va_list ap; \ + va_start(ap, arg18); \ + RETURN_TYPE ret = FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + va_end(ap); \ + return ret; \ + return FUNCNAME##_fake.custom_fake_seq[FUNCNAME##_fake.custom_fake_seq_len-1](arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + } \ + } \ + if(FUNCNAME##_fake.custom_fake){ \ + RETURN_TYPE ret; \ + va_list ap; \ + va_start(ap, arg18); \ + ret = FUNCNAME##_fake.custom_fake(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15, arg16, arg17, arg18, ap); \ + va_end(ap); \ + SAVE_RET_HISTORY(FUNCNAME, ret); \ + return ret; \ + } \ + RETURN_FAKE_RESULT(FUNCNAME) \ + } \ + DEFINE_RESET_FUNCTION(FUNCNAME) \ + +#define FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + DECLARE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + DEFINE_FAKE_VALUE_FUNC20_VARARG(RETURN_TYPE, FUNCNAME, ARG0_TYPE, ARG1_TYPE, ARG2_TYPE, ARG3_TYPE, ARG4_TYPE, ARG5_TYPE, ARG6_TYPE, ARG7_TYPE, ARG8_TYPE, ARG9_TYPE, ARG10_TYPE, ARG11_TYPE, ARG12_TYPE, ARG13_TYPE, ARG14_TYPE, ARG15_TYPE, ARG16_TYPE, ARG17_TYPE, ARG18_TYPE, ...) \ + +/* MSVC expand macro fix */ +#define EXPAND(x) x + +#define PP_NARG_MINUS2(...) EXPAND(PP_NARG_MINUS2_(__VA_ARGS__, PP_RSEQ_N_MINUS2())) + +#define PP_NARG_MINUS2_(...) EXPAND(PP_ARG_MINUS2_N(__VA_ARGS__)) + +#define PP_ARG_MINUS2_N(returnVal, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N + +#define PP_RSEQ_N_MINUS2() 20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 + +#define PP_NARG_MINUS1(...) EXPAND(PP_NARG_MINUS1_(__VA_ARGS__, PP_RSEQ_N_MINUS1())) + +#define PP_NARG_MINUS1_(...) EXPAND(PP_ARG_MINUS1_N(__VA_ARGS__)) + +#define PP_ARG_MINUS1_N( _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, N, ...) N + +#define PP_RSEQ_N_MINUS1() 20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 + + + +/* DECLARE AND DEFINE FAKE FUNCTIONS - PLACE IN TEST FILES */ + +#define FAKE_VALUE_FUNC(...) EXPAND(FUNC_VALUE_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define FUNC_VALUE_(N,...) EXPAND(FUNC_VALUE_N(N,__VA_ARGS__)) + +#define FUNC_VALUE_N(N,...) EXPAND(FAKE_VALUE_FUNC ## N(__VA_ARGS__)) + + +#define FAKE_VOID_FUNC(...) EXPAND(FUNC_VOID_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define FUNC_VOID_(N,...) EXPAND(FUNC_VOID_N(N,__VA_ARGS__)) + +#define FUNC_VOID_N(N,...) EXPAND(FAKE_VOID_FUNC ## N(__VA_ARGS__)) + + +#define FAKE_VALUE_FUNC_VARARG(...) EXPAND(FUNC_VALUE_VARARG_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define FUNC_VALUE_VARARG_(N,...) EXPAND(FUNC_VALUE_VARARG_N(N,__VA_ARGS__)) + +#define FUNC_VALUE_VARARG_N(N,...) EXPAND(FAKE_VALUE_FUNC ## N ## _VARARG(__VA_ARGS__)) + + +#define FAKE_VOID_FUNC_VARARG(...) EXPAND(FUNC_VOID_VARARG_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define FUNC_VOID_VARARG_(N,...) EXPAND(FUNC_VOID_VARARG_N(N,__VA_ARGS__)) + +#define FUNC_VOID_VARARG_N(N,...) EXPAND(FAKE_VOID_FUNC ## N ## _VARARG(__VA_ARGS__)) + + + +/* DECLARE FAKE FUNCTIONS - PLACE IN HEADER FILES */ + +#define DECLARE_FAKE_VALUE_FUNC(...) EXPAND(DECLARE_FUNC_VALUE_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define DECLARE_FUNC_VALUE_(N,...) EXPAND(DECLARE_FUNC_VALUE_N(N,__VA_ARGS__)) + +#define DECLARE_FUNC_VALUE_N(N,...) EXPAND(DECLARE_FAKE_VALUE_FUNC ## N(__VA_ARGS__)) + + +#define DECLARE_FAKE_VOID_FUNC(...) EXPAND(DECLARE_FUNC_VOID_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define DECLARE_FUNC_VOID_(N,...) EXPAND(DECLARE_FUNC_VOID_N(N,__VA_ARGS__)) + +#define DECLARE_FUNC_VOID_N(N,...) EXPAND(DECLARE_FAKE_VOID_FUNC ## N(__VA_ARGS__)) + + +#define DECLARE_FAKE_VALUE_FUNC_VARARG(...) EXPAND(DECLARE_FUNC_VALUE_VARARG_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define DECLARE_FUNC_VALUE_VARARG_(N,...) EXPAND(DECLARE_FUNC_VALUE_VARARG_N(N,__VA_ARGS__)) + +#define DECLARE_FUNC_VALUE_VARARG_N(N,...) EXPAND(DECLARE_FAKE_VALUE_FUNC ## N ## _VARARG(__VA_ARGS__)) + + +#define DECLARE_FAKE_VOID_FUNC_VARARG(...) EXPAND(DECLARE_FUNC_VOID_VARARG_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define DECLARE_FUNC_VOID_VARARG_(N,...) EXPAND(DECLARE_FUNC_VOID_VARARG_N(N,__VA_ARGS__)) + +#define DECLARE_FUNC_VOID_VARARG_N(N,...) EXPAND(DECLARE_FAKE_VOID_FUNC ## N ## _VARARG(__VA_ARGS__)) + + + +/* DEFINE FAKE FUNCTIONS - PLACE IN SOURCE FILES */ + +#define DEFINE_FAKE_VALUE_FUNC(...) EXPAND(DEFINE_FUNC_VALUE_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define DEFINE_FUNC_VALUE_(N,...) EXPAND(DEFINE_FUNC_VALUE_N(N,__VA_ARGS__)) + +#define DEFINE_FUNC_VALUE_N(N,...) EXPAND(DEFINE_FAKE_VALUE_FUNC ## N(__VA_ARGS__)) + + +#define DEFINE_FAKE_VOID_FUNC(...) EXPAND(DEFINE_FUNC_VOID_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define DEFINE_FUNC_VOID_(N,...) EXPAND(DEFINE_FUNC_VOID_N(N,__VA_ARGS__)) + +#define DEFINE_FUNC_VOID_N(N,...) EXPAND(DEFINE_FAKE_VOID_FUNC ## N(__VA_ARGS__)) + + +#define DEFINE_FAKE_VALUE_FUNC_VARARG(...) EXPAND(DEFINE_FUNC_VALUE_VARARG_(PP_NARG_MINUS2(__VA_ARGS__), __VA_ARGS__)) + +#define DEFINE_FUNC_VALUE_VARARG_(N,...) EXPAND(DEFINE_FUNC_VALUE_VARARG_N(N,__VA_ARGS__)) + +#define DEFINE_FUNC_VALUE_VARARG_N(N,...) EXPAND(DEFINE_FAKE_VALUE_FUNC ## N ## _VARARG(__VA_ARGS__)) + + +#define DEFINE_FAKE_VOID_FUNC_VARARG(...) EXPAND(DEFINE_FUNC_VOID_VARARG_(PP_NARG_MINUS1(__VA_ARGS__), __VA_ARGS__)) + +#define DEFINE_FUNC_VOID_VARARG_(N,...) EXPAND(DEFINE_FUNC_VOID_VARARG_N(N,__VA_ARGS__)) + +#define DEFINE_FUNC_VOID_VARARG_N(N,...) EXPAND(DEFINE_FAKE_VOID_FUNC ## N ## _VARARG(__VA_ARGS__)) + + + + +#endif /* FAKE_FUNCTIONS */ diff --git a/unittest/mock/gio_fake.h b/unittest/mock/gio_fake.h new file mode 100644 index 0000000..8181065 --- /dev/null +++ b/unittest/mock/gio_fake.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2019 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. + */ + +#ifndef MOCK_GIO_H_ +#define MOCK_GIO_H_ + +#include "mock.h" + +#include <glib.h> +#include <gio/gio.h> + +DECLARE_FAKE_VALUE_FUNC(GDBusConnection*, g_bus_get_sync, + GBusType, GCancellable*, GError**); + +DECLARE_FAKE_VALUE_FUNC(GDBusProxy*, g_dbus_proxy_new_sync, + GDBusConnection*, GDBusProxyFlags, GDBusInterfaceInfo*, + const gchar*, const gchar*, const gchar*, GCancellable*, GError**); + +DECLARE_FAKE_VALUE_FUNC(GDBusNodeInfo*, g_dbus_node_info_new_for_xml, + const gchar*, GError**); + +DECLARE_FAKE_VALUE_FUNC(guint, g_bus_own_name_on_connection, GDBusConnection*, + const gchar*, GBusNameOwnerFlags,GBusNameAcquiredCallback, + GBusNameLostCallback, gpointer, GDestroyNotify); + +DECLARE_FAKE_VALUE_FUNC(guint, g_dbus_connection_register_object, + GDBusConnection*, const gchar*, GDBusInterfaceInfo*, + const GDBusInterfaceVTable*, gpointer, GDestroyNotify, GError**); + +DECLARE_FAKE_VOID_FUNC(g_dbus_method_invocation_return_value, + GDBusMethodInvocation*, GVariant*); + +DECLARE_FAKE_VALUE_FUNC(GVariant*, g_dbus_connection_call_sync, GDBusConnection*, + const gchar*, const gchar*, const gchar*, const gchar*, GVariant*, + const GVariantType*, GDBusCallFlags, gint, GCancellable*, GError**); + +DECLARE_FAKE_VALUE_FUNC(const gchar*, g_dbus_method_invocation_get_sender, + GDBusMethodInvocation*); + +DECLARE_FAKE_VOID_FUNC(g_bus_unown_name, guint); + +DECLARE_FAKE_VALUE_FUNC(gboolean, g_dbus_connection_emit_signal, + GDBusConnection*, const gchar*, const gchar*, const gchar*, const gchar*, + GVariant*, GError**); + +DECLARE_FAKE_VALUE_FUNC(gboolean, g_dbus_connection_flush_sync, + GDBusConnection*, GCancellable*, GError**); + +DECLARE_FAKE_VOID_FUNC(g_dbus_node_info_unref, GDBusNodeInfo*); + +DECLARE_FAKE_VALUE_FUNC(guint, g_dbus_connection_signal_subscribe, + GDBusConnection*, const gchar*, const gchar*, const gchar*, const gchar*, + const gchar*, GDBusSignalFlags, GDBusSignalCallback, gpointer, + GDestroyNotify); + +DECLARE_FAKE_VALUE_FUNC(gboolean, g_dbus_interface_skeleton_export, + GDBusInterfaceSkeleton*, GDBusConnection*, const gchar*, GError**); + +#endif //MOCK_GIO_H_ diff --git a/unittest/mock/glib_fake.h b/unittest/mock/glib_fake.h new file mode 100755 index 0000000..8b0d066 --- /dev/null +++ b/unittest/mock/glib_fake.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2019 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. + */ + +#ifndef MOCK_GLIB_H_ +#define MOCK_GLIB_H_ + +#include <glib.h> + +#include "mock.h" + +DECLARE_FAKE_VOID_FUNC3_VARARG(g_variant_get, GVariant*, const gchar*, ...); +DECLARE_FAKE_VALUE_FUNC3_VARARG(gboolean, g_variant_iter_loop, GVariantIter*, + const gchar*, ...); +DECLARE_FAKE_VOID_FUNC(g_variant_iter_free, GVariantIter*); +DECLARE_FAKE_VOID_FUNC(g_variant_unref, GVariant*); +DECLARE_FAKE_VALUE_FUNC2_VARARG(GVariant*, g_variant_new, const gchar*, ...); +DECLARE_FAKE_VALUE_FUNC(gpointer, g_hash_table_lookup, GHashTable*, gconstpointer); +DECLARE_FAKE_VALUE_FUNC(guint, g_hash_table_foreach_remove, GHashTable*, + GHRFunc, gpointer); +DECLARE_FAKE_VALUE_FUNC(gboolean, g_hash_table_insert, GHashTable*, + gpointer, gpointer); + +#endif //MOCK_GLIB_H_ diff --git a/unittest/mock/mock.cc b/unittest/mock/mock.cc new file mode 100644 index 0000000..817dce1 --- /dev/null +++ b/unittest/mock/mock.cc @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2019 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 "alarm_dbus.h" +#include "aul_fake.h" +#include "cynara_fake.h" +#include "gio_fake.h" +#include "glib_fake.h" +#include "mock.h" +#include "notification_fake.h" + +DEFINE_FFF_GLOBALS; + +/* gio.h */ +DEFINE_FAKE_VALUE_FUNC(GDBusConnection*, g_bus_get_sync, + GBusType, GCancellable*, GError**); +DEFINE_FAKE_VALUE_FUNC(GDBusProxy*, g_dbus_proxy_new_sync, + GDBusConnection*, GDBusProxyFlags, GDBusInterfaceInfo*, + const gchar*, const gchar*, const gchar*, GCancellable*, GError**); +DEFINE_FAKE_VALUE_FUNC(GDBusNodeInfo*, g_dbus_node_info_new_for_xml, + const gchar*, GError**); +DEFINE_FAKE_VALUE_FUNC(guint, g_bus_own_name_on_connection, GDBusConnection*, + const gchar*, GBusNameOwnerFlags,GBusNameAcquiredCallback, + GBusNameLostCallback, gpointer, GDestroyNotify); +DEFINE_FAKE_VALUE_FUNC(guint, g_dbus_connection_register_object, + GDBusConnection*, const gchar*, GDBusInterfaceInfo*, + const GDBusInterfaceVTable*, gpointer, GDestroyNotify, GError**); +DEFINE_FAKE_VOID_FUNC(g_dbus_method_invocation_return_value, + GDBusMethodInvocation*, GVariant*); +DEFINE_FAKE_VOID_FUNC(g_bus_unown_name, guint); +DEFINE_FAKE_VALUE_FUNC(gboolean, g_dbus_connection_emit_signal, + GDBusConnection*, const gchar*, const gchar*, const gchar*, const gchar*, + GVariant*, GError**); +DEFINE_FAKE_VALUE_FUNC(gboolean, g_dbus_connection_flush_sync, + GDBusConnection*, GCancellable*, GError**); +DEFINE_FAKE_VOID_FUNC(g_dbus_node_info_unref, GDBusNodeInfo*); +DEFINE_FAKE_VALUE_FUNC(guint, g_dbus_connection_signal_subscribe, + GDBusConnection*, const gchar*, const gchar*, const gchar*, const gchar*, + const gchar*, GDBusSignalFlags, GDBusSignalCallback, gpointer, + GDestroyNotify); +DEFINE_FAKE_VALUE_FUNC(gboolean, g_dbus_interface_skeleton_export, + GDBusInterfaceSkeleton*, GDBusConnection*, const gchar*, GError**); + +/* alarm_dbus.h */ +DEFINE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_get_info_sync, + AlarmManager*, gint, gint*, gint*, gint*, gint*, gint*, gint*, gint*, gint*, gint*, gint*, + gint*, gint*, gint*, gint*, GCancellable*, GError**); +DEFINE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_create_appsvc_sync, + AlarmManager*, gint, gint, gint, gint, gint, gint, gint, gint, gint, gint, gint, + gint, gint, gint, const char*, gint*, gint*, GCancellable*, GError**); +DEFINE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_get_appsvc_info_sync, + AlarmManager*, gint, gchar**, gint*, GCancellable*, GError**); +DEFINE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_create_noti_sync, + AlarmManager*, gint, gint, gint, gint, gint, gint, gint, gint, gint, gint, gint, + gint, gint, gint, const char*, gint*, gint*, GCancellable*, GError**); +DEFINE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_get_noti_info_sync, + AlarmManager*, gint, gchar**, gint*, GCancellable*, GError**); +DEFINE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_set_rtc_time_sync, AlarmManager*, gint, gint, gint, gint, gint, gint, gint*, GCancellable*, GError**); +DEFINE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_delete_sync, AlarmManager*, gint, gint*, GCancellable*, GError**); +DEFINE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_delete_all_sync, AlarmManager*, gint*, GCancellable*, GError**); +DEFINE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_get_number_of_ids_sync, AlarmManager*, gint*, gint*, GCancellable*, GError**); +DEFINE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_get_list_of_ids_sync, AlarmManager*, gint, GVariant**, gint*, gint*, GCancellable*, GError**); +DEFINE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_get_next_duetime_sync, AlarmManager*, gint, gint*, gint*, GCancellable*, GError**); +DEFINE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_create_periodic_sync, AlarmManager*, const gchar*, const gchar*, gint, gint, gint, gint*, gint*, GCancellable*, GError**); +DEFINE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_set_time_sync, AlarmManager*, gint, gint*, GCancellable*, GError**); +DEFINE_FAKE_VOID_FUNC(alarm_manager_call_alarm_set_time, AlarmManager*, gint, GCancellable*, GAsyncReadyCallback, gpointer); +DEFINE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_set_timezone_sync, AlarmManager*, const char*, gint*, GCancellable*, GError**); +DEFINE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_set_time_with_propagation_delay_sync, AlarmManager*, guint, guint, guint, guint, gint*, GCancellable*, GError**); +DEFINE_FAKE_VOID_FUNC(alarm_manager_call_alarm_set_time_with_propagation_delay, AlarmManager*, guint, guint, guint, guint, GCancellable*, GAsyncReadyCallback, gpointer); +DEFINE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_update_sync, AlarmManager*, gint, gint, gint, gint, gint, gint, gint, gint, gint, gint, gint, gint, gint, gint, gint, gint*, GCancellable*, GError**); +DEFINE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_set_global_sync, AlarmManager*, gint, gboolean, gint*, GCancellable*, GError**); +DEFINE_FAKE_VALUE_FUNC(gboolean, alarm_manager_call_alarm_get_global_sync, AlarmManager*, gint, gboolean*, gint*, GCancellable*, GError**); + +/* glib_fake.h */ +DEFINE_FAKE_VALUE_FUNC(GVariant*, g_dbus_connection_call_sync, GDBusConnection*, + const gchar*, const gchar*, const gchar*, const gchar*, GVariant*, + const GVariantType*, GDBusCallFlags, gint, GCancellable*, GError**); +DEFINE_FAKE_VALUE_FUNC(const gchar*, g_dbus_method_invocation_get_sender, GDBusMethodInvocation*); +DEFINE_FAKE_VOID_FUNC3_VARARG(g_variant_get, GVariant*, const gchar*, ...); +DEFINE_FAKE_VALUE_FUNC3_VARARG(gboolean, g_variant_iter_loop, GVariantIter*, const gchar*, ...); +DEFINE_FAKE_VOID_FUNC(g_variant_iter_free, GVariantIter*); +DEFINE_FAKE_VOID_FUNC(g_variant_unref, GVariant*); +DEFINE_FAKE_VALUE_FUNC2_VARARG(GVariant*, g_variant_new, const gchar*, ...); +DEFINE_FAKE_VALUE_FUNC(gpointer, g_hash_table_lookup, GHashTable*, gconstpointer); +DEFINE_FAKE_VALUE_FUNC(guint, g_hash_table_foreach_remove, GHashTable*, + GHRFunc, gpointer); +DEFINE_FAKE_VALUE_FUNC(gboolean, g_hash_table_insert, GHashTable*, + gpointer, gpointer); + +/* aul.h */ +DEFINE_FAKE_VALUE_FUNC(int, aul_app_get_appid_bypid, int, char*, int); + +/* notification.h */ +DEFINE_FAKE_VALUE_FUNC(notification_h, notification_create, notification_type_e); +DEFINE_FAKE_VALUE_FUNC(GVariant*, notification_ipc_make_gvariant_from_noti, notification_h, bool); + +/* cynara_fake.h */ +DEFINE_FAKE_VALUE_FUNC(int, cynara_initialize, cynara**, + const cynara_configuration*); +DEFINE_FAKE_VALUE_FUNC(int, cynara_creds_gdbus_get_user, GDBusConnection*, + const gchar*, enum cynara_user_creds, gchar **); +DEFINE_FAKE_VALUE_FUNC(int, cynara_creds_gdbus_get_client, GDBusConnection*, + const gchar*, enum cynara_client_creds, gchar **); +DEFINE_FAKE_VALUE_FUNC(char*, cynara_session_from_pid, pid_t); +DEFINE_FAKE_VALUE_FUNC(int, cynara_check, cynara*, const char*, const char*, + const char*, const char*); + diff --git a/unittest/mock/mock.h b/unittest/mock/mock.h new file mode 100644 index 0000000..0a8cab4 --- /dev/null +++ b/unittest/mock/mock.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019 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. + */ + +#ifndef MOCK_MOCK_H__ +#define MOCK_MOCK_H__ + +#include "fff.h" + +#endif // MOCK_MOCK_H__ diff --git a/unittest/mock/notification_fake.h b/unittest/mock/notification_fake.h new file mode 100644 index 0000000..28e86f2 --- /dev/null +++ b/unittest/mock/notification_fake.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019 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. + */ + +#ifndef MOCK_NOTIFICATION_H_ +#define MOCK_NOTIFICATION_H_ + +#include <glib.h> +#include <notification.h> +#include <notification_ipc.h> + +#include "mock.h" + +DECLARE_FAKE_VALUE_FUNC(notification_h, notification_create, notification_type_e); +DECLARE_FAKE_VALUE_FUNC(GVariant*, notification_ipc_make_gvariant_from_noti, + notification_h, bool); + +#endif //MOCK_NOTIFICATION_H_ diff --git a/unittest/unittest.cpp b/unittest/unittest.cpp new file mode 100755 index 0000000..e214950 --- /dev/null +++ b/unittest/unittest.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2019 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 <gmock/gmock.h> +#include <gtest/gtest.h> +#include <unistd.h> + +#include "unittest.h" + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + + return RUN_ALL_TESTS(); +} + diff --git a/unittest/unittest.h b/unittest/unittest.h new file mode 100755 index 0000000..a413179 --- /dev/null +++ b/unittest/unittest.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2019 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. + */ +#ifndef __ALARM_MANAGER_UNITTEST_H__ +#define __ALARM_MANAGER_UNITTEST_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <glib.h> + +#ifdef __cplusplus +} +#endif + +#endif //__ALARM_MANAGER_UNITTEST_H__ |